diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 625a3cc8bcd812e91926c2e909a1188ae8016e3e..f1328069a61e844d5332d37f109a949e6e902e20 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,11 +24,14 @@ variables: - 'ivas-conformance' - 'ivas-conformance-linux' - 'check-float-reference' + - 'check-clipping' - 'test-branch-vs-input-passthrough' + GIT_CLEAN_FLAGS: -ffdxq TESTCASE_TIMEOUT_STV_SANITIZERS: 180 - TESTCASE_TIMEOUT_LTV_SANITIZERS: 1200 + TESTCASE_TIMEOUT_LTV_SANITIZERS: 2400 BASOP_REFERENCE_BRANCH: "ivas-float-update" + SCALE_FACTOR: "3.162" default: @@ -70,6 +73,9 @@ workflow: - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'check-float-reference' variables: IVAS_PIPELINE_NAME: 'check-float-reference: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'check-clipping' + variables: + IVAS_PIPELINE_NAME: 'Check core input clipping: $CI_COMMIT_BRANCH' - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'test-branch-vs-input-passthrough' variables: IVAS_PIPELINE_NAME: 'Pass-through comparison vs input: $CI_COMMIT_BRANCH' @@ -125,6 +131,11 @@ stages: # automatically disable #DEBUGGING macro in options.h using /**/-comment - sed -i.bak -e "s/^[[:space:]]*\(#define[[:space:]]*DEBUGGING\)/\/\*\1\*\//g" lib_com/options.h +.enable-debugging-macro: &enable-debugging-macro +# automatically enable #DEBUGGING macro in options.h using either /**/-comment or //-comment + - sed -i.bak -e "s/\/\*\ *\(#define\ *DEBUGGING\ *\)\*\//\1/g" lib_com/options.h + - sed -i.bak -e "s/\/\/\ *\(#define\ *DEBUGGING\ *\)/\1/g" lib_com/options.h + .merge-request-comparison-setup-codec: &merge-request-comparison-setup-codec ### build test binaries, initial clean for paranoia reasons - *disable-debugging-macro @@ -268,6 +279,7 @@ stages: when: never - if: $MANUAL_PIPELINE_TYPE == 'check-float-reference' when: never + - if: $MANUAL_PIPELINE_TYPE == 'check-clipping' - if: $MANUAL_PIPELINE_TYPE == 'test-branch-vs-input-passthrough' when: never - when: on_success @@ -1644,6 +1656,36 @@ test-long-self-test: junit: - report-junit-ltv.xml +check-clipping: + tags: + - ivas-linux + stage: test + timeout: "30 minutes" + rules: + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'check-clipping' + allow_failure: + exit_codes: + - 123 + script: + - *print-common-info + - *enable-debugging-macro + - make -j + - tests/scale_pcm.py ./scripts/testv/ $SCALE_FACTOR # Default: 3.162 (+10 dB). Can be set in manual trigger. + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --update_ref 1 --html=report.html --self-contained-html --junit-xml=report-junit.xml --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec + - python3 scripts/parse_xml_report.py report-junit.xml report.csv --clipping + artifacts: + name: "check-clipping--sha-$CI_COMMIT_SHORT_SHA--results" + when: always + expire_in: 2 weeks + paths: + - report-junit.xml + - report.html + - report.csv + expose_as: "check-clipping results" + reports: + junit: + - report-junit.xml + test-branch-vs-input-passthrough: tags: - ivas-linux @@ -1679,6 +1721,7 @@ test-branch-vs-input-passthrough: junit: - report-junit.xml + # --------------------------------------------------------------- # Scheduled jobs on main # --------------------------------------------------------------- diff --git a/apps/decoder.c b/apps/decoder.c index 681939cde2dedc8cf76c3c687b73e017e61ac654..c2c64e6ade11b3a284ff2198d2184b831001c152 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -54,11 +54,6 @@ #include "debug.h" #endif #include "wmc_auto.h" -#ifdef OBJ_EDITING_API -#ifdef OBJ_EDITING_EXAMPLE -#include -#endif -#endif #define WMC_TOOL_SKIP @@ -155,12 +150,33 @@ typedef struct AcousticEnvironmentSequence aeSequence; bool dpidEnabled; uint16_t directivityPatternId[IVAS_MAX_NUM_OBJECTS]; -#ifdef OBJ_EDITING_EXAMPLE +#ifdef OBJ_EDITING_COMMANDLINE bool objEditEnabled; #endif } DecArguments; +#ifdef FIX_HRTF_LOAD +typedef struct +{ + hrtfFileReader *hrtfReader; + char *hrtfFileName; + + IVAS_DEC_HRTF_HANDLE *hHrtfTD; + IVAS_DEC_HRTF_CREND_HANDLE *hSetOfHRTF; + IVAS_DEC_HRTF_STATISTICS_HANDLE *hHrtfStatistics; + + IVAS_BIN_RENDERER_TYPE binaural_renderer; + IVAS_BIN_RENDERER_TYPE binaural_renderer_old; + IVAS_BIN_RENDERER_TYPE binaural_renderer_sec; + IVAS_BIN_RENDERER_TYPE binaural_renderer_sec_old; + + IVAS_AUDIO_CONFIG intern_audio_config; + int16_t room_reverb_flag; + +} IVAS_DEC_HRTF_BINARY_WRAPPER; + +#endif /*------------------------------------------------------------------------------------------* * Local functions prototypes @@ -168,14 +184,23 @@ typedef struct static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); static void usage_dec( void ); +#ifdef FIX_HRTF_LOAD +static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec ); +static ivas_error IVAS_DEC_LoadHrtfFromFile( IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, IVAS_DEC_HANDLE hIvasDec, const int32_t output_Fs ); +#else static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec ); - +#endif #ifdef DEBUGGING static ivas_error printBitstreamInfoVoip( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec ); static int16_t app_own_random( int16_t *seed ); static IVAS_DEC_FORCED_REND_MODE parseForcedRendModeDec( char *forcedRendModeChar ); #endif +#ifdef OBJ_EDITING_EXAMPLE +static void do_object_editing( IVAS_EDITABLE_PARAMETERS *editableParameters ); +#endif + /*------------------------------------------------------------------------------------------* * main() @@ -205,9 +230,13 @@ int main( RenderConfigReader *renderConfigReader = NULL; int16_t *pcmBuf = NULL; IVAS_RENDER_FRAMESIZE asked_frame_size; +#ifdef FIX_HRTF_LOAD + IVAS_DEC_HRTF_BINARY_WRAPPER hHrtfBinary; +#else IVAS_DEC_HRTF_HANDLE *hHrtfTD = NULL; IVAS_DEC_HRTF_CREND_HANDLE *hSetOfHRTF = NULL; IVAS_DEC_HRTF_STATISTICS_HANDLE *hHrtfStatistics = NULL; +#endif #ifdef DEBUGGING int32_t noClipping; int32_t cnt_frames_limited; @@ -224,6 +253,12 @@ int main( reset_mem( USE_BYTES ); #endif +#ifdef FIX_HRTF_LOAD + hHrtfBinary.hHrtfTD = NULL; /* just to avoid compilation warning */ + hHrtfBinary.hSetOfHRTF = NULL; /* just to avoid compilation warning */ + hHrtfBinary.hHrtfStatistics = NULL; /* just to avoid compilation warning */ +#endif + splitRendBits.bits_buf = splitRendBitsBuf; /*------------------------------------------------------------------------------------------* @@ -408,27 +443,6 @@ int main( } } -#ifndef FIX_1158_FASTCONV_REVERB_HRTF - /*------------------------------------------------------------------------------------------* - * Open renderer configuration reader file - *------------------------------------------------------------------------------------------*/ - - if ( arg.renderConfigEnabled ) - { - /* sanity check */ - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && arg.non_diegetic_pan_enabled == false ) - { - fprintf( stderr, "\nError: Renderer configuration file cannot be used in this output configuration.\n\n" ); - goto cleanup; - } - - if ( ( error = RenderConfigReader_open( arg.renderConfigFilename, &renderConfigReader ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError: Can't open Renderer configuration file %s \n\n", arg.renderConfigFilename ); - goto cleanup; - } - } -#endif /*------------------------------------------------------------------------------------------* * Configure the decoder @@ -437,8 +451,13 @@ int main( asked_frame_size = arg.renderFramesize; uint16_t aeID = arg.aeSequence.count > 0 ? arg.aeSequence.pID[0] : 65535; +#ifdef OBJ_EDITING_COMMANDLINE + if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.tsmEnabled, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.non_diegetic_pan_enabled, arg.non_diegetic_pan_gain, + arg.dpidEnabled, aeID, arg.objEditEnabled, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.tsmEnabled, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.non_diegetic_pan_enabled, arg.non_diegetic_pan_gain, arg.dpidEnabled, aeID, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -591,15 +610,11 @@ int main( } } #else -#ifdef FIX_VOIP_FUNCTIONS if ( ( error = IVAS_DEC_PrintConfig( hIvasDec, 1, arg.voipMode ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_PrintConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } -#else - IVAS_DEC_PrintConfig( hIvasDec, 1, arg.voipMode ); -#endif #endif /*-------------------------------------------------------------------* @@ -624,13 +639,11 @@ int main( goto cleanup; } -#ifdef FIX_1158_FASTCONV_REVERB_HRTF if ( ( error = RenderConfigReader_open( arg.renderConfigFilename, &renderConfigReader ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError: Can't open Renderer configuration file %s \n\n", arg.renderConfigFilename ); goto cleanup; } -#endif if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) { @@ -731,6 +744,14 @@ int main( if ( arg.hrtfReaderEnabled ) { +#ifdef FIX_HRTF_LOAD + hHrtfBinary.hrtfReader = hrtfReader; + hHrtfBinary.hrtfFileName = arg.hrtfFileName; + hHrtfBinary.binaural_renderer = IVAS_BIN_RENDERER_TYPE_NONE; + hHrtfBinary.binaural_renderer_sec = IVAS_BIN_RENDERER_TYPE_NONE; + hHrtfBinary.room_reverb_flag = 0; + hHrtfBinary.intern_audio_config = IVAS_AUDIO_CONFIG_INVALID; +#else if ( ( error = IVAS_DEC_GetHrtfHandle( hIvasDec, &hHrtfTD ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_GetHrtfHandle failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -827,6 +848,7 @@ int main( destroy_hrtf_statistics( hHrtfStatistics ); } } +#endif } /*------------------------------------------------------------------------------------------* @@ -848,11 +870,19 @@ int main( if ( arg.voipMode ) { +#ifdef FIX_HRTF_LOAD + error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec ); +#else error = decodeVoIP( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec ); +#endif } else { +#ifdef FIX_HRTF_LOAD + error = decodeG192( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, &splitRendBits, hIvasDec, pcmBuf ); +#else error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, &splitRendBits, hIvasDec, pcmBuf ); +#endif } if ( error == IVAS_ERR_OK || error == IVAS_ERR_END_OF_FILE ) @@ -868,7 +898,11 @@ int main( } else { +#ifdef FIX_HRTF_LOAD + fprintf( stderr, "\nDecoding finished prematurely: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); +#else fprintf( stdout, "Decoding finished prematurely\n\n" ); +#endif goto cleanup; } @@ -904,6 +938,11 @@ cleanup: #endif if ( arg.hrtfReaderEnabled ) { +#ifdef FIX_HRTF_LOAD + destroy_td_hrtf( hHrtfBinary.hHrtfTD ); + destroy_SetOfHRTF( hHrtfBinary.hSetOfHRTF ); + destroy_hrtf_statistics( hHrtfBinary.hHrtfStatistics ); +#else IVAS_DEC_GetHrtfHandle( hIvasDec, &hHrtfTD ); destroy_td_hrtf( hHrtfTD ); @@ -912,6 +951,7 @@ cleanup: IVAS_DEC_GetHrtfStatisticsHandle( hIvasDec, &hHrtfStatistics ); destroy_hrtf_statistics( hHrtfStatistics ); +#endif } IVAS_DEC_Close( &hIvasDec ); @@ -1119,11 +1159,10 @@ static bool parseCmdlIVAS_dec( arg->directivityPatternId[i] = 65535; } -#ifdef OBJ_EDITING_EXAMPLE +#ifdef OBJ_EDITING_COMMANDLINE arg->objEditEnabled = false; -#endif - +#endif /*-----------------------------------------------------------------* * Initialization *-----------------------------------------------------------------*/ @@ -1576,8 +1615,7 @@ static bool parseCmdlIVAS_dec( i += tmp; } - -#ifdef OBJ_EDITING_EXAMPLE +#ifdef OBJ_EDITING_COMMANDLINE else if ( strcmp( argv_to_upper, "-OBJ_EDIT" ) == 0 ) { arg->objEditEnabled = true; @@ -1785,13 +1823,13 @@ static void usage_dec( void ) fprintf( stdout, "-aeid ID | File : Acoustic environment ID (number > 0)\n" ); fprintf( stdout, " alternatively, it can be a text file where each line contains \"ID duration\"\n" ); fprintf( stdout, " for BINAURAL_ROOM_REVERB output configuration.\n" ); +#ifdef OBJ_EDITING_COMMANDLINE + fprintf( stdout, "-obj_edit : Enable objects editing\n" ); +#endif fprintf( stdout, "-level level : Complexity level, level = (1, 2, 3), will be defined after characterisation. \n" ); fprintf( stdout, " Currently, all values default to level 3 (full functionality).\n" ); fprintf( stdout, "-q : Quiet mode, no frame counter\n" ); fprintf( stdout, " default is deactivated\n" ); -#ifdef OMASA_OBJECT_EDITING - fprintf( stdout, "-obj_edit : enable object editing\n" ); -#endif #ifdef DEBUG_MODE_INFO #ifdef DEBUG_MODE_INFO_TWEAK fprintf( stdout, "-info : specify subfolder name for debug output\n" ); @@ -2104,6 +2142,9 @@ static ivas_error initOnFirstGoodFrame( static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, +#ifdef FIX_HRTF_LOAD + IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, +#endif RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, @@ -2159,10 +2200,6 @@ static ivas_error decodeG192( return error; } -#ifdef OBJ_EDITING_API - IVAS_EDITABLE_PARAMETERS editableParameters; -#endif - IVAS_RENDER_CONFIG_DATA renderConfig; RenderConfigReader *renderConfigReader = NULL; @@ -2463,6 +2500,10 @@ static ivas_error decodeG192( } } #endif +#ifdef FIX_HRTF_LOAD + /* Feed into decoder and decode transport channels */ + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, bit_stream, num_bits, bfi ) ) != IVAS_ERR_OK ) +#else /* Feed into decoder */ if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, bit_stream, num_bits, bfi #ifdef OBJ_EDITING_API @@ -2471,79 +2512,77 @@ static ivas_error decodeG192( splitRendBits #endif ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError: could not feed frame to decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } -#ifdef OBJ_EDITING_API -#ifdef OBJ_EDITING_EXAMPLE - if ( arg.objEditEnabled ) + +#ifdef FIX_HRTF_LOAD + /* Read main parameters from the bitstream to set-up the decoder */ + hHrtfBinary->binaural_renderer_old = hHrtfBinary->binaural_renderer; + hHrtfBinary->binaural_renderer_sec_old = hHrtfBinary->binaural_renderer_sec; + if ( ( error = IVAS_DEC_ReadFormat( hIvasDec, &hHrtfBinary->binaural_renderer, &hHrtfBinary->binaural_renderer_sec, &hHrtfBinary->room_reverb_flag, &hHrtfBinary->intern_audio_config ) ) != IVAS_ERR_OK ) { + return error; + } - /* Do object info editing here */ - /* get object parameters */ - if ( ( error = IVAS_DEC_GetEditableParameters( hIvasDec, &editableParameters ) ) != IVAS_ERR_OK ) + /* Placeholder for memory reallocation */ + /* ... */ + + /* Load HRTF binary file data */ + if ( arg.hrtfReaderEnabled ) + { + if ( ( error = IVAS_DEC_LoadHrtfFromFile( hHrtfBinary, hIvasDec, arg.output_Fs ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nError: could not get the editable parameters: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nIVAS_DEC_LoadHrtfFromFile failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } + } - /* edit object parameters...*/ - - /* put the objects equally spaced at the horizontal plane */ - /* and play a little bit with the gains... */ - int16_t obj_idx, non_diegetic_obj_idx; - int16_t num_nondiegetic_objects; + /* decode transport channels, do TSM and feed to renderer */ + if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, isSplitRend, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } - num_nondiegetic_objects = 0; - for ( obj_idx = 0; obj_idx < editableParameters.num_obj; obj_idx++ ) - { - if ( !editableParameters.ism_metadata[obj_idx].non_diegetic_flag ) - { - num_nondiegetic_objects++; - } - } - if ( num_nondiegetic_objects ) - { - float start_angle, angle_inc; - angle_inc = 360.0f / (float) num_nondiegetic_objects; - start_angle = angle_inc / 2.0f; - for ( obj_idx = 0, non_diegetic_obj_idx = 0; obj_idx < editableParameters.num_obj; obj_idx++ ) - { - if ( !editableParameters.ism_metadata[obj_idx].non_diegetic_flag ) - { - editableParameters.ism_metadata[obj_idx].elevation = 0.0f; - editableParameters.ism_metadata[obj_idx].azimuth = start_angle + (float) non_diegetic_obj_idx * angle_inc; - non_diegetic_obj_idx++; - } - } - } +#endif +#ifdef OBJ_EDITING_API + /* Object metadata editing */ + if ( arg.objEditEnabled ) + { + IVAS_EDITABLE_PARAMETERS editableParameters; - /* breakover object gains */ - for ( obj_idx = 0; obj_idx < editableParameters.num_obj; obj_idx++ ) + /* get object parameters */ + if ( ( error = IVAS_DEC_GetEditableParameters( hIvasDec, &editableParameters ) ) != IVAS_ERR_OK ) { - editableParameters.ism_metadata[obj_idx].gain = 0.5f + (float) ( ( frame + obj_idx * 50 ) % 250 ) / 250.0f; + fprintf( stderr, "\nError: could not get the editable parameters: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + return error; } - editableParameters.gain_bed = 0.5f; + /* Do object metadata editing here ... */ +#ifdef OBJ_EDITING_EXAMPLE + do_object_editing( &editableParameters ); - /* set new object parameters*/ +#endif + /* set new object parameters */ if ( ( error = IVAS_DEC_SetEditableParameters( hIvasDec, editableParameters ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError: could not set the editable parameters: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; + return error; } } -#endif + /* Do the final preparations needed for rendering */ if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError: could not prepare the renderer: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } -#endif } +#endif + /* Render */ if ( isSplitRend ) { if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBits, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) @@ -2557,14 +2596,24 @@ static ivas_error decodeG192( } else { - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, IVAS_DEC_PCM_INT16, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) +#ifdef OBJ_EDITING_API + if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesToRender, IVAS_DEC_PCM_INT16, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nError in IVAS_DEC_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nError in IVAS_DEC_GetSamplesRenderer(): %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } +#else + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, IVAS_DEC_PCM_INT16, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } +#endif + nSamplesRendered += nSamplesRendered_loop; nSamplesToRender -= nSamplesRendered_loop; } + if ( needNewFrame ) { frame++; @@ -3041,6 +3090,9 @@ static ivas_error writeJbmTraceFileFrameWrapper( const void *data, void *writer static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, +#ifdef FIX_HRTF_LOAD + IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, +#endif RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, @@ -3091,6 +3143,10 @@ static ivas_error decodeVoIP( int16_t vec_pos_update, vec_pos_len; int16_t nOutSamples = 0; +#ifdef FIX_HRTF_LOAD + bool bitstreamReadDone = false; +#endif + #ifdef OBJ_EDITING_API bool parameterAvailableForEditing = false; uint16_t nSamplesRendered = 0; @@ -3381,30 +3437,90 @@ static ivas_error decodeVoIP( while ( nSamplesRendered < nOutSamples ) { #endif - #ifdef SUPPORT_JBM_TRACEFILE - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter +#ifdef FIX_HRTF_LOAD #ifdef OBJ_EDITING_API - , - &nSamplesRendered, ¶meterAvailableForEditing + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, &nSamplesRendered, ¶meterAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, systemTime_ms ) ) != IVAS_ERR_OK ) +#endif +#else +#ifdef OBJ_EDITING_API + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &nSamplesRendered, ¶meterAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, writeJbmTraceFileFrameWrapper, jbmTraceWriter, systemTime_ms ) ) != IVAS_ERR_OK ) +#endif +#endif +#else +#ifdef FIX_HRTF_LOAD +#ifdef OBJ_EDITING_API + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &bitstreamReadDone, &nSamplesRendered, ¶meterAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &bitstreamReadDone, systemTime_ms ) ) != IVAS_ERR_OK ) #endif - ) ) != IVAS_ERR_OK ) #else - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, &nSamplesRendered, ¶meterAvailableForEditing #ifdef OBJ_EDITING_API - & nSamplesRendered, - ¶meterAvailableForEditing + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, &nSamplesRendered, ¶meterAvailableForEditing ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) +#endif #endif - ) ) != IVAS_ERR_OK ) #endif { fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } +#ifdef FIX_HRTF_LOAD + + if ( bitstreamReadDone == true ) + { + /* Read main parameters from the bitstream to set-up the decoder */ + hHrtf->binaural_renderer_old = hHrtf->binaural_renderer; + hHrtf->binaural_renderer_sec_old = hHrtf->binaural_renderer_sec; + if ( ( error = IVAS_DEC_ReadFormat( hIvasDec, &hHrtf->binaural_renderer, &hHrtf->binaural_renderer_sec, &hHrtf->room_reverb_flag, &hHrtf->intern_audio_config ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Placeholder for memory reallocation */ + /* ... */ + + /* Load HRTF binary file data */ + if ( arg.hrtfReaderEnabled ) + { + if ( ( error = IVAS_DEC_LoadHrtfFromFile( hHrtf, hIvasDec, arg.output_Fs ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_LoadHrtfFromFile failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + } + +#endif #ifdef OBJ_EDITING_API - if ( parameterAvailableForEditing == true ) + /* Object metadata editing */ + if ( arg.objEditEnabled && parameterAvailableForEditing == true ) { - /* do the object editing here */ + IVAS_EDITABLE_PARAMETERS editableParameters; + + /* get object parameters */ + if ( ( error = IVAS_DEC_GetEditableParameters( hIvasDec, &editableParameters ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not get the editable parameters: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + return error; + } + + /* Do object metadata editing here ... */ +#ifdef OBJ_EDITING_EXAMPLE + do_object_editing( &editableParameters ); + +#endif + /* set new object parameters */ + if ( ( error = IVAS_DEC_SetEditableParameters( hIvasDec, editableParameters ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not set the editable parameters: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + return error; + } } } /* while ( nSamplesRendered < nOutSamples ) */ #endif @@ -3690,6 +3806,60 @@ cleanup: return error; } +#ifdef OBJ_EDITING_EXAMPLE + +/*---------------------------------------------------------------------* + * do_object_editing() + * + * Example function to edit objects parameters + *---------------------------------------------------------------------*/ + +static void do_object_editing( + IVAS_EDITABLE_PARAMETERS *editableParameters ) +{ + /* put the objects equally spaced at the horizontal plane */ + /* and play a little bit with the gains... */ + int16_t obj_idx, non_diegetic_obj_idx; + int16_t num_nondiegetic_objects; + + num_nondiegetic_objects = 0; + for ( obj_idx = 0; obj_idx < editableParameters->num_obj; obj_idx++ ) + { + if ( !editableParameters->ism_metadata[obj_idx].non_diegetic_flag ) + { + num_nondiegetic_objects++; + } + } + + if ( num_nondiegetic_objects ) + { + float start_angle, angle_inc; + angle_inc = 360.0f / (float) num_nondiegetic_objects; + start_angle = angle_inc / 2.0f; + for ( obj_idx = 0, non_diegetic_obj_idx = 0; obj_idx < editableParameters->num_obj; obj_idx++ ) + { + if ( !editableParameters->ism_metadata[obj_idx].non_diegetic_flag ) + { + editableParameters->ism_metadata[obj_idx].elevation = 0.0f; + editableParameters->ism_metadata[obj_idx].azimuth = start_angle + (float) non_diegetic_obj_idx * angle_inc; + non_diegetic_obj_idx++; + } + } + } + + /* breakover object gains */ + for ( obj_idx = 0; obj_idx < editableParameters->num_obj; obj_idx++ ) + { + editableParameters->ism_metadata[obj_idx].gain = 0.5f + (float) ( ( frame + obj_idx * 50 ) % 250 ) / 250.0f; + } + + editableParameters->gain_bed = 0.5f; + + + return; +} + +#endif #ifdef DEBUGGING @@ -3715,4 +3885,182 @@ static IVAS_DEC_FORCED_REND_MODE parseForcedRendModeDec( } #endif +#ifdef FIX_HRTF_LOAD + +/*---------------------------------------------------------------------* + * IVAS_DEC_LoadHrtfFromFile() + * + * + *---------------------------------------------------------------------*/ + +static ivas_error IVAS_DEC_LoadHrtfFromFile( + IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, + IVAS_DEC_HANDLE hIvasDec, + const int32_t output_Fs ) +{ + ivas_error error; + IVAS_BIN_RENDERER_TYPE binaural_renderer, binaural_renderer_sec; + + if ( hHrtfBinary == NULL || hIvasDec == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + binaural_renderer = hHrtfBinary->binaural_renderer; + binaural_renderer_sec = hHrtfBinary->binaural_renderer_sec; + + if ( ( binaural_renderer != hHrtfBinary->binaural_renderer_old ) || + ( binaural_renderer_sec != hHrtfBinary->binaural_renderer_sec_old ) || + ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + { + /*------------------------------------------------------------------------------------------* + * Release HRTF binary data + *------------------------------------------------------------------------------------------*/ + + if ( !( binaural_renderer == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && binaural_renderer_sec != IVAS_BIN_RENDERER_TYPE_TDREND && hHrtfBinary->hHrtfTD != NULL ) + { + destroy_td_hrtf( hHrtfBinary->hHrtfTD ); + } + + if ( !( binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && hHrtfBinary->hSetOfHRTF != NULL ) + { + destroy_SetOfHRTF( hHrtfBinary->hSetOfHRTF ); + } + + if ( ( error = IVAS_DEC_HRTF_binary_close( hIvasDec, hHrtfBinary->binaural_renderer_old ) ) != IVAS_ERR_OK ) + { + return error; + } + + /*------------------------------------------------------------------------------------------* + * Load HRTF binary data + *------------------------------------------------------------------------------------------*/ + + if ( ( error = IVAS_DEC_HRTF_binary_open( hIvasDec, binaural_renderer ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = IVAS_DEC_HRTF_binary_open( hIvasDec, binaural_renderer_sec ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer_sec == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) + { + if ( ( error = IVAS_DEC_GetHrtfHandle( hIvasDec, &hHrtfBinary->hHrtfTD ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetHrtfHandle failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + return error; + } + + if ( ( error = load_HRTF_binary( *hHrtfBinary->hHrtfTD, hHrtfBinary->hrtfReader ) ) != IVAS_ERR_OK ) + { + if ( error != IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA ) + { + fprintf( stderr, "\nError in loading HRTF binary file %s \n\n", hHrtfBinary->hrtfFileName ); + return error; + } + else + { + destroy_td_hrtf( hHrtfBinary->hHrtfTD ); + } + } + } + + if ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) + { + if ( ( error = IVAS_DEC_GetHrtfCRendHandle( hIvasDec, &hHrtfBinary->hSetOfHRTF ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetHrtfCRendHandle failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + return error; + } + + if ( ( error = create_SetOfHRTF_from_binary( *hHrtfBinary->hSetOfHRTF, hHrtfBinary->hrtfReader, output_Fs ) ) != IVAS_ERR_OK ) + { + if ( error != IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA ) + { + fprintf( stderr, "\nError in loading HRTF binary file %s \n\n", hHrtfBinary->hrtfFileName ); + return error; + } + else + { + destroy_SetOfHRTF( hHrtfBinary->hSetOfHRTF ); + } + } + } + + if ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) + { + IVAS_DEC_HRTF_FASTCONV_HANDLE *hHrtfFastConv = NULL; + if ( ( error = IVAS_DEC_GetHrtfFastConvHandle( hIvasDec, &hHrtfFastConv ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetHrtfFastConvHandle failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + return error; + } + + if ( ( error = load_fastconv_HRTF_from_binary( *hHrtfFastConv, hHrtfBinary->room_reverb_flag, hHrtfBinary->intern_audio_config, hHrtfBinary->hrtfReader ) ) != IVAS_ERR_OK ) + { + if ( error != IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA ) + { + fprintf( stderr, "\nError in loading HRTF binary file %s \n\n", hHrtfBinary->hrtfFileName ); + return error; + } + else + { + destroy_fastconv_hrtf( hHrtfFastConv ); + } + } + } + + if ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) + { + IVAS_DEC_HRTF_PARAMBIN_HANDLE *hHrtfParambin = NULL; + if ( ( error = IVAS_DEC_GetHrtfParamBinHandle( hIvasDec, &hHrtfParambin ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetHrtfParamBinHandle failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + return error; + } + + if ( ( error = load_parambin_HRTF_from_binary( *hHrtfParambin, hHrtfBinary->hrtfReader ) ) != IVAS_ERR_OK ) + { + if ( error != IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA ) + { + fprintf( stderr, "\nError in loading HRTF binary file %s \n\n", hHrtfBinary->hrtfFileName ); + return error; + } + else + { + destroy_parambin_hrtf( hHrtfParambin ); + } + } + } + } + + if ( hHrtfBinary->hHrtfStatistics == NULL ) + { + if ( ( error = IVAS_DEC_GetHrtfStatisticsHandle( hIvasDec, &hHrtfBinary->hHrtfStatistics ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetHrtfHandle failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + return error; + } + + if ( ( error = load_reverb_binary( *hHrtfBinary->hHrtfStatistics, output_Fs, hHrtfBinary->hrtfReader ) ) != IVAS_ERR_OK ) + { + if ( error != IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA ) + { + fprintf( stderr, "\nError in loading HRTF binary file %s \n\n", hHrtfBinary->hrtfFileName ); + return error; + } + else + { + destroy_hrtf_statistics( hHrtfBinary->hHrtfStatistics ); + } + } + } + + return IVAS_ERR_OK; +} +#endif + #undef WMC_TOOL_SKIP diff --git a/apps/encoder.c b/apps/encoder.c index f64986ec84806593f683db4f9412aa275b7ede47..4caa60803d8cad63471931608cc2cb2e719d65b9 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -195,6 +195,8 @@ int main( #ifdef DEBUG_SBA int16_t numTransportChannels = 1; #endif + int32_t noClipping; + float maxOverload, minOverload; #endif #ifdef DEBUGGING @@ -792,6 +794,12 @@ int main( } #ifdef DEBUGGING + if ( ( noClipping = IVAS_ENC_GetNoCLipping( hIvasEnc, &maxOverload, &minOverload ) ) > 0 ) + { + fprintf( stdout, "Core input overload detected: %d samples!!!\n", noClipping ); + fprintf( stdout, "Max overload value: %f \n", maxOverload ); + fprintf( stdout, "Min overload value: %f \n\n", minOverload ); + } print_snr(); #endif /*------------------------------------------------------------------------------------------* diff --git a/apps/renderer.c b/apps/renderer.c index 5ca8e170fee5554f950ba63aab073fd94fef8d02..767d4bb60d6567193d6299324a5d0b86135a0678 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -615,7 +615,11 @@ static int16_t get_cldfb_in_flag( int16_t cldfb_in_flag; cldfb_in_flag = 0; +#ifdef FIX_HRTF_LOAD + if ( renderConfig->split_rend_config.rendererSelection == IVAS_BIN_RENDERER_TYPE_FASTCONV ) +#else if ( renderConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) +#endif { #ifdef DEBUGGING cldfb_in_flag = 1; @@ -945,7 +949,11 @@ int main( goto cleanup; } +#ifdef FIX_HRTF_LOAD + if ( ( error = load_fastconv_HRTF_from_binary( *hHrtfFastConv, 0, IVAS_AUDIO_CONFIG_INVALID, hrtfFileReader ) ) != IVAS_ERR_OK ) +#else if ( ( error = load_fastconv_HRTF_from_binary( *hHrtfFastConv, hrtfFileReader ) ) != IVAS_ERR_OK ) +#endif { if ( error != IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA ) { diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 7890d25379f124b02d8a73255429605fca2bd17a..c0123bf7fdd918b52b30b1677a00bb592adf085e 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -140,6 +140,7 @@ typedef struct _IVAS_EDITABLE_PARAMETERS int16_t num_obj; IVAS_ISM_METADATA ism_metadata[IVAS_MAX_NUM_OBJECTS]; float gain_bed; + } IVAS_EDITABLE_PARAMETERS; #endif @@ -213,6 +214,18 @@ typedef struct _IVAS_JBM_TRACE_DATA } IVAS_JBM_TRACE_DATA; +#ifdef FIX_HRTF_LOAD +typedef enum _ivas_binaural_renderer_type +{ + IVAS_BIN_RENDERER_TYPE_NONE, + IVAS_BIN_RENDERER_TYPE_CREND, + IVAS_BIN_RENDERER_TYPE_FASTCONV, + IVAS_BIN_RENDERER_TYPE_PARAMBIN, + IVAS_BIN_RENDERER_TYPE_TDREND, + IVAS_BIN_RENDERER_TYPE_DEFAULT, + +} IVAS_BIN_RENDERER_TYPE; +#endif /*----------------------------------------------------------------------------------* * Split rendering API constants, structures, and enums @@ -251,6 +264,7 @@ typedef enum } ISAR_SPLIT_REND_CODEC; +#ifndef FIX_HRTF_LOAD typedef enum { ISAR_SPLIT_REND_RENDERER_SELECTION_CREND, @@ -260,6 +274,7 @@ typedef enum ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT, } ISAR_SPLIT_REND_RENDERER_SELECTION; +#endif typedef struct _ISAR_SPLIT_REND_BITS_DATA { @@ -291,7 +306,11 @@ typedef struct _ISAR_SPLIT_REND_CONFIG int16_t codec_frame_size_ms; /* Codec frame size in milliseconds, only relevant with LC3plus */ ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; ISAR_SPLIT_REND_CODEC codec; +#ifdef FIX_HRTF_LOAD + IVAS_BIN_RENDERER_TYPE rendererSelection; +#else ISAR_SPLIT_REND_RENDERER_SELECTION rendererSelection; +#endif int16_t lc3plus_highres; } ISAR_SPLIT_REND_CONFIG_DATA, *ISAR_SPLIT_REND_CONFIG_HANDLE; diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 105c0e8057fc08f9b1f63be8e0b0aa4d3fc8771d..4e6ad47f249fe7551212aed8faafc94327e2836c 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -233,7 +233,11 @@ typedef enum #define SID_MDCT_STEREO 0x1 /* 1| 0| 0 */ #define SID_ISM 0x2 /* 0| 1| 0 */ #define SID_MASA_1TC 0x3 /* 1| 1| 0 */ +#ifdef FIX_1209_SID_SIGNALING +/*reserved*/ /*0x4*/ /* 0| 0| 1 */ +#else #define SID_MULTICHANNEL 0x4 /* 0| 0| 1 */ +#endif #define SID_SBA_1TC 0x5 /* 1| 0| 1 */ #define SID_SBA_2TC 0x6 /* 0| 1| 1 */ #define SID_MASA_2TC 0x7 /* 1| 1| 1 */ diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 11727c4e5deee06032b2d7ff1b63db8e396058d3..905be753a5a2ef08ae4903c377d0d76666ece15d 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -77,6 +77,9 @@ typedef enum IVAS_ERR_EXT_ORIENTATION_NOT_SUPPORTED, IVAS_ERR_DIRECTIVITY_NOT_SUPPORTED, IVAS_ERR_ACOUSTIC_ENVIRONMENT_NOT_SUPPORTED, +#ifdef OBJ_EDITING_API + IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, +#endif IVAS_ERR_INVALID_HRTF, IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA, IVAS_ERR_INVALID_INPUT_FORMAT, @@ -254,6 +257,10 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) return "Directivity not supported"; case IVAS_ERR_ACOUSTIC_ENVIRONMENT_NOT_SUPPORTED: return "Acoustic environment not supported"; +#ifdef OBJ_EDITING_API + case IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED: + return "Objects editing not supported"; +#endif case IVAS_ERR_INVALID_HRTF: return "Unsupported HRTF filter set"; case IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA: diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 700a9cc75cb2420b0466364d1c2e35169d78cdc8..847cb924f46d5b45aefd38e1009b9e23d6c83248 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -318,11 +318,20 @@ ivas_error ivas_dec( int16_t *data /* o : output synthesis signal */ ); +#ifdef FIX_HRTF_LOAD +ivas_error ivas_dec_get_format( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +#endif ivas_error ivas_dec_setup( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ); ivas_error create_sce_dec( @@ -660,10 +669,13 @@ ivas_error ivas_mc_enc_config( ivas_error ivas_mc_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t idx, /* i : LS config. index */ + const int16_t idx /* i : LS config. index */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ + #endif ); /*! r: MC format mode (MCT, McMASA, ParamMC) */ @@ -810,7 +822,7 @@ void ivas_jbm_dec_feed_tc_to_renderer( ); #ifdef OBJ_EDITING_API -void ivas_jbm_dec_prepare_renderer( +void ivas_dec_prepare_renderer( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); #endif @@ -1024,11 +1036,6 @@ ivas_error ivas_ism_metadata_dec( DEC_CORE_HANDLE st0 /* i : core-coder handle */ ); -#ifdef OBJ_EDITING_API -void ivas_ism_renderer_update_md( - Decoder_Struct *st_ivas /* i/o: main IVAS decoder handle */ -); -#endif /*----------------------------------------------------------------------------------* * Parametric ISM prototypes @@ -1077,10 +1084,13 @@ ivas_error ivas_ism_enc_config( ivas_error ivas_ism_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const ISM_MODE last_ism_mode, /* i/o: last ISM mode */ + const ISM_MODE last_ism_mode /* i/o: last ISM mode */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : number of samples flushed on renderer change*/ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ); ivas_error ivas_param_ism_dec_open( @@ -1099,18 +1109,18 @@ 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 */ + const uint16_t nCldfbSlots, /* i : number of CLDFB slots in transport channels */ float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ ); #ifdef OBJ_EDITING_API void ivas_param_ism_dec_dequant_md( - Decoder_Struct *st_ivas + Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ ); void ivas_param_ism_dec_prepare_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nCldfbSlots /* i : number of CLDFB slots in transport channels */ ); #endif @@ -3471,10 +3481,13 @@ void ivas_sba_set_cna_cng_flag( ); ivas_error ivas_sba_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesFlushed, /* o : number of samples flushed */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ); ivas_error ivas_sba_digest_tc( @@ -3793,7 +3806,7 @@ void ivas_mc_paramupmix_dec_read_BS( void ivas_mc_paramupmix_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 CLDFB slots in transport channels */ const int16_t nSamplesForRendering /* i : number of samples provided */ ); @@ -3863,14 +3876,14 @@ 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 */ - float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output*/ + const uint8_t nCldfbSlots, /* i : number of CLDFB slots in transport channels */ + float *transport_channels_f[] /* i/o: synthesized core-coder transport channels/DirAC output*/ ); #ifdef OBJ_EDITING_API void ivas_param_mc_dec_prepare_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots /* i : number of CLDFB slots in the transport channels */ ); #endif @@ -4929,10 +4942,13 @@ void ivas_masa_enc_reconfigure( ); ivas_error ivas_masa_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ + #endif ); ivas_error ivas_masa_encode( @@ -5609,6 +5625,18 @@ ivas_error ivas_osba_render_sf( float *output_f[] /* o : rendered time signal */ ); +#ifdef OBJ_EDITING_API +void ivas_osba_stereo_add_channels( + float *tc_f[], /* i : transport channels */ + float *output_f[], /* i/o: output channels */ + const float gain, /* i : gain bed value */ + const int16_t nchan_out, /* i : number of output channels */ + const int16_t nchan_ism, /* i : number of ISM channels */ + const int16_t ism_mode, /* i : ISM mode */ + const int16_t n_samples_to_render /* i : output frame length per channel */ +); +#endif + void ivas_osba_data_close( SBA_ISM_DATA_HANDLE *hSbaIsmData /* i/o: OSBA rendering handle */ ); @@ -5617,6 +5645,8 @@ ISM_MODE ivas_osba_ism_mode_select( const int32_t ivas_total_brate, /* i : IVAS total bitrate */ const int16_t nchan_ism /* i : number of input ISM's */ ); + + /*----------------------------------------------------------------------------------* * OMASA prototypes *---------------------------------------------------------------------------------*/ @@ -5634,10 +5664,13 @@ ivas_error ivas_omasa_enc_config( ); ivas_error ivas_omasa_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ); void ivas_omasa_set_config( diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index 549676882135c43141a1b9ece23ce88e0fc490da..d8ec6d0ff59ea41017c4a8b52633b74886f5daf2 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -1257,7 +1257,11 @@ static void ivas_calc_mat_inv( int16_t sign = 1; ivas_calc_mat_det( dbl_in_re, dim, &det_re ); +#ifdef NONBE_FIX_1213_SBA_DET_MAT_INV_3BY3 + det = det_re > 0 ? 1 / max( IVAS_DBL_EPS, det_re ) : 1 / min( det_re, -IVAS_DBL_EPS ); +#else det = det_re > 0 ? 1 / max( IVAS_DBL_EPS, det_re ) : min( det_re, -IVAS_DBL_EPS ); +#endif for ( i = 0; i < dim; i++ ) { diff --git a/lib_com/options.h b/lib_com/options.h index 926960226d1e20bb1c86d359f936e3174c39a9e6..b82706a7eb022af29454c4379f57ddff739baeef 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -157,9 +157,11 @@ #define OBJ_EDITING_INTERFACE /* Interface for object editing */ #ifdef OBJ_EDITING_INTERFACE #define OBJ_EDITING_API /* object editing changes related to the API */ +#define OBJ_EDITING_COMMANDLINE /* obj editing command-line option */ #define OBJ_EDITING_EXAMPLE /* obj editing example code in decoder.c */ #define OMASA_OBJECT_EDITING /* Nokia: object editing interface for OMASA */ #define OBJ_EDITING_PARAMISM_BIN /* Nokia: object editing for ParamISM to binaural */ +#define FIX_BRATE_SWITCHING /* VA: fix bitrate switching cases in OMASA and OSBA */ #endif /* ################### Start BE switches ################################# */ @@ -169,20 +171,34 @@ #define TMP_FIX_1119_SPLIT_RENDERING_VOIP /* FhG: Add error check for unsupported config: split rendering with VoIP mode */ -#define FIX_1158_FASTCONV_REVERB_HRTF /* Philips: issue 1158: Rendering with FastConv to BINAURAL_ROOM_REVERB uses BRIR convolution instead of HRTF */ #define FIX_587_DEFAULT_REVERB /* Philips: issue 587: inconsistent default reverb parameters across renderers */ -#define FIX_VOIP_FUNCTIONS /* VA: fix data type mismatch in IVAS_DEC_VoIP_SetScale() + add sanity checks to API functions */ + +#define FIX_HRTF_LOAD /* VA: issue 1187: fix memory issue when HRTFs are loaded from a binary file */ +#define FIX_1209_SID_SIGNALING /* VA: issue 1209: remove dead code in IVAS SID signaling */ + /* #################### End BE switches ################################## */ /* #################### Start NON-BE switches ############################ */ + +#define NONBE_FIX_1213_SBA_DET_MAT_INV_3BY3 /*Dolby: issue 1213: fix for inverse of det < 0*/ + /* any switch which is non-be wrt selection floating point code */ /* all switches in this category should start with "NONBE_" */ -#define NONBE_FIX_1174_MCMASA_LBR_LOOP_ERROR /* Nokia: Fix issue 1174 by removing the unnecessary inner loop causing problems. */ #define NONBE_FIX_1176_OSBA_REVERB_JBM_ASAN_ERROR /* Ericsson: Issue 1176, fix in TDREND_firfilt for subframes shorter than the filter length */ +#define NONBE_FIX_1197_OMASA_META_BUFFER /* Nokia: OMASA ISM_MASA_MODE_PARAM_ONE_OBJ history zero in rateswitching */ +#define NONBE_FIX_1212_TONAL_MDCT_CONCEALMENT /* FhG: Fix issue 1212, zero IGF spec also in 1st concealed frame */ + + +#define FIX_1139_REV_COLORATION_SHORT_T60 /* Nokia,FhG: Fix issue 1139, prevent sound coloration artefacts at very low reverberation times */ +#define NONBE_FIX_1208_DFT_STEREO_PLC_BURST /* Ericsson: Issue 1208, fix for overflow of sample offset counter for burst error in DFT Stereo PLC. */ +#define FIX_1206_ZERO_OUT_IMDCT_BUFFERS_FOR_MCT_IGNORE /* FhG: zero out all relevant imdct buffers in MCT decoding of channels with mct_chan_mode == MCT_CHAN_MODE_IGNORE */ +#define NONBE_1199_OMASA_JBM_BRATE_SW_FLUSH /* VA: issue 1199: fix bug in renderer flush in OMASA JBM bitrate switching */ +#define NONBE_1200_ISM_JBM_BRATE_SW_FLUSH /* VA: issue 1200: fix bug in renderer flush in ISM JBM bitrate switching */ + /* ##################### End NON-BE switches ########################### */ diff --git a/lib_com/prot.h b/lib_com/prot.h index c8f70bb4fc22ff2de71e2429edccfeb865f51127..1df0eb7838c43f12e504e570a71dbc1474407f8c 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -222,6 +222,17 @@ void mvs2s( const int16_t n /* i : vector size */ ); +#ifdef DEBUGGING +/*! r: number of overload samples */ +uint32_t check_clipping( + const float x[], /* i : input vector */ + const int16_t n, /* i : vector size */ + float *maxOverload, /* i/o: max overload value */ + float *minOverload /* i/o: max overload value */ +); + +#endif +/*! r: number of clipped samples */ uint32_t mvr2s( const float x[], /* i : input vector */ int16_t y[], /* o : output vector */ diff --git a/lib_com/tools.c b/lib_com/tools.c index 9dfa8b9f81bc999cb6770fafc2cba16d6303fd53..b235d5d499d17299577b47a33f41da52aaa7e671 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -373,6 +373,46 @@ void mvs2s( return; } +#ifdef DEBUGGING +/*! r: number of overload samples */ +uint32_t check_clipping( + const float x[], /* i : input vector */ + const int16_t n, /* i : vector size */ + float *maxOverload, /* i/o: max overload value */ + float *minOverload /* i/o: max overload value */ +) +{ + int16_t i; + float temp; + uint32_t noClipping = 0; + + for ( i = 0; i < n; i++ ) + { + temp = x[i]; + + if ( temp >= ( MAX16B_FLT + 0.5f ) ) + { + noClipping++; + if ( temp > *maxOverload ) + { + *maxOverload = temp; + } + } + else if ( temp <= ( MIN16B_FLT - 0.5f ) ) + { + noClipping++; + if ( temp < *minOverload ) + { + *minOverload = temp; + } + } + } + + return noClipping; +} + +#endif +/*! r: number of clipped samples */ uint32_t mvr2s( const float x[], /* i : input vector */ int16_t y[], /* o : output vector */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 7bab860ae7d847696013a3f89593a416840ad3fc..269c6bff981ab0720112b7dd1ffc170c09ff4ed1 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1144,6 +1144,13 @@ ivas_error ivas_binRenderer_open( hBinRenderer->render_lfe = 1; } +#ifdef FIX_HRTF_LOAD + if ( st_ivas->hHrtfFastConv == NULL && st_ivas->hDecoderConfig->Opt_HRTF_binary ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "HRTF binary file present but not used in FastConv renderer" ); + } +#endif + /* Load HRTF tables */ if ( ( error = ivas_binaural_hrtf_open( &st_ivas->hHrtfFastConv, st_ivas->hIntSetup.output_config, st_ivas->renderer_type ) ) != IVAS_ERR_OK ) { @@ -1219,9 +1226,33 @@ ivas_error ivas_binRenderer_open( { #ifdef FIX_587_DEFAULT_REVERB pRoomAcoustics = ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ? &( st_ivas->hRenderConfig->roomAcoustics ) : NULL; - if ( ( error = ivas_binaural_reverb_init( &( hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, hBinRenderer->conv_band, hBinRenderer->timeSlots, pRoomAcoustics, st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtfFastConv->fastconvReverberationTimes, st_ivas->hHrtfFastConv->fastconvReverberationEneCorrections ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_binaural_reverb_init( &( hBinRenderer->hReverb ), + st_ivas->hHrtfStatistics, + hBinRenderer->conv_band, + hBinRenderer->timeSlots, + pRoomAcoustics, + st_ivas->hDecoderConfig->output_Fs, + st_ivas->hHrtfFastConv->fastconvReverberationTimes, + st_ivas->hHrtfFastConv->fastconvReverberationEneCorrections +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + hBinRenderer->earlyPartEneCorrection +#endif + ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_binaural_reverb_init( &( hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, hBinRenderer->conv_band, hBinRenderer->timeSlots, &( st_ivas->hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtfFastConv->fastconvReverberationTimes, st_ivas->hHrtfFastConv->fastconvReverberationEneCorrections ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_binaural_reverb_init( &( hBinRenderer->hReverb ), + st_ivas->hHrtfStatistics, + hBinRenderer->conv_band, + hBinRenderer->timeSlots, + &( st_ivas->hRenderConfig->roomAcoustics ), + st_ivas->hDecoderConfig->output_Fs, + st_ivas->hHrtfFastConv->fastconvReverberationTimes, + st_ivas->hHrtfFastConv->fastconvReverberationEneCorrections +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + hBinRenderer->earlyPartEneCorrection +#endif + ) ) != IVAS_ERR_OK ) #endif { return error; diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 63f3cc026d327b309d856672f04889041192d474..0984693976cbb8908ff984c5fa9693f84e23018b 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -89,6 +89,378 @@ static AUDIO_CONFIG ivas_set_audio_config_from_sba_order( return output_config; } +#ifdef FIX_HRTF_LOAD + +/*---------------------------------------------------------------------* + * ivas_dec_get_format( ) + * + * Read main parameters from the bitstream to set-up the decoder: + * - IVAS format + * - IVAS format specific signaling + *---------------------------------------------------------------------*/ + +ivas_error ivas_dec_get_format( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +) +{ + int16_t k, idx, num_bits_read; + int16_t nchan_ism, element_mode_flag; + int16_t sba_order, sba_planar, sba_analysis_order; + int32_t ivas_total_brate; + uint16_t *bit_stream_orig; + AUDIO_CONFIG signaled_config; +#ifdef FIX_1209_SID_SIGNALING + ivas_error error; +#endif + + num_bits_read = 0; + element_mode_flag = 0; + + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + bit_stream_orig = st_ivas->bit_stream; + + /*-------------------------------------------------------------------* + * Read IVAS format + *-------------------------------------------------------------------*/ + +#ifdef FIX_1209_SID_SIGNALING + if ( ( error = ivas_read_format( st_ivas, &num_bits_read ) ) != IVAS_ERR_OK ) + { + return error; + } +#else + ivas_read_format( st_ivas, &num_bits_read ); +#endif + + if ( st_ivas->ini_frame > 0 && st_ivas->ivas_format != st_ivas->last_ivas_format && + !( st_ivas->ivas_format == MASA_FORMAT && st_ivas->last_ivas_format == MASA_ISM_FORMAT ) && + !( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->last_ivas_format == MASA_FORMAT ) ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } + + /*-------------------------------------------------------------------* + * Read other signaling (ISM/MC mode, number of channels, etc.) + *-------------------------------------------------------------------*/ + + if ( is_DTXrate( ivas_total_brate ) == 0 ) + { + /*-------------------------------------------------------------------* + * Read IVAS format related signaling: + * - in ISM : read number of objects + * - in SBA : read SBA planar flag and SBA order + * - in MASA : read number of TC + * - in MC : read LS setup + *-------------------------------------------------------------------*/ + + if ( st_ivas->ivas_format == STEREO_FORMAT ) + { + element_mode_flag = 1; + } + else if ( st_ivas->ivas_format == ISM_FORMAT ) + { + /* read the number of objects */ + nchan_ism = 1; + k = (int16_t) ( ( ivas_total_brate / FRAMES_PER_SEC ) - 1 ); + while ( st_ivas->bit_stream[k] && nchan_ism < MAX_NUM_OBJECTS ) + { + nchan_ism++; + k--; + } + + if ( st_ivas->ini_frame > 0 && nchan_ism != st_ivas->nchan_ism ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } + + st_ivas->nchan_ism = nchan_ism; + st_ivas->ism_mode = ivas_ism_mode_select( nchan_ism, ivas_total_brate ); + + st_ivas->nchan_transport = nchan_ism; + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + st_ivas->nchan_transport = MAX_PARAM_ISM_WAVE; + } + } + else if ( st_ivas->ivas_format == SBA_FORMAT ) + { + /* read Ambisonic (SBA) planar flag */ + sba_planar = st_ivas->bit_stream[num_bits_read]; + num_bits_read += SBA_PLANAR_BITS; + + if ( st_ivas->ini_frame > 0 && sba_planar != st_ivas->sba_planar ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the SBA planar/3D layout is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong SBA planar flag signalled!" ); + } + + /* read Ambisonic (SBA) order */ + sba_order = st_ivas->bit_stream[num_bits_read + 1]; + sba_order += 2 * st_ivas->bit_stream[num_bits_read]; + + if ( st_ivas->ini_frame > 0 && sba_order != st_ivas->sba_order ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the SBA order is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong SBA order signalled!" ); + } + + sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, sba_order ); + st_ivas->nchan_transport = ivas_get_sba_num_TCs( ivas_total_brate, sba_analysis_order ); + } + else if ( st_ivas->ivas_format == MASA_FORMAT ) + { + /* read number of MASA transport channels */ + if ( st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 1] ) + { + st_ivas->nchan_transport = 2; + element_mode_flag = 1; + } + else + { + st_ivas->nchan_transport = 1; + } + + /* this should be non-zero if original input format was MASA_ISM_FORMAT */ + st_ivas->ism_mode = ISM_MODE_NONE; + nchan_ism = st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 3] + 2 * st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 2]; + + if ( nchan_ism > 0 ) + { + /* the input_ivas_format should be MASA_ISM_FORMAT, but we cannot initialize it now */ + /* info about the number of objects: + '00' - MASA format at the encoder + '01' - MASA_ISM_FORMAT at the encoder, with 4 objects + '10' - MASA_ISM_FORMAT at the encoder, with 3 objects + '11' - MASA_ISM_FORMAT at the encoder, with 1 or 2 objects + reading if 1 or 2 objects is performed later + */ + nchan_ism = 5 - nchan_ism; + if ( st_ivas->nchan_transport == 1 && nchan_ism == 2 ) + { + nchan_ism = 1; + } + + /* for MASA_ISM_FORMAT at input the number of MASA transport channels is always 2 and the corresponding bit is not used here*/ + st_ivas->nchan_transport = 2; + element_mode_flag = 1; + } + + if ( st_ivas->ini_frame > 0 && nchan_ism != st_ivas->nchan_ism ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } + + st_ivas->nchan_ism = nchan_ism; + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + st_ivas->nchan_transport = 2; /* always 2 MASA transport channels */ + + /* the number of objects are written at the end of the bitstream */ + 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, nchan_ism ); + + if ( st_ivas->ini_frame > 0 && nchan_ism != st_ivas->nchan_ism ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } + + st_ivas->nchan_ism = nchan_ism; + } + else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + /* the number of objects is written at the end of the bitstream, in the SBA metadata */ + 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; + + if ( st_ivas->ini_frame > 0 && nchan_ism != st_ivas->nchan_ism ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } + + st_ivas->nchan_ism = nchan_ism; + + /* read Ambisonic (SBA) planar flag */ + /*sba_planar = st_ivas->bit_stream[num_bits_read];*/ + num_bits_read += SBA_PLANAR_BITS; + + /* read Ambisonic (SBA) order (0 for signaling OSBA format at low bitrates)*/ + sba_order = st_ivas->bit_stream[num_bits_read + 1]; + sba_order += 2 * st_ivas->bit_stream[num_bits_read]; + num_bits_read += SBA_ORDER_BITS; + + /* read the real Ambisonic order when the above bits are used to signal OSBA format */ + if ( ivas_total_brate < IVAS_24k4 ) + { + sba_order = st_ivas->bit_stream[num_bits_read + 1]; + sba_order += 2 * st_ivas->bit_stream[num_bits_read]; + num_bits_read += SBA_ORDER_BITS; + } + + if ( st_ivas->ini_frame > 0 && sba_order != st_ivas->sba_order ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the SBA order is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong SBA order signalled!" ); + } + + st_ivas->ism_mode = ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism ); + + sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, sba_order ); + st_ivas->nchan_transport = ivas_get_sba_num_TCs( ivas_total_brate, sba_analysis_order ); + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + /* read MC configuration */ + idx = 0; + for ( k = 0; k < MC_LS_SETUP_BITS; k++ ) + { + if ( st_ivas->bit_stream[num_bits_read + k] ) + { + idx += 1 << ( MC_LS_SETUP_BITS - 1 - k ); + } + } + num_bits_read += MC_LS_SETUP_BITS; + + signaled_config = ivas_mc_map_ls_setup_to_output_config( idx ); + + if ( st_ivas->ini_frame > 0 && st_ivas->transport_config != signaled_config ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Switching of MC configurations is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong MC configuration signalled!" ); + } + + st_ivas->mc_mode = ivas_mc_mode_select( ivas_mc_map_output_config_to_mc_ls_setup( signaled_config ), st_ivas->hDecoderConfig->ivas_total_brate ); + st_ivas->transport_config = signaled_config; + } + + /*-------------------------------------------------------------------* + * Read element mode + *-------------------------------------------------------------------*/ + + if ( st_ivas->ini_frame == 0 && element_mode_flag ) + { + /* read stereo technology info */ + if ( ivas_total_brate < MIN_BRATE_MDCT_STEREO ) + { + /* 1 bit */ + if ( st_ivas->bit_stream[num_bits_read] ) + { + st_ivas->element_mode_init = 1 + IVAS_CPE_DFT; + } + else + { + st_ivas->element_mode_init = 0 + IVAS_CPE_DFT; + } + } + else + { + st_ivas->element_mode_init = IVAS_CPE_MDCT; + } + } + } + else if ( ivas_total_brate == IVAS_SID_5k2 ) + { + switch ( st_ivas->sid_format ) + { + case SID_DFT_STEREO: + st_ivas->element_mode_init = IVAS_CPE_DFT; + break; + case SID_MDCT_STEREO: + st_ivas->element_mode_init = IVAS_CPE_MDCT; + break; + case SID_ISM: + st_ivas->element_mode_init = IVAS_SCE; + break; + case SID_MASA_1TC: + st_ivas->element_mode_init = IVAS_SCE; + st_ivas->nchan_transport = 1; + break; + case SID_MASA_2TC: + if ( st_ivas->bit_stream[ivas_total_brate / FRAMES_PER_SEC - 1 - SID_FORMAT_NBITS] == 1 ) + { + st_ivas->element_mode_init = IVAS_CPE_MDCT; + } + else + { + st_ivas->element_mode_init = IVAS_CPE_DFT; + } + st_ivas->nchan_transport = 2; + break; + case SID_SBA_1TC: + st_ivas->element_mode_init = IVAS_SCE; + break; + case SID_SBA_2TC: + st_ivas->element_mode_init = IVAS_CPE_MDCT; + break; + } + + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + /* read the number of objects */ + nchan_ism = 1; + k = (int16_t) ( ( ivas_total_brate / FRAMES_PER_SEC ) - 1 - SID_FORMAT_NBITS ); + while ( st_ivas->bit_stream[k] && nchan_ism < MAX_NUM_OBJECTS ) + { + nchan_ism++; + k--; + } + k--; + + if ( st_ivas->ini_frame > 0 && nchan_ism != st_ivas->nchan_ism ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Changing the number of ISMs is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong number of objects signalled!" ); + } + + st_ivas->nchan_ism = nchan_ism; + + /* read ism_mode */ + st_ivas->ism_mode = ISM_MODE_DISC; + if ( nchan_ism > 2 ) + { + k -= nchan_ism; /* SID metadata flags */ + idx = st_ivas->bit_stream[k]; + st_ivas->ism_mode = (ISM_MODE) ( idx + 1 ); + } + + st_ivas->nchan_transport = nchan_ism; + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + st_ivas->nchan_transport = MAX_PARAM_ISM_WAVE; + } + } + } + + st_ivas->bit_stream = bit_stream_orig; + + return IVAS_ERR_OK; +} + +#endif /*-------------------------------------------------------------------* * ivas_dec_setup() @@ -97,10 +469,13 @@ static AUDIO_CONFIG ivas_set_audio_config_from_sba_order( *-------------------------------------------------------------------*/ ivas_error ivas_dec_setup( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ) { int16_t k, idx, num_bits_read; @@ -120,7 +495,14 @@ ivas_error ivas_dec_setup( * Read IVAS format *-------------------------------------------------------------------*/ +#ifdef FIX_1209_SID_SIGNALING + if ( ( error = ivas_read_format( st_ivas, &num_bits_read ) ) != IVAS_ERR_OK ) + { + return error; + } +#else ivas_read_format( st_ivas, &num_bits_read ); +#endif /*-------------------------------------------------------------------* * Read other signling (ISM/MC mode, number of channels, etc.) @@ -154,7 +536,11 @@ ivas_error ivas_dec_setup( st_ivas->nchan_ism = nchan_ism; +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -172,7 +558,11 @@ ivas_error ivas_dec_setup( num_bits_read += SBA_ORDER_BITS; if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->last_active_ivas_total_brate && ivas_total_brate > IVAS_SID_5k2 ) { +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_sba_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -199,6 +589,9 @@ ivas_error ivas_dec_setup( } /* this should be non-zero if original input format was MASA_ISM_FORMAT */ +#ifdef NONBE_1199_OMASA_JBM_BRATE_SW_FLUSH + st_ivas->ism_mode = ISM_MODE_NONE; +#endif st_ivas->nchan_ism = st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 3] + 2 * st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 2]; if ( st_ivas->nchan_ism > 0 ) @@ -216,6 +609,7 @@ ivas_error ivas_dec_setup( { st_ivas->nchan_ism = 1; } + /* for MASA_ISM_FORMAT at input the number of MASA transport channels is always 2 and the corresponding bit is not used here*/ st_ivas->nchan_transport = 2; element_mode_flag = 1; @@ -234,8 +628,11 @@ ivas_error ivas_dec_setup( } else { - +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_masa_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -243,7 +640,11 @@ ivas_error ivas_dec_setup( } else { +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_omasa_dec_config( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -264,7 +665,11 @@ 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 ) ) { +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_omasa_dec_config( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -292,9 +697,14 @@ ivas_error ivas_dec_setup( st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; num_bits_read += SBA_ORDER_BITS; } + if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->last_active_ivas_total_brate ) { +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_sba_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -340,7 +750,11 @@ ivas_error ivas_dec_setup( num_bits_read += MC_LS_SETUP_BITS; /* select MC format mode; reconfigure the MC format decoder */ +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_mc_dec_config( st_ivas, idx ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_mc_dec_config( st_ivas, idx, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -425,7 +839,11 @@ ivas_error ivas_dec_setup( st_ivas->hDecoderConfig->ivas_total_brate = IVAS_24k4; } +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_sba_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -435,6 +853,14 @@ ivas_error ivas_dec_setup( } } +#ifdef NONBE_1199_OMASA_JBM_BRATE_SW_FLUSH + if ( st_ivas->ini_frame > 0 && st_ivas->ivas_format == MASA_FORMAT ) + { + st_ivas->nchan_ism = 0; + st_ivas->ism_mode = ISM_MODE_NONE; + } + +#endif if ( st_ivas->ivas_format == ISM_FORMAT ) { ISM_MODE last_ism_mode = st_ivas->ism_mode; @@ -471,7 +897,11 @@ ivas_error ivas_dec_setup( last_ism_mode = st_ivas->ism_mode; } +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -599,6 +1029,15 @@ static ivas_error ivas_read_format( if ( st_ivas->sba_order == 0 ) { st_ivas->ivas_format = SBA_ISM_FORMAT; + +#ifdef FIX_HRTF_LOAD + /* read the real Ambisonic order when the above bits are used to signal OSBA format */ + if ( ivas_total_brate < IVAS_24k4 ) + { + st_ivas->sba_order = st_ivas->bit_stream[*num_bits_read + 2 + SBA_PLANAR_BITS + SBA_ORDER_BITS]; + st_ivas->sba_order += 2 * st_ivas->bit_stream[*num_bits_read + 1 + SBA_PLANAR_BITS + SBA_ORDER_BITS]; + } +#endif } } ( *num_bits_read )++; @@ -626,11 +1065,12 @@ static ivas_error ivas_read_format( break; case SID_ISM: st_ivas->ivas_format = ISM_FORMAT; - break; +#ifndef FIX_1209_SID_SIGNALING case SID_MULTICHANNEL: st_ivas->ivas_format = MC_FORMAT; break; +#endif case SID_SBA_1TC: st_ivas->ivas_format = SBA_FORMAT; st_ivas->element_mode_init = IVAS_SCE; @@ -655,7 +1095,9 @@ static ivas_error ivas_read_format( } break; default: +#ifndef FIX_1209_SID_SIGNALING /* This should actually be impossible, since only 3 bits are read, so if this happens something is broken */ +#endif return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Invalid value %c found in SID format field.", st_ivas->sid_format ); } @@ -842,6 +1284,7 @@ ivas_error ivas_init_decoder_front( } } +#ifndef FIX_HRTF_LOAD /*-------------------------------------------------------------------* * Allocate HRTF binary handle *--------------------------------------------------------------------*/ @@ -872,7 +1315,7 @@ ivas_error ivas_init_decoder_front( return error; } } - +#endif /*-------------------------------------------------------------------* * Allocate and initialize Binaural Renderer configuration handle *--------------------------------------------------------------------*/ @@ -2908,6 +3351,19 @@ static ivas_error doSanityChecks_IVAS( } } +#ifdef OBJ_EDITING_COMMANDLINE + if ( st_ivas->hDecoderConfig->Opt_ObjEdit_on ) + { +#ifdef FIX_BRATE_SWITCHING + if ( !( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) +#else + if ( !( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) ) +#endif + { + return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Wrong set-up: Obect editing is not supported in this IVAS format." ); + } + } +#endif #ifdef DEBUGGING if ( ( st_ivas->hDecoderConfig->force_rend == FORCE_TD_RENDERER ) && ( ( st_ivas->ivas_format != MC_FORMAT && st_ivas->ivas_format != ISM_FORMAT ) || ( output_config != IVAS_AUDIO_CONFIG_BINAURAL && output_config != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) || ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode != MC_MODE_MCT ) ) ) { diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 36945f81550f347f6e8e3813bd2456fca27036bb..bd0e7075e6577ed1e09ed0e87fb0cff36aca3a86 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -47,12 +47,15 @@ *-------------------------------------------------------------------------*/ static ivas_error ivas_ism_bitrate_switching_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t nchan_transport_old, /* i : last number of transport channels */ - const ISM_MODE last_ism_mode, /* i : last ISM mode */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t nchan_transport_old, /* i : last number of transport channels */ + const ISM_MODE last_ism_mode /* i : last ISM mode */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : number of samples rendered */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ) { ivas_error error; @@ -64,11 +67,15 @@ static ivas_error ivas_ism_bitrate_switching_dec( int16_t tc_nchan_allocate_new; int16_t tc_granularity_new; int16_t nchan_out_buff, nchan_out_buff_old; +#ifndef FIX_HRTF_LOAD AUDIO_CONFIG intern_config_old; IVAS_OUTPUT_SETUP hIntSetupOld; RENDERER_TYPE renderer_type_old; +#endif +#ifndef FIX_HRTF_LOAD error = IVAS_ERR_OK; +#endif nCPE_old = st_ivas->nCPE; nSCE_old = st_ivas->nSCE; @@ -104,12 +111,14 @@ static ivas_error ivas_ism_bitrate_switching_dec( return error; } +#ifndef FIX_HRTF_LOAD /* save old IntSetup, might be needed for JBM flushing...*/ intern_config_old = st_ivas->intern_config; hIntSetupOld = st_ivas->hIntSetup; tc_granularity_new = 1; renderer_type_old = st_ivas->renderer_type; +#endif /*-----------------------------------------------------------------* * Initialize the needed renderer struct and destroy the unnecessary renderer struct *-----------------------------------------------------------------*/ @@ -124,7 +133,9 @@ static ivas_error ivas_ism_bitrate_switching_dec( ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->hDecoderConfig->output_config ); } +#ifndef NONBE_1200_ISM_JBM_BRATE_SW_FLUSH { +#endif /* transfer subframe info from DirAC or ParamMC to central tc buffer */ /* only do this if we are not having done everything already in the TC decoding part and having only played out from the TC buffer */ if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hSpatParamRendCom != NULL && st_ivas->hTcBuffer->tc_buffer_mode != TC_BUFFER_MODE_BUFFER ) @@ -142,10 +153,23 @@ static ivas_error ivas_ism_bitrate_switching_dec( if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { - if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, MC_MODE_NONE, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) - { - return error; - } +#ifdef FIX_HRTF_LOAD + /* flush already done in IVAS_DEC_ReadFormat() */ +#else +#ifdef NONBE_1200_ISM_JBM_BRATE_SW_FLUSH + /* write back info for correct rendering of the flushable samples */ + int16_t nchan_transport_ref = st_ivas->nchan_transport; + st_ivas->nchan_transport = nchan_transport_old; + +#endif + if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, MC_MODE_NONE, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifdef NONBE_1200_ISM_JBM_BRATE_SW_FLUSH + st_ivas->nchan_transport = nchan_transport_ref; +#endif +#endif } /* JBM: when granularity goes up set samples to discard at the beginning of the frame */ else if ( tc_granularity_new > st_ivas->hTcBuffer->n_samples_granularity ) @@ -155,7 +179,9 @@ static ivas_error ivas_ism_bitrate_switching_dec( return error; } } +#ifndef NONBE_1200_ISM_JBM_BRATE_SW_FLUSH } +#endif if ( st_ivas->ism_mode != last_ism_mode ) { @@ -177,9 +203,11 @@ static ivas_error ivas_ism_bitrate_switching_dec( { /* close the parametric binaural renderer */ ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); + #ifdef OBJ_EDITING_PARAMISM_BIN /* Close omasa data struct (used for object editing) */ ivas_omasa_data_close( &st_ivas->hMasaIsmData ); + #endif /* Open the TD Binaural renderer */ if ( st_ivas->hHrtfTD == NULL || st_ivas->hBinRendererTd == NULL ) @@ -311,19 +339,26 @@ static ivas_error ivas_ism_bitrate_switching_dec( * floating-point output audio buffers *-----------------------------------------------------------------*/ +#ifndef NONBE_1200_ISM_JBM_BRATE_SW_FLUSH { +#endif nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } +#ifndef NONBE_1200_ISM_JBM_BRATE_SW_FLUSH } +#endif /*-----------------------------------------------------------------* * JBM TC buffers *-----------------------------------------------------------------*/ + +#ifndef NONBE_1200_ISM_JBM_BRATE_SW_FLUSH { +#endif int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; @@ -359,9 +394,15 @@ static ivas_error ivas_ism_bitrate_switching_dec( mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); } +#ifndef NONBE_1200_ISM_JBM_BRATE_SW_FLUSH } +#endif +#ifdef FIX_HRTF_LOAD + return IVAS_ERR_OK; +#else return error; +#endif } @@ -373,18 +414,23 @@ static ivas_error ivas_ism_bitrate_switching_dec( *-------------------------------------------------------------------------*/ ivas_error ivas_ism_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const ISM_MODE last_ism_mode, /* i/o: last ISM mode */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const ISM_MODE last_ism_mode /* i/o: last ISM mode */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : number of samples flushed when the renderer granularity changes */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ) { int32_t ivas_total_brate; ivas_error error; int16_t nchan_transport_old; +#ifndef FIX_HRTF_LOAD error = IVAS_ERR_OK; +#endif ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; /* Assumes that num of input objects are constant */ @@ -413,9 +459,13 @@ ivas_error ivas_ism_dec_config( if ( st_ivas->ini_active_frame != 0 ) { /* ISM bit-rate switching */ - if ( ( st_ivas->ism_mode != last_ism_mode ) || ( st_ivas->hDecoderConfig->ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) + if ( ( st_ivas->ism_mode != last_ism_mode ) || ( ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) { +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -437,7 +487,12 @@ ivas_error ivas_ism_dec_config( /* ISM mode switching */ if ( st_ivas->ism_mode != last_ism_mode ) { + +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -463,5 +518,9 @@ ivas_error ivas_ism_dec_config( break; } +#ifdef FIX_HRTF_LOAD + return IVAS_ERR_OK; +#else return error; +#endif } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index ace799d92e720c2a8967c8293a24420ddea6b1d4..db93983e592bbd9a547ffd5027e8711e651d433d 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -802,9 +802,9 @@ 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 */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nCldfbSlots, /* i : number of CLDFB slots in transport channels */ + float *transport_channels_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ ) { #ifndef OBJ_EDITING_API @@ -850,8 +850,8 @@ void ivas_param_ism_dec_digest_tc( nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; } -#endif +#endif push_wmops( "ivas_param_ism_dec_digest_tc" ); #ifndef OBJ_EDITING_API @@ -929,8 +929,8 @@ void ivas_param_ism_dec_digest_tc( } } } -#endif +#endif if ( st_ivas->hDecoderConfig->Opt_tsm ) { /*TODO : FhG to check*/ @@ -944,7 +944,6 @@ void ivas_param_ism_dec_digest_tc( { if ( st_ivas->hDecoderConfig->Opt_tsm ) { - float RealBuffer[CLDFB_NO_CHANNELS_MAX]; float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; @@ -952,8 +951,8 @@ void ivas_param_ism_dec_digest_tc( mvr2r( RealBuffer, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands ); mvr2r( ImagBuffer, &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands ); } - #ifndef OBJ_EDITING_API + ivas_param_ism_collect_slot( hParamIsmDec, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], ch, ref_power, cx_diag ); #endif } @@ -978,13 +977,14 @@ void ivas_param_ism_dec_digest_tc( #ifdef OBJ_EDITING_API /*-------------------------------------------------------------------------* - * ivas_param_ism_dec_prepare_renderer() + * ivas_param_ism_dec_dequant_md() * * *-------------------------------------------------------------------------*/ void ivas_param_ism_dec_dequant_md( - Decoder_Struct *st_ivas ) + Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ +) { /* De-quantization */ if ( !( st_ivas->hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 || st_ivas->hDecoderConfig->ivas_total_brate == FRAME_NO_DATA ) ) @@ -1009,8 +1009,8 @@ void ivas_param_ism_dec_dequant_md( *-------------------------------------------------------------------------*/ void ivas_param_ism_dec_prepare_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nCldfbSlots /* i : number of CLDFB slots in transport channels */ ) { int16_t ch, nchan_transport, nchan_out, nchan_out_woLFE, i; @@ -1134,6 +1134,7 @@ void ivas_param_ism_dec_prepare_renderer( } #endif + /*-------------------------------------------------------------------------* * ivas_ism_param_dec_tc_gain_ajust() * @@ -1450,8 +1451,8 @@ void ivas_param_ism_params_to_masa_param_mapping( { st_ivas->hISMDTX.dtx_flag = 1; } -#endif +#endif if ( st_ivas->hISMDTX.dtx_flag ) { float energy_ratio; @@ -1524,6 +1525,7 @@ void ivas_param_ism_params_to_masa_param_mapping( hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx] = 0.0; } } + #ifdef OBJ_EDITING_PARAMISM_BIN for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) { diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 9b882089b15dfef4ccfe335236defb1b4ce842ce..4e4fb628a44cb3d8bec825760f569ef9bada1f93 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -247,6 +247,7 @@ void ivas_ism_render_sf( rotateAziEle( st_ivas->hIsmMetaData[i]->last_azimuth, st_ivas->hIsmMetaData[i]->last_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); #endif } + if ( st_ivas->hEFAPdata != NULL ) { efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP ); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 29b2cd140379307b64145cbcc49e58f3a2c17567..f096ff4116fc6f79f7644ddfad82c3e2963767b4 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -150,6 +150,7 @@ ivas_error ivas_jbm_dec_tc( } ivas_ism_dtx_limit_noise_energy_for_near_silence( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport ); + #ifdef OBJ_EDITING_API ivas_param_ism_dec_dequant_md( st_ivas ); #endif @@ -160,6 +161,7 @@ ivas_error ivas_jbm_dec_tc( { return error; } + #ifdef OBJ_EDITING_API ivas_param_ism_dec_dequant_md( st_ivas ); #endif @@ -1248,36 +1250,15 @@ ivas_error ivas_jbm_dec_render( /* add already rendered SBA part */ #ifdef OBJ_EDITING_API - if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - float gain = st_ivas->hSbaIsmData->gain_bed; - if ( gain != 1.0f && gain >= 0.0f ) - { - int16_t i; - for ( n = 0; n < nchan_out; n++ ) - { - for ( i = 0; i < *nSamplesRendered; i++ ) - { - p_output[n][i] += p_tc[n + st_ivas->nchan_ism][i] * gain; - } - } - } - else - { - for ( n = 0; n < nchan_out; n++ ) - { - v_add( p_output[n], p_tc[n + st_ivas->nchan_ism], p_output[n], *nSamplesRendered ); - } - } - } - else -#endif + ivas_osba_stereo_add_channels( p_tc, p_output, st_ivas->hSbaIsmData->gain_bed, nchan_out, st_ivas->nchan_ism, st_ivas->ism_mode, *nSamplesRendered ); +#else { for ( n = 0; n < nchan_out; n++ ) { v_add( p_output[n], p_tc[n + st_ivas->nchan_ism], p_output[n], *nSamplesRendered ); } } +#endif } else if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { @@ -1547,7 +1528,7 @@ ivas_error ivas_jbm_dec_render( /*--------------------------------------------------------------------------* - * ivas_jbm_dec_dec_flush_renderer() + * ivas_jbm_dec_flush_renderer() * * Flush samples if renderer granularity changes on a bitrate change *--------------------------------------------------------------------------*/ @@ -2999,20 +2980,21 @@ void ivas_jbm_masa_sf_to_sf_map( return; } + #ifdef OBJ_EDITING_API /*--------------------------------------------------------------------------* - * ivas_jbm_dec_prepare_renderer() + * ivas_dec_prepare_renderer() * - * prepare IVAS JBM renderer routine + * prepare IVAS renderer routine *--------------------------------------------------------------------------*/ -void ivas_jbm_dec_prepare_renderer( +void ivas_dec_prepare_renderer( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { int16_t n, n_render_timeslots; - push_wmops( "ivas_jbm_dec_prepare_renderer" ); + push_wmops( "ivas_dec_prepare_renderer" ); n_render_timeslots = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; @@ -3031,7 +3013,6 @@ void ivas_jbm_dec_prepare_renderer( } else if ( st_ivas->ivas_format == ISM_FORMAT ) { - /* Rendering */ if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) @@ -3055,7 +3036,6 @@ void ivas_jbm_dec_prepare_renderer( } else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { ivas_ism_dec_digest_tc( st_ivas ); @@ -3118,18 +3098,20 @@ void ivas_jbm_dec_prepare_renderer( if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_DIRAC ) { - int16_t num_objects; + int16_t nchan_transport_ism; + /* Delay the signal to match CLDFB delay. Delay the whole buffer. */ - num_objects = 0; + nchan_transport_ism = 0; if ( ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC ) { - num_objects = 1; + nchan_transport_ism = 1; } else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { - num_objects = st_ivas->nchan_ism; + nchan_transport_ism = st_ivas->nchan_ism; } - for ( n = 0; n < num_objects; n++ ) + + for ( n = 0; n < nchan_transport_ism; n++ ) { if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) { @@ -3147,12 +3129,14 @@ void ivas_jbm_dec_prepare_renderer( v_multc( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], OMASA_TDREND_MATCHING_GAIN, st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available ); #endif } + if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { delay_signal( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); } } #ifdef OMASA_OBJECT_EDITING + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) { int16_t tcBufferSize; @@ -3160,9 +3144,9 @@ void ivas_jbm_dec_prepare_renderer( if ( st_ivas->hMasaIsmData->masa_gain_is_edited ) { - for ( int16_t ch = 0; ch < 2; ch++ ) + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) { - v_multc( st_ivas->hTcBuffer->tc[ch], st_ivas->hMasaIsmData->gain_masa_edited, st_ivas->hTcBuffer->tc[ch], tcBufferSize ); + v_multc( st_ivas->hTcBuffer->tc[n], st_ivas->hMasaIsmData->gain_masa_edited, st_ivas->hTcBuffer->tc[n], tcBufferSize ); } } } diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 2335f14147dfc7019f32222f4530f52878485daa..26732a868b7407b0e07e2dac35ebafb2bd664a38 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -151,12 +151,28 @@ ivas_error ivas_masa_decode( { if ( !( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) { +#if ( defined FIX_HRTF_LOAD || defined NONBE_1199_OMASA_JBM_BRATE_SW_FLUSH ) + if ( ivas_format == MASA_FORMAT ) + { + /* re-read the number of objects, needed in case of bad frame */ + ch = 5 - ( st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 3] + 2 * st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 2] ); + + if ( ch == 5 ) + { + ch = 0; + } + st_ivas->nchan_ism = ch; + } + + if ( ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) +#else if ( ivas_format == MASA_FORMAT ) { /* re-read the number of objects, needed in case of bad frame */ st_ivas->nchan_ism = 5 - ( st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 3] + 2 * st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 2] ); } if ( ivas_format == MASA_FORMAT && st_ivas->nchan_ism != 5 ) +#endif { /* there was OMASA in the input */ hMasa->config.input_ivas_format = MASA_ISM_FORMAT; @@ -1305,10 +1321,13 @@ static int16_t decode_lfe_to_total_energy_ratio( *-------------------------------------------------------------------*/ ivas_error ivas_masa_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ) { int16_t n, tmp, num_bits; @@ -1321,8 +1340,9 @@ ivas_error ivas_masa_dec_reconfigure( int16_t pos_idx; int32_t ism_total_brate; +#ifndef FIX_HRTF_LOAD error = IVAS_ERR_OK; - +#endif ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; @@ -1470,6 +1490,7 @@ ivas_error ivas_masa_dec_reconfigure( ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp, st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate ); +#ifndef NONBE_1199_OMASA_JBM_BRATE_SW_FLUSH if ( st_ivas->ivas_format == MASA_FORMAT ) { if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) @@ -1481,6 +1502,7 @@ ivas_error ivas_masa_dec_reconfigure( st_ivas->ism_mode = ISM_MODE_NONE; } +#endif { int16_t tc_nchan_to_allocate; int16_t tc_nchan_transport; @@ -1517,10 +1539,14 @@ ivas_error ivas_masa_dec_reconfigure( { if ( n_samples_granularity < st_ivas->hTcBuffer->n_samples_granularity ) { +#ifdef FIX_HRTF_LOAD + /* flush already done in IVAS_DEC_ReadFormat() */ +#else if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, n_samples_granularity, st_ivas->renderer_type, st_ivas->intern_config, &st_ivas->hIntSetup, MC_MODE_NONE, ISM_MASA_MODE_DISC, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) { return error; } +#endif } } } @@ -1561,7 +1587,11 @@ ivas_error ivas_masa_dec_reconfigure( } } +#ifdef FIX_HRTF_LOAD + return IVAS_ERR_OK; +#else return error; +#endif } diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 934fc6fac24e34dd8e54f9ef6cbf3fb46ec3b090..59d3c1cb79b5a831fc738763b5a159351b5cb106 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1322,8 +1322,8 @@ 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 */ - float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ + const uint8_t nCldfbSlots, /* i : number of CLDFB slots in transport channels */ + float *transport_channels_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ ) { PARAM_MC_DEC_HANDLE hParamMC; @@ -1349,8 +1349,8 @@ void ivas_param_mc_dec_digest_tc( /* format converter */ int16_t channel_active[MAX_OUTPUT_CHANNELS]; IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; -#endif +#endif hParamMC = st_ivas->hParamMC; assert( hParamMC ); @@ -1524,6 +1524,7 @@ void ivas_param_mc_dec_digest_tc( return; } + #ifdef OBJ_EDITING_API /*------------------------------------------------------------------------- * ivas_param_mc_dec_prepare_renderer() @@ -1532,8 +1533,8 @@ void ivas_param_mc_dec_digest_tc( *------------------------------------------------------------------------*/ void ivas_param_mc_dec_prepare_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots /* i : number of CLDFB slots in transport channels */ ) { PARAM_MC_DEC_HANDLE hParamMC; @@ -1605,7 +1606,6 @@ void ivas_param_mc_dec_prepare_renderer( ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); - /* loop over two bands at a time */ for ( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx += 2 ) { @@ -1628,6 +1628,7 @@ void ivas_param_mc_dec_prepare_renderer( { continue; } + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], is_next_band ? cx_next_band : cx, @@ -1680,6 +1681,7 @@ void ivas_param_mc_dec_prepare_renderer( { continue; } + /* generate mixing matrices */ ivas_param_mc_get_mixing_matrices( hParamMC, hSynthesisOutputSetup, diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index 41cdf081fb4c0d16622744e798c2487706490fd4..0748d26bec2333db61809a400bcf24783b8cc656 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -186,9 +186,9 @@ void ivas_mc_paramupmix_dec_read_BS( *------------------------------------------------------------------------*/ void ivas_mc_paramupmix_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 int16_t nSamplesForRendering /* i : number of samples provided */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots, /* i : number of CLDFB slots in transport channels */ + const int16_t nSamplesForRendering /* i : number of samples provided */ ) { MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 08e2de73cd7cefff2f6e4d5c872d5550a2127888..fe2ca5dbaaf3356cdd37c1cbe47f992d2aeb29b1 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -54,7 +54,11 @@ * Local function prototypes *-----------------------------------------------------------------------*/ +#ifdef FIX_HRTF_LOAD +static ivas_error ivas_mc_dec_reconfig( Decoder_Struct *st_ivas ); +#else static ivas_error ivas_mc_dec_reconfig( Decoder_Struct *st_ivas, uint16_t *nSamplesRendered, const PCM_RESOLUTION pcm_resolution, void *data ); +#endif /*--------------------------------------------------------------------------* @@ -661,11 +665,14 @@ void ivas_mct_dec_close( /*! r : MC format mode */ ivas_error ivas_mc_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t idx, /* i : LS config. index */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t idx /* i : LS config. index */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ) { AUDIO_CONFIG signaled_config; @@ -700,7 +707,11 @@ ivas_error ivas_mc_dec_config( { if ( st_ivas->hDecoderConfig->last_ivas_total_brate != st_ivas->hDecoderConfig->ivas_total_brate || last_mc_mode != st_ivas->mc_mode ) { +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_mc_dec_reconfig( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_mc_dec_reconfig( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -721,10 +732,13 @@ ivas_error ivas_mc_dec_config( *-------------------------------------------------------------------------*/ static ivas_error ivas_mc_dec_reconfig( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ) { int16_t nchan_transport_old, nSCE_old, nCPE_old, sba_dirac_stereo_flag_old, nchan_hp20_old; @@ -738,11 +752,15 @@ static ivas_error ivas_mc_dec_reconfig( int16_t tc_nchan_tc_new; int16_t tc_nchan_allocate_new; int16_t tc_granularity_new; +#ifndef FIX_HRTF_LOAD AUDIO_CONFIG intern_config_old; IVAS_OUTPUT_SETUP hIntSetupOld; +#endif int16_t nchan_out_buff_old, nchan_out_buff; +#ifndef FIX_HRTF_LOAD error = IVAS_ERR_OK; +#endif ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; nchan_transport_old = st_ivas->nchan_transport; nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); @@ -770,11 +788,13 @@ static ivas_error ivas_mc_dec_reconfig( } st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); +#ifndef FIX_HRTF_LOAD /* save old IntSetup, might be needed for JBM flushing...*/ intern_config_old = st_ivas->intern_config; hIntSetupOld = st_ivas->hIntSetup; tc_granularity_new = 1; +#endif /* renderer might have changed, reselect */ renderer_type_old = st_ivas->renderer_type; ivas_renderer_select( st_ivas ); @@ -808,10 +828,14 @@ static ivas_error ivas_mc_dec_reconfig( tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs ); if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { +#ifdef FIX_HRTF_LOAD + /* flush already done in IVAS_DEC_ReadFormat() */ +#else if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, last_mc_mode, ISM_MODE_NONE, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) { return error; } +#endif } /* JBM: when granularity goes up set samples to discard at the beginning of the frame */ else if ( tc_granularity_new > st_ivas->hTcBuffer->n_samples_granularity ) @@ -1299,7 +1323,6 @@ static ivas_error ivas_mc_dec_reconfig( /*-----------------------------------------------------------------* * JBM TC buffers *-----------------------------------------------------------------*/ - { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; @@ -1362,7 +1385,6 @@ static ivas_error ivas_mc_dec_reconfig( } } - /*-----------------------------------------------------------------* * floating-point output audio buffers *-----------------------------------------------------------------*/ @@ -1374,5 +1396,9 @@ static ivas_error ivas_mc_dec_reconfig( return error; } +#ifdef FIX_HRTF_LOAD + return IVAS_ERR_OK; +#else return error; +#endif } diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 3f8ff738c7c6f29aa1ae032ee21f9f59f88c538d..e07b44da0344350a2d21aef592262d3232d281c0 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -865,6 +865,15 @@ void ivas_mdct_core_reconstruct( { set_f( &synth[k * L_frame[ch]], 0.f, L_frame[ch] ); set_f( &synthFB[k * L_frame[ch]], 0.f, L_frameTCX[ch] ); +#ifdef FIX_1206_ZERO_OUT_IMDCT_BUFFERS_FOR_MCT_IGNORE + /* Note: these buffers are not subframe-based, hence no indexing with k */ + set_f( &st->hHQ_core->old_outLB[0], 0.f, L_frame[ch] ); + set_f( &st->hHQ_core->old_out[0], 0.f, L_frameTCX[ch] ); + set_f( &st->hTcxDec->syn_Overl[0], 0.f, L_frame[ch] / 2 ); + set_f( &st->hTcxDec->syn_OverlFB[0], 0.f, L_frameTCX[ch] / 2 ); + set_f( &st->hTcxDec->syn_Overl_TDAC[0], 0.f, L_frame[ch] / 2 ); + set_f( &st->hTcxDec->syn_Overl_TDACFB[0], 0.f, L_frameTCX[ch] / 2 ); +#endif } } diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 77d89242a923d89bf808127443ea22cb32a839fa..0e6c1025df49ff6250f3a47918635d3f79e1343f 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -61,6 +61,15 @@ ivas_error ivas_td_binaural_open( num_src = st_ivas->nchan_ism; } +#ifdef FIX_HRTF_LOAD + if ( st_ivas->hHrtfTD == NULL && st_ivas->hDecoderConfig->Opt_HRTF_binary && + ( st_ivas->ivas_format != SBA_ISM_FORMAT ) // ToDo: temporary hack to avoid ASAN errors -> see issue #1202 + ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "HRTF binary file present but not used in TD renderer" ); + } +#endif + 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->hRenderConfig->distAtt, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns ); } @@ -171,6 +180,7 @@ ivas_error ivas_td_binaural_renderer_sf( c_indx++; } } + if ( subframe_idx == ism_md_subframe_update_jbm ) { #ifdef OBJ_EDITING_API @@ -178,6 +188,7 @@ ivas_error ivas_td_binaural_renderer_sf( { ISM_METADATA_FRAME ismMetaData[MAX_NUM_OBJECTS]; ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS]; + for ( nS = 0; nS < nchan_ism; nS++ ) { ismMetaData[nS].azimuth = st_ivas->hIsmMetaData[nS]->edited_azimuth; diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 3ab3757688f1aa611fda0a3bd3719ad0c06c9973..439a6baba10ca197fb6fc732460f61eb9944ff3b 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -220,10 +220,13 @@ void ivas_omasa_data_close( *--------------------------------------------------------------------------*/ ivas_error ivas_omasa_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ) { #ifdef OMASA_OBJECT_EDITING @@ -271,7 +274,11 @@ ivas_error ivas_omasa_dec_config( { st_ivas->hCPE[0]->nchan_out = 1; } +#ifdef FIX_HRTF_LOAD + else if ( ( error = ivas_masa_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) +#else else if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -424,6 +431,24 @@ ivas_error ivas_omasa_dec_config( ivas_omasa_separate_object_renderer_close( st_ivas ); } +#ifdef NONBE_FIX_1197_OMASA_META_BUFFER + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && st_ivas->hMasaIsmData != NULL ) /* this structure is in use only in ISM_MASA_MODE_PARAM_ONE_OBJ */ + { + MASA_ISM_DATA_HANDLE hMasaIsmData = st_ivas->hMasaIsmData; + for ( int16_t 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 ( int16_t 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 ); + } +#endif + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) { if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) @@ -547,7 +572,6 @@ ivas_error ivas_omasa_dec_config( } } - return IVAS_ERR_OK; } @@ -776,6 +800,7 @@ void ivas_omasa_dirac_rend_jbm( for ( n = 0; n < st_ivas->nchan_ism; n++ ) { mvr2r( &output_f[n + CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[n], *nSamplesRendered ); + #ifdef OMASA_OBJECT_EDITING /* Gain discrete objects, if edited */ if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] ) @@ -784,6 +809,7 @@ void ivas_omasa_dirac_rend_jbm( } #endif } + #ifdef OMASA_OBJECT_EDITING /* Gain MASA part, if edited */ if ( st_ivas->hMasaIsmData->masa_gain_is_edited ) diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index eaf5d11a7e894e41a6aab1229e5329a593567797..bb5f547beb299fd4f8d08244e4879593313a8124 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -300,3 +300,56 @@ ivas_error ivas_osba_render_sf( return IVAS_ERR_OK; } + + +#ifdef OBJ_EDITING_API +/*-------------------------------------------------------------------------* + * ivas_osba_stereo_add_channels() + * + * + *-------------------------------------------------------------------------*/ + +void ivas_osba_stereo_add_channels( + float *tc_f[], /* i : transport channels */ + float *output_f[], /* i/o: output channels */ + const float gain, /* i : gain bed value */ + const int16_t nchan_out, /* i : number of output channels */ + const int16_t nchan_ism, /* i : number of ISM channels */ + const int16_t ism_mode, /* i : ISM mode */ + const int16_t n_samples_to_render /* i : output frame length per channel */ +) +{ + int16_t n; + + if ( ism_mode == ISM_SBA_MODE_DISC ) + { + if ( gain != 1.0f && gain >= 0.0f ) + { + int16_t i; + for ( n = 0; n < nchan_out; n++ ) + { + for ( i = 0; i < n_samples_to_render; i++ ) + { + output_f[n][i] += tc_f[n + nchan_ism][i] * gain; + } + } + } + else + { + for ( n = 0; n < nchan_out; n++ ) + { + v_add( output_f[n], tc_f[n + nchan_ism], output_f[n], n_samples_to_render ); + } + } + } + else + { + for ( n = 0; n < nchan_out; n++ ) + { + v_add( output_f[n], tc_f[n + nchan_ism], output_f[n], n_samples_to_render ); + } + } + + return; +} +#endif diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index a3e62b9702970eef5eabb7889bf6e50d42b407f1..11e23d0b7b0814ab2824f337192483b1ce52b375 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -141,11 +141,7 @@ void ivas_renderer_select( { *internal_config = IVAS_AUDIO_CONFIG_HOA3; -#ifdef FIX_1158_FASTCONV_REVERB_HRTF if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#endif { *renderer_type = RENDERER_BINAURAL_FASTCONV; } diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 9a6df407d4ed569dfd5ab38276ea27287616c2e8..0f3dfba4c01202bd2369e4bd959126c7d9f255e2 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -101,10 +101,13 @@ void ivas_sba_set_cna_cng_flag( *-------------------------------------------------------------------*/ ivas_error ivas_sba_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifndef FIX_HRTF_LOAD + , uint16_t *nSamplesFlushed, /* o : number of samples flushed */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ) { int16_t nchan_transport_old, nSCE_old, nCPE_old, nchan_hp20_old; @@ -161,7 +164,9 @@ ivas_error ivas_sba_dec_reconfigure( st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); +#ifndef FIX_HRTF_LOAD *nSamplesFlushed = 0; +#endif granularity_new = st_ivas->hTcBuffer->n_samples_granularity; /* we may need to flush only for binaural and OSBA and TSM */ @@ -209,6 +214,9 @@ ivas_error ivas_sba_dec_reconfigure( /* flush renderer on granularity change form 5ms to 1.25ms, again only possible for binaural rendering */ if ( granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { +#ifdef FIX_HRTF_LOAD + /* flush already done in IVAS_DEC_ReadFormat() */ +#else /* write back info for correct rendering of the flushable samples */ st_ivas->sba_analysis_order = sba_analysis_order_old_flush; st_ivas->hDecoderConfig->ivas_total_brate = last_ivas_total_brate; @@ -221,6 +229,7 @@ ivas_error ivas_sba_dec_reconfigure( /* restore correct values for the current frame*/ st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate; +#endif } else if ( granularity_new > st_ivas->hTcBuffer->n_samples_granularity ) { @@ -658,7 +667,11 @@ ivas_error ivas_sba_dec_reconfigure( return error; } +#ifdef FIX_HRTF_LOAD + return IVAS_ERR_OK; +#else return error; +#endif } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 2515b1cc99cd3610a05685511cb51fd1e86fe1cf..9ed05b1ae203c99fd806c028a6bd05b12d25bf6a 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1028,6 +1028,9 @@ typedef struct decoder_config_structure int16_t Opt_ExternalOrientation; /* indicates whether external orientations are used */ int16_t Opt_dpid_on; /* indicates whether Directivity pattern option is used */ int16_t Opt_aeid_on; /* indicates whether Acoustic environment option is used */ +#ifdef OBJ_EDITING_COMMANDLINE + int16_t Opt_ObjEdit_on; /* indicates whether object editing option is used */ +#endif #ifdef DEBUGGING /* temp. development parameters */ int16_t force_rend; /* forced TD/CLDFB binaural renderer (for ISM and MC) */ diff --git a/lib_dec/ivas_stereo_dft_plc.c b/lib_dec/ivas_stereo_dft_plc.c index 31f86bc348d824d2521a594eaa77dea7a060076f..30fb49f4ce83c6c883c5a8ce3ca3b39ce67fd72a 100644 --- a/lib_dec/ivas_stereo_dft_plc.c +++ b/lib_dec/ivas_stereo_dft_plc.c @@ -80,6 +80,9 @@ void stereo_dft_res_ecu( float fac; float trigo_dec[STEREO_DFT32MS_N_8k / 2 + 1]; int16_t trigo_step; +#ifdef NONBE_FIX_1208_DFT_STEREO_PLC_BURST + int16_t time_offs; +#endif set_zero( pDFT_RES, L_FRAME8k ); @@ -106,7 +109,12 @@ void stereo_dft_res_ecu( if ( k == 0 ) { mvr2r( pDFT_RES, res_buf, L_FRAME8k ); +#ifdef NONBE_FIX_1208_DFT_STEREO_PLC_BURST + time_offs = min( MAX16B, hStereoDft->time_offs + output_frame ); + stereo_dft_res_subst_spec( hStereoDft, res_buf, DFT_PRED_RES, time_offs, L_res, L_FRAME8k, k, num_plocs, plocs, plocsi, FALSE ); +#else stereo_dft_res_subst_spec( hStereoDft, res_buf, DFT_PRED_RES, hStereoDft->time_offs + output_frame, L_res, L_FRAME8k, k, num_plocs, plocs, plocsi, FALSE ); +#endif rfft( res_buf, trigo_dec, L_FRAME8k, +1 ); @@ -133,7 +141,11 @@ void stereo_dft_res_ecu( } /*in case of burst error*/ +#ifdef NONBE_FIX_1208_DFT_STEREO_PLC_BURST + hStereoDft->time_offs = min( MAX16B, hStereoDft->time_offs + L_FRAME8k ); +#else hStereoDft->time_offs += L_FRAME8k; +#endif } set_zero( DFT_PRED_RES, 2 * L_res ); diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index fdfb1ab55ba3962143c0f7bf0dd229344837ed9e..66d70060c8cfb23f869b82698a47125b697aaf1e 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -103,8 +103,6 @@ struct IVAS_DEC uint16_t nSamplesFlushed; void *flushbuffer; IVAS_DEC_PCM_TYPE pcmType; - bool hasEditableParameters; - bool enableParameterEditing; bool hasBeenPreparedRendering; #endif }; @@ -122,7 +120,11 @@ static ivas_error evs_dec_main( Decoder_Struct *st_ivas, const int16_t nOutSampl static ivas_error input_format_API_to_internal( IVAS_DEC_INPUT_FORMAT input_format, int16_t *bitstream_format_internal, int16_t *sdp_hf_only, const bool is_voip_enabled ); static void init_decoder_config( DECODER_CONFIG_HANDLE hDecoderConfig ); static ivas_error IVAS_DEC_VoIP_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ); +#ifdef FIX_HRTF_LOAD +static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels ); +#else static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels, uint8_t *nOutChannels, uint16_t *nSamplesRendered, const IVAS_DEC_PCM_TYPE pcmType, void *data ); +#endif static ivas_error IVAS_DEC_GetTcSamples( IVAS_DEC_HANDLE hIvasDec, float *pcmBuf, int16_t *nOutSamples ); static ivas_error IVAS_DEC_RendererFeedTcSamples( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesForRendering, int16_t *nSamplesResidual, float *pcmBuf ); static ivas_error IVAS_DEC_GetRenderedSamples( IVAS_DEC_HANDLE hIvasDec, const uint16_t nSamplesForRendering, uint16_t *nSamplesRendered, uint16_t *nSamplesAvailableNext, const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf ); @@ -188,8 +190,6 @@ ivas_error IVAS_DEC_Open( hIvasDec->flushbuffer = NULL; hIvasDec->pcmType = IVAS_DEC_PCM_INVALID; hIvasDec->nSamplesFlushed = 0; - hIvasDec->hasEditableParameters = false; - hIvasDec->enableParameterEditing = false; hIvasDec->hasBeenPreparedRendering = false; #endif @@ -323,6 +323,9 @@ static void init_decoder_config( hDecoderConfig->Opt_ExternalOrientation = 0; hDecoderConfig->Opt_dpid_on = 0; hDecoderConfig->Opt_aeid_on = 0; +#ifdef OBJ_EDITING_COMMANDLINE + hDecoderConfig->Opt_ObjEdit_on = 0; +#endif return; } @@ -365,12 +368,14 @@ void IVAS_DEC_Close( { free( ( *phIvasDec )->apaExecBuffer ); } + #ifdef OBJ_EDITING_API if ( ( *phIvasDec )->flushbuffer != NULL ) { free( ( *phIvasDec )->flushbuffer ); } #endif + free( *phIvasDec ); *phIvasDec = NULL; phIvasDec = NULL; @@ -437,16 +442,16 @@ ivas_error IVAS_DEC_Configure( const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ const bool dpidEnabled, /* i : enable directivity pattern option */ const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ - const bool delayCompensationEnabled /* i : enable delay compensation */ +#ifdef OBJ_EDITING_COMMANDLINE + const bool objEditEnabled, /* i : enable object editing */ +#endif + const bool delayCompensationEnabled /* i : enable delay compensation */ ) { Decoder_Struct *st_ivas; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; -#ifndef FIX_VOIP_FUNCTIONS - error = IVAS_ERR_OK; -#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; @@ -498,6 +503,9 @@ ivas_error IVAS_DEC_Configure( hDecoderConfig->Opt_ExternalOrientation = enableExternalOrientation; hDecoderConfig->Opt_dpid_on = (int16_t) dpidEnabled; hDecoderConfig->Opt_aeid_on = acousticEnvironmentId != 65535 ? TRUE : FALSE; +#ifdef OBJ_EDITING_COMMANDLINE + hDecoderConfig->Opt_ObjEdit_on = (int16_t) objEditEnabled; +#endif if ( renderFramesize == IVAS_RENDER_FRAMESIZE_UNKNOWN ) { @@ -544,16 +552,16 @@ ivas_error IVAS_DEC_Configure( if ( tsmEnabled && ( outputConfig == IVAS_AUDIO_CONFIG_BINAURAL || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) { hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); + if ( hIvasDec->flushbuffer == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate JBM flush buffer" ); + } hIvasDec->pcmType = IVAS_DEC_PCM_INT16; set_s( (int16_t *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); } #endif -#ifdef FIX_VOIP_FUNCTIONS return IVAS_ERR_OK; -#else - return error; -#endif } @@ -749,9 +757,6 @@ ivas_error IVAS_DEC_EnableVoIP( { DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; -#ifndef FIX_VOIP_FUNCTIONS - error = IVAS_ERR_OK; -#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { @@ -819,11 +824,7 @@ ivas_error IVAS_DEC_EnableVoIP( } #endif -#ifdef FIX_VOIP_FUNCTIONS return IVAS_ERR_OK; -#else - return error; -#endif } @@ -837,11 +838,16 @@ ivas_error IVAS_DEC_FeedFrame_Serial( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t *serial, /* i : buffer containing serial input bitstream. Each bit should be stored as a single uint16_t value */ const uint16_t num_bits, /* i : number of bits in input bitstream */ - int16_t bfi /* i : bad frame indicator flag */ +#ifdef FIX_HRTF_LOAD + int16_t bfi /* i : bad frame indicator flag */ +#else #ifdef OBJ_EDITING_API - , - int16_t isSplitRend, - ISAR_SPLIT_REND_BITS_DATA *splitRendBits + int16_t bfi, /* i : bad frame indicator flag */ + const int16_t isSplitRend, /* i : split rendering enabled flag */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +#else + int16_t bfi /* i : bad frame indicator flag */ +#endif #endif ) { @@ -919,15 +925,192 @@ ivas_error IVAS_DEC_FeedFrame_Serial( hIvasDec->nSamplesRendered = 0; hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; +#ifndef FIX_HRTF_LOAD #ifdef OBJ_EDITING_API - /* Decode TCs, do TSM and feed to renderer. - If TSM is generally enabled, we have to wait for the first good frame. - Otherwise, we directly decode the first frame in any case. - */ + /* Decode TCs, do TSM and feed to renderer */; + if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, isSplitRend, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } + +#endif +#endif + return IVAS_ERR_OK; +} + +#ifdef FIX_HRTF_LOAD + +/*---------------------------------------------------------------------* + * IVAS_DEC_ReadFormat( ) + * + * Read main parameters from the bitstream to set-up the decoder: + * - IVAS fromat + * - IVAS format specific signaling + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_ReadFormat( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_BIN_RENDERER_TYPE *binaural_renderer, /* o : binaural renderer type */ + IVAS_BIN_RENDERER_TYPE *binaural_renderer_sec, /* o : secondary binaural renderer type */ + int16_t *room_reverb_flag, /* o : room reverb flag */ + IVAS_AUDIO_CONFIG *intern_audio_config /* o : internal audio configuration */ +) +{ + ivas_error error; + Decoder_Struct *st_ivas; + IVAS_FORMAT ivas_format_old; + ISM_MODE ism_mode_old; + MC_MODE mc_mode_old; + int16_t nchan_transport_old; + AUDIO_CONFIG intern_config_old, transport_config_old; + RENDERER_TYPE renderer_type_old; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasDec->st_ivas; + ivas_format_old = st_ivas->ivas_format; + ism_mode_old = st_ivas->ism_mode; + mc_mode_old = st_ivas->mc_mode; + nchan_transport_old = st_ivas->nchan_transport; + intern_config_old = st_ivas->intern_config; + transport_config_old = st_ivas->transport_config; + renderer_type_old = st_ivas->renderer_type; + + if ( st_ivas->ivas_format == MONO_FORMAT ) + { + return IVAS_ERR_OK; + } + + if ( st_ivas->bfi == 0 ) + { + if ( ( error = ivas_dec_get_format( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ivas_format_old != st_ivas->ivas_format && st_ivas->ini_frame > 0 && !( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) ) + { + return ( IVAS_ERROR( IVAS_ERR_INVALID_INPUT_FORMAT, "IVAS format switching is not allowed." ) ); + } + + ivas_renderer_select( st_ivas ); + + switch ( st_ivas->renderer_type ) + { + case RENDERER_BINAURAL_OBJECTS_TD: + *binaural_renderer = IVAS_BIN_RENDERER_TYPE_TDREND; + break; + case RENDERER_BINAURAL_MIXER_CONV: + case RENDERER_BINAURAL_MIXER_CONV_ROOM: + *binaural_renderer = IVAS_BIN_RENDERER_TYPE_CREND; + break; + case RENDERER_BINAURAL_FASTCONV: + *binaural_renderer = IVAS_BIN_RENDERER_TYPE_FASTCONV; + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + { + *room_reverb_flag = 1; + } + + break; + case RENDERER_BINAURAL_FASTCONV_ROOM: + *binaural_renderer = IVAS_BIN_RENDERER_TYPE_FASTCONV; + *room_reverb_flag = 1; + break; + case RENDERER_BINAURAL_PARAMETRIC: + case RENDERER_BINAURAL_PARAMETRIC_ROOM: + *binaural_renderer = IVAS_BIN_RENDERER_TYPE_PARAMBIN; + break; + default: + *binaural_renderer = IVAS_BIN_RENDERER_TYPE_NONE; + break; + } + + *binaural_renderer_sec = IVAS_BIN_RENDERER_TYPE_NONE; + if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL ) + { + *binaural_renderer_sec = IVAS_BIN_RENDERER_TYPE_TDREND; + } + + *intern_audio_config = st_ivas->intern_config; + + if ( ( renderer_type_old != st_ivas->renderer_type && renderer_type_old != RENDERER_DISABLE ) || + ( st_ivas->ini_active_frame > 0 && ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ism_mode != ISM_MASA_MODE_DISC ) ) + { + /* JBM: when granularity goes down (e.g. Discrete ISM with TD Obj Renderer -> ParamISM with binaural fastconv + render what still fits in the new granularity */ + int16_t tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs ); +#ifdef NONBE_1200_ISM_JBM_BRATE_SW_FLUSH + st_ivas->nchan_transport = nchan_transport_old; +#else + // st_ivas->nchan_transport = nchan_transport_old; // ToDo: temporarily deactivated to keep FIX_HRTF_LOAD bit-exact but this is likely a bug in the main -> see issue #1200 +#endif +#ifndef NONBE_1199_OMASA_JBM_BRATE_SW_FLUSH + if ( st_ivas->ivas_format == MASA_FORMAT ) + { + st_ivas->nchan_ism = 0; // ToDo: temporary hack to keep FIX_HRTF_LOAD bit-exact but this is likely a bug in the main -> see issue #1199 + } + +#endif + if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) + { + if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &st_ivas->hIntSetup, mc_mode_old, ism_mode_old, &hIvasDec->nSamplesFlushed, pcm_type_API_to_internal( hIvasDec->pcmType ), hIvasDec->flushbuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + } + + st_ivas->ism_mode = ism_mode_old; + st_ivas->mc_mode = mc_mode_old; + st_ivas->nchan_transport = nchan_transport_old; + st_ivas->intern_config = intern_config_old; + st_ivas->transport_config = transport_config_old; + st_ivas->renderer_type = renderer_type_old; + + return IVAS_ERR_OK; +} + +#endif +#if ( defined FIX_HRTF_LOAD || defined OBJ_EDITING_API ) + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSamplesDecoder( ) + * + * Main function to decode transport channels, do TSM and feed to renderer. + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetSamplesDecoder( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t isSplitRend, /* i : split rendering enabled flag */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + ivas_error error; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* If TSM is generally enabled, we have to wait for the first good frame. + Otherwise, we directly decode the first frame in any case. */ +#ifdef FIX_HRTF_LOAD + if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) +#else if ( ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && hIvasDec->hasBeenFedFirstGoodFrame ) || !hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) +#endif { uint16_t l_ts, nTimeScalerOutSamples; +#ifdef FIX_HRTF_LOAD + uint8_t nTransportChannels; +#else uint8_t nTransportChannels, nOutChannels; +#endif int16_t nResidualSamples, nSamplesTcsScaled, nOutSamplesElse; if ( isSplitRend ) @@ -938,7 +1121,11 @@ ivas_error IVAS_DEC_FeedFrame_Serial( } } +#ifdef FIX_HRTF_LOAD + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &hIvasDec->nSamplesFlushed, hIvasDec->pcmType, hIvasDec->flushbuffer ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -995,6 +1182,8 @@ ivas_error IVAS_DEC_FeedFrame_Serial( } hIvasDec->hasBeenFedFrame = false; } + +#ifdef OBJ_EDITING_API hIvasDec->hasBeenPreparedRendering = false; if ( hIvasDec->st_ivas->hIsmMetaData[0] ) @@ -1045,6 +1234,7 @@ ivas_error IVAS_DEC_FeedFrame_Serial( return IVAS_ERR_OK; } +#endif #ifdef OBJ_EDITING_API /*---------------------------------------------------------------------* @@ -1052,18 +1242,31 @@ ivas_error IVAS_DEC_FeedFrame_Serial( * * *---------------------------------------------------------------------*/ + ivas_error IVAS_DEC_GetEditableParameters( - IVAS_DEC_HANDLE hIvasDec, - IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters ) + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters /* o : object editing parameters handle */ +) { - ivas_error error; - int16_t dirac_read_idx; + int16_t dirac_read_idx, obj; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasEditableParameters == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } +#ifdef FIX_BRATE_SWITCHING + if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || + hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT || + hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT || + ( hIvasDec->st_ivas->ivas_format == MASA_FORMAT && hIvasDec->st_ivas->nchan_ism > 0 ) ) ) +#else if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || ( hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT && hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) || ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) ) ) +#endif { - return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Object editing no supported in this operation mode." ); + return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing is not supported in this operation mode." ); } if ( hIvasEditableParameters == NULL || hIvasDec == NULL || hIvasDec->st_ivas == NULL ) @@ -1077,7 +1280,6 @@ ivas_error IVAS_DEC_GetEditableParameters( { if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_DISC || hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - int16_t obj; for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) { hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth; @@ -1088,6 +1290,7 @@ ivas_error IVAS_DEC_GetEditableParameters( hIvasEditableParameters->ism_metadata[obj].gain = hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain; hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag; } + if ( hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { hIvasEditableParameters->gain_bed = 1.0f; @@ -1095,7 +1298,6 @@ ivas_error IVAS_DEC_GetEditableParameters( } else if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_PARAM ) { - int16_t obj; for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) { hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hParamIsmDec->azimuth_values[obj]; @@ -1107,17 +1309,21 @@ ivas_error IVAS_DEC_GetEditableParameters( hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = 0; } } + else if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_NONE ) + { + hIvasEditableParameters->num_obj = 0; + } +#ifdef DEBUGGING else { assert( 0 && "This should never happen!" ); } +#endif } #ifdef OMASA_OBJECT_EDITING else if ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) { /* object editing possible only in two highest OMASA modes */ - int16_t obj; - if ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) @@ -1164,29 +1370,41 @@ ivas_error IVAS_DEC_GetEditableParameters( } #endif - error = IVAS_ERR_OK; - - return error; + return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * IVAS_DEC_SetEditableParameters( ) * * Main function to decode to PCM data *---------------------------------------------------------------------*/ + ivas_error IVAS_DEC_SetEditableParameters( - IVAS_DEC_HANDLE hIvasDec, - IVAS_EDITABLE_PARAMETERS hIvasEditableParameters ) + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_EDITABLE_PARAMETERS hIvasEditableParameters /* i : object editing parameters handle */ +) { - ivas_error error; - int16_t dirac_read_idx; + int16_t dirac_read_idx, obj; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + +#ifdef FIX_BRATE_SWITCHING + if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || + hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT || + hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT || + ( hIvasDec->st_ivas->ivas_format == MASA_FORMAT && hIvasDec->st_ivas->nchan_ism > 0 ) ) ) +#else if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || ( hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT && hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) || ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) ) || hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) +#endif { - return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Object editing no supported in this operation mode." ); + return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing no supported in this operation mode." ); } if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) @@ -1194,8 +1412,6 @@ ivas_error IVAS_DEC_SetEditableParameters( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - error = IVAS_ERR_OK; - #ifdef DEBUGGING assert( hIvasEditableParameters.num_obj == hIvasDec->st_ivas->nchan_ism ); #endif @@ -1204,7 +1420,6 @@ ivas_error IVAS_DEC_SetEditableParameters( { if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_DISC || hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - int16_t obj; for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) { hIvasDec->st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; @@ -1226,7 +1441,6 @@ ivas_error IVAS_DEC_SetEditableParameters( } else if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_PARAM ) { - int16_t obj; for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) { #ifdef OBJ_EDITING_PARAMISM_BIN @@ -1256,11 +1470,19 @@ ivas_error IVAS_DEC_SetEditableParameters( } #endif } + #ifdef OBJ_EDITING_PARAMISM_BIN /* MASA is not present with the ISM format */ hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; #endif } + else if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_NONE ) + { + if ( hIvasEditableParameters.num_obj != 0 ) + { + return IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED; + } + } else { assert( 0 && "This should never happen!" ); @@ -1269,8 +1491,7 @@ ivas_error IVAS_DEC_SetEditableParameters( #ifdef OMASA_OBJECT_EDITING else if ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) { - int16_t obj; - int32_t id_th; + int16_t id_th; float threshold_azi, threshold_ele; for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) @@ -1315,7 +1536,7 @@ ivas_error IVAS_DEC_SetEditableParameters( * which in turn depends from the object priority and importance: * importance -> priority -> number of bits -> elevation resolution -> elevation ring index -> azimuth resolution. * leading to elevation_resolution -> elevation threshold and azimuth resolution -> azimuth threshold */ - id_th = (int) ( fabsf( (float) hIvasDec->st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); + id_th = (int16_t) ( fabsf( (float) hIvasDec->st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); threshold_azi = 360.0f / (float) no_phi_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 1][id_th]; threshold_ele = delta_theta_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 3]; @@ -1387,34 +1608,43 @@ ivas_error IVAS_DEC_SetEditableParameters( } #endif - return error; + return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * IVAS_DEC_PrepareRenderer( ) * - * prepare IVAS JBM renderer + * prepare IVAS renderer *---------------------------------------------------------------------*/ + ivas_error IVAS_DEC_PrepareRenderer( IVAS_DEC_HANDLE hIvasDec ) { - ivas_error error; - - error = IVAS_ERR_OK; - - if ( hIvasDec == NULL ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - ivas_jbm_dec_prepare_renderer( hIvasDec->st_ivas ); + ivas_dec_prepare_renderer( hIvasDec->st_ivas ); + hIvasDec->hasBeenPreparedRendering = true; - return error; -} + return IVAS_ERR_OK; +} #endif +#ifdef OBJ_EDITING_API + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSamplesRenderer( ) + * + * Main function to render the decoded data to output data + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetSamplesRenderer( +#else /*---------------------------------------------------------------------* * IVAS_DEC_GetSamples( ) * @@ -1423,6 +1653,7 @@ ivas_error IVAS_DEC_PrepareRenderer( ivas_error IVAS_DEC_GetSamples( +#endif IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ @@ -1450,7 +1681,6 @@ ivas_error IVAS_DEC_GetSamples( nTransportChannels = 0; #endif - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; @@ -1524,9 +1754,9 @@ ivas_error IVAS_DEC_GetSamples( } } #endif +#ifndef OBJ_EDITING_API { /* check if we need to run the setup function, tc decoding and feeding the renderer */ -#ifndef OBJ_EDITING_API if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) { int16_t nResidualSamples, nSamplesTcsScaled; @@ -1589,34 +1819,34 @@ ivas_error IVAS_DEC_GetSamples( hIvasDec->hasBeenFedFrame = false; } #else - nOutChannels = (uint8_t) hIvasDec->st_ivas->hDecoderConfig->nchan_out; - hIvasDec->hasBeenFedFrame = false; - /* check for possible flushed samples from a rate switch */ - if ( hIvasDec->nSamplesFlushed > 0 ) - { - void *pPcmBuffer; + nOutChannels = (uint8_t) hIvasDec->st_ivas->hDecoderConfig->nchan_out; + hIvasDec->hasBeenFedFrame = false; + /* check for possible flushed samples from a rate switch */ + if ( hIvasDec->nSamplesFlushed > 0 ) + { + void *pPcmBuffer; #ifdef DEBUGGING - assert( hIvasDec->pcmType == pcmType ); + assert( hIvasDec->pcmType == pcmType ); #endif - pPcmBuffer = pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ); - if ( pcmType == IVAS_DEC_PCM_INT16 ) - { - mvs2s( (int16_t *) hIvasDec->flushbuffer, pPcmBuffer, hIvasDec->nSamplesFlushed * nOutChannels ); - } - else if ( pcmType == IVAS_DEC_PCM_FLOAT ) - { - mvr2r( (float *) hIvasDec->flushbuffer, pPcmBuffer, hIvasDec->nSamplesFlushed * nOutChannels ); - } + pPcmBuffer = pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ); + if ( pcmType == IVAS_DEC_PCM_INT16 ) + { + mvs2s( (int16_t *) hIvasDec->flushbuffer, pPcmBuffer, hIvasDec->nSamplesFlushed * nOutChannels ); + } + else if ( pcmType == IVAS_DEC_PCM_FLOAT ) + { + mvr2r( (float *) hIvasDec->flushbuffer, pPcmBuffer, hIvasDec->nSamplesFlushed * nOutChannels ); + } #ifdef DEBUGGING - else - { - assert( 0 && "wrong PCM type for the flush buffer!" ); - } -#endif - nSamplesRendered += hIvasDec->nSamplesFlushed; - hIvasDec->nSamplesFlushed = 0; + else + { + assert( 0 && "wrong PCM type for the flush buffer!" ); } #endif + nSamplesRendered += hIvasDec->nSamplesFlushed; + hIvasDec->nSamplesFlushed = 0; + } +#endif /* render IVAS frames directly to the output buffer */ nSamplesToRender = nSamplesAsked - nSamplesRendered; @@ -1636,7 +1866,9 @@ ivas_error IVAS_DEC_GetSamples( { *needNewFrame = false; } +#ifndef OBJ_EDITING_API } +#endif } *nOutSamples = nSamplesRendered; @@ -1679,13 +1911,11 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( int16_t ro_md_flag; IVAS_QUATERNION Quaternion; -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#endif error = IVAS_ERR_OK; st_ivas = hIvasDec->st_ivas; output_config = st_ivas->hDecoderConfig->output_config; @@ -1700,8 +1930,8 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( { return error; } -#endif +#endif numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; #ifdef OBJ_EDITING_API @@ -1709,6 +1939,10 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( if ( hIvasDec->flushbuffer == NULL ) { hIvasDec->flushbuffer = (void *) malloc( numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float ) ); + if ( hIvasDec->flushbuffer == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate flush buffer" ); + } hIvasDec->pcmType = IVAS_DEC_PCM_FLOAT; set_zero( (float *) hIvasDec->flushbuffer, numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); } @@ -1744,11 +1978,19 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( } } +#ifdef OBJ_EDITING_API + /* render */ + if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, numSamplesPerChannelToDecode, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) + { + return error; + } +#else /* Decode and render */ if ( ( error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannelToDecode, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) { return error; } +#endif /* change buffer layout */ for ( i = 0; i < numSamplesPerChannelToDecode; ++i ) @@ -1859,30 +2101,38 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( *---------------------------------------------------------------------*/ static ivas_error IVAS_DEC_Setup( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t *nTcBufferGranularity, /* o : granularity of the TC Buffer */ - uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t *nTcBufferGranularity, /* o : granularity of the TC Buffer */ + uint8_t *nTransportChannels /* o : number of decoded transport PCM channels */ +#ifndef FIX_HRTF_LOAD + , uint8_t *nOutChannels, /* o : number of decoded out channels (PCM or CLDFB) */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame */ const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ +#endif ) { ivas_error error; +#ifndef FIX_HRTF_LOAD *nSamplesRendered = 0; - +#endif if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { if ( hIvasDec->st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) { *nTransportChannels = MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; +#ifndef FIX_HRTF_LOAD *nOutChannels = MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; +#endif } else { *nTransportChannels = 1; +#ifndef FIX_HRTF_LOAD *nOutChannels = 1; +#endif } } else @@ -1901,7 +2151,11 @@ static ivas_error IVAS_DEC_Setup( if ( st_ivas->bfi == 0 ) { +#ifdef FIX_HRTF_LOAD + if ( ( error = ivas_dec_setup( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_dec_setup( st_ivas, nSamplesRendered, pcm_type_API_to_internal( pcmType ), data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1909,8 +2163,9 @@ static ivas_error IVAS_DEC_Setup( *nTransportChannels = (uint8_t) st_ivas->hTcBuffer->nchan_transport_jbm; *nTcBufferGranularity = (uint16_t) st_ivas->hTcBuffer->n_samples_granularity; +#ifndef FIX_HRTF_LOAD *nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; - +#endif /*-----------------------------------------------------------------* * ISAR: @@ -2129,13 +2384,11 @@ ivas_error IVAS_DEC_GetFormat( IVAS_DEC_BS_FORMAT *format /* o : format detected from bitstream fed to the decoder */ ) { -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#endif if ( hIvasDec->hasDecodedFirstGoodFrame ) { *format = mapIvasFormat( hIvasDec->st_ivas->ivas_format ); @@ -2229,13 +2482,11 @@ ivas_error IVAS_DEC_GetNumOutputChannels( int16_t *numOutputChannels /* o : number of PCM output channels */ ) { -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#endif if ( hIvasDec->hasDecodedFirstGoodFrame ) { *numOutputChannels = hIvasDec->st_ivas->hDecoderConfig->nchan_out; @@ -2319,7 +2570,6 @@ ivas_error IVAS_DEC_GetObjectMetadata( metadata->gainFactor = hIsmMeta->edited_gain; metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; } -#ifdef OBJ_EDITING_API else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { metadata->azimuth = st_ivas->hParamIsmDec->edited_azimuth_values[objectIdx]; @@ -2331,7 +2581,6 @@ ivas_error IVAS_DEC_GetObjectMetadata( metadata->gainFactor = 1.f; metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; } -#endif else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { metadata->azimuth = st_ivas->hIsmMetaData[objectIdx]->edited_azimuth; @@ -2712,6 +2961,137 @@ ivas_error IVAS_DEC_GetHrtfStatisticsHandle( return IVAS_ERR_OK; } +#ifdef FIX_HRTF_LOAD + +/*---------------------------------------------------------------------* + * IVAS_DEC_HRTF_binary_open( ) + * + * Allocate HRTF binary handles + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_HRTF_binary_open( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_BIN_RENDERER_TYPE binaural_renderer /* i : binaural renderer type */ +) +{ + ivas_error error; + Decoder_Struct *st_ivas; + + st_ivas = hIvasDec->st_ivas; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) + { + /* TD binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfTD == NULL ) + { + if ( ( error = ivas_HRTF_binary_open( &( st_ivas->hHrtfTD ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* Crend binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hSetOfHRTF == NULL ) + { + if ( ( error = ivas_HRTF_CRend_binary_open( &( st_ivas->hSetOfHRTF ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* FastConv binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfFastConv == NULL ) + { + if ( ( error = ivas_HRTF_fastconv_binary_open( &st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* Parametric binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfParambin == NULL ) + { + if ( ( error = ivas_HRTF_parambin_binary_open( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( st_ivas->hHrtfStatistics == NULL ) + { + if ( ( error = ivas_HRTF_statistics_binary_open( &st_ivas->hHrtfStatistics ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_HRTF_binary_close( ) + * + * + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_HRTF_binary_close( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_BIN_RENDERER_TYPE binaural_renderer_old /* i : previous binaural renderer type */ +) +{ + Decoder_Struct *st_ivas; + + st_ivas = hIvasDec->st_ivas; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary && st_ivas->ini_frame > 0 ) + { + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && + ( hIvasDec->st_ivas->ivas_format != SBA_ISM_FORMAT ) // ToDo: temporary hack to avoid ASAN errors -> see issue #1202 + ) + { + ivas_HRTF_binary_close( &st_ivas->hHrtfTD ); + } + + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + { + /* CRend binaural renderer handle */ + ivas_HRTF_CRend_binary_close( &st_ivas->hSetOfHRTF ); + } + + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + { + /* Fastconv HRTF memories */ + ivas_binaural_hrtf_close( &st_ivas->hHrtfFastConv ); + + /* Fastconv HRTF filters */ + ivas_HRTF_fastconv_binary_close( &st_ivas->hHrtfFastConv ); + } + + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + { + + /* Parametric binauralizer HRTF filters */ + ivas_HRTF_parambin_binary_close( &st_ivas->hHrtfParambin ); + } + } + + return IVAS_ERR_OK; +} + +#endif + /*---------------------------------------------------------------------* * copyRendererConfigStruct( ) * @@ -2782,6 +3162,13 @@ ivas_error IVAS_DEC_GetRenderConfig( return copyRendererConfigStruct( hIvasDec->st_ivas->hRenderConfig, hRCout ); } + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetDefaultRenderConfig( ) + * + * + *---------------------------------------------------------------------*/ + /*! r: error code*/ ivas_error IVAS_DEC_GetDefaultRenderConfig( IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render config handle */ @@ -2877,7 +3264,19 @@ ivas_error IVAS_DEC_FeedRenderConfig( if ( hIvasDec->st_ivas->hDiracDecBin[0] != NULL && hIvasDec->st_ivas->hDiracDecBin[0]->hReverb != NULL ) { ivas_binaural_reverb_close( &( hIvasDec->st_ivas->hDiracDecBin[0]->hReverb ) ); - if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hDiracDecBin[0]->hReverb ), hIvasDec->st_ivas->hHrtfStatistics, hIvasDec->st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), hIvasDec->st_ivas->hDecoderConfig->output_Fs, NULL, NULL ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hDiracDecBin[0]->hReverb ), + hIvasDec->st_ivas->hHrtfStatistics, + hIvasDec->st_ivas->hSpatParamRendCom->num_freq_bands, + CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( hRenderConfig->roomAcoustics ), + hIvasDec->st_ivas->hDecoderConfig->output_Fs, + NULL, + NULL +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + NULL +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -2886,7 +3285,19 @@ ivas_error IVAS_DEC_FeedRenderConfig( if ( hIvasDec->st_ivas->hBinRenderer != NULL && hIvasDec->st_ivas->hBinRenderer->hReverb != NULL ) { ivas_binaural_reverb_close( &( hIvasDec->st_ivas->hBinRenderer->hReverb ) ); - if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hBinRenderer->hReverb ), hIvasDec->st_ivas->hHrtfStatistics, hIvasDec->st_ivas->hBinRenderer->conv_band, hIvasDec->st_ivas->hBinRenderer->timeSlots, &( hRenderConfig->roomAcoustics ), hIvasDec->st_ivas->hDecoderConfig->output_Fs, NULL, NULL ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hBinRenderer->hReverb ), + hIvasDec->st_ivas->hHrtfStatistics, + hIvasDec->st_ivas->hBinRenderer->conv_band, + hIvasDec->st_ivas->hBinRenderer->timeSlots, + &( hRenderConfig->roomAcoustics ), + hIvasDec->st_ivas->hDecoderConfig->output_Fs, + NULL, + NULL +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + NULL +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -3089,13 +3500,11 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( int16_t partialCopyFrameType, partialCopyOffset; int16_t result; -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || au == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#endif if ( auSize == 0 ) { return IVAS_ERR_OK; /* ignore empty/NO_DATA frame - shouldn't be transmitted in RTP */ @@ -3162,6 +3571,7 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_SetScale( ) * @@ -3174,22 +3584,12 @@ ivas_error IVAS_DEC_VoIP_SetScale( const int16_t scale /* i : TSM scale to set in percent of the default frame size */ ) { -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#else - ivas_error error; - - error = IVAS_ERR_OK; -#endif -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm == 0 ) -#else - if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm == false ) -#endif { return IVAS_ERR_TSM_NOT_ENABLED; } @@ -3199,11 +3599,7 @@ ivas_error IVAS_DEC_VoIP_SetScale( hIvasDec->tsm_max_scaling = maxScaling; } -#ifdef FIX_VOIP_FUNCTIONS return IVAS_ERR_OK; -#else - return error; -#endif } @@ -3227,13 +3623,11 @@ ivas_error IVAS_DEC_TSM_SetQuality( const float quality /* i : target TSM quality */ ) { -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#endif if ( !hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) { return IVAS_ERR_TSM_NOT_ENABLED; @@ -3254,21 +3648,22 @@ ivas_error IVAS_DEC_TSM_SetQuality( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_VoIP_GetSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ - const uint32_t systemTimestamp_ms /* i : current system timestamp */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ #ifdef SUPPORT_JBM_TRACEFILE - , JbmTraceFileWriterFn jbmWriterFn, - void *jbmWriter + void *jbmWriter, +#endif +#ifdef FIX_HRTF_LOAD + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ #endif #ifdef OBJ_EDITING_API - , - uint16_t *nSamplesRendered, - bool *parametersAvailableForEditing + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ #endif + const uint32_t systemTimestamp_ms /* i : current system timestamp */ ) { Decoder_Struct *st_ivas; @@ -3284,13 +3679,11 @@ ivas_error IVAS_DEC_VoIP_GetSamples( #endif uint8_t nOutChannels; -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->hVoIP == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#endif st_ivas = hIvasDec->st_ivas; hDecoderConfig = st_ivas->hDecoderConfig; hVoIP = hIvasDec->hVoIP; @@ -3385,28 +3778,35 @@ ivas_error IVAS_DEC_VoIP_GetSamples( bsCompactToSerial( dataUnit->data, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize ); - - if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 -#if defined( OBJ_EDITING_API ) - , - 0, - 0 +#ifdef FIX_HRTF_LOAD + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 ) ) != IVAS_ERR_OK ) +#else +#ifdef OBJ_EDITING_API + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0, 0, 0 ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 ) ) != IVAS_ERR_OK ) +#endif #endif - ) ) != IVAS_ERR_OK ) { return error; } +#ifdef FIX_HRTF_LOAD + + *bitstreamReadDone = true; +#endif } else if ( hIvasDec->hasDecodedFirstGoodFrame ) { /* Decoder has been initialized with first good frame - do PLC */ - if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 -#if defined( OBJ_EDITING_API ) - , - 0, - 0 +#ifdef FIX_HRTF_LOAD + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 ) ) != IVAS_ERR_OK ) +#else +#ifdef OBJ_EDITING_API + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1, 0, 0 ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 ) ) != IVAS_ERR_OK ) +#endif #endif - ) ) != IVAS_ERR_OK ) { return error; } @@ -3440,14 +3840,22 @@ ivas_error IVAS_DEC_VoIP_GetSamples( JB4_FreeDataUnit( hVoIP->hJBM, dataUnit ); } +#ifdef FIX_HRTF_LOAD + if ( hIvasDec->hasBeenFedFirstGoodFrame && *bitstreamReadDone == true ) + { + /* new bitstream was feeded, return for reconfiguration */ + return IVAS_ERR_OK; + } + +#endif if ( !hIvasDec->hasBeenFedFirstGoodFrame ) { hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; hIvasDec->nSamplesRendered = 0; } + #ifdef OBJ_EDITING_API - /* :TODO: only return here if we really have editing initialized */ - if ( hIvasDec->hasBeenFedFirstGoodFrame && hIvasDec->hasEditableParameters == true && hIvasDec->enableParameterEditing == true ) + if ( hIvasDec->hasBeenFedFirstGoodFrame ) { *parametersAvailableForEditing = true; return IVAS_ERR_OK; @@ -3477,6 +3885,27 @@ ivas_error IVAS_DEC_VoIP_GetSamples( { int16_t nSamplesToRender, nSamplesRendered_loop; bool tmp; + +#ifdef FIX_HRTF_LOAD + /* decode TCs, do TSM and prepare the renderer */ + if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) + { + if ( hIvasDec->nSamplesAvailableNext == 0 || hIvasDec->nSamplesAvailableNext == hIvasDec->nSamplesFrame ) + { + uint16_t nSamplesFlushed_ref = hIvasDec->nSamplesFlushed; + + if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, 0, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + hIvasDec->nSamplesFlushed = nSamplesFlushed_ref; + + *bitstreamReadDone = false; + } + } +#endif + #ifdef OBJ_EDITING_API nSamplesToRender = nSamplesPerChannel - *nSamplesRendered; #else @@ -3487,7 +3916,6 @@ ivas_error IVAS_DEC_VoIP_GetSamples( /* check if we still need to prepare the renderer */ if ( hIvasDec->hasBeenPreparedRendering == false ) { - if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) { return error; @@ -3495,9 +3923,9 @@ ivas_error IVAS_DEC_VoIP_GetSamples( } #endif - /* render IVAS frames directly to the output buffer */ + /* render IVAS frames directly to the output buffer */ #ifdef OBJ_EDITING_API - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) #endif @@ -3561,13 +3989,11 @@ ivas_error IVAS_DEC_Flush( uint16_t nSamplesToRender; uint16_t nSamplesFlushedLocal; -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#endif *nSamplesFlushed = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); nSamplesToRender = (uint16_t) *nSamplesFlushed; @@ -3596,13 +4022,11 @@ bool IVAS_DEC_VoIP_IsEmpty( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesAsked ) { -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#endif return ( ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->nSamplesAvailableNext < nSamplesAsked ) ); } @@ -3709,11 +4133,7 @@ ivas_error IVAS_DEC_GetJbmData( ) { -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || JbmTraceData == NULL ) -#else - if ( hIvasDec->hVoIP == NULL ) -#endif { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -4004,6 +4424,13 @@ static ivas_error printConfigInfo_dec( { fprintf( stdout, "Acoustic environment ID:ON\n" ); } +#ifdef OBJ_EDITING_COMMANDLINE + + if ( st_ivas->hDecoderConfig->Opt_ObjEdit_on ) + { + fprintf( stdout, "Objects editing : ON\n" ); + } +#endif } /*-----------------------------------------------------------------* @@ -4025,29 +4452,19 @@ static ivas_error printConfigInfo_dec( * Print decoder set-up info *---------------------------------------------------------------------*/ -#ifdef FIX_VOIP_FUNCTIONS ivas_error IVAS_DEC_PrintConfig( -#else -void IVAS_DEC_PrintConfig( -#endif const IVAS_DEC_HANDLE hIvasDec, const bool quietModeEnabled, const bool voipMode ) { -#ifdef FIX_VOIP_FUNCTIONS if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#endif printConfigInfo_dec( hIvasDec->st_ivas, hIvasDec->bitstreamformat, voipMode, quietModeEnabled ); -#ifdef FIX_VOIP_FUNCTIONS return IVAS_ERR_OK; -#else - return; -#endif } diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 50476c964bda0a25f0e19907be177b64ad6a0533..fb5cee39fa042d36f9fd61bc22c9e37a624eac44 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -123,7 +123,7 @@ ivas_error IVAS_DEC_Configure( const uint32_t sampleRate, /* i : output sampling frequency */ const IVAS_AUDIO_CONFIG outputConfig, /* i : audio configuration */ const bool tsmEnabled, /* i : enable TSM */ - const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ + const IVAS_RENDER_FRAMESIZE renderFramesize,/* i : rendering frame size */ const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ const bool enableHeadRotation, /* i : enable head rotation for binaural output */ @@ -134,6 +134,9 @@ ivas_error IVAS_DEC_Configure( const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ const bool dpidEnabled, /* i : enable directivity pattern option */ const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ +#ifdef OBJ_EDITING_COMMANDLINE + const bool objEditEnabled, /* i : enable object editing */ +#endif const bool delayCompensationEnabled /* i : enable delay compensation */ ); @@ -149,23 +152,47 @@ ivas_error IVAS_DEC_FeedFrame_Serial( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t *serial, /* i : buffer containing serial input bitstream. Each bit should be stored as a single uint16_t value */ const uint16_t num_bits, /* i : number of bits in input bitstream */ +#ifdef FIX_HRTF_LOAD + int16_t bfi /* i : bad frame indicator flag */ +#else +#ifdef OBJ_EDITING_API + int16_t bfi, /* i : bad frame indicator flag */ + const int16_t isSplitRend, /* i : split rendering enabled flag */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +#else int16_t bfi /* i : bad frame indicator flag */ -#if defined( OBJ_EDITING_API ) - , - int16_t isSplitRend, - ISAR_SPLIT_REND_BITS_DATA *splitRendBits +#endif #endif ); +#ifdef FIX_HRTF_LOAD +ivas_error IVAS_DEC_ReadFormat( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_BIN_RENDERER_TYPE *binaural_renderer, /* o : binaural renderer type */ + IVAS_BIN_RENDERER_TYPE *binaural_renderer_sec,/* o: secondary binaural renderer type */ + int16_t *room_reverb_flag, /* o : room reverb flag */ + IVAS_AUDIO_CONFIG *intern_audio_config /* o : internal audio configuration */ +); + +#endif +#if( defined FIX_HRTF_LOAD || defined OBJ_EDITING_API) +/*! r: decoder error code */ +ivas_error IVAS_DEC_GetSamplesDecoder( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t isSplitRend, /* i : split rendering enabled flag */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +); + +#endif #ifdef OBJ_EDITING_API ivas_error IVAS_DEC_GetEditableParameters( - IVAS_DEC_HANDLE hIvasDec, - IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters /* o : object editing parameters handle */ ); ivas_error IVAS_DEC_SetEditableParameters( - IVAS_DEC_HANDLE hIvasDec, - IVAS_EDITABLE_PARAMETERS hIvasEditableParameters + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_EDITABLE_PARAMETERS hIvasEditableParameters /* i : object editing parameters handle */ ); ivas_error IVAS_DEC_PrepareRenderer( @@ -174,7 +201,11 @@ ivas_error IVAS_DEC_PrepareRenderer( #endif /*! r: decoder error code */ +#ifdef OBJ_EDITING_API +ivas_error IVAS_DEC_GetSamplesRenderer( +#else ivas_error IVAS_DEC_GetSamples( +#endif IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ @@ -299,16 +330,18 @@ ivas_error IVAS_DEC_VoIP_GetSamples( uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ void *pcmBuf, /* o : output synthesis signal */ - const uint32_t systemTimestamp_ms /* i : current system timestamp */ #ifdef SUPPORT_JBM_TRACEFILE - , JbmTraceFileWriterFn jbmWriterFn, - void* jbmWriter + JbmTraceFileWriterFn jbmWriterFn, + void *jbmWriter, +#endif +#ifdef FIX_HRTF_LOAD + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ #endif #ifdef OBJ_EDITING_API - , - uint16_t *nSamplesRendered, - bool *parametersAvailableForEditing + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ #endif + const uint32_t systemTimestamp_ms /* i : current system timestamp */ ); ivas_error IVAS_DEC_Flush( @@ -451,6 +484,18 @@ ivas_error IVAS_DEC_GetHrtfStatisticsHandle( IVAS_DEC_HRTF_STATISTICS_HANDLE **hHrtfStatistics /* o : HRTF statistics handle */ ); +#ifdef FIX_HRTF_LOAD +ivas_error IVAS_DEC_HRTF_binary_open( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_BIN_RENDERER_TYPE binaural_renderer /* i : binaural renderer type */ +); + +ivas_error IVAS_DEC_HRTF_binary_close( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_BIN_RENDERER_TYPE binaural_renderer_old /* i : previous binaural renderer type */ +); + +#endif /*! r: error code*/ ivas_error IVAS_DEC_GetRenderConfig( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ @@ -513,11 +558,7 @@ const char *IVAS_DEC_GetErrorMessage( ivas_error error /* i : decoder error code enum */ ); -#ifdef FIX_VOIP_FUNCTIONS ivas_error IVAS_DEC_PrintConfig( -#else -void IVAS_DEC_PrintConfig( -#endif const IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ const bool quietModeEnabled, /* i : quiet mode flag: if true, reduces the amount of config info printed */ const bool voipMode diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index 9ed4a298e64a96fb1a68b56cb2ec7475ab92cd2c..12b5236964ac1c3f4f6f60bde8b9f0eef8700d05 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -545,7 +545,11 @@ void TonalMDCTConceal_InsertNoise( for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) { +#ifdef NONBE_FIX_1212_TONAL_MDCT_CONCEALMENT + mdctSpectrum[l] = 0.0f; +#else mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; +#endif } } /* actual fadeout is done in this case */ diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index a3a2bec2573d72bcaa9d7b193ecede972e1c3900..292cbd6a5fc4d2738e8d0b94c3c76600dffb7fd9 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -471,6 +471,10 @@ ivas_error ivas_cpe_enc( for ( n = 0; n < n_CoreChannels; n++ ) { +#ifdef DEBUGGING + st_ivas->noClipping += check_clipping( hCPE->hCoreCoder[n]->input, input_frame, &st_ivas->maxOverload, &st_ivas->minOverload ); + +#endif error = pre_proc_front_ivas( NULL, hCPE, hCPE->element_brate, nb_bits_metadata, input_frame, n, old_inp_12k8[n], old_inp_16k[n], &ener[n], &relE[n], A[n], Aw[n], epsP[n], lsp_new[n], lsp_mid[n], &vad_hover_flag[n], &attack_flag[n], realBuffer[n], imagBuffer[n], old_wsp[n], pitch_fr[n], voicing_fr[n], &loc_harm[n], &cor_map_sum[n], &vad_flag_dtx[n], enerBuffer[n], diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 05621dfaaaf765870ec498d27afefef931b71ce9..c4ad5e3c9cadae7f1c40fcf244126a462d78312b 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -161,9 +161,11 @@ void ivas_write_format_sid( case ISM_FORMAT: ind = SID_ISM; break; +#ifndef FIX_1209_SID_SIGNALING case MC_FORMAT: ind = SID_MULTICHANNEL; break; +#endif case SBA_FORMAT: switch ( element_mode ) { @@ -410,6 +412,11 @@ ivas_error ivas_init_encoder( st_ivas->nchan_transport = -1; +#ifdef DEBUGGING + st_ivas->noClipping = 0; + st_ivas->maxOverload = 0; + st_ivas->minOverload = 0; +#endif /*-----------------------------------------------------------------* * Allocate floating-point input audio buffers *-----------------------------------------------------------------*/ diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 6e2732f44a4e3e5c34d70b033f1023522519658b..c72431bd0bbba983877532e2df681f8215524060 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -172,6 +172,10 @@ ivas_error ivas_ism_enc( * Front Pre-processing *----------------------------------------------------------------*/ +#ifdef DEBUGGING + st_ivas->noClipping += check_clipping( hSCE->hCoreCoder[0]->input, input_frame, &st_ivas->maxOverload, &st_ivas->minOverload ); + +#endif error = pre_proc_front_ivas( hSCE, NULL, hSCE->element_brate, nb_bits_metadata[sce_id], input_frame, 0, old_inp_12k8[sce_id][0], old_inp_16k[sce_id][0], &ener[sce_id][0], &relE[sce_id][0], A[sce_id][0], Aw[sce_id][0], epsP[sce_id][0], lsp_new[sce_id][0], lsp_mid[sce_id][0], &vad_hover_flag[sce_id][0], &attack_flag[sce_id][0], realBuffer[sce_id][0], imagBuffer[sce_id][0], old_wsp[sce_id][0], pitch_fr[sce_id][0], voicing_fr[sce_id][0], &loc_harm[sce_id][0], &cor_map_sum[sce_id][0], &vad_flag_dtx[sce_id][0], enerBuffer[sce_id][0], diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index fcaad77e88476102acab2be2cd1423fec1c154a1..47571ae858b8b930ea988cd25c7238577c0b6f4f 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -1765,14 +1765,7 @@ static void reduce_metadata_further( /* Copy spread coherence to the rest of subframes for the coherence coding algorithm. */ for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) { -#ifdef NONBE_FIX_1174_MCMASA_LBR_LOOP_ERROR hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[0]; -#else - for ( band = 0; band < numCodingBands; band++ ) - { - hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[0]; - } -#endif } /* Surround coherence is already merged through time */ diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index 8f5d472ea95f605c7159b8a4001d6260bbc2c12d..257e8061953cd4b5d4e58d9cca2c7f6aac579660 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -180,6 +180,10 @@ ivas_error ivas_sce_enc( * Front Pre-processing *----------------------------------------------------------------*/ +#ifdef DEBUGGING + st_ivas->noClipping += check_clipping( hSCE->hCoreCoder[0]->input, input_frame, &st_ivas->maxOverload, &st_ivas->minOverload ); + +#endif error = pre_proc_front_ivas( hSCE, NULL, hSCE->element_brate, nb_bits_metadata, input_frame, 0, old_inp_12k8[0], old_inp_16k[0], &ener[0], &relE[0], A[0], Aw[0], epsP[0], lsp_new[0], lsp_mid[0], &vad_hover_flag[0], &attack_flag[0], realBuffer[0], imagBuffer[0], old_wsp[0], pitch_fr[0], voicing_fr[0], &loc_harm[0], &cor_map_sum[0], &vad_flag_dtx[0], enerBuffer[0], diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 4bb9a5f417688a732afcf8b227b81c76c1ba9035..ad844b95d5252e8250c6ab645d2dc5e6dfba8c5d 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1246,6 +1246,11 @@ typedef struct int16_t nCPE; /* number of total CPEs */ SCE_ENC_HANDLE hSCE[MAX_SCE]; /* SCE handles */ CPE_ENC_HANDLE hCPE[MCT_MAX_BLOCKS]; /* CPE handles */ +#ifdef DEBUGGING + int32_t noClipping; /* number of clipped samples */ + float maxOverload; /* Maximum overload value */ + float minOverload; /* Maximum overload value */ +#endif /* multichannel modules */ ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS]; /* ISM metadata handles (storage for one frame of read ISM metadata) */ diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 23e666a7f096a69cbc154b9d6515f4c7efea8923..acc1358db65f612d9e40e5df7a5be79cbbb4d949 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -2417,3 +2417,23 @@ static void init_encoder_config( return; } + +#ifdef DEBUGGING + +/*---------------------------------------------------------------------* + * IVAS_ENC_GetNoCLipping() + * + * return number of clipped samples + *---------------------------------------------------------------------*/ + +int32_t IVAS_ENC_GetNoCLipping( + IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ + float *maxOverload, /* o : Max overload value */ + float *minOverload /* o : Min overload value */ +) +{ + *maxOverload = hIvasEnc->st_ivas->maxOverload; + *minOverload = hIvasEnc->st_ivas->minOverload; + return hIvasEnc->st_ivas->noClipping; +} +#endif diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 2f40c1ab1beda5b883618dbd755b2a68076989f0..7ece6666523f1320245369cd700ef2e732054fd4 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -383,6 +383,13 @@ void IVAS_ENC_PrintDisclaimer( void ); +#ifdef DEBUGGING +int32_t IVAS_ENC_GetNoCLipping( + IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ + float *maxOverload, /* o : Max overload value */ + float *minOverload /* o : Min overload value */ +); +#endif /* clang-format on */ #endif /* LIB_ENC_H */ diff --git a/lib_isar/lib_isar_post_rend.c b/lib_isar/lib_isar_post_rend.c index 101768bb3468183213a7f80db644c3510499abf9..38c25ff21ae4c65dbc75874e129e72d2a5066dcd 100644 --- a/lib_isar/lib_isar_post_rend.c +++ b/lib_isar/lib_isar_post_rend.c @@ -1116,7 +1116,11 @@ ivas_error ISAR_POST_REND_InitConfig( hIvasRend->splitRenderConfig.isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */ hIvasRend->splitRenderConfig.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; hIvasRend->splitRenderConfig.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; +#ifdef FIX_HRTF_LOAD + hIvasRend->splitRenderConfig.rendererSelection = IVAS_BIN_RENDERER_TYPE_DEFAULT; +#else hIvasRend->splitRenderConfig.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; +#endif } return IVAS_ERR_OK; diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 4e23dc51e98ead33f08b8f6d0e8553c5e7bc04e2..19b08dbe81e4498520231e8e52bee2fe074e7417 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -245,9 +245,33 @@ ivas_error ivas_dirac_dec_init_binaural_data( if ( hDiracDecBin->hReverb == NULL && pos_idx == 0 ) /* open reverb only for the main direction */ { #ifdef FIX_587_DEFAULT_REVERB - if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, st_ivas->hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, pRoomAcoustics, output_Fs, ( *phHrtfParambin )->parametricReverberationTimes, ( *phHrtfParambin )->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, + st_ivas->hHrtfStatistics, + nBins, + CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + pRoomAcoustics, + output_Fs, + ( *phHrtfParambin )->parametricReverberationTimes, + ( *phHrtfParambin )->parametricReverberationEneCorrections +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + hDiracDecBin->earlyPartEneCorrection +#endif + ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, st_ivas->hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( st_ivas->hRenderConfig->roomAcoustics ), output_Fs, ( *phHrtfParambin )->parametricReverberationTimes, ( *phHrtfParambin )->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, + st_ivas->hHrtfStatistics, + nBins, + CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( st_ivas->hRenderConfig->roomAcoustics ), + output_Fs, + ( *phHrtfParambin )->parametricReverberationTimes, + ( *phHrtfParambin )->parametricReverberationEneCorrections +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + hDiracDecBin->earlyPartEneCorrection +#endif + ) ) != IVAS_ERR_OK ) #endif { return error; @@ -1222,6 +1246,7 @@ static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( uint16_t ismDirIndex; ismDirIndex = dirIndex - hSpatParamRendCom->numParametricDirections; assert( hMasaIsmData != NULL && "hMasaIsmData should not be NULL if we use it" ); + #ifdef OMASA_OBJECT_EDITING if ( hMasaIsmData->ism_dir_is_edited[ismDirIndex] ) { @@ -2991,7 +3016,6 @@ void ivas_omasa_preProcessStereoTransportsForEditedObjects( float masaEneThisCh[2]; float ratioAccNewDivisor; - gainMasaPow2 = 1.0f; if ( masaGainEdited ) { @@ -3025,6 +3049,7 @@ void ivas_omasa_preProcessStereoTransportsForEditedObjects( panGainsOut[ismDirIndex][ch] = panGainsIn[ismDirIndex][ch]; } } + /* Determine pan enes */ for ( ch = 0; ch < 2; ch++ ) { @@ -3193,15 +3218,17 @@ void ivas_omasa_preProcessStereoTransportsForEditedObjects( #endif /* Limit target energies to non-negative values */ - for ( ch = 0; ch < 2; ch++ ) - { - totalTargetEneCh[ch] = max( totalTargetEneCh[ch], 0.0f ); - } - - /* Diffuse ratio accumulation based on gaining */ +#ifdef NONBE_FIX_1197_OMASA_META_BUFFER + /* due to rounding, the sum may exceed 1.0f ever so slightly, so clip it */ + ratioAccOrig = min( ratioAccOrig, 1.0f ); +#endif if ( masaGainEdited ) { +#ifdef NONBE_FIX_1197_OMASA_META_BUFFER + ratioAccNew += gainMasaPow2 * ( 1.0f - ratioAccOrig ); +#else ratioAccNew += gainMasaPow2 * ( 1 - ratioAccOrig ); +#endif } else { diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index dbe5cc8d0675ff9b442b11d7bfd4bd1e558fe8e6..4b1c5764b7aeacb062136a52403c5603610a018d 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -552,6 +552,7 @@ ivas_error TDREND_Update_object_positions( { return error; } + #ifdef OBJ_EDITING_INTERFACE if ( ( error = TDREND_MIX_SRC_SetGain( hBinRendererTd, nS, hIsmMetaData[nS]->gain ) ) != IVAS_ERR_OK ) { diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 4f570e6182897732a508e0767ec18c75affb86d8..6079f93b5bcf703e9ada4f28c78509a14956dbee 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -106,7 +106,7 @@ ivas_error TDREND_MIX_SRC_SetPos( --------------------------------------------------------------------*/ ivas_error TDREND_MIX_SRC_SetDir( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Direction vector */ ) @@ -132,17 +132,18 @@ ivas_error TDREND_MIX_SRC_SetDir( return IVAS_ERR_OK; } + #ifdef OBJ_EDITING_INTERFACE /*-------------------------------------------------------------------* - * TDREND_MIX_SRC_SetSourceGain() + * TDREND_MIX_SRC_SetGain() * * Set source gain --------------------------------------------------------------------*/ ivas_error TDREND_MIX_SRC_SetGain( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - const int16_t SrcInd, /* i : Source index */ - const float Gain /* i : Gain */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const int16_t SrcInd, /* i : Source index */ + const float Gain /* i : Gain */ ) { TDREND_SRC_SPATIAL_SetGain( hBinRendererTd->Sources[SrcInd], Gain ); @@ -151,6 +152,7 @@ ivas_error TDREND_MIX_SRC_SetGain( } #endif + /*-------------------------------------------------------------------* * TDREND_MIX_SRC_SetDirAtten() * @@ -158,7 +160,7 @@ ivas_error TDREND_MIX_SRC_SetGain( --------------------------------------------------------------------*/ ivas_error TDREND_MIX_SRC_SetDirAtten( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */ ) @@ -570,9 +572,12 @@ static void TDREND_SRC_SPATIAL_SetGain( ) { Src_p->SrcRend_p->SrcGain_p[0] = Gain; + + return; } #endif + /*-------------------------------------------------------------------* * TDREND_SRC_SPATIAL_GetDirGain() * diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 8e6980b0548fda0ab1a9c66dc70c00b7c2b01446..b3a826e71ee7b99963b23ab35b261596b78af1f1 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -722,9 +722,9 @@ ivas_error TDREND_MIX_SRC_SetDir( #ifdef OBJ_EDITING_INTERFACE ivas_error TDREND_MIX_SRC_SetGain( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - const int16_t SrcInd, /* i : Source index */ - const float Gain /* i : Gain */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const int16_t SrcInd, /* i : Source index */ + const float Gain /* i : Gain */ ); #endif @@ -746,9 +746,9 @@ ivas_error TDREND_MIX_SRC_SetPlayState( #ifdef OBJ_EDITING_API ivas_error TDREND_MIX_SRC_SetSrcGain( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - const int16_t SrcInd, /* i : Source index */ - const float SrcGain_p /* i : Source gain */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const int16_t SrcInd, /* i : Source index */ + const float SrcGain_p /* i : Source gain */ ); #endif @@ -938,9 +938,12 @@ ivas_error ivas_binaural_reverb_init( const int32_t sampling_rate, /* i : sampling rate */ const float *defaultTimes, /* i : default reverberation times */ const float *defaultEne /* i : default reverberation energies */ + #ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + float *earlyEne /* i/o: Early part energies to be modified */ + #endif ); - void ivas_binaural_reverb_close( REVERB_STRUCT_HANDLE *hReverb /* i/o: binaural reverb handle */ ); diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index eabaf2d4cbae004d5418ffe9e1e532437a4df283..950e9ee8bf39ad0c202da42702914dd8ab0408cc 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -148,7 +148,11 @@ ivas_error ivas_render_config_init_from_rom( ( *hRenderConfig )->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ ( *hRenderConfig )->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; ( *hRenderConfig )->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; +#ifdef FIX_HRTF_LOAD + ( *hRenderConfig )->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_DEFAULT; +#else ( *hRenderConfig )->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; +#endif ( *hRenderConfig )->split_rend_config.lc3plus_highres = 0; return IVAS_ERR_OK; diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index eb3c05a0ccb8c2313a807f50b6f86874bc1ac963..bc3bd4c6054ec5ea6758f1dfd6466e783544f9d8 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -56,6 +56,10 @@ #define CLDFB_SLOTS_PER_SECOND 800 /* Used for initializing reverb */ +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 +#define REV_TIME_THRESHOLD ( 0.2f ) +#endif + #define INNER_BLK_SIZE 80 /* size of data blocks used for more efficient delay line and IIR filter processing */ /* should be a divisor of the frame length at any sampling rate and an even number*/ #define FFT_FILTER_WND_FLAT_REGION ( 0.40f ) /* flat section (==1) length of FFT filter window, in proportion to overlap */ @@ -254,6 +258,19 @@ static void ivas_binaural_reverb_setReverbTimes( } currentEnergy *= attenuationFactorPerSampleSq; } +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + /* In some configurations with small T60s it is possible the number of taps randomizes to zero. + Ensure at least 1 filter tap. */ + if ( tap == 0 ) + { + hReverb->tapPhaseShiftType[bin][ch][0] = (int16_t) ( binRend_rand( hReverb ) % 4 ); + hReverb->tapPointersReal[bin][ch][0] = &( hReverb->loopBufReal[bin][0] ); + hReverb->tapPointersImag[bin][ch][0] = &( hReverb->loopBufImag[bin][0] ); + tap = 1; + actualizedEnergy = 1; + } +#endif + hReverb->taps[bin][ch] = tap; /* Number of taps determined at the above random procedure */ } @@ -1864,14 +1881,24 @@ ivas_error ivas_binaural_reverb_init( const int32_t sampling_rate, /* i : sampling rate */ const float *defaultTimes, /* i : default reverberation times */ const float *defaultEne /* i : default reverberation energies */ +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + float *earlyEne /* i/o: Early part energies to be modified */ +#endif ) { ivas_error error; +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + int16_t preDelay, bin; + float revTimes[CLDFB_NO_CHANNELS_MAX]; + float revEne[CLDFB_NO_CHANNELS_MAX]; +#else const float *revTimes; const float *revEne; float t60[CLDFB_NO_CHANNELS_MAX]; float ene[CLDFB_NO_CHANNELS_MAX]; int16_t preDelay; +#endif error = IVAS_ERR_OK; @@ -1881,10 +1908,22 @@ ivas_error ivas_binaural_reverb_init( if ( ( roomAcoustics != NULL ) && roomAcoustics->override ) #endif { +#ifndef FIX_1139_REV_COLORATION_SHORT_T60 revTimes = t60; revEne = ene; +#endif - if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfStatistics, sampling_rate, t60, ene ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, + hHrtfStatistics, + sampling_rate, +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + revTimes, + revEne +#else + t60, + ene +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -1892,11 +1931,47 @@ ivas_error ivas_binaural_reverb_init( } else { +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + for ( bin = 0; bin < CLDFB_NO_CHANNELS_MAX; bin++ ) + { + revTimes[bin] = defaultTimes[bin]; + revEne[bin] = defaultEne[bin]; + } +#else revTimes = defaultTimes; revEne = defaultEne; +#endif preDelay = 10; } +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + for ( bin = 0; bin < CLDFB_NO_CHANNELS_MAX; bin++ ) + { + /* Adjust the room effect parameters when the reverberation time is less than a threshold value, to avoid + spectral artefacts with the synthetic reverberator. */ + if ( revTimes[bin] < REV_TIME_THRESHOLD ) + { + float adjustedEarlyEne, adjustedLateEne, adjustedRevTime; + float revTimeModifier, energyModifier; + + /* Adjust reverberation times, higher towards a threshold */ + revTimeModifier = fmaxf( 0.0f, 1.0f - ( revTimes[bin] / REV_TIME_THRESHOLD ) ); + adjustedRevTime = ( 1.0f - revTimeModifier ) * revTimes[bin]; + adjustedRevTime += revTimeModifier * ( revTimes[bin] + REV_TIME_THRESHOLD ) * 0.5f; + energyModifier = ( adjustedRevTime - revTimes[bin] ) / adjustedRevTime; + + /* Adjust early and late energies, by moving late energy to early energy */ + adjustedEarlyEne = earlyEne[bin] + revEne[bin] * energyModifier; + adjustedLateEne = revEne[bin] * ( 1.0f - energyModifier ); + + /* Store adjusted room effect parameters to be used in reverb processing */ + revTimes[bin] = adjustedRevTime; + revEne[bin] = adjustedLateEne; + earlyEne[bin] = adjustedEarlyEne; + } + } +#endif + error = ivas_binaural_reverb_open( hReverbPr, numBins, numCldfbSlotsPerFrame, sampling_rate, revTimes, revEne, preDelay ); return error; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 264b68bf1278ec5498756121e0f2b58c3d13a59b..1d16f0d2f07e04618b54a4ef6ae9be6eea4bfcae 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2509,7 +2509,11 @@ static ivas_error updateSbaPanGains( case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: { +#ifdef FIX_HRTF_LOAD + if ( hRendCfg->split_rend_config.rendererSelection == IVAS_BIN_RENDERER_TYPE_FASTCONV ) +#else if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) +#endif { assert( *rendCtx.pOutSampleRate == 48000 && "split binaural fast conv mode is currently supported with 48k sampling rate only" ); if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) @@ -2529,7 +2533,11 @@ static ivas_error updateSbaPanGains( } case IVAS_AUDIO_CONFIG_BINAURAL: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: +#ifdef FIX_HRTF_LOAD + if ( hRendCfg->split_rend_config.rendererSelection == IVAS_BIN_RENDERER_TYPE_FASTCONV ) +#else if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) +#endif { if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { @@ -3372,7 +3380,11 @@ static int16_t getCldfbRendFlag( { isCldfbRend = 0; } +#ifdef FIX_HRTF_LOAD + else if ( ( numMasaInputs > 0 ) || ( numSbaInputs > 0 && hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_BIN_RENDERER_TYPE_FASTCONV ) ) +#else else if ( ( numMasaInputs > 0 ) || ( numSbaInputs > 0 && hIvasRend->hRendererConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) ) +#endif { isCldfbRend = 1; } @@ -3892,7 +3904,11 @@ ivas_error IVAS_REND_GetDelay( { if ( hIvasRend->splitRendWrapper != NULL && hIvasRend->splitRendWrapper->hBinHrSplitPreRend != NULL ) { +#ifdef FIX_HRTF_LOAD + if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_BIN_RENDERER_TYPE_FASTCONV ) +#else if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) +#endif { latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns; } @@ -4312,7 +4328,19 @@ ivas_error IVAS_REND_FeedRenderConfig( if ( pMasaInput->hMasaExtRend->hDiracDecBin[0] != NULL && pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb != NULL ) { ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb ); - if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb, + hIvasRend->hHrtfs.hHrtfStatistics, + pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, + CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( hRenderConfig->roomAcoustics ), + *pMasaInput->base.ctx.pOutSampleRate, + NULL, + NULL +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + NULL +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -4321,7 +4349,19 @@ ivas_error IVAS_REND_FeedRenderConfig( if ( pMasaInput->hMasaExtRend->hReverb != NULL ) { ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hReverb ); - if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hReverb, + hIvasRend->hHrtfs.hHrtfStatistics, + pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, + CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( hRenderConfig->roomAcoustics ), + *pMasaInput->base.ctx.pOutSampleRate, + NULL, + NULL +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + NULL +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -6540,7 +6580,11 @@ static ivas_error renderSbaToSplitBinaural( push_wmops( "renderSbaToSplitBinaural" ); +#ifdef FIX_HRTF_LOAD + if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_BIN_RENDERER_TYPE_FASTCONV ) +#else if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) +#endif { renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, 1, getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ); @@ -6577,7 +6621,11 @@ static ivas_error renderSbaToBinaural( int16_t subframe_idx; push_wmops( "renderSbaToBinaural" ); +#ifdef FIX_HRTF_LOAD + if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_BIN_RENDERER_TYPE_FASTCONV ) +#else if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) +#endif { float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; @@ -8408,9 +8456,33 @@ static ivas_error ivas_masa_ext_rend_parambin_init( if ( hDiracDecBin->hReverb == NULL && pos_idx == 0 ) /* open reverb only for the main direction */ { #ifdef FIX_587_DEFAULT_REVERB - if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, pRoomAcoustics, output_Fs, ( *phHrtfParambin )->parametricReverberationTimes, ( *phHrtfParambin )->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, + hHrtfStatistics, + nBins, + CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + pRoomAcoustics, + output_Fs, + ( *phHrtfParambin )->parametricReverberationTimes, + ( *phHrtfParambin )->parametricReverberationEneCorrections +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + hDiracDecBin->earlyPartEneCorrection +#endif + ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRendCfg->roomAcoustics ), output_Fs, ( *phHrtfParambin )->parametricReverberationTimes, ( *phHrtfParambin )->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, + hHrtfStatistics, + nBins, + CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( hRendCfg->roomAcoustics ), + output_Fs, + ( *phHrtfParambin )->parametricReverberationTimes, + ( *phHrtfParambin )->parametricReverberationEneCorrections +#ifdef FIX_1139_REV_COLORATION_SHORT_T60 + , + hDiracDecBin->earlyPartEneCorrection +#endif + ) ) != IVAS_ERR_OK ) #endif { return error; diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 640f2721e68a61972fa020f2ec9b6e009ed2949c..b4a0b24ea9fdbe1b63a805f5b5f4554eb45541d8 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -1437,6 +1437,7 @@ static ivas_error create_fastconv_HRTF_from_rawdata( { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "renderer type not compliant" ); } + /* HRIR */ if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) { @@ -1886,7 +1887,11 @@ static ivas_error create_parambin_HRTF_from_rawdata( ivas_error load_fastconv_HRTF_from_binary( IVAS_DEC_HRTF_FASTCONV_HANDLE hHrtfFastConv, /* i/o: FastConv HRTF handle */ - const hrtfFileReader *hrtfReader /* i : pointer to hrtfFileReader handle */ +#ifdef FIX_HRTF_LOAD + const int16_t room_reverb_flag, /* i : room reverb flag */ + const IVAS_AUDIO_CONFIG intern_audio_config, /* i : internal audio configuration */ +#endif + const hrtfFileReader *hrtfReader /* i : pointer to hrtfFileReader handle */ ) { FILE *f_hrtf; @@ -1934,7 +1939,17 @@ ivas_error load_fastconv_HRTF_from_binary( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "HRTF binary file not compliant (number of HRTF)" ); } +#ifdef FIX_HRTF_LOAD + if ( ( hrtf_header.rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && + ( ( hrtf_header.input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_HOA3 && intern_audio_config == IVAS_AUDIO_CONFIG_HOA3 ) || + ( hrtf_header.input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_HOA2 && intern_audio_config == IVAS_AUDIO_CONFIG_HOA2 ) || + ( hrtf_header.input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_FOA && intern_audio_config == IVAS_AUDIO_CONFIG_FOA ) || + ( hrtf_header.input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) ) ) || + ( ( hrtf_header.rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV || hrtf_header.rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM ) && room_reverb_flag == 1 ) || + ( ( hrtf_header.rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV || hrtf_header.rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM ) && intern_audio_config == IVAS_AUDIO_CONFIG_INVALID ) ) +#else if ( ( hrtf_header.rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV ) || ( hrtf_header.rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM ) ) +#endif { if ( fread( hrtf_data, 1, hrtf_header.data_size, f_hrtf ) != hrtf_header.data_size ) { diff --git a/lib_util/hrtf_file_reader.h b/lib_util/hrtf_file_reader.h index dbb38c3d888719c629203f58aad3c21184d4a36a..0ea25d323e478fbf3aae715acdac1601038577f9 100644 --- a/lib_util/hrtf_file_reader.h +++ b/lib_util/hrtf_file_reader.h @@ -132,7 +132,11 @@ void destroy_SetOfHRTF( ivas_error load_fastconv_HRTF_from_binary( IVAS_DEC_HRTF_FASTCONV_HANDLE hHrtfFastConv, /* i/o: FastConv HRTF handle */ - const hrtfFileReader *hrtfReader /* i : pointer to hrtfFileReader handle */ +#ifdef FIX_HRTF_LOAD + const int16_t room_reverb_flag, /* i : room reverb flag */ + IVAS_AUDIO_CONFIG intern_audio_config, /* i : internal audio configuration */ +#endif + const hrtfFileReader *hrtfReader /* i : pointer to hrtfFileReader handle */ ); /*---------------------------------------------------------------------* diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index e07660f4d7314dad740455abbd15b68532557a22..8ad75acdd201427fe6a9bbaa8378ca0078075a72 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2649,19 +2649,35 @@ ivas_error RenderConfigReader_read( { if ( strcmp( pValue, "CREND" ) == 0 ) { +#ifdef FIX_HRTF_LOAD + hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_CREND; +#else hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_CREND; +#endif } else if ( strcmp( pValue, "FASTCONV" ) == 0 ) { +#ifdef FIX_HRTF_LOAD + hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_FASTCONV; +#else hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV; +#endif } else if ( strcmp( pValue, "PARAMBIN" ) == 0 ) { +#ifdef FIX_HRTF_LOAD + hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_PARAMBIN; +#else hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN; +#endif } else if ( strcmp( pValue, "TDREND" ) == 0 ) { +#ifdef FIX_HRTF_LOAD + hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_TDREND; +#else hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND; +#endif } else { diff --git a/readme.txt b/readme.txt index e6fbd729ead207359e6e304a12d7ea5f9ff29388..fb183d6f9e08dd5351d35321ab22907ca58e4c47 100644 --- a/readme.txt +++ b/readme.txt @@ -260,8 +260,8 @@ Usage for IVAS: IVAS_dec.exe [Options] OutputConf Fs bitstream_file output_file Mandatory parameters: --------------------- OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA, - HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, - BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, EXT + HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, + BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, EXT By default, channel order and loudspeaker positions are equal to the encoder. For loudspeaker outputs, OutputConf can be a custom loudspeaker layout file. See below for details. @@ -289,7 +289,7 @@ Options: Format files, the magic word in the mime file is used to determine which of the two supported formats is in use. default bitstream file format is G.192 --fr L : render frame size in ms L=(5,10,20), default is 20 +-fr L : render frame size in ms L=(5,10,20), default is 20 -hrtf File : HRTF filter File used in BINAURAL rendering -T File : Head rotation specified by external trajectory File -otr tracking_type : Head orientation tracking type: 'none', 'ref', 'avg', 'ref_vec' @@ -305,8 +305,9 @@ Options: -dpid ID : Directivity pattern ID(s) (space-separated list of up to 4 numbers can be specified) for binaural output configuration -aeid ID | File : Acoustic environment ID (number > 0) or - alternatively, it can be a text file where each line contains "ID duration" - for BINAURAL_ROOM_REVERB output configuration. + alternatively, it can be a text file where each line contains "ID duration" + for BINAURAL_ROOM_REVERB output configuration. +-obj_edit : Enable objects editing -level level : Complexity level, level = (1, 2, 3), will be defined after characterisation. -om File : Coded metadata File for BINAURAL_SPLIT_PCM OutputConf Currently, all values default to level 3 (full functionality). @@ -327,7 +328,7 @@ Options: -of Format : Audio Format of output file Alternatively, it can be a custom loudspeaker layout File -fs : Input sampling rate in kHz (16, 32, 48) - required only with raw PCM inputs --fr L : render frame size in ms L=(5,10,20), default is 20 +-fr L : render frame size in ms L=(5,10,20), default is 20 -hrtf File : Custom HRTF File for binaural rendering (only for binaural outputs) -T File : Head rotation trajectory File for simulation of head tracking (only for binaural outputs) -otr tracking_type : Head orientation tracking type: 'none', 'ref', 'avg' or `ref_vec` or `ref_vec_lev` (only for binaural outputs) @@ -340,8 +341,7 @@ Options: -dpid ID : Directivity pattern ID(s) (space-separated list of up to 4 numbers can be specified) for binaural output configuration -aeid ID | File : Acoustic environment ID (number > 0) - alternatively, it can be a text file where each line contains "ID duration" - for BINAURAL_ROOM_REVERB output configuration. + alternatively, it can be a text file where each line contains "ID duration" for BINAURAL_ROOM_REVERB output configuration. -lp Position : Output LFE position. Comma-delimited triplet of [gain, azimuth, elevation] where gain is linear (like --gain, -g) and azimuth, elevation are in degrees. If specified, overrides the default behavior which attempts to map input to output LFE channel(s) diff --git a/scripts/IvasBuildAndRunChecks.py b/scripts/IvasBuildAndRunChecks.py index c1f31e433d4085d860ca7e833078e9ff555e8a14..8ef154838305ec553cc3a72d769e2fdcf33ee0c3 100755 --- a/scripts/IvasBuildAndRunChecks.py +++ b/scripts/IvasBuildAndRunChecks.py @@ -32,6 +32,7 @@ import os.path import sys +import platform import pyivastest.constants as constants from pyivastest import IvasScriptsCommon @@ -39,6 +40,19 @@ from pyivastest.IvasSvnBuilder import * RET_CODE_FAILURE = 101 +bin_ext = "" +if platform.system() == "Windows": + bin_ext = ".exe" + +default_encdec_bin_path = constants.WC_BASE_DIR +default_enc = os.path.realpath( + os.path.join(default_encdec_bin_path, "IVAS_cod" + bin_ext) +) +default_dec = os.path.realpath( + os.path.join(default_encdec_bin_path, "IVAS_dec" + bin_ext) +) +default_out = os.path.join(".", "out") # change that to something else? + class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): def __init__(self): @@ -100,9 +114,25 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): help="pass the '-s' argument to the wmc tool to only measure memory", action="store_true", ) + self.parser.add_argument( + "--basop", + help="build the basop version for instrumentation", + action="store_true", + ) + self.parser.add_argument( + "-e", + "--enc", + help="Encoder binary to use instead of instrumenting and building it anew", + default=None, + ) + self.parser.add_argument( + "-d", + "--dec", + help="Decoder binary to use instead of instrumenting and building it anew", + default=None, + ) def run(self): - self.parse_args() if self.args["error"] or self.args["exit"]: exit() @@ -142,6 +172,8 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): sample_rate_dec_out=self.args["srout"], enable_logging=True, logger_name="{}.br".format(self.logger.name), + enc_ext=self.args["enc"], + dec_ext=self.args["dec"], ) elif self.args["srcdir"]: @@ -152,6 +184,8 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): sample_rate_dec_out=self.args["srout"], enable_logging=True, logger_name="{}.br".format(self.logger.name), + enc_ext=self.args["enc"], + dec_ext=self.args["dec"], ) modes = self.args["formats"] @@ -165,6 +199,7 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): formats_fname=self.args["format_file"], max_workers=self.args["max_workers"], mem_only=self.args["wmc_tool_mem_only"], + basop=self.args["basop"], ) else: br.add_check( @@ -181,7 +216,7 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): br.build_and_run_dict[check]["analyzer"], self.args ) - if self.args["rebuild"] == True: + if self.args["rebuild"]: br.force_build = True checks_ret_val = list() diff --git a/scripts/batch_comp_audio.py b/scripts/batch_comp_audio.py index 56a6b7d5023c2962f4a522d7170592a00275e455..7e488fcfbe6c1a09ef7ca8f0e6d3157f663c0eb7 100755 --- a/scripts/batch_comp_audio.py +++ b/scripts/batch_comp_audio.py @@ -56,7 +56,8 @@ DIFF_STR = { def main(args): tool = args.tool - if tool != "pyaudio3dtools" and shutil.which(tool) is None: + # check for MLD will be done by the compare() function + if tool == "CompAudio" and shutil.which(tool) is None: print(f"{tool} not in PATH - abort.") sys.exit(-1) diff --git a/scripts/parse_xml_report.py b/scripts/parse_xml_report.py index e0f02238e4fddd970567023b2637975e4ead4213..902b31f0acfd1ad27a1413e7fc06cc4f6717f7be 100644 --- a/scripts/parse_xml_report.py +++ b/scripts/parse_xml_report.py @@ -67,11 +67,16 @@ if __name__ == "__main__": action="store_true", help="Parse using EVS 26.444 formats", ) + parser.add_argument( + "--clipping", + action="store_true", + help="Extract clipping information. Available if encoder has been run with DEBUGGING active.", + ) parser.add_argument( "--skip_formats", action="store_true", help="Parse without formats and categories. Suitable for general tests which do not match the IVAS categories.", - ) + ) args = parser.parse_args() xml_report = args.xml_report csv_file = args.csv_file @@ -80,6 +85,11 @@ if __name__ == "__main__": if args.evs: FORMATS = EVS_FORMATS CATEGORIES = EVS_CATEGORIES + else: + FORMATS = IVAS_FORMATS + CATEGORIES = IVAS_CATEGORIES + if args.clipping: + PROPERTIES += ["ENC_CORE_OVL","MAX_OVL","MIN_OVL"] if args.skip_formats: FORMATS = NO_FORMATS CATEGORIES = NO_CATEGORIES diff --git a/scripts/pyivastest/IvasSvnBuilder.py b/scripts/pyivastest/IvasSvnBuilder.py index e437843d166aed0faa37f3f8bca0c77a563e456c..ccd0c68325abe72dfb1e88c36f391c054349078b 100644 --- a/scripts/pyivastest/IvasSvnBuilder.py +++ b/scripts/pyivastest/IvasSvnBuilder.py @@ -227,6 +227,7 @@ class IvasBuilder(IvasBaseClass): defines_to_disable=[], instrumented=False, mem_only=False, + basop=False, ): """ @@ -274,7 +275,11 @@ class IvasBuilder(IvasBaseClass): os.path.join(self.src_dir, "scripts", "prepare_instrumentation.sh") ] if mem_only: + instrument_cmd.append("-m") instrument_cmd.append("mem_only") + if basop: + instrument_cmd.append("-p") + instrument_cmd.append("basop") build_log.write(" ".join(instrument_cmd)) build_log.write("\n") build_result = subprocess.run( @@ -644,6 +649,7 @@ class IvasSvnBuilder(IvasBuilder): defines_to_disable=[], instrumented=False, mem_only=False, + basop=False, ): """ @@ -673,6 +679,7 @@ class IvasSvnBuilder(IvasBuilder): defines_to_disable=defines_to_disable, instrumented=instrumented, mem_only=mem_only, + basop=basop, ) @@ -695,6 +702,8 @@ class IvasBuilderAndRunner(IvasBaseClass): console_logger_level="", logger_name="IvasBuilderAndRunner", log_level=logging.DEBUG, + enc_ext=None, + dec_ext=None, ): super().__init__( enable_logging=enable_logging, @@ -729,6 +738,8 @@ class IvasBuilderAndRunner(IvasBaseClass): self.sample_rate_enc_in = sample_rate_enc_in self.sample_rate_dec_out = sample_rate_dec_out self.force_build = False + self.enc_ext = enc_ext + self.dec_ext = dec_ext @classmethod def fromSvn( @@ -781,6 +792,7 @@ class IvasBuilderAndRunner(IvasBaseClass): max_workers=1, timeout=None, mem_only=False, + basop=False, ): """ @@ -826,6 +838,7 @@ class IvasBuilderAndRunner(IvasBaseClass): self.build_and_run_dict[cfg_name]["instrumented"] = instrumented self.build_and_run_dict[cfg_name]["mem_only"] = mem_only self.build_and_run_dict[cfg_name]["make_options"] = make_options + self.build_and_run_dict[cfg_name]["basop"] = basop else: self.logger.console("Adding config {}".format(cfg_name), logging.INFO) run_dir = os.path.join(self.builder.src_dir, cfg_name) @@ -871,6 +884,7 @@ class IvasBuilderAndRunner(IvasBaseClass): "mem_only": mem_only, "make_options": make_options, "analyzer": new_analyzer, + "basop": basop, } } self.build_and_run_dict.update(cfg_dict) @@ -1054,6 +1068,7 @@ class IvasBuilderAndRunner(IvasBaseClass): defines_to_disable=cfg["defines_to_disable"], instrumented=cfg["instrumented"], mem_only=cfg["mem_only"], + basop=cfg["basop"], ) self.build_and_run_dict[cfg_name]["runner"].encoder = self.builder.encoder self.build_and_run_dict[cfg_name]["runner"].decoder = self.builder.decoder @@ -1079,11 +1094,23 @@ class IvasBuilderAndRunner(IvasBaseClass): if self.builder.src_dir == "": self.builder.get_svn_source() run_dir = os.path.join(self.builder.src_dir, cfg_name) + + # if both encoder and decoder are given as external binaries, create dir and copy both, this skips the build later + if self.dec_ext is not None and self.enc_ext is not None: + os.makedirs(run_dir, exist_ok=True) + shutil.copy( + self.enc_ext, os.path.join(run_dir, os.path.basename(self.enc_ext)) + ) + shutil.copy( + self.dec_ext, os.path.join(run_dir, os.path.basename(self.dec_ext)) + ) + if not os.path.exists(run_dir) or self.force_build: # we have to build first self.build(cfg_name) else: # check if binaries are in the directory + # first, copy external binaries # test for EVS vs IVAS if os.path.exists( os.path.join( @@ -1119,6 +1146,20 @@ class IvasBuilderAndRunner(IvasBaseClass): ) ) self.build(cfg_name) + + # if one of the external binaries was given, copy it over, overwriting the existing one + # we should not get here if both are given, then building is skipped altogether + if self.enc_ext is not None: + shutil.copy( + self.enc_ext, + os.path.join(run_dir, os.path.basename(self.enc_ext)), + ) + if self.dec_ext is not None: + shutil.copy( + self.dec_ext, + os.path.join(run_dir, os.path.basename(self.dec_ext)), + ) + self.build_and_run_dict[cfg_name]["runner"].dir_name = run_dir self.build_and_run_dict[cfg_name]["analyzer"].dir = run_dir self.build_and_run_dict[cfg_name]["runner"].run() @@ -1196,7 +1237,6 @@ class IvasBuilderAndRunner(IvasBaseClass): max_workers=1, usan_supp_file=None, ): - n_cpus = cpu_count() # do not use all cores to avoid weird getting-stuck issues observed on Mac... make_options = ["-j", f"{n_cpus - 2}"] @@ -1255,6 +1295,7 @@ class IvasBuilderAndRunner(IvasBaseClass): formats_fname="", max_workers=1, mem_only=False, + basop=False, ): """ @@ -1288,6 +1329,7 @@ class IvasBuilderAndRunner(IvasBaseClass): formats_fname=formats_fname, max_workers=max_workers, mem_only=mem_only, + basop=basop, ) # TODO: this is used nowhere, is this still needed? diff --git a/scripts/smoke_test_complexity_basop.sh b/scripts/smoke_test_complexity_basop.sh new file mode 100755 index 0000000000000000000000000000000000000000..014f67b72931f9ef13d00473b60ddc13b8169379 --- /dev/null +++ b/scripts/smoke_test_complexity_basop.sh @@ -0,0 +1,235 @@ +#! /usr/bin/bash + +# (C) 2022-2024 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. + +function usage { + echo + echo "Usage:" + echo " smoke_test_complexity_basop.sh [--max_cores nMaxCores -e encPath -d decPath]" + echo + echo " nMaxCores - the number of CPUs to use (default 42)" + echo " encPath - path to IVAS_cod" + echo " decPath - path to IVAS_dec" + exit +} + +if [ ! -d "lib_com" ]; then + echo "not in root directory! - please run in IVAS root" + exit 1 +fi + +MAX_CORES="42" +ENC_PATH="" +DEC_PATH="" +while getopts ":-:e:d:" OPTIONS; do + case ${OPTIONS} in + -) + case "${OPTARG}" in + max_cores) + MAX_CORES="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 )) + ;; + esac;; + e) + ENC_PATH=${OPTARG} + ;; + d) + DEC_PATH=${OPTARG} + ;; + h | *) + usage + ;; + esac +done + +enc_cmd="" +dec_cmd="" +if [ "$ENC_PATH" != "" ]; then + enc_cmd="-e $ENC_PATH" +fi +if [ "$DEC_PATH" != "" ]; then + dec_cmd="-d $DEC_PATH" +fi + +cfg=./scripts/config/ci_linux_ltv.json +ism_md_cmd="--ism_metadata_files /usr/local/ltv/ltvISM1.csv /usr/local/ltv/ltvISM2.csv /usr/local/ltv/ltvISM3.csv /usr/local/ltv/ltvISM4.csv" +duration_arg="" +complexity_cmd="--checks COMPLEXITY --wmc_tool_mem_only --basop --create_complexity_tables" +max_num_workers="--max_workers $MAX_CORES" + +# prepare combined format test signals +echo "\n======================= 0. preparing combined format test inputs =======================\n\n" +./scripts/prepare_combined_format_inputs.py + +# Modes +mono_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^mono) +FOA_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^FOA) +HOA2_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^HOA2) +HOA3_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^HOA3) +PlanarFOA_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^PlanarFOA) +PlanarHOA2_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^PlanarHOA2) +PlanarHOA3_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^PlanarHOA3) +MASA_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^MASA) +MC_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^MC) +stereo_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^stereo) +stereoDmx_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^StereoDmx) +OMASA_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^OMASA) +OSBA_ISM1_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^OSBA_ISM1) +OSBA_ISM2_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^OSBA_ISM2) +OSBA_ISM3_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^OSBA_ISM3) +OSBA_ISM4_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^OSBA_ISM4) +ISM1_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM1) +ISM2_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM2) +ISM3_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM3) +ISM4_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM4) +ISM_plus1_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM+1) +ISM_plus2_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM+2) +ISM_plus3_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM+3) +ISM_plus4_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM+4) + + +echo "\n======================= 1. Mono =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_mono_no_fec -m $mono_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_mono.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 2. FOA =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_FOA_no_fec -m $FOA_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_FOA.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 3. HOA2 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_HOA2_no_fec -m $HOA2_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_HOA2.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 4. HOA3 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_HOA3_no_fec -m $HOA3_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_HOA3.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 5. PlanarFOA =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_PlanarFOA_no_fec -m $PlanarFOA_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_PlanarFOA.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 6. PlanarHOA2 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_PlanarHOA2_no_fec -m $PlanarHOA2_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_PlanarHOA2.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 7. PlanarHOA3 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_PlanarHOA3_no_fec -m $PlanarHOA3_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_PlanarHOA3.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 8. MASA =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_MASA_no_fec -m $MASA_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_MASA.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 9. MC =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_MC_no_fec -m $MC_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_MC.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 10. stereo =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_stereo_no_fec -m $stereo_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_stereo.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 11. stereoDmx =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_stereoDmx_no_fec -m $stereoDmx_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_stereoDmx.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 12. OMASA =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_OMASA_no_fec -m $OMASA_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_OMASA.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 13. OSBA ISM1 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_OSBA_ISM1_no_fec -m $OSBA_ISM1_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_OSBA_ISM1.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 14. OSBA ISM2 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_OSBA_ISM2_no_fec -m $OSBA_ISM2_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_OSBA_ISM2.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 15. OSBA ISM3 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_OSBA_ISM3_no_fec -m $OSBA_ISM3_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_OSBA_ISM3.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 16. OSBA ISM4 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_OSBA_ISM4_no_fec -m $OSBA_ISM4_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_OSBA_ISM4.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 17. ISM1 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_ISM1_no_fec -m $ISM1_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM1.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 18. ISM2 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_ISM2_no_fec -m $ISM2_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM2.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 19. ISM3 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_ISM3_no_fec -m $ISM3_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM3.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 20. ISM4 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_ISM4_no_fec -m $ISM4_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM4.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 21. ISM1 + extended metadata =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_ISM_plus1_no_fec -m $ISM_plus1_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM_plus1.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 22. ISM2 + extended metadata =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_ISM_plus2_no_fec -m $ISM_plus2_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM_plus2.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 23. ISM3 + extended metadata =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_ISM_plus3_no_fec -m $ISM_plus3_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM_plus3.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 24. ISM4 + extended metadata =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $enc_cmd $dec_cmd $complexity_cmd ltv_complexity_ISM_plus4_no_fec -m $ISM_plus4_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM_plus4.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ diff --git a/scripts/ssnr.py b/scripts/ssnr.py index 89ac4c6bf999adf8a9530e718a94651e2ba9ac52..3bcd309c1e1be806cd3a68800d776292a9fd4cf2 100644 --- a/scripts/ssnr.py +++ b/scripts/ssnr.py @@ -4,31 +4,6 @@ import pathlib from pyaudio3dtools import audiofile, audioarray -def main(args): - ref_sig, fs_ref = audiofile.readfile(args.ref_file) - test_sig, fs_test = audiofile.readfile(args.test_file) - - if fs_ref != fs_test: - print("Files need to have same sampling rate!") - return -1 - - len_seg = int(20 * fs_ref / 1000) - print(len_seg, ref_sig.shape, test_sig.shape) - ssnr = audioarray.ssnr( - ref_sig, - test_sig, - len_seg, - args.thresh_low, - args.thresh_high, - args.apply_thresholds_on_ref_only, - ) - - for i, s in enumerate(ssnr, start=1): - print(f"Channel {i}: {s}") - - return 0 - - if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("ref_file", type=pathlib.Path, help="Reference signal wav file") @@ -56,7 +31,40 @@ if __name__ == "__main__": help="Use this to apply the thresholding on signal power to the reference signal only.\n" "This makes the implementation behaviour conform to the MPEG-D conformance spec.", ) + parser.add_argument( + "--print-ctest-measurement", + action="store_true", + default=False, + help="Print easy to parse single SSNR value", + ) args = parser.parse_args() - sys.exit(main(args)) + ref_sig, fs_ref = audiofile.readfile(args.ref_file) + test_sig, fs_test = audiofile.readfile(args.test_file) + + if fs_ref != fs_test: + print("Files need to have same sampling rate!") + sys.exit(1) + + len_seg = int(20 * fs_ref / 1000) + print(len_seg, ref_sig.shape, test_sig.shape) + ssnr = audioarray.ssnr( + ref_sig, + test_sig, + len_seg, + args.thresh_low, + args.thresh_high, + args.apply_thresholds_on_ref_only, + ) + + for i, s in enumerate(ssnr, start=1): + print(f"Channel {i}: {s}") + + if args.print_ctest_measurement: + min_ssnr = ssnr.min() + print( + f'{min_ssnr}' + ) + + sys.exit(0) diff --git a/scripts/tools/Darwin/wav-diff b/scripts/tools/Darwin/wav-diff index 88823c01f9b11a117cee9a8447b8a981bb4ad5a5..7cb4dce0e8abae24311e777219a0a94c950cf2f4 100755 Binary files a/scripts/tools/Darwin/wav-diff and b/scripts/tools/Darwin/wav-diff differ diff --git a/scripts/tools/Linux/wav-diff b/scripts/tools/Linux/wav-diff index 47f77e82b56e51b84bc52ab7fb01d605d6265ab6..ad8638be3f21a6706f397d07ced816b8b43f84d6 100755 Binary files a/scripts/tools/Linux/wav-diff and b/scripts/tools/Linux/wav-diff differ diff --git a/scripts/tools/Win32/wav-diff.exe b/scripts/tools/Win32/wav-diff.exe index b87b0888e4da8b559be017c4fb8c15e62152b1cb..1380e3c6c84b650f5f9dd35321e17262729bd69b 100644 --- a/scripts/tools/Win32/wav-diff.exe +++ b/scripts/tools/Win32/wav-diff.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92c49557ce750bd1eb05278ced4a64b98d66a654f3604b8003f72f4a05df8df3 -size 889344 +oid sha256:7e72c4c9d2b773e94233720d8fddb4689446ab9f593d329629b6261a6918720b +size 889856 diff --git a/tests/codec_be_on_mr_nonselection/test_param_file.py b/tests/codec_be_on_mr_nonselection/test_param_file.py index 5d6b5cbaa1fa7b3bb126d6da34f7c7e643d401bb..13a49c3f329c706fdc00f7cd7759889da1a9c564 100644 --- a/tests/codec_be_on_mr_nonselection/test_param_file.py +++ b/tests/codec_be_on_mr_nonselection/test_param_file.py @@ -151,7 +151,6 @@ def convert_test_string_to_tag(test_string): # hack to have stv/ltv/evs in the test name @pytest.mark.parametrize("param_file_id", [PARAM_FILE_ID]) def test_param_file_tests( - record_property, props_to_record, encoder_only, decoder_only, @@ -259,7 +258,7 @@ def test_param_file_tests( cmp_result_msg += enc_test_result_msg props = parse_properties(cmp_result_msg, False, props_to_record) for k, v in props.items(): - record_property(k, v) + dut_encoder_frontend.record_property(k, v) if enc_test_result: pytest.fail("Too high difference in encoder statistics found.") @@ -452,7 +451,7 @@ def test_param_file_tests( props = parse_properties(cmp_result_msg, output_differs, props_to_record) for k, v in props.items(): - record_property(k, v) + dut_decoder_frontend.record_property(k, v) metadata_differs = False diff --git a/tests/codec_be_on_mr_nonselection/test_sba.py b/tests/codec_be_on_mr_nonselection/test_sba.py index 885ac488ad36b2ec2cad0b1ae762c4536fa0cecb..e8ae17f55b6da65a09d6a00e624792640f728cd5 100644 --- a/tests/codec_be_on_mr_nonselection/test_sba.py +++ b/tests/codec_be_on_mr_nonselection/test_sba.py @@ -92,7 +92,6 @@ def check_and_makedir(dir_path): @pytest.mark.parametrize("tag", tag_list) @pytest.mark.parametrize("sampling_rate", sample_rate_list) def test_pca_enc( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -164,7 +163,6 @@ def test_pca_enc( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -200,7 +198,6 @@ def test_pca_enc( @pytest.mark.parametrize("gain_flag", gain_list) @pytest.mark.parametrize("sid", SID_list) def test_sba_enc_system( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -327,7 +324,7 @@ def test_sba_enc_system( enc_test_result_msg, enc_test_result != 0, props_to_record ) for k, v in props.items(): - record_property(k, v) + dut_encoder_frontend.record_property(k, v) # report compare result if enc_test_result != 0: @@ -335,7 +332,6 @@ def test_sba_enc_system( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -367,7 +363,6 @@ def test_sba_enc_system( @pytest.mark.parametrize("bitrate", ivas_br_HOA2) @pytest.mark.parametrize("tag", tag_list_HOA2) def test_spar_hoa2_enc_system( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -464,7 +459,7 @@ def test_spar_hoa2_enc_system( enc_test_result_msg, enc_test_result != 0, props_to_record ) for k, v in props.items(): - record_property(k, v) + dut_encoder_frontend.record_property(k, v) # report compare result if enc_test_result != 0: @@ -472,7 +467,6 @@ def test_spar_hoa2_enc_system( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -504,7 +498,6 @@ def test_spar_hoa2_enc_system( @pytest.mark.parametrize("bitrate", ivas_br_HOA3) @pytest.mark.parametrize("tag", tag_list_HOA3) def test_spar_hoa3_enc_system( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -595,7 +588,7 @@ def test_spar_hoa3_enc_system( enc_test_result_msg, enc_test_result != 0, props_to_record ) for k, v in props.items(): - record_property(k, v) + dut_encoder_frontend.record_property(k, v) # report compare result if enc_test_result != 0: @@ -603,7 +596,6 @@ def test_spar_hoa3_enc_system( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -637,7 +629,6 @@ def test_spar_hoa3_enc_system( @pytest.mark.parametrize("tag", tag_list_bw_force) @pytest.mark.parametrize("sample_rate_bw_idx", sample_rate_bw_idx_list) def test_sba_enc_BWforce_system( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -746,7 +737,7 @@ def test_sba_enc_BWforce_system( enc_test_result_msg, enc_test_result != 0, props_to_record ) for k, v in props.items(): - record_property(k, v) + dut_encoder_frontend.record_property(k, v) # report compare result if enc_test_result != 0: @@ -754,7 +745,6 @@ def test_sba_enc_BWforce_system( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -790,7 +780,6 @@ def test_sba_enc_BWforce_system( @pytest.mark.parametrize("sampling_rate", sample_rate_list) @pytest.mark.parametrize("gain_flag", gain_list) def test_sba_plc_system( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -886,7 +875,6 @@ def test_sba_plc_system( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -1042,7 +1030,6 @@ def sba_enc( def sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -1158,7 +1145,7 @@ def sba_dec( text_to_parse = reason props = parse_properties(text_to_parse, cmp_result != 0, props_to_record) for k, v in props.items(): - record_property(k, v) + dut_decoder_frontend.record_property(k, v) # report compare result if cmp_result != 0: diff --git a/tests/conftest.py b/tests/conftest.py index 8f3e4e961bc7e87499d0c9af4642fe96d84f22ad..989f080c906d28e954d252c8aeec4d133242151c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -57,6 +57,12 @@ from .constants import ( ODG, MAX_ENC_DIFF, MAX_ENC_DIFF_PATTERN, + ENC_CORE_OVL, + ENC_CORE_OVL_PATTERN, + MAX_OVL, + MAX_OVL_PATTERN, + MIN_OVL, + MIN_OVL_PATTERN, SCRIPTS_DIR, ) @@ -322,11 +328,10 @@ def get_enc_stats(request) -> bool: @pytest.fixture(scope="session", autouse=True) def get_odg(request): """ - Return indication to compute ssnr during ref/dut comparison. + Return indication to compute PEAQ ODG during ref/dut comparison. """ return request.config.option.odg - @pytest.fixture(scope="session") def abs_tol(request) -> int: """ @@ -358,6 +363,8 @@ def dut_encoder_path(request) -> str: """ if request.config.option.dut_encoder_path: return request.config.option.dut_encoder_path + if request.config.option.update_ref == "1": + return None here = Path(__file__).parent.resolve() system = platform.system() @@ -378,13 +385,14 @@ def dut_encoder_path(request) -> str: class EncoderFrontend: - def __init__(self, path, enc_type, timeout=None) -> None: + def __init__(self, path, enc_type, record_property, timeout=None) -> None: self._path = Path(path).absolute() self._type = enc_type self.returncode = None self.stdout = None self.stderr = None self.timeout = timeout + self.record_property = record_property def extract_enc_stats( self, @@ -533,6 +541,15 @@ class EncoderFrontend: self.returncode = result.returncode self.stderr = result.stderr.decode("ascii") self.stdout = result.stdout.decode("ascii") + + # Record core encoder clipping + for (prop, pattern) in [(ENC_CORE_OVL,ENC_CORE_OVL_PATTERN),(MAX_OVL,MAX_OVL_PATTERN),(MIN_OVL,MIN_OVL_PATTERN)]: + val = 0 + search_result = re.search(pattern, self.stdout) + if search_result: + val = search_result.group(1) + self.record_property( prop, val ) + if self.stdout: stdout_str = textwrap.indent(self.stdout, prefix="\t") log_dbg_msg(f"{self._type} encoder stdout:\n{stdout_str}") @@ -559,16 +576,20 @@ class EncoderFrontend: @pytest.fixture(scope="function") -def dut_encoder_frontend(dut_encoder_path, request) -> EncoderFrontend: +def dut_encoder_frontend(dut_encoder_path, request, record_property) -> Union[None, EncoderFrontend]: """ Return a :class:`conftest.EncoderFrontend` instance as DUT for the test session. """ - timeout = request.config.getoption("--testcase_timeout") - encoder = EncoderFrontend(dut_encoder_path, "DUT", timeout=timeout) + encoder = None + + if dut_encoder_path: + timeout = request.config.getoption("--testcase_timeout") + encoder = EncoderFrontend(dut_encoder_path, "DUT", record_property, timeout=timeout) yield encoder - # Fixture teardown - encoder._check_run() + if encoder is not None: + # Fixture teardown + encoder._check_run() @pytest.fixture(scope="session") @@ -602,7 +623,7 @@ def ref_encoder_path(request) -> str: @pytest.fixture(scope="function") -def ref_encoder_frontend(ref_encoder_path, request) -> Union[None, EncoderFrontend]: +def ref_encoder_frontend(ref_encoder_path, request, record_property) -> Union[None, EncoderFrontend]: """ Return a :class:`conftest.EncoderFrontend` instance as REF for the test session. """ @@ -610,7 +631,7 @@ def ref_encoder_frontend(ref_encoder_path, request) -> Union[None, EncoderFronte if ref_encoder_path: timeout = request.config.getoption("--testcase_timeout") - encoder = EncoderFrontend(ref_encoder_path, "REF", timeout=timeout) + encoder = EncoderFrontend(ref_encoder_path, "REF", record_property, timeout=timeout) yield encoder @@ -627,6 +648,9 @@ def dut_decoder_path(request) -> str: if request.config.option.dut_decoder_path: return request.config.option.dut_decoder_path + if request.config.option.update_ref == "1": + return None + here = Path(__file__).parent.resolve() system = platform.system() @@ -646,7 +670,7 @@ def dut_decoder_path(request) -> str: class DecoderFrontend: - def __init__(self, path, dec_type, timeout=None, fr=20) -> None: + def __init__(self, path, dec_type, record_property, timeout=None, fr=20) -> None: self._path = str(Path(path).absolute()) self._type = dec_type self.returncode = None @@ -654,6 +678,7 @@ class DecoderFrontend: self.stderr = None self.timeout = timeout self.fr = fr + self.record_property = record_property def run( self, @@ -821,20 +846,21 @@ class DecoderFrontend: @pytest.fixture(scope="function") -def dut_decoder_frontend(dut_decoder_path, request) -> DecoderFrontend: +def dut_decoder_frontend(dut_decoder_path, request, record_property) -> Union[None, DecoderFrontend]: """ Return a :class:`conftest.DecoderFrontend` instance as DUT for the test session. """ - decoder = DecoderFrontend( - dut_decoder_path, - "DUT", - timeout=request.config.getoption("--testcase_timeout"), - fr=request.config.option.dut_fr, - ) + decoder = None + + if dut_decoder_path: + timeout = request.config.getoption("--testcase_timeout") + decoder = DecoderFrontend(dut_decoder_path, "DUT", record_property, timeout=timeout, fr=request.config.option.dut_fr) + yield decoder - # Fixture teardown - decoder._check_run() + if decoder is not None: + # Fixture teardown + decoder._check_run() @pytest.fixture(scope="session") @@ -868,7 +894,7 @@ def ref_decoder_path(request) -> str: @pytest.fixture(scope="function") -def ref_decoder_frontend(ref_decoder_path, request) -> Union[None, DecoderFrontend]: +def ref_decoder_frontend(ref_decoder_path, request, record_property) -> Union[None, DecoderFrontend]: """ Return a :class:`conftest.DecoderFrontend` instance as DUT for the test session. """ @@ -876,7 +902,7 @@ def ref_decoder_frontend(ref_decoder_path, request) -> Union[None, DecoderFronte if ref_decoder_path: timeout = request.config.getoption("--testcase_timeout") - decoder = DecoderFrontend(ref_decoder_path, "REF", timeout=timeout) + decoder = DecoderFrontend(ref_decoder_path, "REF", record_property, timeout=timeout) yield decoder @@ -1059,7 +1085,6 @@ def parse_properties(text_to_parse: str, output_differs: bool, props_to_record: if max_enc_diff: max_enc_diff = float(max_enc_diff) props[MAX_ENC_DIFF] = max_enc_diff - return props diff --git a/tests/constants.py b/tests/constants.py index c2e84e50b71834715df52eaebdfac22c1b15d838..36dabd0584c78e8f02e39ba90242654654fe38c6 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -12,7 +12,9 @@ MAX_ABS_DIFF = "MAXIMUM ABS DIFF" SSNR = "SSNR" ODG = "ODG" MAX_ENC_DIFF = "MAXIMUM ENC DIFF" - +ENC_CORE_OVL = "ENC_CORE_OVL" +MAX_OVL = "MAX_OVL" +MIN_OVL = "MIN_OVL" # regex patterns for parsing the output from comparisons -> mainly for BASOP ci MLD_PATTERN = r"MLD: ([\d\.]*)" @@ -21,6 +23,9 @@ ODG_PATTERN_PQEVALAUDIO = r"Objective Difference Grade: (-*\d*\.\d*)" ODG_PATTERN = r"ODG: (-*\d*\.\d*)" SSNR_PATTERN = r"Channel \d* SSNR: (nan|[+-]*inf|[-*\d\.]*)" MAX_ENC_DIFF_PATTERN = r"MAXIMUM ENC DIFF: (\d+) \((\d+\.\d+)%\)" +ENC_CORE_OVL_PATTERN = r"Core input overload detected: (\d+)" +MAX_OVL_PATTERN = r"Max overload value: (\d+\.\d+)" +MIN_OVL_PATTERN = r"Min overload value: (-*\d+\.\d+)" # minimum difference between ref and dut encoder file lengths diff --git a/tests/test_26444.py b/tests/test_26444.py index fa6214c66a8c5164ba636346839c8041aa7ae197..08d0ff77c5baed9e51243046d39040e97627d073 100644 --- a/tests/test_26444.py +++ b/tests/test_26444.py @@ -78,7 +78,6 @@ for s in scripts: @pytest.mark.parametrize("test_tag", list(test_dict.keys())) def test_evs_26444( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -180,7 +179,7 @@ def test_evs_26444( props = parse_properties(reason, output_differs, props_to_record) for k, v in props.items(): - record_property(k, v) + ref_decoder_frontend.record_property(k, v) equal &= not output_differs else: