diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6e5c88431ce306aa3f4e8267a42f5f42330b2e52..625a3cc8bcd812e91926c2e909a1188ae8016e3e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,7 @@ variables: - 'ivas-conformance' - 'ivas-conformance-linux' - 'check-float-reference' + - 'test-branch-vs-input-passthrough' GIT_CLEAN_FLAGS: -ffdxq TESTCASE_TIMEOUT_STV_SANITIZERS: 180 TESTCASE_TIMEOUT_LTV_SANITIZERS: 1200 @@ -69,7 +70,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 == 'test-branch-vs-input-passthrough' + variables: + IVAS_PIPELINE_NAME: 'Pass-through comparison vs input: $CI_COMMIT_BRANCH' stages: - .pre @@ -265,6 +268,8 @@ stages: when: never - if: $MANUAL_PIPELINE_TYPE == 'check-float-reference' when: never + - if: $MANUAL_PIPELINE_TYPE == 'test-branch-vs-input-passthrough' + when: never - when: on_success .rules-merge-request: @@ -1639,6 +1644,40 @@ test-long-self-test: junit: - report-junit-ltv.xml +test-branch-vs-input-passthrough: + tags: + - ivas-linux + stage: compare + timeout: "30 minutes" # TBD + rules: + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'test-branch-vs-input-passthrough' + allow_failure: + exit_codes: + - 123 + script: + - *print-common-info + - make -j + + - exit_code=0 + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --html=report.html --self-contained-html --junit-xml=report-junit.xml --compare_to_input --mld --ssnr --odg || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + - python3 scripts/parse_xml_report.py report-junit.xml report.csv + - if [ $zero_errors != 1 ]; then echo "Run errors encountered!"; exit $EXIT_CODE_FAIL; fi + - if [ $exit_code -eq 1 ]; then echo "Differences encountered."; exit $EXIT_CODE_NON_BE; fi + - exit 0 + + artifacts: + name: "test-branch-vs-input-passthrough--sha-$CI_COMMIT_SHORT_SHA--results" + when: always + expire_in: 4 mos + paths: + - report-junit.xml + - report.html + - report.csv + expose_as: "test-branch-vs-input-passthrough results" + reports: + junit: + - report-junit.xml # --------------------------------------------------------------- # Scheduled jobs on main diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index b7c9cc3bdb54a4ed12f99cf0334067da83e0728a..5534c8a0191afe5419f543c6ef6f08703e531fc8 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -472,7 +472,12 @@ common_ivas_c - + + common_ivas_c + + + common_ivas_c + @@ -552,4 +557,4 @@ {b95b7bed-a666-4a00-9332-2b528638503e} - + \ No newline at end of file diff --git a/Workspace_msvc/lib_isar.vcxproj.filters b/Workspace_msvc/lib_isar.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..b2dc7ffc7029d125a21bb1988b115770e45b00c1 --- /dev/null +++ b/Workspace_msvc/lib_isar.vcxproj.filters @@ -0,0 +1,109 @@ + + + + + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + isar_c + + + + + + + isar_h + + + isar_h + + + isar_h + + + isar_h + + + isar_h + + + isar_h + + + isar_h + + + isar_h + + + isar_h + + + isar_h + + + + + {afca9c26-7922-4c24-aa3a-cbf00aa2b6d1} + + + {1ce7afb2-7474-42f5-b477-2d854c093429} + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj.filters b/Workspace_msvc/lib_util.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..3c865e1dc1851eada99e055b2bd83781e21ecac0 --- /dev/null +++ b/Workspace_msvc/lib_util.vcxproj.filters @@ -0,0 +1,177 @@ + + + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + util_c + + + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + util_h + + + + + {214bf366-8f03-4160-9ebe-daa6844c3754} + + + {65ae801b-f259-4632-b413-22996b07a7bf} + + + \ No newline at end of file diff --git a/apps/decoder.c b/apps/decoder.c index fc003928e92dcd7154c8bbba7f3e93d177058bca..681939cde2dedc8cf76c3c687b73e017e61ac654 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -590,8 +590,16 @@ int main( fprintf( stdout, "FEC: %.2f %%\n", arg.FER ); } } +#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 /*-------------------------------------------------------------------* @@ -679,7 +687,9 @@ int main( fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", aeID ); goto cleanup; } +#ifndef FIX_587_DEFAULT_REVERB renderConfig.roomAcoustics.override = true; +#endif } /* ISAR frame size is set from command line, not renderer config file. diff --git a/apps/renderer.c b/apps/renderer.c index 52d6e81d099feb163957605d62f60a40c1b728df..5ca8e170fee5554f950ba63aab073fd94fef8d02 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1044,7 +1044,9 @@ int main( fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", aeID ); exit( -1 ); } +#ifndef FIX_587_DEFAULT_REVERB renderConfig.roomAcoustics.override = 1; +#endif } /* ISAR frame size is set from command line, not renderer config file. diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 47fbbb9db21b89d728e4224aeb3de71ab332dd42..babb9f3e0e68062ab27a37ea298370d6ad31ea89 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1428,7 +1428,6 @@ uint16_t get_indice_1( return st->bit_stream[pos]; } -#define WMC_TOOL_SKIP /*-------------------------------------------------------------------* * reset_indices_enc() @@ -1468,6 +1467,7 @@ void reset_indices_dec( return; } + /*-------------------------------------------------------------------* * write_indices_to_stream() * @@ -1838,6 +1838,7 @@ void convertBytestreamToSerial( } } + /*-------------------------------------------------------------------* * decoder_selectCodec() * @@ -2515,8 +2516,8 @@ void ivas_set_bitstream_pointers( return; } - #ifdef DEBUGGING + /*-------------------------------------------------------------------* * preview_indices() * @@ -2786,14 +2787,15 @@ ivas_error preview_indices( return error; } -#endif +#endif /*-------------------------------------------------------------------* * read_indices() * - * Read indices from an ITU-T G.192 bitstream to the buffer - * Simulate packet losses by inserting frame erasures + * Detect SID, NO_DATA, BFI, etc. and set bitstream pointers + * Set ivas_total_brate + * Note: each bit is represented in bitsream buffer as a uint16_t of value 0 or 1 *-------------------------------------------------------------------*/ /*! r: 1 = reading OK, 0 = problem */ @@ -2838,8 +2840,8 @@ ivas_error read_indices( /* convert the frame length to total bitrate */ total_brate = (int32_t) ( num_bits * FRAMES_PER_SEC ); - /* verify that a valid num bits value is present in the G.192 file */ - /* only AMRWB, EVS or IVAS bitrates or 0(NO DATA) are allowed in G.192 file frame reading */ + /* verify that a valid num bits value is present */ + /* only AMRWB, EVS or IVAS bitrates or 0(NO DATA) are allowed */ if ( st_ivas->ivas_format != MONO_FORMAT ) { k = 0; @@ -2858,7 +2860,7 @@ ivas_error read_indices( } else if ( k == SIZE_IVAS_BRATE_TBL ) { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) detected! Exiting ! \n", total_brate ); } else { @@ -2871,12 +2873,12 @@ ivas_error read_indices( if ( rate2EVSmode( total_brate, NULL ) < 0 ) /* negative value means that a valid rate was not found */ { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) detected! Exiting ! \n", total_brate ); } } - /* G.192 RX DTX handler*/ - /* handle SID_FIRST, SID_BAD, SPEECH_LOST, NO_DATA as properly as possible for the ITU-T G.192 format */ + /* RX DTX handler*/ + /* handle SID_FIRST, SID_BAD, SPEECH_LOST, NO_DATA */ /* (total_brate, bfi , st_CNG) = rx_handler(received frame type, [previous frame type], past CNG state, past core) */ curr_ft_good_sp = 0; curr_ft_bad_sp = 0; @@ -3036,7 +3038,6 @@ ivas_error read_indices( /* GOOD frame */ if ( st_ivas->bfi == 0 || st_ivas->bfi == FRAMEMODE_FUTURE ) { - /* GOOD frame - convert ITU-T G.192 words to short values */ st_ivas->hDecoderConfig->ivas_total_brate = total_brate; } @@ -3050,6 +3051,7 @@ ivas_error read_indices( return error; } + /*-------------------------------------------------------------------* * get_rfFrameType() * @@ -3467,5 +3469,3 @@ void dtx_read_padding_bits( return; } - -#undef WMC_TOOL_SKIP diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 8cbdfcb3cd362f76c6514b67a6c10d9653ca76b9..7890d25379f124b02d8a73255429605fca2bd17a 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -312,7 +312,9 @@ typedef enum typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { +#ifndef FIX_587_DEFAULT_REVERB int16_t override; +#endif int16_t nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ float pFc_input[IVAS_CLDFB_NO_CHANNELS_MAX]; /* Center frequencies for which following values are provided: */ float pAcoustic_rt60[IVAS_CLDFB_NO_CHANNELS_MAX]; /* - The room's T60 per center frequency */ diff --git a/lib_com/options.h b/lib_com/options.h index ff1bc4ed7ac2e0512e86d17fefc9f74901b44859..926960226d1e20bb1c86d359f936e3174c39a9e6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -170,6 +170,8 @@ #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 */ /* #################### End BE switches ################################## */ @@ -180,6 +182,7 @@ #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 */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 6de77455cc37ccd976c8d1d18605ba590ddd2f55..7bab860ae7d847696013a3f89593a416840ad3fc 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1075,6 +1075,9 @@ ivas_error ivas_binRenderer_open( BINAURAL_RENDERER_HANDLE hBinRenderer; int16_t convBand, k; ivas_error error; +#ifdef FIX_587_DEFAULT_REVERB + const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pRoomAcoustics; +#endif error = IVAS_ERR_OK; @@ -1214,7 +1217,12 @@ ivas_error ivas_binRenderer_open( /* Allocate memories needed for reverb module */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) { +#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 ) +#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 ) +#endif { return error; } diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index a3d3c7492a650c8a1bd9f0e5362e8b94480f2708..fdfb1ab55ba3962143c0f7bf0dd229344837ed9e 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -444,7 +444,9 @@ ivas_error IVAS_DEC_Configure( 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; @@ -547,7 +549,11 @@ ivas_error IVAS_DEC_Configure( } #endif +#ifdef FIX_VOIP_FUNCTIONS + return IVAS_ERR_OK; +#else return error; +#endif } @@ -743,9 +749,9 @@ 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 ) { @@ -813,7 +819,11 @@ ivas_error IVAS_DEC_EnableVoIP( } #endif +#ifdef FIX_VOIP_FUNCTIONS + return IVAS_ERR_OK; +#else return error; +#endif } @@ -1669,6 +1679,13 @@ 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; @@ -2112,6 +2129,13 @@ 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 ); @@ -2205,6 +2229,13 @@ 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; @@ -2710,7 +2741,9 @@ static ivas_error copyRendererConfigStruct( break; } #endif +#ifndef FIX_587_DEFAULT_REVERB hRCout->roomAcoustics.override = hRCin->roomAcoustics.override; +#endif hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; hRCout->roomAcoustics.inputPreDelay = hRCin->roomAcoustics.inputPreDelay; @@ -2798,7 +2831,9 @@ ivas_error IVAS_DEC_FeedRenderConfig( hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_CREND; } #endif +#ifndef FIX_587_DEFAULT_REVERB hRenderConfig->roomAcoustics.override = renderConfig.roomAcoustics.override; +#endif hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.roomAcoustics.acousticPreDelay; hRenderConfig->roomAcoustics.inputPreDelay = renderConfig.roomAcoustics.inputPreDelay; @@ -3002,7 +3037,10 @@ static bool isSidFrame( return false; } -static void bsCompactToSerial( const uint8_t *compact, uint16_t *serial, uint16_t num_bits ) +static void bsCompactToSerial( + const uint8_t *compact, + uint16_t *serial, + const uint16_t num_bits ) { /* Bitstream conversion is not counted towards complexity and memory usage */ #define WMC_TOOL_SKIP @@ -3051,6 +3089,13 @@ 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 */ @@ -3129,11 +3174,22 @@ 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; } @@ -3143,7 +3199,11 @@ ivas_error IVAS_DEC_VoIP_SetScale( hIvasDec->tsm_max_scaling = maxScaling; } +#ifdef FIX_VOIP_FUNCTIONS + return IVAS_ERR_OK; +#else return error; +#endif } @@ -3167,6 +3227,13 @@ 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; @@ -3217,6 +3284,13 @@ 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; @@ -3454,13 +3528,18 @@ static void update_voip_rendered20ms( const int16_t nSamplesRendered ) { int16_t nSamplesRenderedTotal; + nSamplesRenderedTotal = hIvasDec->hVoIP->nSamplesRendered20ms + nSamplesRendered; + /* we have crossed a 20ms border, reset the time scaling done flag */ if ( nSamplesRenderedTotal >= hIvasDec->hVoIP->nSamplesFrame ) { hIvasDec->timeScalingDone = 0; } + hIvasDec->hVoIP->nSamplesRendered20ms = nSamplesRenderedTotal % hIvasDec->hVoIP->nSamplesFrame; + + return; } @@ -3482,6 +3561,13 @@ 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; @@ -3510,6 +3596,13 @@ 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 ) ); } @@ -3616,7 +3709,11 @@ 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; } @@ -3928,14 +4025,29 @@ 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 dafae6518ed95256ce27d9c077a1dc2996b11647..50476c964bda0a25f0e19907be177b64ad6a0533 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -513,7 +513,11 @@ 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_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 1d63b23d09e6e03dffc49e53410ab204e6bd04a3..4e23dc51e98ead33f08b8f6d0e8553c5e7bc04e2 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -143,6 +143,9 @@ ivas_error ivas_dirac_dec_init_binaural_data( ivas_error error; float frequency_axis[CLDFB_NO_CHANNELS_MAX]; int16_t num_poses, pos_idx; +#ifdef FIX_587_DEFAULT_REVERB + const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pRoomAcoustics; +#endif num_poses = 1; if ( st_ivas->hSplitBinRend != NULL ) @@ -220,10 +223,16 @@ ivas_error ivas_dirac_dec_init_binaural_data( if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { mvr2r( ( *phHrtfParambin )->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); +#ifdef FIX_587_DEFAULT_REVERB + pRoomAcoustics = NULL; +#endif } else { set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX ); +#ifdef FIX_587_DEFAULT_REVERB + pRoomAcoustics = &( st_ivas->hRenderConfig->roomAcoustics ); +#endif } /* reconfiguration needed when Reverb. parameters are changed -> close and open the handle again */ @@ -235,7 +244,11 @@ 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 ) +#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 ) +#endif { return error; } diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index f0c24ef8482a4a1f41bd7d66e9135ea504e24e85..cd734f659d00fa3548407ec5942a7747090646b6 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -260,9 +260,14 @@ void TDREND_firfilt( /* Handle memory */ p_signal = buffer + filterlength - 1; - mvr2r( mem, buffer, filterlength - 1 ); /* Insert memory */ + mvr2r( mem, buffer, filterlength - 1 ); /* Insert memory */ +#ifdef NONBE_FIX_1176_OSBA_REVERB_JBM_ASAN_ERROR + mvr2r( signal, p_signal, subframe_length ); /* Insert current frame */ + mvr2r( p_signal + subframe_length - filterlength + 1, mem, filterlength - 1 ); /* Update memory for next frame */ +#else mvr2r( signal, buffer + filterlength - 1, subframe_length ); /* Insert current frame */ mvr2r( signal + subframe_length - filterlength + 1, mem, filterlength - 1 ); /* Update memory for next frame */ +#endif /* Convolution */ for ( i = 0; i < subframe_length; i++ ) diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index 124b5e5767d73d5afbbcf68040e2877e250b3fe7..eabaf2d4cbae004d5418ffe9e1e532437a4df283 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -113,7 +113,9 @@ ivas_error ivas_render_config_init_from_rom( #ifdef DEBUGGING ( *hRenderConfig )->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; #endif +#ifndef FIX_587_DEFAULT_REVERB ( *hRenderConfig )->roomAcoustics.override = FALSE; +#endif ( *hRenderConfig )->roomAcoustics.nBands = IVAS_REVERB_DEFAULT_N_BANDS; ( *hRenderConfig )->roomAcoustics.acousticPreDelay = IVAS_REVERB_DEFAULT_PRE_DELAY; ( *hRenderConfig )->roomAcoustics.inputPreDelay = IVAS_REVERB_DEFAULT_INPUT_DELAY; diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 7ea38fe2a701806c1264c5e15a01b0c015280046..eb3c05a0ccb8c2313a807f50b6f86874bc1ac963 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -1116,7 +1116,9 @@ ivas_error ivas_reverb_open( #ifdef DEBUGGING pState->pConfig.renderer_type_override = hRenderConfig->renderer_type_override; #endif +#ifndef FIX_587_DEFAULT_REVERB pState->pConfig.roomAcoustics.override = hRenderConfig->roomAcoustics.override; +#endif pState->pConfig.roomAcoustics.nBands = hRenderConfig->roomAcoustics.nBands; if ( hRenderConfig->roomAcoustics.use_er == 1 ) @@ -1873,7 +1875,11 @@ ivas_error ivas_binaural_reverb_init( error = IVAS_ERR_OK; +#ifdef FIX_587_DEFAULT_REVERB + if ( roomAcoustics != NULL ) +#else if ( ( roomAcoustics != NULL ) && roomAcoustics->override ) +#endif { revTimes = t60; revEne = ene; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index e3538025eca02a194e18b07ae216d5e7a91da5c9..264b68bf1278ec5498756121e0f2b58c3d13a59b 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4191,7 +4191,9 @@ ivas_error IVAS_REND_GetRenderConfig( break; } #endif +#ifndef FIX_587_DEFAULT_REVERB hRCout->roomAcoustics.override = hRCin->roomAcoustics.override; +#endif hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; hRCout->roomAcoustics.inputPreDelay = hRCin->roomAcoustics.inputPreDelay; @@ -4248,8 +4250,9 @@ ivas_error IVAS_REND_FeedRenderConfig( #ifdef DEBUGGING hRenderConfig->renderer_type_override = renderConfig.renderer_type_override; #endif - +#ifndef FIX_587_DEFAULT_REVERB hRenderConfig->roomAcoustics.override = renderConfig.roomAcoustics.override; +#endif hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.roomAcoustics.acousticPreDelay; hRenderConfig->roomAcoustics.inputPreDelay = renderConfig.roomAcoustics.inputPreDelay; @@ -8309,6 +8312,9 @@ static ivas_error ivas_masa_ext_rend_parambin_init( ivas_error error; float frequency_axis[CLDFB_NO_CHANNELS_MAX]; int16_t pos_idx; +#ifdef FIX_587_DEFAULT_REVERB + const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pRoomAcoustics; +#endif error = IVAS_ERR_OK; @@ -8387,15 +8393,25 @@ static ivas_error ivas_masa_ext_rend_parambin_init( if ( *inputMasa->base.ctx.pOutConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { mvr2r( ( *phHrtfParambin )->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); +#ifdef FIX_587_DEFAULT_REVERB + pRoomAcoustics = NULL; +#endif } else { set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX ); +#ifdef FIX_587_DEFAULT_REVERB + pRoomAcoustics = &( hRendCfg->roomAcoustics ); +#endif } 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 ) +#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 ) +#endif { return error; } diff --git a/scripts/cut_bs.py b/scripts/cut_bs.py index 37f19733df609436176b22f16c6eb348370430ec..e54e99fdfecbbd694a23791b61f9652b78024f50 100755 --- a/scripts/cut_bs.py +++ b/scripts/cut_bs.py @@ -39,75 +39,63 @@ SID_BITS = {35, 48, 104} SYNC_WORDS = {b"!k", b" k"} -def cut_to_length(fp, fp_out, length): - assert length > 0 - +def get_next_frame(fp): + eof = False + n_bits = 0 + data = None + sync_word = fp.read(2) + if sync_word == b"": + eof = True + return (sync_word, n_bits, data, eof) + if sync_word not in SYNC_WORDS: + raise ValueError("Bad Sync word!") + n_bits = struct.unpack("h", fp.read(2))[0] + data = fp.read(n_bits * 2) + return (sync_word, n_bits, data, eof) + + +def write_frame(fp_out, sync_word, n_bits, data): + fp_out.write(sync_word) + fp_out.write(struct.pack("h", n_bits)) + fp_out.write(data) + + +def cut_from_start(fp, fp_out, start_frame=0, length=-1, start_with_sid=False): fr_cnt = 0 - - for f in range(length): - sync_word = fp.read(2) - if sync_word == b"": - return fr_cnt - if sync_word not in SYNC_WORDS: - raise ValueError("Bad Sync word!") - n_bits_bs = fp.read(2) - n_bits = struct.unpack("h", n_bits_bs)[0] - fp_out.write(sync_word) - fp_out.write(n_bits_bs) - fp_out.write(fp.read(n_bits * 2)) - fr_cnt += 1 - - return fr_cnt - - -def cut_from_start(fp, fp_out, start_frame=0, start_with_sid=False): + extracted_frames_cnt = 0 + eof = False # cut until start frame - fr_cnt = 0 - cut_cnt = 0 - for cur_frame in range(start_frame): - sync_word = fp.read(2) - if sync_word == b"": - return (fr_cnt, cut_cnt) - if sync_word not in SYNC_WORDS: - raise ValueError("Bad Sync word!") - n_bits = struct.unpack("h", fp.read(2))[0] - fp.read(n_bits * 2) - fr_cnt += 1 - cut_cnt += 1 + while fr_cnt < start_frame and not eof: + (sync_word, n_bits, data, eof) = get_next_frame(fp) + if not eof: + fr_cnt += 1 + # cut until SID frame if start_with_sid: found = False - while not found: - sync_word = fp.read(2) - if sync_word == b"": - return (fr_cnt, cut_cnt) - if sync_word not in SYNC_WORDS: - raise ValueError("Bad Sync word!") - n_bits_bs = fp.read(2) - n_bits = struct.unpack("h", n_bits_bs)[0] - if n_bits in SID_BITS: - found = True - fp_out.write(sync_word) - fp_out.write(n_bits_bs) - fp_out.write(fp.read(n_bits * 2)) - else: - fp.read(n_bits * 2) - cut_cnt += 1 + while not found and not eof: + (sync_word, n_bits, data, eof) = get_next_frame(fp) + if not eof: + if n_bits in SID_BITS: + found = True + fp.seek(-(4 + n_bits * 2), 1) # Found SID, rewind + else: + fr_cnt += 1 + # transfer frames + while length != 0 and not eof: + (sync_word, n_bits, data, eof) = get_next_frame(fp) + if not eof: + write_frame(fp_out, sync_word, n_bits, data) + fr_cnt += 1 + extracted_frames_cnt += 1 + length -= 1 + + # count remaining frames, if any + while not eof: + (sync_word, n_bits, data, eof) = get_next_frame(fp) + if not eof: fr_cnt += 1 - # transfer remaining frames - while True: - sync_word = fp.read(2) - if sync_word == b"": - break - if sync_word not in SYNC_WORDS: - raise ValueError("Bad Sync word!") - n_bits_bs = fp.read(2) - n_bits = struct.unpack("h", n_bits_bs)[0] - fp_out.write(sync_word) - fp_out.write(n_bits_bs) - fp_out.write(fp.read(n_bits * 2)) - fr_cnt += 1 - return (fr_cnt, cut_cnt) + return (fr_cnt, extracted_frames_cnt) if __name__ == "__main__": @@ -138,24 +126,25 @@ if __name__ == "__main__": if not os.path.exists(os.path.realpath(my_args.bs_in)): print(f"\nInput file {my_args.bs_in} does not exist!") sys.exit(-1) - if not os.path.exists(os.path.realpath(my_args.bs_out)): - print(f"\nOutput file {my_args.bs_out} does not exist, creating it!") - else: - print(f"\nOutput file {my_args.bs_out} does exist, overwriting it!") + if os.path.exists(os.path.realpath(my_args.bs_out)): + print(f"\nOutput file {my_args.bs_out} exists, overwriting it!") with open(my_args.bs_in, "rb") as fp_in: with open(my_args.bs_out, "wb") as fp_out: - if my_args.sid or my_args.frame: - fr_cnt, cut_cnt = cut_from_start( - fp_in, fp_out, start_frame=my_args.frame, start_with_sid=my_args.sid + fr_cnt, extracted_frames_cnt = cut_from_start( + fp_in, + fp_out, + start_frame=my_args.frame, + length=my_args.length, + start_with_sid=my_args.sid, + ) + if extracted_frames_cnt == 0: + print(f"\nExtracted 0 frames!") + sys.exit(-1) + if my_args.length != -1 and extracted_frames_cnt != my_args.length: + print( + f"Warning! Requested {my_args.length}, only {extracted_frames_cnt} obtained!" ) - if my_args.sid and (fr_cnt == cut_cnt): - print("Warning! No SID frame found in bitstream!") - print(f"Cut {cut_cnt} of {fr_cnt} frames from {my_args.bs_in}") - elif my_args.length: - fr_cnt = cut_to_length(fp_in, fp_out, my_args.length) - if fr_cnt != my_args.length: - print( - f"Warning! Could not cut to length {my_args.length} as bitstream only contained {fr_cnt} frames!" - ) - print(f"Cut {my_args.bs_in} to {fr_cnt} frames") + print( + f"Extracted {extracted_frames_cnt} out of {fr_cnt} frames from {my_args.bs_in}" + ) diff --git a/scripts/parse_xml_report.py b/scripts/parse_xml_report.py index 3be7a9ca0b62e62d2469a07c9142a8fdd3879a84..e0f02238e4fddd970567023b2637975e4ead4213 100644 --- a/scripts/parse_xml_report.py +++ b/scripts/parse_xml_report.py @@ -31,6 +31,7 @@ EVS_FORMATS = { "EVS_JBM_dec": r"Readme_JBM_dec", } +NO_FORMATS = {"Default": r".*"} IVAS_CATEGORIES = { "Normal operation": r".*", @@ -48,6 +49,8 @@ EVS_CATEGORIES = { "JBM": r"JBM", } +NO_CATEGORIES = {"N/A": r".*"} + # Main routine if __name__ == "__main__": parser = argparse.ArgumentParser( @@ -64,15 +67,23 @@ if __name__ == "__main__": action="store_true", help="Parse using EVS 26.444 formats", ) + 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 + FORMATS = IVAS_FORMATS + CATEGORIES = IVAS_CATEGORIES if args.evs: FORMATS = EVS_FORMATS CATEGORIES = EVS_CATEGORIES - else: - FORMATS = IVAS_FORMATS - CATEGORIES = IVAS_CATEGORIES + if args.skip_formats: + FORMATS = NO_FORMATS + CATEGORIES = NO_CATEGORIES + tree = ElementTree.parse(xml_report) testsuite = tree.find(".//testsuite") diff --git a/scripts/pyaudio3dtools/audioarray.py b/scripts/pyaudio3dtools/audioarray.py index 06c3d42171390c1a7fe39618fe7a230389b53ddf..5741c1ada40fd956bf9a8022261e05719d2b3ae7 100644 --- a/scripts/pyaudio3dtools/audioarray.py +++ b/scripts/pyaudio3dtools/audioarray.py @@ -239,6 +239,8 @@ def compare( ssnr_thresh_high: float = np.inf, apply_thresholds_to_ref_only: bool = False, test_start_offset_ms: int = 0, + ref_jbm_tf: Optional[Path] = None, + test_jbm_tf: Optional[Path] = None, ) -> dict: """Compare two audio arrays @@ -284,7 +286,11 @@ def compare( test = test[test_start_offset_samples:, :] framesize = fs // 50 - diff = abs(test - ref) + if ref.shape[0] != test.shape[0]: + min_len = min(ref.shape[0], test.shape[0]) + diff = abs(test[:min_len, :] - ref[:min_len, :]) + else: + diff = abs(test - ref) max_diff = int(diff.max()) result = { "bitexact": True, @@ -355,37 +361,75 @@ def compare( result["nframes_diff_percentage"] = nframes_diff_percentage if get_mld: + + def parse_wav_diff(proc: subprocess.CompletedProcess) -> float: + line = proc.stdout.splitlines()[-1].strip() + start = line.find(">") + 1 + stop = line.rfind("<") + mld = float(line[start:stop].strip()) + + return mld + + # TODO probably needs a fix to show up in pytest + if proc.returncode: + print(f"{proc.stderr}\n{proc.stdout}") + return mld_max + mld_max = 0 toolsdir = Path(__file__).parent.parent.joinpath("tools") - + curr_platform = platform.system() if curr_platform not in {"Windows", "Linux", "Darwin"}: - raise NotImplementedError(f"MLD tool not available for {curr_platform}") + raise NotImplementedError( + f"wav-diff tool not available for {curr_platform}" + ) search_path = toolsdir.joinpath(curr_platform.replace("Windows", "Win32")) - mld = search_path.joinpath("mld") + wdiff = search_path.joinpath("wav-diff") - if not mld.exists(): - mld = shutil.which("mld") - if mld is None: - raise FileNotFoundError(f"MLD tool not found in {search_path} or PATH!") - warnings.warn(f"MLD binary not found in {search_path}! Falling back to {mld}!") + if not wdiff.exists(): + wdiff = shutil.which("wav-diff") + if wdiff is None: + raise FileNotFoundError( + f"wav-diff tool not found in {search_path} or PATH!" + ) with tempfile.TemporaryDirectory() as tmpdir: - for i in range(nchannels): - tmpfile_ref = Path(tmpdir).joinpath(f"ref_ch{i+1}.wav") - tmpfile_test = Path(tmpdir).joinpath(f"test_ch{i+1}.wav") - r48 = np.clip( - resample(ref[:, i].astype(float), fs, 48000), -32768, 32767 - ).astype( - np.int16 - ) # Convert to float for resample, then to int16 for wavfile.write - t48 = np.clip( - resample(test[:, i].astype(float), fs, 48000), -32768, 32767 - ).astype(np.int16) - wavfile.write(str(tmpfile_ref), 48000, r48) - wavfile.write(str(tmpfile_test), 48000, t48) - out = subprocess.check_output([mld, tmpfile_ref, tmpfile_test]) - mld_max = max(mld_max, float(out.split()[3])) + tmpfile_ref = Path(tmpdir).joinpath("ref.wav") + tmpfile_test = Path(tmpdir).joinpath("test.wav") + + + ### need to resample to 48kHz for MLD computation to be correct + if fs != 48000: + ref_tmp = np.clip( + resample(ref.astype(float), fs, 48000), -32768, 32767 + ) + test_tmp = np.clip( + resample(test.astype(float), fs, 48000), -32768, 32767 + ) + else: + ref_tmp = ref.copy() + test_tmp = test.copy() + + wavfile.write(str(tmpfile_ref), 48000, ref_tmp.astype(np.int16)) + wavfile.write(str(tmpfile_test), 48000, test_tmp.astype(np.int16)) + + cmd = [ + str(wdiff), + "--print-ctest-measurement", + str(tmpfile_ref), + str(tmpfile_test), + ] + if ref_jbm_tf and test_jbm_tf: + cmd.extend( + [ + "--ref-jbm-trace", + str(ref_jbm_tf), + "--cut-jbm-trace", + str(test_jbm_tf), + ] + ) + proc = subprocess.run(cmd, capture_output=True, text=True) + mld_max = parse_wav_diff(proc) result["MLD"] = mld_max diff --git a/scripts/self_test.py b/scripts/self_test.py index 714366bcf1cd6a426c74428a951e4c45743bafeb..7688fc50f9427655b17ddb67f35cf652a8c42474 100755 --- a/scripts/self_test.py +++ b/scripts/self_test.py @@ -48,9 +48,9 @@ import pyivastest.constants as constants import pyivastest.ivas_svn as svn from pyivastest import IvasScriptsCommon from pyivastest.IvasModeAnalyzer import * -from pyivastest.IvasModeCollector import * from pyivastest.IvasModeRunner import * from pyivastest.IvasSvnBuilder import * +from pyivastest.IvasModeCollector import IvasModeCollector BW_TO_SR = {"nb": 8, "wb": 16, "swb": 32, "fb": 48} SR_TO_BW = {"8": "nb", "16": "wb", "32": "swb", "48": "fb"} @@ -1276,11 +1276,27 @@ class SelfTest(IvasScriptsCommon.IvasScript): self.logger.console( "Create mode: ignoring all other optional commandline arguments regarding reference and test conditions" ) - self.args["encref"] = default_enc_test - self.args["decref"] = default_dec_test - self.args["srcdirref"] = constants.WC_BASE_DIR + + if self.args["encref"] is None: + if self.args["enctest"] is not None: + # use Test encoder binary for reference generation + self.args["encref"] = os.path.realpath(self.args["enctest"]) + else: + self.args["encref"] = default_enc_test + + if self.args["decref"] is None: + if self.args["dectest"] is not None: + # use Test decoder binary for reference generation + self.args["decref"] = os.path.realpath(self.args["dectest"]) + else: + self.args["decref"] = default_dec_test + + if self.args["srcdirref"] is None: + self.args["srcdirref"] = constants.WC_BASE_DIR + if self.valgrind is not None and self.args["valgrind"] is True: valgrind_ref = self.valgrind + create_mode = True run_ref = True else: diff --git a/scripts/tools/Darwin/LICENSE_wav-diff.txt b/scripts/tools/Darwin/LICENSE_wav-diff.txt new file mode 100644 index 0000000000000000000000000000000000000000..8a8ff77f25e4117b972b6c644b3595584b99e9e0 --- /dev/null +++ b/scripts/tools/Darwin/LICENSE_wav-diff.txt @@ -0,0 +1,31 @@ +/****************************************************************************************************** + + (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. + +*******************************************************************************************************/ \ No newline at end of file diff --git a/scripts/tools/Darwin/thirdPartyLegalnotices/licenses_wav-diff.html b/scripts/tools/Darwin/thirdPartyLegalnotices/licenses_wav-diff.html new file mode 100644 index 0000000000000000000000000000000000000000..1bdee68950575ca1db5c3b71da74ad7986efc1a7 --- /dev/null +++ b/scripts/tools/Darwin/thirdPartyLegalnotices/licenses_wav-diff.html @@ -0,0 +1,1817 @@ + + + + + + + +
+
+

