Skip to content
Commits on Source (50)
...@@ -388,6 +388,28 @@ codec-asan: ...@@ -388,6 +388,28 @@ codec-asan:
- test_output.txt - test_output.txt
expose_as: "asan selftest results" expose_as: "asan selftest results"
# code selftest testvectors with address-sanitizer binaries
codec-usan:
extends:
- .test-job-linux
- .rules-merge-request
stage: test
needs: ["build-codec-sanitizers-linux"]
script:
- *print-common-info
- make clean
- make -j CLANG=3
- UBSAN_OPTIONS=suppressions=scripts/ubsan.supp,report_error_type=1 python3 scripts/self_test.py --create
- grep_exit_code=0
- grep UndefinedBehaviorSanitizer scripts/ref/logs/* || grep_exit_code=$?
- if [ $grep_exit_code != 1 ] ; then echo "Run errors in self_test.py with Clang undefined-behavior-sanitizer"; exit 1; fi
artifacts:
name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results"
expire_in: 1 week
paths:
- scripts/ref/logs/
expose_as: "usan selftest results"
# test renderer executable # test renderer executable
renderer-smoke-test: renderer-smoke-test:
extends: extends:
...@@ -455,6 +477,33 @@ renderer-msan: ...@@ -455,6 +477,33 @@ renderer-msan:
junit: junit:
- report-junit.xml - report-junit.xml
# test renderer executable with cmake + usan
renderer-usan:
extends:
- .test-job-linux
- .rules-merge-request
needs: ["build-codec-linux-cmake"]
stage: test
script:
- cmake -B cmake-build -G "Unix Makefiles" -DCLANG=usan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true
- cmake --build cmake-build -- -j
- UBSAN_OPTIONS=suppressions=scripts/ubsan.supp,report_error_type=1,log_path=usan_log_catchall python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py
- grep_exit_code=0
- touch usan_log_empty # Creates an empty file, this is to avoid "grep: usan_log_*: No such file or directory" in case no USAN failures are reported from pytest
- grep UndefinedBehaviorSanitizer usan_log_* || grep_exit_code=$?
- if [ $grep_exit_code != 1 ] ; then echo "Run errors in test_renderer.py with Clang undefined-behavior-sanitizer"; exit 1; fi
artifacts:
name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results"
expire_in: 1 week
when: always
paths:
- report-junit.xml
expose_as: "renderer usan pytest results"
reports:
junit:
- report-junit.xml
# compare renderer bitexactness between target and source branch # compare renderer bitexactness between target and source branch
renderer-pytest-on-merge-request: renderer-pytest-on-merge-request:
extends: extends:
......
...@@ -70,8 +70,20 @@ if(UNIX) ...@@ -70,8 +70,20 @@ if(UNIX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
elseif("${CLANG}" MATCHES "3" OR "${CLANG}" MATCHES "usan") elseif("${CLANG}" MATCHES "3" OR "${CLANG}" MATCHES "usan")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined") # NOTE: keep in sync with list in Makefile
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined") set(USAN_CHECKS_ENABLE
undefined # Default checks
# Extra checks
float-divide-by-zero
implicit-conversion
local-bounds
)
list(JOIN USAN_CHECKS_ENABLE "," USAN_CHECKS_ENABLE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=${USAN_CHECKS_ENABLE} -fsanitize-recover=${USAN_CHECKS_ENABLE}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${USAN_CHECKS_ENABLE} -fsanitize-recover=${USAN_CHECKS_ENABLE}")
else()
message(FATAL_ERROR "Unknown CLANG setting: ${CLANG}")
endif() endif()
endif() endif()
# GCOV # GCOV
......
...@@ -77,8 +77,12 @@ LDFLAGS += -fsanitize=address ...@@ -77,8 +77,12 @@ LDFLAGS += -fsanitize=address
endif endif
ifeq "$(CLANG)" "3" ifeq "$(CLANG)" "3"
CC = $(CCCLANG) CC = $(CCCLANG)
CFLAGS += -fsanitize=undefined # NOTE: keep in sync with list in CMakeLists.txt
LDFLAGS += -fsanitize=undefined usan_checks = undefined,float-divide-by-zero,implicit-conversion,local-bounds
CFLAGS += -fsanitize=$(usan_checks)
CFLAGS += -fsanitize-recover=$(usan_checks)
LDFLAGS += -fsanitize=$(usan_checks)
LDFLAGS += -fsanitize-recover=$(usan_checks)
endif endif
ifeq "$(RELEASE)" "1" ifeq "$(RELEASE)" "1"
......
...@@ -175,6 +175,9 @@ typedef struct ...@@ -175,6 +175,9 @@ typedef struct
float lfeConfigElevation; float lfeConfigElevation;
bool lfeCustomRoutingEnabled; bool lfeCustomRoutingEnabled;
char inLfePanningMatrixFile[RENDERER_MAX_CLI_ARG_LENGTH]; char inLfePanningMatrixFile[RENDERER_MAX_CLI_ARG_LENGTH];
#ifdef FIX_488_SYNC_DELAY
float syncMdDelay;
#endif
} CmdlnArgs; } CmdlnArgs;
typedef enum typedef enum
...@@ -203,6 +206,9 @@ typedef enum ...@@ -203,6 +206,9 @@ typedef enum
#endif #endif
CmdLnOptionId_referenceVectorFile, CmdLnOptionId_referenceVectorFile,
CmdLnOptionId_exteriorOrientationFile, CmdLnOptionId_exteriorOrientationFile,
#ifdef FIX_488_SYNC_DELAY
CmdLnOptionId_syncMdDelay,
#endif
} CmdLnOptionId; } CmdLnOptionId;
static const CmdLnParser_Option cliOptions[] = { static const CmdLnParser_Option cliOptions[] = {
...@@ -342,6 +348,14 @@ static const CmdLnParser_Option cliOptions[] = { ...@@ -342,6 +348,14 @@ static const CmdLnParser_Option cliOptions[] = {
.matchShort = "exof", .matchShort = "exof",
.description = "External orientation trajectory file for simulation of external orientations", .description = "External orientation trajectory file for simulation of external orientations",
}, },
#ifdef FIX_488_SYNC_DELAY
{
.id = CmdLnOptionId_syncMdDelay,
.match = "sync_md_delay",
.matchShort = "smd",
.description = "Metadata Synchronization Delay in ms, Default is 0. Quantized by 5ms subframes for TDRenderer (13ms -> 10ms -> 2subframes)",
},
#endif
}; };
...@@ -1113,6 +1127,9 @@ int main( ...@@ -1113,6 +1127,9 @@ int main(
if ( args.inConfig.numAudioObjects > 0 ) if ( args.inConfig.numAudioObjects > 0 )
{ {
IVAS_REND_SetTotalNumberOfObjects( hIvasRend, args.inConfig.numAudioObjects ); IVAS_REND_SetTotalNumberOfObjects( hIvasRend, args.inConfig.numAudioObjects );
#ifdef FIX_488_SYNC_DELAY
IVAS_REND_SetIsmMetadataDelay( hIvasRend, args.syncMdDelay );
#endif
} }
IVAS_REND_LfePanMtx lfePanMatrix; IVAS_REND_LfePanMtx lfePanMatrix;
...@@ -1687,6 +1704,8 @@ int main( ...@@ -1687,6 +1704,8 @@ int main(
} }
} }
} }
#ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SPLIT_REND_WITH_HEAD_ROT
for ( i = 0; i < args.inConfig.numBinBuses; ++i ) for ( i = 0; i < args.inConfig.numBinBuses; ++i )
{ {
...@@ -1897,6 +1916,13 @@ int main( ...@@ -1897,6 +1916,13 @@ int main(
} }
#endif #endif
#ifdef FIX_488_SYNC_DELAY
if ( args.inConfig.numAudioObjects != 0 && ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
{
fprintf( stdout, "\n\nMetadata delayed %d subframes\n\n", (int16_t) round( args.syncMdDelay / ( 1000 / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ) );
}
#endif
if ( !args.quietModeEnabled && args.delayCompensationEnabled ) if ( !args.quietModeEnabled && args.delayCompensationEnabled )
{ {
fprintf( stdout, "\nRenderer delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale ); fprintf( stdout, "\nRenderer delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale );
...@@ -2483,6 +2509,10 @@ static CmdlnArgs defaultArgs( ...@@ -2483,6 +2509,10 @@ static CmdlnArgs defaultArgs(
args.lfeCustomRoutingEnabled = false; args.lfeCustomRoutingEnabled = false;
clearString( args.inLfePanningMatrixFile ); clearString( args.inLfePanningMatrixFile );
#ifdef FIX_488_SYNC_DELAY
args.syncMdDelay = 0;
#endif
return args; return args;
} }
...@@ -2622,6 +2652,13 @@ static void parseOption( ...@@ -2622,6 +2652,13 @@ static void parseOption(
exit( -1 ); exit( -1 );
} }
break; break;
#ifdef FIX_488_SYNC_DELAY
case CmdLnOptionId_syncMdDelay:
assert( numOptionValues == 1 );
/* Metadata Delay to sync with audio delay in ms */
args->syncMdDelay = strtof( optionValues[0], NULL );
break;
#endif
default: default:
assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); assert( 0 && "This should be unreachable - all command line options should be explicitly handled." );
break; break;
......
...@@ -158,9 +158,26 @@ ...@@ -158,9 +158,26 @@
#define FIX_559_EXTL_IGF_MISMATCH /* VA: issue 559: fix mismatch between st->extl and st->igf observed as crash in PlanarSBA bitrate switching */ #define FIX_559_EXTL_IGF_MISMATCH /* VA: issue 559: fix mismatch between st->extl and st->igf observed as crash in PlanarSBA bitrate switching */
#define FIX_571_REVERB_NOT_ACTIVATED_ISM /* Philips: Issue 571: Reverb not activated for discrete and parametric ISM */ #define FIX_571_REVERB_NOT_ACTIVATED_ISM /* Philips: Issue 571: Reverb not activated for discrete and parametric ISM */
#define FIX_QMETA_SID_5k2 /* Nokia: Issue 137: enable using full 5.2k bitrate in MASA SID */ #define FIX_QMETA_SID_5k2 /* Nokia: Issue 137: enable using full 5.2k bitrate in MASA SID */
#define FIX_578_PARAMMC_ILD_BS /* FhG: Issue 578: transmitt also center ILD in band 0 when LFE is active in 3TC ParamMC */
#define FIX_UNCLR_ISSUE /* VoiceAge: issue 574: Fix UNCLR mis-classifications in noisy speech stereo */
#define FIX_TCX_LOWRATE_LIMITATION /* VA: issue 577: TCX bitrate limitation only when DEBUGGING is active */
#define FIX_575_LOW_OVERLAP_PLC_RECOVERY /* FhG: Issue 575 fix for PLC and transistion to TCX5*/
#define FIX_488_SYNC_DELAY /* Eri: Issue 488: Waveform and MD desynchronized in external renderer */
#define FIX_550_FIRST_FRAME_ACCESS /* Eri: Issue 550: TD Object renderer: first frame accesses wrong transport channel offsets */ #define FIX_550_FIRST_FRAME_ACCESS /* Eri: Issue 550: TD Object renderer: first frame accesses wrong transport channel offsets */
#define FIX_550_FIRST_FRAME_ACCESS_ALT /* Eri: Issue 550: Should be merged with FIX_550_FIRST_FRAME_ACCESS above, or accepted at the same time */ #define FIX_550_FIRST_FRAME_ACCESS_ALT /* Eri: Issue 550: Should be merged with FIX_550_FIRST_FRAME_ACCESS above, or accepted at the same time */
#define FIX_569_TD_FILTER_LENGTH /* Eri: Issue 569: If an HRTF binary file exceeds the SFX_SPAT_BIN_MAX_FILTER_LENGTH the decoder crashes. This truncates the filter when generated from the model. */ #define FIX_569_TD_FILTER_LENGTH /* Eri: Issue 569: If an HRTF binary file exceeds the SFX_SPAT_BIN_MAX_FILTER_LENGTH the decoder crashes. This truncates the filter when generated from the model. */
#define ISM_FB_16k4 /* VA: Issue: 579: change BW from SWB to FB in NxISM conditions to match the EVS codec */
#define FIX_580_PARAMMC_ENER_BURSTS /* FhG: issue 580: energy bursts due to ILD holding when energy relations change too much */
#define FIX_550_FIRST_FRAME_ACCESS /* Eri: Issue 550: TD Object renderer: first frame accesses wrong transport channel offsets */
#define FIX_550_FIRST_FRAME_ACCESS_ALT /* Eri: Issue 550: Should be merged with FIX_550_FIRST_FRAME_ACCESS above, or accepted at the same time */
#define FIX_569_TD_FILTER_LENGTH /* Eri: Issue 569: If an HRTF binary file exceeds the SFX_SPAT_BIN_MAX_FILTER_LENGTH the decoder crashes. This truncates the filter when generated from the model. */
#define FIX_595_SHL_NOGLOB /* FhG: Issue 595: compilation with BASOP_NOGLOB disabled */ #define FIX_595_SHL_NOGLOB /* FhG: Issue 595: compilation with BASOP_NOGLOB disabled */
#define UPDATE_FASTCONV_SBA_FILTER /* Dlb: Issue 584: Update SBA CLDFB-Domain HRTFs */ #define UPDATE_FASTCONV_SBA_FILTER /* Dlb: Issue 584: Update SBA CLDFB-Domain HRTFs */
#define FIX_570_SF_EXT_ORIENTATION #define FIX_570_SF_EXT_ORIENTATION
...@@ -171,6 +188,7 @@ ...@@ -171,6 +188,7 @@
#define FIX_MEM_REALLOC_IND_LIST /* VA: issue 601: failure of the automatic memory re-allocation mechanism when ind_list[] buffer is depleted in MASA mode with 2 TC*/ #define FIX_MEM_REALLOC_IND_LIST /* VA: issue 601: failure of the automatic memory re-allocation mechanism when ind_list[] buffer is depleted in MASA mode with 2 TC*/
#define FIX_1720_HRTF_FASTCONV /* Dlb : Binaural and Binaural room format RAM saving in SBA mode */ #define FIX_1720_HRTF_FASTCONV /* Dlb : Binaural and Binaural room format RAM saving in SBA mode */
#define JBM_PARAMUPMIX /* Dlb: Issue 471: Integrate the Multichannel Parametric Upmix into the JBM path */ #define JBM_PARAMUPMIX /* Dlb: Issue 471: Integrate the Multichannel Parametric Upmix into the JBM path */
#define FIX_194_LFE_DELAY_EXTREND /* FhG: Issue 194: Fix delay alignment of LFE in external renderer */
#define FIX_582_INDEX_OUT_OF_BOUNDS_SNS_AVQ_DEC /* FhG: fix an undefined behaviour error in SNS AVQ decoding */ #define FIX_582_INDEX_OUT_OF_BOUNDS_SNS_AVQ_DEC /* FhG: fix an undefined behaviour error in SNS AVQ decoding */
#define FIX_614_ADD_TO_NULL_PTR_DIRAC_SETUP /* FhG: Issue 614: prevent adding to a null pointer in dirac setup code */ #define FIX_614_ADD_TO_NULL_PTR_DIRAC_SETUP /* FhG: Issue 614: prevent adding to a null pointer in dirac setup code */
#define UPDATE_REVERB_UTILS /* Use CLDFB HRTFs of the appropriate SBA order in get_IR_from_filter_taps() */ #define UPDATE_REVERB_UTILS /* Use CLDFB HRTFs of the appropriate SBA order in get_IR_from_filter_taps() */
...@@ -190,6 +208,9 @@ ...@@ -190,6 +208,9 @@
#define FIX_622_SILENCE_USAN_WARNING /* FhG: silenceusan warning in ifft code */ #define FIX_622_SILENCE_USAN_WARNING /* FhG: silenceusan warning in ifft code */
#define FIX_615_UBSAN_SPAR_TO_DIRAC /*Dlb : Fix for UBSAN issue 615*/ #define FIX_615_UBSAN_SPAR_TO_DIRAC /*Dlb : Fix for UBSAN issue 615*/
#define FIX_626_VARIABLE_TYPE_MDCT_CONC /* FhG: trivial fix to fix USAN error */
#define FIX_616_DIV_ZERO_MCT /*FhG : Fix UBSAN division by zero error of issue 616*/
/* ################## End BE DEVELOPMENT switches ######################### */ /* ################## End BE DEVELOPMENT switches ######################### */
......
...@@ -126,7 +126,11 @@ void TonalMDCTConceal_SaveFreqSignal( ...@@ -126,7 +126,11 @@ void TonalMDCTConceal_SaveFreqSignal(
const int16_t infoIGFStartLine ) const int16_t infoIGFStartLine )
{ {
float *temp; float *temp;
#ifdef FIX_626_VARIABLE_TYPE_MDCT_CONC
uint16_t nOldSamples;
#else
int16_t nOldSamples; int16_t nOldSamples;
#endif
assert( nNewSamples > 0 && nNewSamples <= 2 * L_FRAME_MAX ); assert( nNewSamples > 0 && nNewSamples <= 2 * L_FRAME_MAX );
......
...@@ -143,8 +143,13 @@ static void AdjustChannelRatios( ...@@ -143,8 +143,13 @@ static void AdjustChannelRatios(
} }
for ( i = 3; i < nChannels; i++ ) for ( i = 3; i < nChannels; i++ )
{ {
#ifdef FIX_616_DIV_ZERO_MCT
cur_ratio = (float) chBitRatios[i] / ( sum_ratio + FLT_MIN );
tar_ratio = (float) force_ch_bit_ratios[i] / ( sum_tar_ratio + FLT_MIN );
#else
cur_ratio = (float) chBitRatios[i] / sum_ratio; cur_ratio = (float) chBitRatios[i] / sum_ratio;
tar_ratio = (float) force_ch_bit_ratios[i] / sum_tar_ratio; tar_ratio = (float) force_ch_bit_ratios[i] / sum_tar_ratio;
#endif
tar_ratio = min( tar_ratio, cur_ratio ); tar_ratio = min( tar_ratio, cur_ratio );
chBitRatios[i] = (int16_t) ( tar_ratio * sum_tar_ratio ); chBitRatios[i] = (int16_t) ( tar_ratio * sum_tar_ratio );
......
...@@ -681,6 +681,9 @@ ivas_error ivas_td_binaural_renderer_ext( ...@@ -681,6 +681,9 @@ ivas_error ivas_td_binaural_renderer_ext(
const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* i : Combined head and external orientations */ const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* i : Combined head and external orientations */
const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */ const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */
const REVERB_HANDLE hReverb, /* i : Reverberator handle */ const REVERB_HANDLE hReverb, /* i : Reverberator handle */
#ifdef FIX_488_SYNC_DELAY
const int16_t ism_md_subframe_update_ext, /* i: Metadata Delay in subframes to sync with audio delay */
#endif
const int16_t output_frame, /* i : output frame length */ const int16_t output_frame, /* i : output frame length */
float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */
) )
...@@ -693,7 +696,9 @@ ivas_error ivas_td_binaural_renderer_ext( ...@@ -693,7 +696,9 @@ ivas_error ivas_td_binaural_renderer_ext(
IVAS_REND_AudioConfigType inConfigType; IVAS_REND_AudioConfigType inConfigType;
AUDIO_CONFIG transport_config; AUDIO_CONFIG transport_config;
ivas_error error; ivas_error error;
#ifndef FIX_488_SYNC_DELAY
int16_t ism_md_subframe_update_ext; int16_t ism_md_subframe_update_ext;
#endif
float *p_output[MAX_OUTPUT_CHANNELS]; float *p_output[MAX_OUTPUT_CHANNELS];
int16_t ch; int16_t ch;
...@@ -707,7 +712,10 @@ ivas_error ivas_td_binaural_renderer_ext( ...@@ -707,7 +712,10 @@ ivas_error ivas_td_binaural_renderer_ext(
inConfigType = getAudioConfigType( inConfig ); inConfigType = getAudioConfigType( inConfig );
lfe_idx = LFE_CHANNEL; lfe_idx = LFE_CHANNEL;
hIsmMetaData[0] = NULL; hIsmMetaData[0] = NULL;
#ifndef FIX_488_SYNC_DELAY
ism_md_subframe_update_ext = 0; ism_md_subframe_update_ext = 0;
#endif
if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED )
{ {
......
...@@ -579,6 +579,9 @@ ivas_error ivas_td_binaural_renderer_ext( ...@@ -579,6 +579,9 @@ ivas_error ivas_td_binaural_renderer_ext(
const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* i : Combined head and external orientations */ const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* i : Combined head and external orientations */
const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */ const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */
const REVERB_HANDLE hReverb, /* i : Reverberator handle */ const REVERB_HANDLE hReverb, /* i : Reverberator handle */
#ifdef FIX_488_SYNC_DELAY
const int16_t ism_md_subframe_update_ext, /* i: Metadata Delay in subframes to sync with audio delay */
#endif
const int16_t output_frame, /* i : output frame length */ const int16_t output_frame, /* i : output frame length */
float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */
); );
......
...@@ -61,6 +61,10 @@ ...@@ -61,6 +61,10 @@
#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) #define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS )
#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) #define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS )
#ifdef FIX_194_LFE_DELAY_EXTREND
#define MAX_BIN_DELAY_SAMPLES 50 /* Maximum supported rendering latency for binaural IRs */
#endif
#else #else
#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) #define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS )
#endif #endif
...@@ -142,6 +146,9 @@ typedef struct ...@@ -142,6 +146,9 @@ typedef struct
float nonDiegeticPanGain; float nonDiegeticPanGain;
OMASA_ANA_HANDLE hOMasa; OMASA_ANA_HANDLE hOMasa;
uint16_t total_num_objects; uint16_t total_num_objects;
#ifdef FIX_488_SYNC_DELAY
float ism_metadata_delay_ms;
#endif
} input_ism; } input_ism;
typedef struct typedef struct
...@@ -175,6 +182,10 @@ typedef struct ...@@ -175,6 +182,10 @@ typedef struct
float nonDiegeticPanGain; float nonDiegeticPanGain;
lfe_routing lfeRouting; lfe_routing lfeRouting;
float *bufferData; float *bufferData;
#ifdef FIX_194_LFE_DELAY_EXTREND
int16_t binauralDelaySmp;
float *lfeDelayBuffer;
#endif
MCMASA_ANA_HANDLE hMcMasa; MCMASA_ANA_HANDLE hMcMasa;
} input_mc; } input_mc;
...@@ -286,6 +297,30 @@ static void freeInputBaseBufferData( float **data ) ...@@ -286,6 +297,30 @@ static void freeInputBaseBufferData( float **data )
return; return;
} }
#ifdef FIX_194_LFE_DELAY_EXTREND
static ivas_error allocateMcLfeDelayBuffer( float **lfeDelayBuffer, const int16_t data_size )
{
*lfeDelayBuffer = (float *) malloc( data_size * sizeof( float ) );
if ( *lfeDelayBuffer == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for LFE delay buffer" );
}
return IVAS_ERR_OK;
}
static void freeMcLfeDelayBuffer( float **lfeDelayBuffer )
{
if ( *lfeDelayBuffer != NULL )
{
free( *lfeDelayBuffer );
*lfeDelayBuffer = NULL;
}
return;
}
#endif
static IVAS_QUATERNION quaternionInit( static IVAS_QUATERNION quaternionInit(
void ) void )
{ {
...@@ -2133,6 +2168,9 @@ static ivas_error initMcBinauralRendering( ...@@ -2133,6 +2168,9 @@ static ivas_error initMcBinauralRendering(
ivas_error error; ivas_error error;
#ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SPLIT_REND_WITH_HEAD_ROT
int16_t i; int16_t i;
#endif
#ifdef FIX_194_LFE_DELAY_EXTREND
int32_t binauralDelayNs;
#endif #endif
int32_t outSampleRate; int32_t outSampleRate;
...@@ -2251,6 +2289,18 @@ static ivas_error initMcBinauralRendering( ...@@ -2251,6 +2289,18 @@ static ivas_error initMcBinauralRendering(
} }
} }
#ifdef FIX_194_LFE_DELAY_EXTREND
/* determine binaural delay ( used for aligning LFE to output signal ) */
binauralDelayNs = max( ( inputMc->crendWrapper != NULL ) ? inputMc->crendWrapper->binaural_latency_ns : 0,
inputMc->tdRendWrapper.binaural_latency_ns );
inputMc->binauralDelaySmp = (int16_t) roundf( (float) binauralDelayNs * *inputMc->base.ctx.pOutSampleRate / 1000000000.f );
if ( inputMc->binauralDelaySmp > MAX_BIN_DELAY_SAMPLES )
{
return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid delay for LFE binaural rendering!)" );
}
#endif /* FIX_194_LFE_DELAY_EXTREND */
return IVAS_ERR_OK; return IVAS_ERR_OK;
} }
...@@ -2367,6 +2417,13 @@ static ivas_error setRendInputActiveMc( ...@@ -2367,6 +2417,13 @@ static ivas_error setRendInputActiveMc(
return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED;
} }
#ifdef FIX_194_LFE_DELAY_EXTREND
if ( ( error = allocateMcLfeDelayBuffer( &inputMc->lfeDelayBuffer, MAX_BIN_DELAY_SAMPLES ) ) != IVAS_ERR_OK )
{
return error;
}
#endif
if ( ( error = allocateInputBaseBufferData( &inputMc->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) if ( ( error = allocateInputBaseBufferData( &inputMc->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK )
{ {
return error; return error;
...@@ -2381,6 +2438,9 @@ static ivas_error setRendInputActiveMc( ...@@ -2381,6 +2438,9 @@ static ivas_error setRendInputActiveMc(
inputMc->hMcMasa = NULL; inputMc->hMcMasa = NULL;
initRotGains( inputMc->rot_gains_prev ); initRotGains( inputMc->rot_gains_prev );
inputMc->lfeRouting = defaultLfeRouting( inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ); inputMc->lfeRouting = defaultLfeRouting( inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut );
#ifdef FIX_194_LFE_DELAY_EXTREND
set_zero( inputMc->lfeDelayBuffer, MAX_BIN_DELAY_SAMPLES );
#endif
#ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SPLIT_REND_WITH_HEAD_ROT
for ( i = 0; i < (int16_t) ( sizeof( inputMc->splitTdRendWrappers ) / sizeof( *inputMc->splitTdRendWrappers ) ); ++i ) for ( i = 0; i < (int16_t) ( sizeof( inputMc->splitTdRendWrappers ) / sizeof( *inputMc->splitTdRendWrappers ) ); ++i )
...@@ -2425,6 +2485,9 @@ static void clearInputMc( ...@@ -2425,6 +2485,9 @@ static void clearInputMc(
rendCtx = inputMc->base.ctx; rendCtx = inputMc->base.ctx;
#ifdef FIX_194_LFE_DELAY_EXTREND
freeMcLfeDelayBuffer( &inputMc->lfeDelayBuffer );
#endif
freeInputBaseBufferData( &inputMc->bufferData ); freeInputBaseBufferData( &inputMc->bufferData );
initRendInputBase( &inputMc->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx, initRendInputBase( &inputMc->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx,
NULL, 0 ); NULL, 0 );
...@@ -3574,6 +3637,9 @@ ivas_error IVAS_REND_Open( ...@@ -3574,6 +3637,9 @@ ivas_error IVAS_REND_Open(
hIvasRend->inputsMc[i].hReverb = NULL; hIvasRend->inputsMc[i].hReverb = NULL;
hIvasRend->inputsMc[i].tdRendWrapper.hBinRendererTd = NULL; hIvasRend->inputsMc[i].tdRendWrapper.hBinRendererTd = NULL;
hIvasRend->inputsMc[i].bufferData = NULL; hIvasRend->inputsMc[i].bufferData = NULL;
#ifdef FIX_194_LFE_DELAY_EXTREND
hIvasRend->inputsMc[i].lfeDelayBuffer = NULL;
#endif
hIvasRend->inputsMc[i].nonDiegeticPan = nonDiegeticPan; hIvasRend->inputsMc[i].nonDiegeticPan = nonDiegeticPan;
hIvasRend->inputsMc[i].nonDiegeticPanGain = nonDiegeticPanGain; hIvasRend->inputsMc[i].nonDiegeticPanGain = nonDiegeticPanGain;
hIvasRend->inputsMc[i].hMcMasa = NULL; hIvasRend->inputsMc[i].hMcMasa = NULL;
...@@ -4034,7 +4100,7 @@ ivas_error IVAS_REND_AddInput( ...@@ -4034,7 +4100,7 @@ ivas_error IVAS_REND_AddInput(
} }
#ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SPLIT_REND_WITH_HEAD_ROT
if ( hIvasRend->splitRendEncBuffer.data == NULL ) if ( hIvasRend->splitRendEncBuffer.data == NULL && hIvasRend->hRendererConfig != NULL )
{ {
if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig ) ) != IVAS_ERR_OK )
{ {
...@@ -5585,9 +5651,14 @@ static ivas_error renderIsmToBinaural( ...@@ -5585,9 +5651,14 @@ static ivas_error renderIsmToBinaural(
{ {
float tmpTDRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float tmpTDRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k];
ivas_error error; ivas_error error;
#ifdef FIX_488_SYNC_DELAY
int16_t ism_md_subframe_update_ext;
#endif
push_wmops( "renderIsmToBinaural" ); push_wmops( "renderIsmToBinaural" );
#ifdef FIX_488_SYNC_DELAY
/* Metadata Delay to sync with audio delay converted from ms to 5ms (1000/50/4) subframe index */
ism_md_subframe_update_ext = (int16_t) round( ismInput->ism_metadata_delay_ms / ( 1000 / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) );
#endif
copyBufferTo2dArray( ismInput->base.inputBuffer, tmpTDRendBuffer ); copyBufferTo2dArray( ismInput->base.inputBuffer, tmpTDRendBuffer );
if ( ( error = ivas_td_binaural_renderer_ext( &ismInput->tdRendWrapper, if ( ( error = ivas_td_binaural_renderer_ext( &ismInput->tdRendWrapper,
...@@ -5596,6 +5667,9 @@ static ivas_error renderIsmToBinaural( ...@@ -5596,6 +5667,9 @@ static ivas_error renderIsmToBinaural(
ismInput->base.ctx.pCombinedOrientationData, ismInput->base.ctx.pCombinedOrientationData,
&ismInput->currentPos, &ismInput->currentPos,
ismInput->hReverb, ismInput->hReverb,
#ifdef FIX_488_SYNC_DELAY
ism_md_subframe_update_ext,
#endif
outAudio.config.numSamplesPerChannel, outAudio.config.numSamplesPerChannel,
tmpTDRendBuffer ) ) != IVAS_ERR_OK ) tmpTDRendBuffer ) ) != IVAS_ERR_OK )
{ {
...@@ -5761,9 +5835,16 @@ static ivas_error renderIsmToBinauralReverb( ...@@ -5761,9 +5835,16 @@ static ivas_error renderIsmToBinauralReverb(
{ {
float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k];
ivas_error error; ivas_error error;
#ifdef FIX_488_SYNC_DELAY
int16_t ism_md_subframe_update_ext;
#endif
push_wmops( "renderIsmToBinauralRoom" ); push_wmops( "renderIsmToBinauralRoom" );
#ifdef FIX_488_SYNC_DELAY
/* Metadata Delay to sync with audio delay converted from ms to 5ms (1000/50/4) subframe index */
ism_md_subframe_update_ext = (int16_t) round( ismInput->ism_metadata_delay_ms / ( 1000 / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) );
#endif
copyBufferTo2dArray( ismInput->base.inputBuffer, tmpRendBuffer ); copyBufferTo2dArray( ismInput->base.inputBuffer, tmpRendBuffer );
if ( ( error = ivas_td_binaural_renderer_ext( &ismInput->tdRendWrapper, if ( ( error = ivas_td_binaural_renderer_ext( &ismInput->tdRendWrapper,
...@@ -5772,6 +5853,9 @@ static ivas_error renderIsmToBinauralReverb( ...@@ -5772,6 +5853,9 @@ static ivas_error renderIsmToBinauralReverb(
ismInput->base.ctx.pCombinedOrientationData, ismInput->base.ctx.pCombinedOrientationData,
&ismInput->currentPos, &ismInput->currentPos,
ismInput->hReverb, ismInput->hReverb,
#ifdef FIX_488_SYNC_DELAY
ism_md_subframe_update_ext,
#endif
outAudio.config.numSamplesPerChannel, outAudio.config.numSamplesPerChannel,
tmpRendBuffer ) ) != IVAS_ERR_OK ) tmpRendBuffer ) ) != IVAS_ERR_OK )
{ {
...@@ -5915,11 +5999,18 @@ static ivas_error renderIsmToSplitBinaural( ...@@ -5915,11 +5999,18 @@ static ivas_error renderIsmToSplitBinaural(
float tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; float tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k];
int16_t output_frame = ismInput->base.inputBuffer.config.numSamplesPerChannel; int16_t output_frame = ismInput->base.inputBuffer.config.numSamplesPerChannel;
COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; COMBINED_ORIENTATION_HANDLE pCombinedOrientationData;
#ifdef FIX_488_SYNC_DELAY
int16_t ism_md_subframe_update_ext;
#endif
push_wmops( "renderIsmToSplitBinaural" ); push_wmops( "renderIsmToSplitBinaural" );
pSplitRendWrapper = ismInput->base.ctx.pSplitRendWrapper; pSplitRendWrapper = ismInput->base.ctx.pSplitRendWrapper;
pMultiBinPoseData = &pSplitRendWrapper->multiBinPoseData; pMultiBinPoseData = &pSplitRendWrapper->multiBinPoseData;
#ifdef FIX_488_SYNC_DELAY
/* Metadata Delay to sync with audio delay converted from ms to 5ms (1000/50/4) subframe index */
ism_md_subframe_update_ext = (int16_t) round( ismInput->ism_metadata_delay_ms / ( 1000 / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) );
#endif
/* If not yet allocated, open additional instances of TD renderer */ /* If not yet allocated, open additional instances of TD renderer */
for ( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i ) for ( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i )
...@@ -5998,6 +6089,9 @@ static ivas_error renderIsmToSplitBinaural( ...@@ -5998,6 +6089,9 @@ static ivas_error renderIsmToSplitBinaural(
ismInput->base.ctx.pCombinedOrientationData, ismInput->base.ctx.pCombinedOrientationData,
&ismInput->currentPos, &ismInput->currentPos,
NULL, NULL,
#ifdef FIX_488_SYNC_DELAY
ism_md_subframe_update_ext,
#endif
output_frame, output_frame,
tmpProcessing ); tmpProcessing );
if ( error != IVAS_ERR_OK ) if ( error != IVAS_ERR_OK )
...@@ -6013,6 +6107,9 @@ static ivas_error renderIsmToSplitBinaural( ...@@ -6013,6 +6107,9 @@ static ivas_error renderIsmToSplitBinaural(
ismInput->base.ctx.pCombinedOrientationData, ismInput->base.ctx.pCombinedOrientationData,
&ismInput->currentPos, &ismInput->currentPos,
NULL, NULL,
#ifdef FIX_488_SYNC_DELAY
ism_md_subframe_update_ext,
#endif
output_frame, output_frame,
tmpProcessing ); tmpProcessing );
if ( error != IVAS_ERR_OK ) if ( error != IVAS_ERR_OK )
...@@ -6141,6 +6238,7 @@ static ivas_error renderActiveInputsIsm( ...@@ -6141,6 +6238,7 @@ static ivas_error renderActiveInputsIsm(
} }
if ( ( error = renderInputIsm( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) if ( ( error = renderInputIsm( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK )
{ {
return error; return error;
} }
...@@ -6156,13 +6254,21 @@ static ivas_error renderLfeToBinaural( ...@@ -6156,13 +6254,21 @@ static ivas_error renderLfeToBinaural(
#endif #endif
IVAS_REND_AudioBuffer outAudio ) IVAS_REND_AudioBuffer outAudio )
{ {
int16_t i;
int16_t lfe_idx; int16_t lfe_idx;
#ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SPLIT_REND_WITH_HEAD_ROT
int16_t pose_idx, num_poses; int16_t pose_idx, num_poses;
#endif #endif
float gain; float gain;
#ifdef FIX_194_LFE_DELAY_EXTREND
int16_t ear_idx;
float tmpLfeBuffer[MAX_BUFFER_LENGTH_PER_CHANNEL];
int16_t frame_size, num_cpy_smpl_cur_frame, num_cpy_smpl_prev_frame;
const float *lfeInput;
float *writePtr;
#else
int16_t i;
float *readPtr, *writePtr; float *readPtr, *writePtr;
#endif
#ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SPLIT_REND_WITH_HEAD_ROT
assert( ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && "Must be binaural output" ); assert( ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && "Must be binaural output" );
...@@ -6188,8 +6294,24 @@ static ivas_error renderLfeToBinaural( ...@@ -6188,8 +6294,24 @@ static ivas_error renderLfeToBinaural(
return IVAS_ERR_OK; return IVAS_ERR_OK;
} }
#ifdef FIX_194_LFE_DELAY_EXTREND
/* --- Prepare LFE signal to be added to binaural output --- */
lfeInput = getSmplPtr( mcInput->base.inputBuffer, lfe_idx, 0 );
frame_size = mcInput->base.inputBuffer.config.numSamplesPerChannel;
num_cpy_smpl_prev_frame = mcInput->binauralDelaySmp;
num_cpy_smpl_cur_frame = frame_size - num_cpy_smpl_prev_frame;
/* Assuming LFE should be delayed by less that the duration of one frame */
assert( mcInput->binauralDelaySmp < frame_size );
/* Get delayed LFE signal from previous frame, apply gain and save in tmp buffer */
v_multc( mcInput->lfeDelayBuffer, gain, tmpLfeBuffer, num_cpy_smpl_prev_frame );
/* Continue filling tmp buffer, now with LFE signal from current frame */
v_multc( lfeInput, gain, tmpLfeBuffer + num_cpy_smpl_prev_frame, num_cpy_smpl_cur_frame );
/* Save remaining LFE samples of current frame for next frame */
mvr2r( lfeInput + num_cpy_smpl_cur_frame, mcInput->lfeDelayBuffer, num_cpy_smpl_prev_frame );
#endif
#ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SPLIT_REND_WITH_HEAD_ROT
/* Copy LFE to left and right binaural channels */ /* Copy LFE to left and right binaural channels for all poses */
if ( mcInput->base.ctx.pSplitRendWrapper != NULL ) if ( mcInput->base.ctx.pSplitRendWrapper != NULL )
{ {
num_poses = mcInput->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses; num_poses = mcInput->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses;
...@@ -6201,6 +6323,13 @@ static ivas_error renderLfeToBinaural( ...@@ -6201,6 +6323,13 @@ static ivas_error renderLfeToBinaural(
for ( pose_idx = 0; pose_idx < num_poses; ++pose_idx ) for ( pose_idx = 0; pose_idx < num_poses; ++pose_idx )
{ {
#ifdef FIX_194_LFE_DELAY_EXTREND
for ( ear_idx = 0; ear_idx < BINAURAL_CHANNELS; ++ear_idx )
{
writePtr = getSmplPtr( outAudio, pose_idx * BINAURAL_CHANNELS + ear_idx, 0 );
v_add( writePtr, tmpLfeBuffer, writePtr, frame_size );
}
#else
readPtr = getSmplPtr( mcInput->base.inputBuffer, lfe_idx, 0 ); readPtr = getSmplPtr( mcInput->base.inputBuffer, lfe_idx, 0 );
writePtr = getSmplPtr( outAudio, pose_idx * BINAURAL_CHANNELS, 0 ); writePtr = getSmplPtr( outAudio, pose_idx * BINAURAL_CHANNELS, 0 );
for ( i = 0; i < mcInput->base.inputBuffer.config.numSamplesPerChannel; i++ ) for ( i = 0; i < mcInput->base.inputBuffer.config.numSamplesPerChannel; i++ )
...@@ -6214,9 +6343,17 @@ static ivas_error renderLfeToBinaural( ...@@ -6214,9 +6343,17 @@ static ivas_error renderLfeToBinaural(
{ {
*writePtr++ += gain * ( *readPtr++ ); *writePtr++ += gain * ( *readPtr++ );
} }
#endif /* FIX_194_LFE_DELAY_EXTREND */
} }
#else /* SPLIT_REND_WITH_HEAD_ROT */ #else /* SPLIT_REND_WITH_HEAD_ROT */
/* Copy LFE to left and right ears */ /* Copy LFE to left and right ears */
#ifdef FIX_194_LFE_DELAY_EXTREND
for ( ear_idx = 0; ear_idx < BINAURAL_CHANNELS; ++ear_idx )
{
writePtr = getSmplPtr( outAudio, pose_idx * BINAURAL_CHANNELS + ear_idx, 0 );
v_add( writePtr, tmpLfeBuffer, writePtr, frame_size );
}
#else
readPtr = getSmplPtr( mcInput->base.inputBuffer, lfe_idx, 0 ); readPtr = getSmplPtr( mcInput->base.inputBuffer, lfe_idx, 0 );
writePtr = getSmplPtr( outAudio, 0, 0 ); writePtr = getSmplPtr( outAudio, 0, 0 );
for ( i = 0; i < mcInput->base.inputBuffer.config.numSamplesPerChannel; i++ ) for ( i = 0; i < mcInput->base.inputBuffer.config.numSamplesPerChannel; i++ )
...@@ -6230,7 +6367,9 @@ static ivas_error renderLfeToBinaural( ...@@ -6230,7 +6367,9 @@ static ivas_error renderLfeToBinaural(
{ {
*writePtr++ += gain * ( *readPtr++ ); *writePtr++ += gain * ( *readPtr++ );
} }
#endif /* FIX_194_LFE_DELAY_EXTREND */
#endif /* SPLIT_REND_WITH_HEAD_ROT */ #endif /* SPLIT_REND_WITH_HEAD_ROT */
pop_wmops(); pop_wmops();
return IVAS_ERR_OK; return IVAS_ERR_OK;
...@@ -6283,7 +6422,11 @@ static ivas_error renderMcToBinaural( ...@@ -6283,7 +6422,11 @@ static ivas_error renderMcToBinaural(
if ( ( error = ivas_td_binaural_renderer_ext( &mcInput->tdRendWrapper, mcInput->base.inConfig, &mcInput->customLsInput, if ( ( error = ivas_td_binaural_renderer_ext( &mcInput->tdRendWrapper, mcInput->base.inConfig, &mcInput->customLsInput,
mcInput->base.ctx.pCombinedOrientationData, mcInput->base.ctx.pCombinedOrientationData,
NULL, NULL,
mcInput->hReverb, mcInput->base.inputBuffer.config.numSamplesPerChannel, tmpRendBuffer ) ) != IVAS_ERR_OK ) mcInput->hReverb,
#ifdef FIX_488_SYNC_DELAY
0,
#endif
mcInput->base.inputBuffer.config.numSamplesPerChannel, tmpRendBuffer ) ) != IVAS_ERR_OK )
{ {
return error; return error;
} }
...@@ -6387,7 +6530,11 @@ static ivas_error renderMcToBinauralRoom( ...@@ -6387,7 +6530,11 @@ static ivas_error renderMcToBinauralRoom(
if ( ( error = ivas_td_binaural_renderer_ext( &mcInput->tdRendWrapper, mcInput->base.inConfig, &mcInput->customLsInput, if ( ( error = ivas_td_binaural_renderer_ext( &mcInput->tdRendWrapper, mcInput->base.inConfig, &mcInput->customLsInput,
mcInput->base.ctx.pCombinedOrientationData, mcInput->base.ctx.pCombinedOrientationData,
NULL, mcInput->hReverb, mcInput->base.inputBuffer.config.numSamplesPerChannel, tmpRendBuffer ) ) != IVAS_ERR_OK ) NULL, mcInput->hReverb,
#ifdef FIX_488_SYNC_DELAY
0,
#endif
mcInput->base.inputBuffer.config.numSamplesPerChannel, tmpRendBuffer ) ) != IVAS_ERR_OK )
{ {
return error; return error;
} }
...@@ -6699,6 +6846,9 @@ static ivas_error renderMcToSplitBinaural( ...@@ -6699,6 +6846,9 @@ static ivas_error renderMcToSplitBinaural(
&pCombinedOrientationDataLocal, &pCombinedOrientationDataLocal,
NULL, NULL,
mcInput->hReverb, mcInput->hReverb,
#ifdef FIX_488_SYNC_DELAY
0, /* Ism Audio Metadata Delay Sync in ms for External Renderer */
#endif
mcInput->base.inputBuffer.config.numSamplesPerChannel, mcInput->base.inputBuffer.config.numSamplesPerChannel,
tmpRendBuffer ) ) != IVAS_ERR_OK ) tmpRendBuffer ) ) != IVAS_ERR_OK )
{ {
...@@ -8157,6 +8307,33 @@ ivas_error IVAS_REND_SetTotalNumberOfObjects( ...@@ -8157,6 +8307,33 @@ ivas_error IVAS_REND_SetTotalNumberOfObjects(
return IVAS_ERR_OK; return IVAS_ERR_OK;
} }
#ifdef FIX_488_SYNC_DELAY
/*---------------------------------------------------------------------*
* IVAS_REND_SetIsmMetadataDelay( )
*
* Set the Metadata Delay in ms in order to sync with audio delay
*---------------------------------------------------------------------*/
ivas_error IVAS_REND_SetIsmMetadataDelay(
IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */
const float sync_md_delay /* i: Ism Metadata Delay in ms to sync with audio delay */
)
{
int16_t i;
if ( hIvasRend == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i )
{
hIvasRend->inputsIsm[i].ism_metadata_delay_ms = sync_md_delay;
}
return IVAS_ERR_OK;
}
#endif
/*-------------------------------------------------------------------* /*-------------------------------------------------------------------*
* IVAS_REND_GetSamples() * IVAS_REND_GetSamples()
...@@ -8260,6 +8437,7 @@ ivas_error IVAS_REND_GetSamples( ...@@ -8260,6 +8437,7 @@ ivas_error IVAS_REND_GetSamples(
/* Clear original output buffer */ /* Clear original output buffer */
set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel );
#ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SPLIT_REND_WITH_HEAD_ROT
outAudioOrig = outAudio; outAudioOrig = outAudio;
/* Use internal buffer if outputting split rendering bitstream */ /* Use internal buffer if outputting split rendering bitstream */
...@@ -8284,7 +8462,6 @@ ivas_error IVAS_REND_GetSamples( ...@@ -8284,7 +8462,6 @@ ivas_error IVAS_REND_GetSamples(
set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel );
} }
#endif #endif
if ( ( error = renderActiveInputsIsm( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) if ( ( error = renderActiveInputsIsm( hIvasRend, outAudio ) ) != IVAS_ERR_OK )
{ {
return error; return error;
......
...@@ -349,6 +349,13 @@ ivas_error IVAS_REND_SetTotalNumberOfObjects( ...@@ -349,6 +349,13 @@ ivas_error IVAS_REND_SetTotalNumberOfObjects(
const uint16_t total_num_objects /* i : total number of objects */ const uint16_t total_num_objects /* i : total number of objects */
); );
#ifdef FIX_488_SYNC_DELAY
ivas_error IVAS_REND_SetIsmMetadataDelay(
IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */
const float sync_md_delay /* i: Metadata Delay in ms to sync with audio delay */
);
#endif
ivas_error IVAS_REND_GetNumAllObjects( ivas_error IVAS_REND_GetNumAllObjects(
IVAS_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ IVAS_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */
int16_t *numChannels /* o : number of all objects */ int16_t *numChannels /* o : number of all objects */
......
# From self_test.py
alignment:hrtf_file_reader.c
bounds:dec_acelp.c
bounds:enc_acelp.c
bounds:enc_gain.c
bounds:ivas_spar_decoder.c
bounds:trans_direct.c
bounds:trans_inv.c
float-cast-overflow:ivas_dirac_com.c
float-divide-by-zero:ivas_stereo_cng_dec.c
float-divide-by-zero:swb_tbe_enc.c
implicit-integer-sign-change:ACcontextMapping.c
implicit-integer-sign-change:avq_dec.c
implicit-integer-sign-change:bitstream.c
implicit-integer-sign-change:cod4t64.c
implicit-integer-sign-change:dec_prm.c
implicit-integer-sign-change:dec4t64.c
implicit-integer-sign-change:enc_acelp.c
implicit-integer-sign-change:enc_prm.c
implicit-integer-sign-change:enh40.c
implicit-integer-sign-change:inov_dec.c
implicit-integer-sign-change:inov_enc.c
implicit-integer-sign-change:ivas_mdct_core_dec.c
implicit-integer-sign-change:jbm_jb4sb.c
implicit-integer-sign-change:jbm_pcmdsp_apa.c
implicit-integer-sign-change:cod4t64_fast.c
implicit-integer-sign-change:range_enc.c
implicit-integer-sign-change:tcq_position_arith.c
implicit-integer-sign-change:tonalMDCTconcealment.c
implicit-signed-integer-truncation:ACcontextMapping_dec.c
implicit-signed-integer-truncation:ACcontextMapping_enc.c
implicit-signed-integer-truncation:cng_dec.c
implicit-signed-integer-truncation:cod_tcx.c
implicit-signed-integer-truncation:dec_tcx.c
implicit-signed-integer-truncation:hdecnrm.c
implicit-signed-integer-truncation:ivas_qmetadata_enc.c
implicit-signed-integer-truncation:lib_dec.c
implicit-signed-integer-truncation:longarith.c
implicit-signed-integer-truncation:pvq_core_dec.c
implicit-signed-integer-truncation:pvq_core_enc.c
implicit-signed-integer-truncation:tcq_position_arith.c
implicit-signed-integer-truncation:tools.c
null:ivas_dirac_com.c
pointer-overflow:ivas_dirac_dec.c
pointer-overflow:ivas_dirac_output_synthesis_dec.c
pointer-overflow:ivas_dirac_rend.c
shift-base:basop32.c
shift-base:enh40.c
shift-base:enh40.h
shift-base:enh1632.c
shift-base:hq_lr_dec.c
signed-integer-overflow:basop32.c
...@@ -36,13 +36,13 @@ from .utils import * ...@@ -36,13 +36,13 @@ from .utils import *
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:]) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:])
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI)
def test_ambisonics(test_info, in_fmt, out_fmt): def test_ambisonics(test_info, in_fmt, out_fmt):
run_renderer(in_fmt, out_fmt) run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name)
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI)
def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt): def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt):
run_renderer(in_fmt, out_fmt) run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name)
@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST)
...@@ -52,6 +52,7 @@ def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): ...@@ -52,6 +52,7 @@ def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file):
run_renderer( run_renderer(
in_fmt, in_fmt,
out_fmt, out_fmt,
test_case_name=test_info.node.name,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
) )
...@@ -251,7 +252,7 @@ def test_ambisonics_binaural_headrotation_refveclev_vs_refvec( ...@@ -251,7 +252,7 @@ def test_ambisonics_binaural_headrotation_refveclev_vs_refvec(
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:]) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:])
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC)
def test_multichannel(test_info, in_fmt, out_fmt): def test_multichannel(test_info, in_fmt, out_fmt):
run_renderer(in_fmt, out_fmt) run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name)
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
...@@ -260,7 +261,7 @@ def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): ...@@ -260,7 +261,7 @@ def test_multichannel_binaural_static(test_info, in_fmt, out_fmt):
if in_fmt in ["MONO", "STEREO"]: if in_fmt in ["MONO", "STEREO"]:
pytest.skip("MONO or STEREO to Binaural rendering unsupported") pytest.skip("MONO or STEREO to Binaural rendering unsupported")
run_renderer(in_fmt, out_fmt) run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name)
@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST)
...@@ -274,12 +275,14 @@ def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file ...@@ -274,12 +275,14 @@ def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file
run_renderer( run_renderer(
in_fmt, in_fmt,
out_fmt, out_fmt,
test_case_name=test_info.node.name,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
) )
else: else:
run_renderer( run_renderer(
in_fmt, in_fmt,
out_fmt, out_fmt,
test_case_name=test_info.node.name,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
) )
...@@ -319,7 +322,7 @@ def test_multichannel_binaural_headrotation_refvec_rotating(test_info, in_fmt, o ...@@ -319,7 +322,7 @@ def test_multichannel_binaural_headrotation_refvec_rotating(test_info, in_fmt, o
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:]) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:])
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM)
def test_ism(test_info, in_fmt, out_fmt): def test_ism(test_info, in_fmt, out_fmt):
run_renderer(in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt]) run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt])
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
...@@ -331,9 +334,9 @@ def test_ism_binaural_static(test_info, in_fmt, out_fmt): ...@@ -331,9 +334,9 @@ def test_ism_binaural_static(test_info, in_fmt, out_fmt):
in_meta_files = None in_meta_files = None
if out_fmt == "BINAURAL": if out_fmt == "BINAURAL":
run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name, in_meta_files=in_meta_files)
else: else:
run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name, in_meta_files=in_meta_files)
@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST)
...@@ -349,6 +352,7 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): ...@@ -349,6 +352,7 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file):
run_renderer( run_renderer(
in_fmt, in_fmt,
out_fmt, out_fmt,
test_case_name=test_info.node.name,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
in_meta_files=in_meta_files, in_meta_files=in_meta_files,
) )
...@@ -356,6 +360,7 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): ...@@ -356,6 +360,7 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file):
run_renderer( run_renderer(
in_fmt, in_fmt,
out_fmt, out_fmt,
test_case_name=test_info.node.name,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
in_meta_files=in_meta_files, in_meta_files=in_meta_files,
) )
...@@ -400,7 +405,7 @@ def test_ism_binaural_headrotation_refvec_rotating(test_info, in_fmt, out_fmt): ...@@ -400,7 +405,7 @@ def test_ism_binaural_headrotation_refvec_rotating(test_info, in_fmt, out_fmt):
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA)
def test_masa(test_info, in_fmt, out_fmt): def test_masa(test_info, in_fmt, out_fmt):
run_renderer(in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt]) run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt])
""" Custom loudspeaker layouts """ """ Custom loudspeaker layouts """
...@@ -409,7 +414,7 @@ def test_masa(test_info, in_fmt, out_fmt): ...@@ -409,7 +414,7 @@ def test_masa(test_info, in_fmt, out_fmt):
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:]) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:])
@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) @pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST)
def test_custom_ls_input(test_info, in_layout, out_fmt): def test_custom_ls_input(test_info, in_layout, out_fmt):
run_renderer(CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt) run_renderer(CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt, test_case_name=test_info.node.name)
@pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) @pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST)
...@@ -418,6 +423,7 @@ def test_custom_ls_output(test_info, in_fmt, out_fmt): ...@@ -418,6 +423,7 @@ def test_custom_ls_output(test_info, in_fmt, out_fmt):
run_renderer( run_renderer(
in_fmt, in_fmt,
CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"),
test_case_name=test_info.node.name,
) )
...@@ -427,6 +433,7 @@ def test_custom_ls_input_output(test_info, in_fmt, out_fmt): ...@@ -427,6 +433,7 @@ def test_custom_ls_input_output(test_info, in_fmt, out_fmt):
run_renderer( run_renderer(
CUSTOM_LAYOUT_DIR.joinpath(f"{in_fmt}.txt"), CUSTOM_LAYOUT_DIR.joinpath(f"{in_fmt}.txt"),
CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"),
test_case_name=test_info.node.name,
) )
...@@ -436,6 +443,7 @@ def test_custom_ls_input_binaural(test_info, in_layout, out_fmt): ...@@ -436,6 +443,7 @@ def test_custom_ls_input_binaural(test_info, in_layout, out_fmt):
run_renderer( run_renderer(
CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"),
out_fmt, out_fmt,
test_case_name=test_info.node.name,
) )
...@@ -446,6 +454,7 @@ def test_custom_ls_input_binaural_headrotation(test_info, in_layout, out_fmt, tr ...@@ -446,6 +454,7 @@ def test_custom_ls_input_binaural_headrotation(test_info, in_layout, out_fmt, tr
run_renderer( run_renderer(
CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"),
out_fmt, out_fmt,
test_case_name=test_info.node.name,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
) )
...@@ -459,6 +468,7 @@ def test_metadata(test_info, in_fmt, out_fmt): ...@@ -459,6 +468,7 @@ def test_metadata(test_info, in_fmt, out_fmt):
run_renderer( run_renderer(
"META", "META",
out_fmt, out_fmt,
test_case_name=test_info.node.name,
metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"),
) )
...@@ -470,11 +480,11 @@ def test_metadata(test_info, in_fmt, out_fmt): ...@@ -470,11 +480,11 @@ def test_metadata(test_info, in_fmt, out_fmt):
@pytest.mark.parametrize("in_fmt", ["MONO"]) @pytest.mark.parametrize("in_fmt", ["MONO"])
@pytest.mark.parametrize("non_diegetic_pan", ["0", "-30", "45", "90", "-90"]) @pytest.mark.parametrize("non_diegetic_pan", ["0", "-30", "45", "90", "-90"])
def test_non_diegetic_pan_static(test_info, in_fmt, out_fmt, non_diegetic_pan): def test_non_diegetic_pan_static(test_info, in_fmt, out_fmt, non_diegetic_pan):
run_renderer(in_fmt, out_fmt, non_diegetic_pan=non_diegetic_pan) run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name, non_diegetic_pan=non_diegetic_pan)
@pytest.mark.parametrize("out_fmt", ["STEREO"]) @pytest.mark.parametrize("out_fmt", ["STEREO"])
@pytest.mark.parametrize("in_fmt", ["ISM1"]) @pytest.mark.parametrize("in_fmt", ["ISM1"])
@pytest.mark.parametrize("non_diegetic_pan", ["0", "-30", "45", "90", "-90"]) @pytest.mark.parametrize("non_diegetic_pan", ["0", "-30", "45", "90", "-90"])
def test_non_diegetic_pan_ism_static(test_info, in_fmt, out_fmt, non_diegetic_pan): def test_non_diegetic_pan_ism_static(test_info, in_fmt, out_fmt, non_diegetic_pan):
run_renderer(in_fmt, out_fmt, non_diegetic_pan=non_diegetic_pan) run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name, non_diegetic_pan=non_diegetic_pan)
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
import logging import logging
import subprocess as sp import subprocess as sp
import sys import sys
import os
from pathlib import Path from pathlib import Path
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
from typing import Optional, Tuple, Dict from typing import Optional, Tuple, Dict
...@@ -47,11 +48,10 @@ import pyaudio3dtools ...@@ -47,11 +48,10 @@ import pyaudio3dtools
def test_info(request): def test_info(request):
return request return request
def run_cmd(cmd, env=None):
def run_cmd(cmd):
logging.info(f"\nRunning command\n{' '.join(cmd)}\n") logging.info(f"\nRunning command\n{' '.join(cmd)}\n")
try: try:
sp.run(cmd, check=True, capture_output=True, text=True) sp.run(cmd, check=True, capture_output=True, text=True, env=env)
except sp.CalledProcessError as e: except sp.CalledProcessError as e:
raise SystemError( raise SystemError(
f"Command returned non-zero exit status ({e.returncode}): {' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}" f"Command returned non-zero exit status ({e.returncode}): {' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}"
...@@ -114,6 +114,7 @@ def run_renderer( ...@@ -114,6 +114,7 @@ def run_renderer(
output_path_base: str = OUTPUT_PATH_CUT, output_path_base: str = OUTPUT_PATH_CUT,
binary_suffix: str = "", binary_suffix: str = "",
is_comparetest: Optional[bool] = False, is_comparetest: Optional[bool] = False,
test_case_name: Optional[str] = None,
) -> Tuple[np.ndarray, int]: ) -> Tuple[np.ndarray, int]:
"""CuT creation with standalone renderer""" """CuT creation with standalone renderer"""
if trj_file is not None: if trj_file is not None:
...@@ -200,7 +201,12 @@ def run_renderer( ...@@ -200,7 +201,12 @@ def run_renderer(
if config_file is not None: if config_file is not None:
cmd.extend(["-rc", str(config_file)]) cmd.extend(["-rc", str(config_file)])
run_cmd(cmd) # Set env variables for UBSAN
env = os.environ.copy()
if test_case_name and "UBSAN_OPTIONS" in env.keys():
env["UBSAN_OPTIONS"] = env["UBSAN_OPTIONS"] + f",log_path=usan_log_{test_case_name}"
run_cmd(cmd, env)
return pyaudio3dtools.audiofile.readfile(out_file) return pyaudio3dtools.audiofile.readfile(out_file)
...@@ -208,20 +214,21 @@ def compare_renderer_vs_mergetarget(test_info, in_fmt, out_fmt, **kwargs): ...@@ -208,20 +214,21 @@ def compare_renderer_vs_mergetarget(test_info, in_fmt, out_fmt, **kwargs):
ref, ref_fs = run_renderer( ref, ref_fs = run_renderer(
in_fmt, in_fmt,
out_fmt, out_fmt,
test_case_name=test_info.node.name,
binary_suffix=BIN_SUFFIX_MERGETARGET, binary_suffix=BIN_SUFFIX_MERGETARGET,
output_path_base=OUTPUT_PATH_REF, output_path_base=OUTPUT_PATH_REF,
**kwargs, **kwargs,
) )
cut, cut_fs = run_renderer(in_fmt, out_fmt, **kwargs) cut, cut_fs = run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name, **kwargs)
check_BE(test_info, ref, ref_fs, cut, cut_fs) check_BE(test_info, ref, ref_fs, cut, cut_fs)
def compare_renderer_vs_pyscripts(test_info, in_fmt, out_fmt, **kwargs): def compare_renderer_vs_pyscripts(test_info, in_fmt, out_fmt, **kwargs):
ref, ref_fs = run_pyscripts(in_fmt, out_fmt, **kwargs) ref, ref_fs = run_pyscripts(in_fmt, out_fmt, **kwargs)
cut, cut_fs = run_renderer(in_fmt, out_fmt, **kwargs) cut, cut_fs = run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name, **kwargs)
check_BE(test_info, ref, ref_fs, cut, cut_fs) check_BE(test_info, ref, ref_fs, cut, cut_fs)
def compare_renderer_args(test_info, in_fmt, out_fmt, ref_kwargs: Dict, cut_kwargs: Dict): def compare_renderer_args(test_info, in_fmt, out_fmt, ref_kwargs: Dict, cut_kwargs: Dict):
ref, ref_fs = run_renderer(in_fmt, out_fmt, **ref_kwargs) ref, ref_fs = run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name, **ref_kwargs)
cut, cut_fs = run_renderer(in_fmt, out_fmt, **cut_kwargs) cut, cut_fs = run_renderer(in_fmt, out_fmt, test_case_name=test_info.node.name, **cut_kwargs)
check_BE(test_info, ref, ref_fs, cut, cut_fs) check_BE(test_info, ref, ref_fs, cut, cut_fs)
\ No newline at end of file