Third Party Licenses

+

This page lists the licenses of the projects used in wav-diff.

+
+ +

Overview of licenses:

+ + +

All license text:

+ +
+ + + diff --git a/scripts/tools/Darwin/wav-diff b/scripts/tools/Darwin/wav-diff new file mode 100755 index 0000000000000000000000000000000000000000..88823c01f9b11a117cee9a8447b8a981bb4ad5a5 Binary files /dev/null and b/scripts/tools/Darwin/wav-diff differ diff --git a/scripts/tools/Linux/LICENSE_wav-diff.txt b/scripts/tools/Linux/LICENSE_wav-diff.txt new file mode 100644 index 0000000000000000000000000000000000000000..8a8ff77f25e4117b972b6c644b3595584b99e9e0 --- /dev/null +++ b/scripts/tools/Linux/LICENSE_wav-diff.txt @@ -0,0 +1,31 @@ +/****************************************************************************************************** + + (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. + +*******************************************************************************************************/ \ No newline at end of file diff --git a/scripts/tools/Linux/thirdPartyLegalnotices/licenses_wav-diff.html b/scripts/tools/Linux/thirdPartyLegalnotices/licenses_wav-diff.html new file mode 100644 index 0000000000000000000000000000000000000000..1bdee68950575ca1db5c3b71da74ad7986efc1a7 --- /dev/null +++ b/scripts/tools/Linux/thirdPartyLegalnotices/licenses_wav-diff.html @@ -0,0 +1,1817 @@ + + + + + + + +
+
+

Third Party Licenses

+

This page lists the licenses of the projects used in wav-diff.

+
+ +

Overview of licenses:

+ + +

All license text:

+ +
+ + + diff --git a/scripts/tools/Linux/wav-diff b/scripts/tools/Linux/wav-diff new file mode 100755 index 0000000000000000000000000000000000000000..47f77e82b56e51b84bc52ab7fb01d605d6265ab6 Binary files /dev/null and b/scripts/tools/Linux/wav-diff differ diff --git a/scripts/tools/Win32/LICENSE_wav-diff.txt b/scripts/tools/Win32/LICENSE_wav-diff.txt new file mode 100644 index 0000000000000000000000000000000000000000..8a8ff77f25e4117b972b6c644b3595584b99e9e0 --- /dev/null +++ b/scripts/tools/Win32/LICENSE_wav-diff.txt @@ -0,0 +1,31 @@ +/****************************************************************************************************** + + (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. + +*******************************************************************************************************/ \ No newline at end of file diff --git a/scripts/tools/Win32/thirdPartyLegalnotices/licenses_wav-diff.html b/scripts/tools/Win32/thirdPartyLegalnotices/licenses_wav-diff.html new file mode 100644 index 0000000000000000000000000000000000000000..1bdee68950575ca1db5c3b71da74ad7986efc1a7 --- /dev/null +++ b/scripts/tools/Win32/thirdPartyLegalnotices/licenses_wav-diff.html @@ -0,0 +1,1817 @@ + + + + + + + +
+
+

Third Party Licenses

+

This page lists the licenses of the projects used in wav-diff.

+
+ +

Overview of licenses:

+ + +

All license text:

+ +
+ + + diff --git a/scripts/tools/Win32/wav-diff.exe b/scripts/tools/Win32/wav-diff.exe new file mode 100644 index 0000000000000000000000000000000000000000..b87b0888e4da8b559be017c4fb8c15e62152b1cb --- /dev/null +++ b/scripts/tools/Win32/wav-diff.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92c49557ce750bd1eb05278ced4a64b98d66a654f3604b8003f72f4a05df8df3 +size 889344 diff --git a/tests/cmp_pcm.py b/tests/cmp_pcm.py index 5b335840e6634ed3286c4fe0ecc99eaa2bad3302..32defbdd0530e0c845bf68f101d8970090f0a576 100755 --- a/tests/cmp_pcm.py +++ b/tests/cmp_pcm.py @@ -15,7 +15,11 @@ sys.path.append(os.path.join(os.path.dirname(THIS_PATH), "../scripts")) import numpy as np import pyaudio3dtools import pyivastest -from .constants import ODG_PATTERN_PQEVALAUDIO +# Hack to resolve import when using from command line or from within scripts. +try: + from .constants import ODG_PATTERN_PQEVALAUDIO +except ImportError: + from constants import ODG_PATTERN_PQEVALAUDIO def cmp_pcm( @@ -29,6 +33,8 @@ def cmp_pcm( abs_tol=0, get_ssnr=False, get_odg=False, + ref_jbm_tf: Optional[Path] = None, + cut_jbm_tf: Optional[Path] = None, ) -> (int, str): """ Compare 2 PCM files for bitexactness @@ -57,11 +63,17 @@ def cmp_pcm( # In case of wav input, override the nchannels with the one from the wav header nchannels = s1.shape[1] + # In case number of channels do not match, fail already now. Could happen in case of + # comparison to input with for a non-passthrough mode. + if s1.shape[1] != s2.shape[1]: + reason = "FAIL: Number of channels differ." + return 1, reason + if allow_differing_lengths: - # to allow for MLD comparison, shorten longer file - min_len = min(s1.shape[0], s2.shape[0]) - s1 = s1[:min_len, :] - s2 = s2[:min_len, :] + # to allow for MLD comparison, pad shorter file + max_len = max(s1.shape[0], s2.shape[0]) + s1 = np.pad(s1,((0,max_len - s1.shape[0]),(0,0)),mode='constant',constant_values=0) + s2 = np.pad(s2,((0,max_len - s2.shape[0]),(0,0)),mode='constant',constant_values=0) elif s1.shape != s2.shape: print( f"file size in samples: file 1 = {s1.shape[0]},", @@ -81,6 +93,8 @@ def cmp_pcm( get_mld=get_mld, get_ssnr=get_ssnr, ssnr_thresh_low=-50, + ref_jbm_tf=ref_jbm_tf, + test_jbm_tf=cut_jbm_tf, ) output_differs = 0 @@ -176,6 +190,8 @@ if __name__ == "__main__": parser.add_argument("--get_mld", action="store_true") parser.add_argument("--mld_lim", type=float, default=0, dest="mld_lim") parser.add_argument("--get_odg", action="store_true") + parser.add_argument("--get_ssnr", action="store_true") + parser.add_argument("--allow_differing_lengths", action="store_true") args = parser.parse_args() result, msg = cmp_pcm(**vars(args)) 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 9a11b4d6d42be2e143e56dfa2bef0b9b84963640..5d6b5cbaa1fa7b3bb126d6da34f7c7e643d401bb 100644 --- a/tests/codec_be_on_mr_nonselection/test_param_file.py +++ b/tests/codec_be_on_mr_nonselection/test_param_file.py @@ -39,6 +39,7 @@ import platform from pathlib import Path from subprocess import run import pytest +import re import numpy as np from tests.cmp_pcm import cmp_pcm @@ -51,6 +52,17 @@ from tests.constants import ( SCRIPTS_DIR, ) +PASSTHROUGH_CONF = [ + (r"[\s\S]*", "EXT"), # Any input with EXT output is pass-through + (r"-stereo", "STEREO"), + (r"-sba\s?[-+]?1", "FOA"), + (r"-sba\s?[-+]?2", "HOA2"), + (r"-sba\s?[-+]?3", "HOA3"), + (r"-mc\s5_1\s", "5_1"), + (r"-mc\s7_1\s", "7_1"), + (r"-mc\s5_1_4", "5_1_4"), + (r"-mc\s7_1_4", "7_1_4"), +] VALID_DEC_OUTPUT_CONF = [ "MONO", @@ -161,9 +173,22 @@ def test_param_file_tests( get_ssnr, get_enc_stats, get_odg, + compare_to_input, ): enc_opts, dec_opts, sim_opts, eid_opts = param_file_test_dict[test_tag] + # If compare_to_input is set, only run pass-through test cases + if compare_to_input: + passthrough = [ + (a, b) + for (a, b) in PASSTHROUGH_CONF + if re.search(a, enc_opts) and b in dec_opts.split() + ] + if len(passthrough) != 1: + pytest.skip( + "All non-passthrough modes are skipped when --compare-to-input is set" + ) + tag_str = convert_test_string_to_tag(test_tag) # evaluate encoder options @@ -378,7 +403,7 @@ def test_param_file_tests( # set to false per default even if this is no JBM case - makes later check for failure easier tracefile_last_rtp_numbers_differ = False - if len(tracefile_dec) > 0: + if len(tracefile_dec) > 0 and not compare_to_input: dut_tracefile_dec = f"{dut_base_path}/param_file/dec/{tracefile_dec}" ref_tracefile_dec = f"{reference_path}/param_file/dec/{tracefile_dec}" @@ -390,15 +415,26 @@ def test_param_file_tests( ref_tracefile_dec, delimiter=";", usecols=[0] )[-1] tracefile_last_rtp_numbers_differ = dut_rtp_num_last != ref_rtp_num_last + else: + dut_tracefile_dec = None + ref_tracefile_dec = None # same sequence number -> likely no crash, assume length difference is due to difference in TSM # to get MLD and abs diff values for now - even though they might be meaningless due to # shift differences between the two signals - cut longer signal to shorter size allow_differing_lengths = not tracefile_last_rtp_numbers_differ + if compare_to_input: + # If comparing to input, set input as reference and allow different length + ref_file = testv_file + allow_differing_lengths = True + input_md = [x for x in enc_split if "csv" in x] + else: + ref_file = ref_output_file + fs = int(sampling_rate) * 1000 output_differs, reason = cmp_pcm( - ref_output_file, + ref_file, dut_output_file, output_config, fs, @@ -408,8 +444,9 @@ def test_param_file_tests( allow_differing_lengths=allow_differing_lengths, get_ssnr=get_ssnr, get_odg=get_odg, + ref_jbm_tf=ref_tracefile_dec, + cut_jbm_tf=dut_tracefile_dec, ) - md_out_files = get_expected_md_files(ref_output_file, enc_split, output_config) cmp_result_msg += reason @@ -418,9 +455,24 @@ def test_param_file_tests( record_property(k, v) metadata_differs = False - for md_file in md_out_files: - dut_metadata_file = Path(f"{dut_base_path}/param_file/dec/{md_file}") - ref_metadata_file = Path(f"{reference_path}/param_file/dec/{md_file}") + + md_out_files = get_expected_md_files(ref_output_file, enc_split, output_config) + + if compare_to_input: + md_file_pairs = [ + (Path(f"{dut_base_path}/param_file/dec/{md_file}"), md_in_file) + for (md_file, md_in_file) in zip(md_out_files, input_md) + ] + else: + md_file_pairs = [ + ( + Path(f"{dut_base_path}/param_file/dec/{md_file}"), + Path(f"{reference_path}/param_file/dec/{md_file}"), + ) + for md_file in md_out_files + ] + for dut_metadata_file, ref_metadata_file in md_file_pairs: + md_file = os.path.basename(dut_metadata_file) try: if not filecmp.cmp(dut_metadata_file, ref_metadata_file): print("Output metadata differs for file: " + md_file) diff --git a/tests/codec_be_on_mr_nonselection/test_sba.py b/tests/codec_be_on_mr_nonselection/test_sba.py index 98f55b7fe57f89c8ca30609e968ddef31045459e..885ac488ad36b2ec2cad0b1ae762c4536fa0cecb 100644 --- a/tests/codec_be_on_mr_nonselection/test_sba.py +++ b/tests/codec_be_on_mr_nonselection/test_sba.py @@ -114,6 +114,7 @@ def test_pca_enc( get_ssnr, get_odg, get_enc_stats, + compare_to_input, ): pca = True bitrate = "256000" @@ -165,6 +166,7 @@ def test_pca_enc( sba_dec( record_property, props_to_record, + test_vector_path, dut_decoder_frontend, ref_decoder_frontend, reference_path, @@ -187,6 +189,7 @@ def test_pca_enc( abs_tol=abs_tol, get_ssnr=get_ssnr, get_odg=get_odg, + compare_to_input=compare_to_input, ) @@ -223,6 +226,7 @@ def test_sba_enc_system( get_ssnr, get_odg, get_enc_stats, + compare_to_input, ): plc_pattern = None @@ -333,6 +337,7 @@ def test_sba_enc_system( sba_dec( record_property, props_to_record, + test_vector_path, dut_decoder_frontend, ref_decoder_frontend, reference_path, @@ -355,6 +360,7 @@ def test_sba_enc_system( abs_tol=abs_tol, get_ssnr=get_ssnr, get_odg=get_odg, + compare_to_input=compare_to_input, ) @@ -383,6 +389,7 @@ def test_spar_hoa2_enc_system( get_ssnr, get_odg, get_enc_stats, + compare_to_input, ): sampling_rate = "48" pca = False @@ -467,6 +474,7 @@ def test_spar_hoa2_enc_system( sba_dec( record_property, props_to_record, + test_vector_path, dut_decoder_frontend, ref_decoder_frontend, reference_path, @@ -489,6 +497,7 @@ def test_spar_hoa2_enc_system( abs_tol=abs_tol, get_ssnr=get_ssnr, get_odg=get_odg, + compare_to_input=compare_to_input, ) @@ -517,6 +526,7 @@ def test_spar_hoa3_enc_system( get_ssnr, get_odg, get_enc_stats, + compare_to_input, ): sampling_rate = "48" pca = False @@ -595,6 +605,7 @@ def test_spar_hoa3_enc_system( sba_dec( record_property, props_to_record, + test_vector_path, dut_decoder_frontend, ref_decoder_frontend, reference_path, @@ -617,6 +628,7 @@ def test_spar_hoa3_enc_system( abs_tol=abs_tol, get_ssnr=get_ssnr, get_odg=get_odg, + compare_to_input=compare_to_input, ) @@ -649,6 +661,7 @@ def test_sba_enc_BWforce_system( get_ssnr, get_odg, get_enc_stats, + compare_to_input, ): sid = 0 plc_pattern = None @@ -743,6 +756,7 @@ def test_sba_enc_BWforce_system( sba_dec( record_property, props_to_record, + test_vector_path, dut_decoder_frontend, ref_decoder_frontend, reference_path, @@ -765,6 +779,7 @@ def test_sba_enc_BWforce_system( abs_tol=abs_tol, get_ssnr=get_ssnr, get_odg=get_odg, + compare_to_input=compare_to_input, ) @@ -801,6 +816,7 @@ def test_sba_plc_system( get_ssnr, get_odg, get_enc_stats, + compare_to_input, ): sid = 0 pca = False @@ -872,6 +888,7 @@ def test_sba_plc_system( sba_dec( record_property, props_to_record, + test_vector_path, dut_decoder_frontend, ref_decoder_frontend, reference_path, @@ -894,6 +911,7 @@ def test_sba_plc_system( abs_tol=abs_tol, get_ssnr=get_ssnr, get_odg=get_odg, + compare_to_input=compare_to_input, ) @@ -1026,6 +1044,7 @@ def sba_enc( def sba_dec( record_property, props_to_record, + test_vector_path, dut_decoder_frontend, ref_decoder_frontend, reference_path, @@ -1048,6 +1067,7 @@ def sba_dec( abs_tol=0, get_ssnr=False, get_odg=False, + compare_to_input=False, ): dut_pkt_dir = f"{dut_base_path}/sba_bs/pkt" ref_pkt_dir = f"{reference_path}/sba_bs/pkt" @@ -1115,6 +1135,12 @@ def sba_dec( plc_file=plc_file, ) + allow_differing_lengths = False + if compare_to_input: + # If comparing to input, set input as reference and allow different length + ref_out_file = f"{test_vector_path}/{tag}.wav" + allow_differing_lengths = True + sampling_rate_Hz = int(sampling_rate) * 1000 cmp_result, reason = cmp_pcm( dut_out_file, @@ -1124,6 +1150,7 @@ def sba_dec( get_mld=get_mld, mld_lim=get_mld_lim, abs_tol=abs_tol, + allow_differing_lengths=allow_differing_lengths, get_ssnr=get_ssnr, get_odg=get_odg, ) @@ -1136,8 +1163,3 @@ def sba_dec( # report compare result if cmp_result != 0: pytest.fail(text_to_parse) - - # remove DUT output files when test result is OK (to save disk space) - # if not keep_files: - # os.remove(dut_out_file) - # os.remove(dut_pkt_file) diff --git a/tests/conftest.py b/tests/conftest.py index 636881ecefa58e5394eb00afb7024e76b9347ebe..8f3e4e961bc7e87499d0c9af4642fe96d84f22ad 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -260,6 +260,12 @@ def pytest_addoption(parser): default=0, ) + parser.addoption( + "--compare_to_input", + action="store_true", + help="Compare output to the input file instead of reference output. N.B. Only applicable to pass-through tests.", + default=False, + ) @pytest.fixture(scope="session", autouse=True) def update_ref(request): @@ -927,7 +933,7 @@ def reference_path(request) -> str: path = str(path.resolve()) - if request.config.option.update_ref == "0": + if request.config.option.update_ref == "0" and not request.config.option.compare_to_input: if not os.path.isdir(path): raise FileNotFoundError( f"REF path {path} not found!\nPlease generate the references, first!\n!" @@ -968,6 +974,12 @@ def encoder_only(request) -> bool: """ return request.config.getoption("--encoder_only") +@pytest.fixture(scope="session", autouse=True) +def compare_to_input(request) -> bool: + """ + Return value of cmdl param --compare_to_input + """ + return request.config.getoption("--compare_to_input") def pytest_configure(config): config.addinivalue_line("markers", "serial: mark test to run only in serial")