From cc8c2294b054eedecfe3b6ef248957554ce2e621 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 17 Nov 2023 07:21:23 +0100 Subject: [PATCH 01/11] fix #864, use correct information for the JBM control for all rendering sizes --- apps/decoder.c | 162 +++++++++++++++++++++++++++++++++++++++++++++- lib_com/options.h | 2 + lib_dec/lib_dec.c | 41 ++++++++++++ lib_dec/lib_dec.h | 6 ++ 4 files changed, 210 insertions(+), 1 deletion(-) diff --git a/apps/decoder.c b/apps/decoder.c index ca333d9572..84c36e67d5 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -3208,6 +3208,13 @@ static ivas_error decodeVoIP( } #endif +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + if ( vec_pos_update == 0 ) + { + IVAS_DEC_VoIP_Set20msStart( hIvasDec ); + } +#endif + /* read all packets with a receive time smaller than the system time */ while ( nextPacketRcvTime_ms <= systemTime_ms ) { @@ -3399,7 +3406,14 @@ static ivas_error decodeVoIP( vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; #endif frame++; - systemTime_ms += systemTimeInc_ms; +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + if ( vec_pos_update == 0 ) + { +#endif + systemTime_ms += vec_pos_len * systemTimeInc_ms; +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + } +#endif #ifdef WMOPS update_mem(); @@ -3407,6 +3421,152 @@ static ivas_error decodeVoIP( #endif } + +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + int16_t nSamplesFlushed = 0; + + do + { + + + /* Feed into decoder */ + + /* reference vector */ + if ( arg.enableReferenceVectorTracking ) + { + IVAS_VECTOR3 listenerPosition, referencePosition; + if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPosition, &referencePosition ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading listener and reference positions from %s\n", IVAS_DEC_GetErrorMessage( error ), Vector3PairFileReader_getFilePath( referenceVectorReader ) ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_FeedRefVectorData( hIvasDec, listenerPosition, referencePosition ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRefVectorData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* Reference rotation */ + if ( arg.enableReferenceRotation ) + { + IVAS_QUATERNION quaternion; + if ( ( error = HeadRotationFileReading( refRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading reference rotation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( refRotReader ) ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_FeedRefRotData( hIvasDec, quaternion ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRefRotData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* Head-tracking input simulation */ + if ( arg.enableHeadRotation ) + { + IVAS_QUATERNION Quaternion; + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos[0] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0 ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* decode and get samples */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + /* Write current frame */ + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, nSamplesFlushed * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + goto cleanup; + } + + /* Write ISm metadata to external file(s) */ + if ( decodedGoodFrame && arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ || bsFormat == IVAS_DEC_BS_MASA_ISM || bsFormat == IVAS_DEC_BS_SBA_ISM ) + { + if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetNumObjects: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + for ( i = 0; i < numObj; ++i ) + { + IVAS_ISM_METADATA IsmMetadata; + + if ( ( error = IVAS_DEC_GetObjectMetadata( hIvasDec, &IsmMetadata, 0, i ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetObjectMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( IsmFileWriter_writeFrame( IsmMetadata, ismWriters[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing ISM metadata to file %s\n", IsmFileWriter_getFilePath( ismWriters[i] ) ); + goto cleanup; + } + } + } + + if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM ) + { + IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); + goto cleanup; + } + } + } + +#ifdef NONBE_UNIFIED_DECODING_PATHS + vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; +#endif + frame++; + if ( !arg.quietModeEnabled ) + { + fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); +#ifdef DEBUGGING + if ( IVAS_DEC_GetBerDetectFlag( hIvasDec ) ) + { + fprintf( stdout, "\n Decoding error: BER detected in frame %d !!!!!\n", frame - 1 ); + } +#endif + } + } while ( nSamplesFlushed > 0 ); +#endif + /*------------------------------------------------------------------------------------------* * Add zeros at the end to have equal length of synthesized signals *------------------------------------------------------------------------------------------*/ diff --git a/lib_com/options.h b/lib_com/options.h index f44ad78c49..540d8793b8 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -128,6 +128,7 @@ /*#define DEBUG_AGC_ENCODER_CMD_OPTION*/ /* Ability to force enable or disable AGC behaviour in DIRAC/SPAR via command line option */ /*#define DEBUG_JBM_CMD_OPTION*/ /* ability for telling the decoder the frontend fetch size and to not delay compensate for bad frames at the beginning */ /*#define VARIABLE_SPEED_DECODING*/ /* variable speed decoding employing the JBM functioniality; move to DEBUGGING after build for disabled is fixed */ +#define DISABLE_LIMITER /* disable the limiter */ /*Split Rendering Debug switches*/ /*#define DBG_WAV_WRITER*/ /* add debugging function dbgwrite_wav() */ @@ -165,6 +166,7 @@ #define NONBE_FIX_871_ACELP_CRASH_IN_OSBA /* FhG: isse 871: crash in ACELP core encoder with OSBA */ #define NONBE_FIX_225_MASA_EXT_REND /* Nokia: Resolve #225: Complete MASA external renderer implementation */ #define NONBE_FIX_897_USAN_WITH_MASA_RENDERING /* Nokia: issue #897: USAN null pointer in MASA external renderer to Ambisonics */ +#define NONBE_FIX_864_JBM_RENDER_FRAMESIZE /* FhG: issue #864: fix different behaviour of JBM TSM with different render frame sizes */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 5abb39cd86..ab2c618500 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -57,6 +57,9 @@ struct IVAS_DEC_VOIP uint16_t lastDecodedWasActive; JB4_DATAUNIT_HANDLE hCurrentDataUnit; /* Points to the currently processed data unit */ uint16_t *bs_conversion_buf; /* Buffer for bitstream conversion from packed to serial */ +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + int16_t nSamplesRendered20ms; /* how many samples have been rendered since the last 20ms render border*/ +#endif #ifdef SUPPORT_JBM_TRACEFILE IVAS_JBM_TRACE_DATA JbmTraceData; #endif @@ -2612,7 +2615,11 @@ ivas_error IVAS_DEC_VoIP_GetSamples( } } +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + extBufferedSamples = hVoIP->nSamplesRendered20ms + nSamplesBuffered; +#else extBufferedSamples = nSamplesRendered + nSamplesBuffered; +#endif extBufferedTime_ms = extBufferedSamples * 1000 / hDecoderConfig->output_Fs; dataUnit = NULL; @@ -2723,6 +2730,9 @@ ivas_error IVAS_DEC_VoIP_GetSamples( nSamplesRendered += nSamplesToZero; hIvasDec->nSamplesRendered += nSamplesToZero; hIvasDec->nSamplesAvailableNext -= nSamplesToZero; +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + hVoIP->nSamplesRendered20ms += nSamplesToZero; +#endif } else { @@ -2741,6 +2751,9 @@ ivas_error IVAS_DEC_VoIP_GetSamples( } nSamplesRendered += nSamplesRendered_loop; +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + hVoIP->nSamplesRendered20ms += nSamplesRendered_loop; +#endif } } @@ -2748,6 +2761,34 @@ ivas_error IVAS_DEC_VoIP_GetSamples( } +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_Set20msStart( ) + * + * Function to tell the API that a new 20ms rendered samples border has been reached + * needed for correct JBM packet buffer operations + *---------------------------------------------------------------------*/ +ivas_error IVAS_DEC_VoIP_Set20msStart( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + ivas_error error; + + error = IVAS_ERR_OK; + + if ( hIvasDec->hVoIP == NULL ) + { + return IVAS_ERR_UNKNOWN; + } + + hIvasDec->hVoIP->nSamplesRendered20ms = 0; + + + return error; +} + +#endif + /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_Flush( ) * diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 11aa3917ef..5901afe4f4 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -283,6 +283,12 @@ ivas_error IVAS_DEC_VoIP_GetSamples( #endif ); +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE +ivas_error IVAS_DEC_VoIP_Set20msStart( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +); +#endif + ivas_error IVAS_DEC_Flush( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ -- GitLab From 3d9a3ebfd7f5c00cd3bef64b81826589d7eda656 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 17 Nov 2023 07:51:15 +0100 Subject: [PATCH 02/11] move orientation reading if the JBM flush part to the correct place, unset #DISABLE_LIMITER --- apps/decoder.c | 180 +++++++++++++++++++++++++++++++--------------- lib_com/options.h | 2 +- 2 files changed, 123 insertions(+), 59 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 9cdcb140c2..b7a00f2c16 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -3497,64 +3497,6 @@ static ivas_error decodeVoIP( do { - - /* Feed into decoder */ - - /* reference vector */ - if ( arg.enableReferenceVectorTracking ) - { - IVAS_VECTOR3 listenerPosition, referencePosition; - if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPosition, &referencePosition ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError %s while reading listener and reference positions from %s\n", IVAS_DEC_GetErrorMessage( error ), Vector3PairFileReader_getFilePath( referenceVectorReader ) ); - goto cleanup; - } - - if ( ( error = IVAS_DEC_FeedRefVectorData( hIvasDec, listenerPosition, referencePosition ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_FeedRefVectorData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } - } - - /* Reference rotation */ - if ( arg.enableReferenceRotation ) - { - IVAS_QUATERNION quaternion; - if ( ( error = HeadRotationFileReading( refRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError %s while reading reference rotation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( refRotReader ) ); - goto cleanup; - } - - if ( ( error = IVAS_DEC_FeedRefRotData( hIvasDec, quaternion ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_FeedRefRotData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } - } - - /* Head-tracking input simulation */ - if ( arg.enableHeadRotation ) - { - IVAS_QUATERNION Quaternion; - if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos[0] ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); - goto cleanup; - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0 ) ) != IVAS_ERR_OK ) -#endif - { - fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } - } - /* decode and get samples */ #ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) @@ -3633,6 +3575,128 @@ static ivas_error decodeVoIP( } #endif } + +#ifdef NONBE_UNIFIED_DECODING_PATHS + /* reference vector */ + if ( arg.enableReferenceVectorTracking && vec_pos_update == 0 ) + { + IVAS_VECTOR3 listenerPosition, referencePosition; + if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPosition, &referencePosition ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading listener and reference positions from %s\n", IVAS_DEC_GetErrorMessage( error ), Vector3PairFileReader_getFilePath( referenceVectorReader ) ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_FeedRefVectorData( hIvasDec, listenerPosition, referencePosition ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRefVectorData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* Reference rotation */ + if ( arg.enableReferenceRotation && vec_pos_update == 0 ) + { + IVAS_QUATERNION quaternion; + if ( ( error = HeadRotationFileReading( refRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading reference rotation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( refRotReader ) ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_FeedRefRotData( hIvasDec, quaternion ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRefRotData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + int16_t num_subframes; + if ( ( error = IVAS_DEC_GetNumOrientationSubframes( hIvasDec, &num_subframes ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetNumOrientationSubframes failed: \n" ); + goto cleanup; + } + + /* Head-tracking input simulation */ + /* Head-tracking input simulation */ + if ( arg.enableHeadRotation ) + { + IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( headRotReader == NULL ) + { + for ( i = 0; i < num_subframes; i++ ) + { + Quaternions[i].w = -3.0f; + Quaternions[i].x = 0.0f; + Quaternions[i].y = 0.0f; + Quaternions[i].z = 0.0f; + Pos[i].x = 0.0f; + Pos[i].y = 0.0f; + Pos[i].z = 0.0f; + } + } + else + { +#endif + for ( i = 0; i < num_subframes; i++ ) + { + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), + RotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif + + for ( i = 0; i < num_subframes; i++ ) + { + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + DEFAULT_AXIS +#endif + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + } + + if ( arg.enableExternalOrientation ) + { + IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + int8_t enableHeadRotation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + int8_t enableExternalOrientation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + int8_t enableRotationInterpolation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t numFramesToTargetOrientation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( i = 0; i < num_subframes; i++ ) + { + + if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &Quaternions[i], &enableHeadRotation[i], &enableExternalOrientation[i], &enableRotationInterpolation[i], &numFramesToTargetOrientation[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading external orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), + RotationFileReader_getFilePath( externalOrientationFileReader ) ); + goto cleanup; + } + } + for ( i = 0; i < num_subframes; i++ ) + { + if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternions[i], enableHeadRotation[i], enableExternalOrientation[i], enableRotationInterpolation[i], numFramesToTargetOrientation[i], i ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + } +#endif + } while ( nSamplesFlushed > 0 ); #endif diff --git a/lib_com/options.h b/lib_com/options.h index e00d4ec682..a4dc2bfd07 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -128,7 +128,7 @@ /*#define DEBUG_AGC_ENCODER_CMD_OPTION*/ /* Ability to force enable or disable AGC behaviour in DIRAC/SPAR via command line option */ /*#define DEBUG_JBM_CMD_OPTION*/ /* ability for telling the decoder the frontend fetch size and to not delay compensate for bad frames at the beginning */ /*#define VARIABLE_SPEED_DECODING*/ /* variable speed decoding employing the JBM functioniality; move to DEBUGGING after build for disabled is fixed */ -#define DISABLE_LIMITER /* disable the limiter */ +/*#define DISABLE_LIMITER*/ /* disable the limiter */ /*Split Rendering Debug switches*/ /*#define DBG_WAV_WRITER*/ /* add debugging function dbgwrite_wav() */ -- GitLab From a0a21782d26e948222d0019bfcd848d93f4dadf4 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 17 Nov 2023 08:29:24 +0100 Subject: [PATCH 03/11] fix flush function, return immediately if there is nothing to flush. --- lib_dec/lib_dec.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 2c8bf04e3a..326bb2dac8 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -2858,13 +2858,19 @@ ivas_error IVAS_DEC_Flush( nSamplesToRender = (uint16_t) *nSamplesFlushed; /* render IVAS frames */ - +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + error = IVAS_ERR_OK; + if ( nSamplesToRender > 0 ) + { +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT - error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmType, pcmBuf ); + error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmType, pcmBuf ); #else - error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmBuf ); + error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmBuf ); +#endif +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + } #endif - return error; } -- GitLab From 86a8926d86f267c7e7233bb9ccff6ebfd5d253eb Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 17 Nov 2023 09:05:35 +0100 Subject: [PATCH 04/11] do not flush EVS to ensure BE --- lib_dec/lib_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 326bb2dac8..03126f2599 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -2860,13 +2860,13 @@ ivas_error IVAS_DEC_Flush( /* render IVAS frames */ #ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE error = IVAS_ERR_OK; - if ( nSamplesToRender > 0 ) + if ( nSamplesToRender > 0 && hIvasDec->st_ivas->ivas_format != MONO_FORMAT ) { #endif #ifdef SPLIT_REND_WITH_HEAD_ROT error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmType, pcmBuf ); #else - error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmBuf ); + error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmBuf ); #endif #ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE } -- GitLab From 8c97318a61d3206cdf4369e18105cab24075985e Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 17 Nov 2023 09:30:00 +0100 Subject: [PATCH 05/11] fix flushing for EVS --- lib_dec/lib_dec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 03126f2599..4dd8f9412c 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -2870,6 +2870,10 @@ ivas_error IVAS_DEC_Flush( #endif #ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE } + else + { + *nSamplesFlushed = 0; + } #endif return error; } -- GitLab From d0d54aa786b9828f83ab203c6b5da3c07de7d1da Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 8 Dec 2023 09:36:15 +0100 Subject: [PATCH 06/11] keep the 20ms JBM householding inside the API, change ISM TD renderer to really render subframes and in case of combined orientation use the same MD logic as the TD binaural renderer --- apps/decoder.c | 7 -- lib_dec/ivas_ism_renderer.c | 144 +++++++++++++++++++++++++++--------- lib_dec/lib_dec.c | 42 +++++------ lib_dec/lib_dec.h | 6 -- 4 files changed, 128 insertions(+), 71 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index b7a00f2c16..d57f88af56 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -3277,13 +3277,6 @@ static ivas_error decodeVoIP( } #endif -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - if ( vec_pos_update == 0 ) - { - IVAS_DEC_VoIP_Set20msStart( hIvasDec ); - } -#endif - /* read all packets with a receive time smaller than the system time */ while ( nextPacketRcvTime_ms <= systemTime_ms ) { diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 94060ae8ef..7d2c815386 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -254,87 +254,161 @@ void ivas_ism_render_sf( int16_t tc_offset; int16_t interp_offset; float gain, prev_gain; +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + int16_t ism_md_subframe_update_jbm, slots_to_render, first_sf, last_sf, subframe_idx; + int16_t n_samples_rendered_loop; +#endif num_objects = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { num_objects = st_ivas->nchan_ism; } +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, n_samples_to_render / st_ivas->hTcBuffer->n_samples_granularity ); + first_sf = st_ivas->hTcBuffer->subframes_rendered; + last_sf = first_sf; + n_samples_rendered_loop = 0; + while ( slots_to_render > 0 ) + { + slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf]; + last_sf++; + } + +#endif nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; tc_offset = st_ivas->hTcBuffer->n_samples_rendered; interp_offset = st_ivas->hTcBuffer->n_samples_rendered; +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + /* Number of subframes to delay metadata to sync with audio */ + if ( st_ivas->hDecoderConfig->Opt_delay_comp ) + { + ism_md_subframe_update_jbm = max( 0, st_ivas->hTcBuffer->nb_subframes - 3 ); + } + else + { + ism_md_subframe_update_jbm = st_ivas->hTcBuffer->nb_subframes - 2; + } +#endif for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) { set_f( output_f[i], 0.0f, n_samples_to_render ); } +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + int16_t n_samples_in_subframe; + + n_samples_in_subframe = st_ivas->hTcBuffer->n_samples_granularity * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; +#endif + #ifdef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) #else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] ) #endif - { + { +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_in_subframe, n_samples_in_subframe, st_ivas->hIsmRendererData->interpolator ); +#else ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_to_render, n_samples_to_render, st_ivas->hIsmRendererData->interpolator ); - interp_offset = 0; - } +#endif + interp_offset = 0; + } - for ( i = 0; i < num_objects; i++ ) - { - /* Combined rotation: rotate the object positions depending the head and external orientations */ + for ( i = 0; i < num_objects; i++ ) + { + /* Combined rotation: rotate the object positions depending the head and external orientations */ #ifdef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) #else if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) #endif - { + { +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + if ( subframe_idx >= ism_md_subframe_update_jbm ) + { + rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); + } + else + { + rotateAziEle( st_ivas->hIsmMetaData[i]->last_azimuth, st_ivas->hIsmMetaData[i]->last_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); + } +#else rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[0], st_ivas->hIntSetup.is_planar_setup ); +#endif - if ( st_ivas->hEFAPdata != NULL ) - { - efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP ); + if ( st_ivas->hEFAPdata != NULL ) + { + efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP ); + } } - } - lfe_index = 0; - for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ ) - { - if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) ) + lfe_index = 0; + for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ ) { - ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++; - } + if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) ) + { + ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++; + } - gain = st_ivas->hIsmRendererData->gains[i][j]; - prev_gain = st_ivas->hIsmRendererData->prev_gains[i][j]; - if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f ) - { - g1 = &st_ivas->hIsmRendererData->interpolator[interp_offset]; - tc = &st_ivas->hTcBuffer->tc[i][tc_offset]; - for ( k = 0; k < n_samples_to_render; k++ ) + gain = st_ivas->hIsmRendererData->gains[i][j]; + prev_gain = st_ivas->hIsmRendererData->prev_gains[i][j]; + if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f ) { - g2 = 1.0f - *g1; + g1 = &st_ivas->hIsmRendererData->interpolator[interp_offset]; + tc = &st_ivas->hTcBuffer->tc[i][tc_offset]; +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + for ( k = 0; k < n_samples_in_subframe; k++ ) +#else + for ( k = 0; k < n_samples_to_render; k++ ) +#endif + { + g2 = 1.0f - *g1; +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + output_f[j2][k + n_samples_rendered_loop] += ( *( g1++ ) * gain + g2 * prev_gain ) * *( tc++ ); +#else output_f[j2][k] += ( *( g1++ ) * gain + g2 * prev_gain ) * *( tc++ ); +#endif + } } - } - /* update here only in case of head rotation */ + /* update here only in case of head rotation */ #ifdef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) #else if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) #endif - { - st_ivas->hIsmRendererData->prev_gains[i][j] = gain; + { + st_ivas->hIsmRendererData->prev_gains[i][j] = gain; + } } } - } #ifdef NONBE_UNIFIED_DECODING_PATHS - /* update combined orientation access index */ - ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_to_render ); + /* update combined orientation access index */ +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_in_subframe ); +#else + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_to_render ); +#endif +#endif +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + n_samples_rendered_loop += n_samples_in_subframe; + if ( st_ivas->renderer_type == RENDERER_TD_PANNING ) + { + st_ivas->hTcBuffer->subframes_rendered += 1; + st_ivas->hTcBuffer->slots_rendered += st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; + } + tc_offset += n_samples_in_subframe; + interp_offset += n_samples_in_subframe; + } #endif return; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 4dd8f9412c..b99ef856e8 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -134,7 +134,9 @@ static ivas_error set_pcm_buffer_to_zero( void *buffer, const IVAS_DEC_PCM_TYPE #ifdef NONBE_UNIFIED_DECODING_PATHS static int16_t get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize ); #endif - +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE +static void update_voip_rendered20ms( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesRendered ); +#endif /*---------------------------------------------------------------------* * IVAS_DEC_Open() @@ -787,6 +789,9 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->hVoIP->lastDecodedWasActive = 0; hIvasDec->hVoIP->hCurrentDataUnit = NULL; hIvasDec->hVoIP->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + hIvasDec->hVoIP->nSamplesRendered20ms = 0; +#endif #define WMC_TOOL_SKIP /* Bitstream conversion is not counted towards complexity and memory usage */ @@ -1583,6 +1588,9 @@ static ivas_error IVAS_DEC_GetBufferedNumberOfSamples( if ( hIvasDec->st_ivas->hTcBuffer != NULL ) { *nSamplesBuffered = hIvasDec->st_ivas->hTcBuffer->n_samples_buffered - hIvasDec->st_ivas->hTcBuffer->n_samples_rendered; +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + *nSamplesBuffered += hIvasDec->hVoIP->nSamplesRendered20ms; +#endif } return IVAS_ERR_OK; @@ -2658,7 +2666,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( } #ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - extBufferedSamples = hVoIP->nSamplesRendered20ms + nSamplesBuffered; + extBufferedSamples = nSamplesBuffered; #else extBufferedSamples = nSamplesRendered + nSamplesBuffered; #endif @@ -2773,7 +2781,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( hIvasDec->nSamplesRendered += nSamplesToZero; hIvasDec->nSamplesAvailableNext -= nSamplesToZero; #ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - hVoIP->nSamplesRendered20ms += nSamplesToZero; + update_voip_rendered20ms( hIvasDec, nSamplesToZero ); #endif } else @@ -2794,7 +2802,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( nSamplesRendered += nSamplesRendered_loop; #ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - hVoIP->nSamplesRendered20ms += nSamplesRendered_loop; + update_voip_rendered20ms( hIvasDec, nSamplesRendered_loop ); #endif } } @@ -2802,31 +2810,19 @@ ivas_error IVAS_DEC_VoIP_GetSamples( return IVAS_ERR_OK; } - #ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE /*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_Set20msStart( ) + * update_voip_rendered20ms( ) * - * Function to tell the API that a new 20ms rendered samples border has been reached - * needed for correct JBM packet buffer operations + * Function to flush remaining audio in VoIP *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_VoIP_Set20msStart( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ -) -{ - ivas_error error; - - error = IVAS_ERR_OK; - - if ( hIvasDec->hVoIP == NULL ) - { - return IVAS_ERR_UNKNOWN; - } - - hIvasDec->hVoIP->nSamplesRendered20ms = 0; +static void update_voip_rendered20ms( + IVAS_DEC_HANDLE hIvasDec, + const int16_t nSamplesRendered ) +{ - return error; + hIvasDec->hVoIP->nSamplesRendered20ms = ( hIvasDec->hVoIP->nSamplesRendered20ms + nSamplesRendered ) % hIvasDec->hVoIP->nSamplesFrame; } #endif diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 67315a121b..1b5e7e4fcc 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -290,12 +290,6 @@ ivas_error IVAS_DEC_VoIP_GetSamples( #endif ); -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE -ivas_error IVAS_DEC_VoIP_Set20msStart( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ -); -#endif - ivas_error IVAS_DEC_Flush( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ -- GitLab From 745f55ee87ec63ccb7cd85b070cfb17adacbce94 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Mon, 11 Dec 2023 09:32:06 +0100 Subject: [PATCH 07/11] fix TSM, time scaling done flag was not set correctly for non-20ms render frame size. --- lib_com/options.h | 3 ++- lib_dec/lib_dec.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index a4dc2bfd07..4e24b8ad22 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -58,7 +58,7 @@ #ifdef DEBUGGING -/*#define DEBUG_MODE_INFO*/ /* output most important parameters to the subdirectory "res/" */ +/*#define DEBUG_MODE_INFO*/ /* output most important parameters to the subdirectory "res/" */ #ifdef DEBUG_MODE_INFO /*#define DEBUG_MODE_ACELP*/ /* output most important ACELP core parameters to the subdirectory "res/" */ /*#define DEBUG_MODE_TCX*/ /* output most important TCX core parameters to the subdirectory "res/" */ @@ -72,6 +72,7 @@ /*#define DEBUG_MODE_INFO_PLC */ /* define to output PLC related parameters */ /*#define DEBUG_MODE_INFO_ALLRAD*/ /* define to output generated HOA decoding mtx */ /*#define DEBUG_MODE_LFE */ /* define to output LFE relevant parameters */ +/*#define DEBUG_MODE_JBM */ /* define to output JBM relevant parameters */ #endif #ifdef DEBUG_MODE_MDCT diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index b99ef856e8..8a2de056b9 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -81,6 +81,9 @@ struct IVAS_DEC bool Opt_VOIP; /* flag indicating VOIP mode with JBM */ int16_t tsm_scale; /* scale for TSM operation */ int16_t tsm_max_scaling; +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + int16_t timeScalingDone; /* have we done already one TSM in a 20ms frame? */ +#endif #ifdef FIX_899_VARIABLE_SPEED_DECODING float tsm_quality; #endif @@ -174,6 +177,9 @@ ivas_error IVAS_DEC_Open( #ifdef FIX_899_VARIABLE_SPEED_DECODING hIvasDec->tsm_max_scaling = 0; hIvasDec->tsm_quality = 1.0f; +#endif +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + hIvasDec->timeScalingDone = 0; #endif hIvasDec->needNewFrame = false; hIvasDec->nTransportChannelsOld = 0; @@ -1134,19 +1140,26 @@ ivas_error IVAS_DEC_GetSamples( return IVAS_ERR_UNKNOWN; } assert( nTimeScalerOutSamples <= APA_BUF ); +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + hIvasDec->timeScalingDone = 1; +#endif } else { nTimeScalerOutSamples = hIvasDec->nSamplesFrame * nTransportChannels; } nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; - +#ifdef DEBUG_MODE_JBM + dbgwrite( &nTimeScalerOutSamples, sizeof( uint16_t ), 1, 1, "./res/JBM_nTimeScaleOutSamples.dat" ); +#endif /* render IVAS frames */ if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer ) ) != IVAS_ERR_OK ) { return error; } - +#ifdef DEBUG_MODE_JBM + dbgwrite( &nResidualSamples, sizeof( int16_t ), 1, 1, "./res/JBM_nResidualSamples.dat" ); +#endif if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) { /* feed residual samples to TSM for the next call */ @@ -2632,7 +2645,9 @@ ivas_error IVAS_DEC_VoIP_GetSamples( uint32_t extBufferedTime_ms, scale, maxScaling; JB4_DATAUNIT_HANDLE dataUnit; uint16_t extBufferedSamples; +#ifndef NONBE_FIX_864_JBM_RENDER_FRAMESIZE int16_t timeScalingDone; +#endif int16_t result; ivas_error error; int16_t nSamplesRendered; @@ -2641,7 +2656,9 @@ ivas_error IVAS_DEC_VoIP_GetSamples( st_ivas = hIvasDec->st_ivas; hDecoderConfig = st_ivas->hDecoderConfig; hVoIP = hIvasDec->hVoIP; +#ifndef NONBE_FIX_864_JBM_RENDER_FRAMESIZE timeScalingDone = 0; +#endif nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; nSamplesRendered = 0; @@ -2673,6 +2690,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( extBufferedTime_ms = extBufferedSamples * 1000 / hDecoderConfig->output_Fs; dataUnit = NULL; + /* pop one access unit from the jitter buffer */ result = JB4_PopDataUnit( hVoIP->hJBM, systemTimestamp_ms, extBufferedTime_ms, &dataUnit, &scale, &maxScaling ); if ( result != 0 ) @@ -2681,17 +2699,30 @@ ivas_error IVAS_DEC_VoIP_GetSamples( } maxScaling = maxScaling * hDecoderConfig->output_Fs / 1000; - /* avoid time scaling multiple times in one sound card slot */ +#ifdef DEBUG_MODE_JBM + dbgwrite( &extBufferedSamples, sizeof( uint16_t ), 1, 1, "./res/JBM_extBufferedSamples.dat" ); + dbgwrite( &systemTimestamp_ms, sizeof( uint32_t ), 1, 1, "./res/JBM_systemTimestamp.dat" ); + dbgwrite( &scale, sizeof( uint32_t ), 1, 1, "./res/JBM_scale.dat" ); + dbgwrite( &maxScaling, sizeof( uint32_t ), 1, 1, "./res/JBM_maxScale.dat" ); +#endif + + /* avoid time scaling multiple times within one 20ms frame*/ if ( scale != 100U ) { +#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE + if ( hIvasDec->timeScalingDone ) +#else if ( timeScalingDone ) +#endif { scale = 100; } +#ifndef NONBE_FIX_864_JBM_RENDER_FRAMESIZE else { timeScalingDone = 1; } +#endif } /* limit scale to range supported by time scaler */ @@ -2821,8 +2852,14 @@ static void update_voip_rendered20ms( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesRendered ) { - - hIvasDec->hVoIP->nSamplesRendered20ms = ( hIvasDec->hVoIP->nSamplesRendered20ms + nSamplesRendered ) % hIvasDec->hVoIP->nSamplesFrame; + 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; } #endif -- GitLab From bbe9444fbf616b9a881e2c59f673e3cf451466c0 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 24 Jan 2024 07:31:50 +0100 Subject: [PATCH 08/11] moved changes for the ISM BRIR rendering to explixit MR, connected to #968 --- lib_dec/ivas_ism_renderer.c | 144 +++++++++--------------------------- 1 file changed, 35 insertions(+), 109 deletions(-) diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 7d2c815386..94060ae8ef 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -254,161 +254,87 @@ void ivas_ism_render_sf( int16_t tc_offset; int16_t interp_offset; float gain, prev_gain; -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - int16_t ism_md_subframe_update_jbm, slots_to_render, first_sf, last_sf, subframe_idx; - int16_t n_samples_rendered_loop; -#endif num_objects = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { num_objects = st_ivas->nchan_ism; } -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ - slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, n_samples_to_render / st_ivas->hTcBuffer->n_samples_granularity ); - first_sf = st_ivas->hTcBuffer->subframes_rendered; - last_sf = first_sf; - n_samples_rendered_loop = 0; - while ( slots_to_render > 0 ) - { - slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf]; - last_sf++; - } - -#endif nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; tc_offset = st_ivas->hTcBuffer->n_samples_rendered; interp_offset = st_ivas->hTcBuffer->n_samples_rendered; -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - /* Number of subframes to delay metadata to sync with audio */ - if ( st_ivas->hDecoderConfig->Opt_delay_comp ) - { - ism_md_subframe_update_jbm = max( 0, st_ivas->hTcBuffer->nb_subframes - 3 ); - } - else - { - ism_md_subframe_update_jbm = st_ivas->hTcBuffer->nb_subframes - 2; - } -#endif for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) { set_f( output_f[i], 0.0f, n_samples_to_render ); } -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) - { - int16_t n_samples_in_subframe; - - n_samples_in_subframe = st_ivas->hTcBuffer->n_samples_granularity * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; -#endif - #ifdef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) #else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] ) #endif - { -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_in_subframe, n_samples_in_subframe, st_ivas->hIsmRendererData->interpolator ); -#else + { ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_to_render, n_samples_to_render, st_ivas->hIsmRendererData->interpolator ); -#endif - interp_offset = 0; - } + interp_offset = 0; + } - for ( i = 0; i < num_objects; i++ ) - { - /* Combined rotation: rotate the object positions depending the head and external orientations */ + for ( i = 0; i < num_objects; i++ ) + { + /* Combined rotation: rotate the object positions depending the head and external orientations */ #ifdef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) #else if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) #endif - { -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - if ( subframe_idx >= ism_md_subframe_update_jbm ) - { - rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); - } - else - { - rotateAziEle( st_ivas->hIsmMetaData[i]->last_azimuth, st_ivas->hIsmMetaData[i]->last_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); - } -#else + { rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[0], st_ivas->hIntSetup.is_planar_setup ); -#endif - if ( st_ivas->hEFAPdata != NULL ) - { - efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP ); - } + if ( st_ivas->hEFAPdata != NULL ) + { + efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP ); } + } - lfe_index = 0; - for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ ) + lfe_index = 0; + for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ ) + { + if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) ) { - if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) ) - { - ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++; - } + ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++; + } - gain = st_ivas->hIsmRendererData->gains[i][j]; - prev_gain = st_ivas->hIsmRendererData->prev_gains[i][j]; - if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f ) - { - g1 = &st_ivas->hIsmRendererData->interpolator[interp_offset]; - tc = &st_ivas->hTcBuffer->tc[i][tc_offset]; -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - for ( k = 0; k < n_samples_in_subframe; k++ ) -#else + gain = st_ivas->hIsmRendererData->gains[i][j]; + prev_gain = st_ivas->hIsmRendererData->prev_gains[i][j]; + if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f ) + { + g1 = &st_ivas->hIsmRendererData->interpolator[interp_offset]; + tc = &st_ivas->hTcBuffer->tc[i][tc_offset]; for ( k = 0; k < n_samples_to_render; k++ ) -#endif - { - g2 = 1.0f - *g1; -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - output_f[j2][k + n_samples_rendered_loop] += ( *( g1++ ) * gain + g2 * prev_gain ) * *( tc++ ); -#else + { + g2 = 1.0f - *g1; output_f[j2][k] += ( *( g1++ ) * gain + g2 * prev_gain ) * *( tc++ ); -#endif - } } + } - /* update here only in case of head rotation */ + /* update here only in case of head rotation */ #ifdef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) #else if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) #endif - { - st_ivas->hIsmRendererData->prev_gains[i][j] = gain; - } + { + st_ivas->hIsmRendererData->prev_gains[i][j] = gain; } } + } #ifdef NONBE_UNIFIED_DECODING_PATHS - /* update combined orientation access index */ -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_in_subframe ); -#else - ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_to_render ); -#endif -#endif -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE - n_samples_rendered_loop += n_samples_in_subframe; - if ( st_ivas->renderer_type == RENDERER_TD_PANNING ) - { - st_ivas->hTcBuffer->subframes_rendered += 1; - st_ivas->hTcBuffer->slots_rendered += st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; - } - tc_offset += n_samples_in_subframe; - interp_offset += n_samples_in_subframe; - } + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_to_render ); #endif return; -- GitLab From e80cfb8a921ec991ac4226cb9177c255125a5157 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 15 Feb 2024 12:58:01 +0100 Subject: [PATCH 09/11] in new code accept an already accepted switch (namely NONBE_UNIFIED_DECODING_PATHS) --- apps/decoder.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index d28a0e9a35..3af33307ff 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -3443,9 +3443,7 @@ static ivas_error decodeVoIP( } } -#ifdef NONBE_UNIFIED_DECODING_PATHS vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; -#endif frame++; if ( !arg.quietModeEnabled ) { @@ -3458,7 +3456,6 @@ static ivas_error decodeVoIP( #endif } -#ifdef NONBE_UNIFIED_DECODING_PATHS /* reference vector */ if ( arg.enableReferenceVectorTracking && vec_pos_update == 0 ) { @@ -3577,8 +3574,6 @@ static ivas_error decodeVoIP( } } } -#endif - } while ( nSamplesFlushed > 0 ); #endif -- GitLab From 7976c073b0ae75717d19780df0de913f04ade2aa Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 21 Feb 2024 07:31:58 +0100 Subject: [PATCH 10/11] fix for #864, fix JBM for 5ms, address comments, simplify flushing for JBM --- apps/decoder.c | 157 ++++--------------------------------------------- 1 file changed, 12 insertions(+), 145 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 3af33307ff..f712cdb80b 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -3360,10 +3360,10 @@ static ivas_error decodeVoIP( #ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE if ( vec_pos_update == 0 ) { -#endif systemTime_ms += vec_pos_len * systemTimeInc_ms; -#ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE } +#else + systemTime_ms += systemTimeInc_ms; #endif #ifdef WMOPS @@ -3376,20 +3376,19 @@ static ivas_error decodeVoIP( #ifdef NONBE_FIX_864_JBM_RENDER_FRAMESIZE int16_t nSamplesFlushed = 0; - do - { - - /* decode and get samples */ + /* decode and get samples */ #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) #else - if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) #endif - { - fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } + { + fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + if ( nSamplesFlushed ) + { /* Write current frame */ if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, nSamplesFlushed * nOutChannels ) ) != IVAS_ERR_OK ) { @@ -3442,139 +3441,7 @@ static ivas_error decodeVoIP( } } } - - vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; - frame++; - if ( !arg.quietModeEnabled ) - { - fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); -#ifdef DEBUGGING - if ( IVAS_DEC_GetBerDetectFlag( hIvasDec ) ) - { - fprintf( stdout, "\n Decoding error: BER detected in frame %d !!!!!\n", frame - 1 ); - } -#endif - } - - /* reference vector */ - if ( arg.enableReferenceVectorTracking && vec_pos_update == 0 ) - { - IVAS_VECTOR3 listenerPosition, referencePosition; - if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPosition, &referencePosition ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError %s while reading listener and reference positions from %s\n", IVAS_DEC_GetErrorMessage( error ), Vector3PairFileReader_getFilePath( referenceVectorReader ) ); - goto cleanup; - } - - if ( ( error = IVAS_DEC_FeedRefVectorData( hIvasDec, listenerPosition, referencePosition ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_FeedRefVectorData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } - } - - /* Reference rotation */ - if ( arg.enableReferenceRotation && vec_pos_update == 0 ) - { - IVAS_QUATERNION quaternion; - if ( ( error = HeadRotationFileReading( refRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError %s while reading reference rotation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( refRotReader ) ); - goto cleanup; - } - - if ( ( error = IVAS_DEC_FeedRefRotData( hIvasDec, quaternion ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_FeedRefRotData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } - } - int16_t num_subframes; - if ( ( error = IVAS_DEC_GetNumOrientationSubframes( hIvasDec, &num_subframes ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_GetNumOrientationSubframes failed: \n" ); - goto cleanup; - } - - /* Head-tracking input simulation */ - /* Head-tracking input simulation */ - if ( arg.enableHeadRotation ) - { - IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( headRotReader == NULL ) - { - for ( i = 0; i < num_subframes; i++ ) - { - Quaternions[i].w = -3.0f; - Quaternions[i].x = 0.0f; - Quaternions[i].y = 0.0f; - Quaternions[i].z = 0.0f; - Pos[i].x = 0.0f; - Pos[i].y = 0.0f; - Pos[i].z = 0.0f; - } - } - else - { -#endif - for ( i = 0; i < num_subframes; i++ ) - { - if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), - RotationFileReader_getFilePath( headRotReader ) ); - goto cleanup; - } - } -#ifdef SPLIT_REND_WITH_HEAD_ROT - } -#endif - - for ( i = 0; i < num_subframes; i++ ) - { - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i -#ifdef SPLIT_REND_WITH_HEAD_ROT - , - DEFAULT_AXIS -#endif - ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } - } - } - - if ( arg.enableExternalOrientation ) - { - IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - int8_t enableHeadRotation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - int8_t enableExternalOrientation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - int8_t enableRotationInterpolation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - int16_t numFramesToTargetOrientation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - - for ( i = 0; i < num_subframes; i++ ) - { - - if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &Quaternions[i], &enableHeadRotation[i], &enableExternalOrientation[i], &enableRotationInterpolation[i], &numFramesToTargetOrientation[i] ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError %s while reading external orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), - RotationFileReader_getFilePath( externalOrientationFileReader ) ); - goto cleanup; - } - } - for ( i = 0; i < num_subframes; i++ ) - { - if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternions[i], enableHeadRotation[i], enableExternalOrientation[i], enableRotationInterpolation[i], numFramesToTargetOrientation[i], i ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } - } - } - } while ( nSamplesFlushed > 0 ); + } #endif /*------------------------------------------------------------------------------------------* -- GitLab From 527d79bf04e136a5bbfedb3c4b29218b5163dbb7 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 21 Feb 2024 08:07:19 +0100 Subject: [PATCH 11/11] #fix for 864, incorporate fix for #984 --- apps/decoder.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/decoder.c b/apps/decoder.c index 0bc42dd920..10a8ce2370 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -3496,13 +3496,28 @@ static ivas_error decodeVoIP( if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM ) { IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; +#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT + int16_t fullDelayNumSamples[3]; + float delayMs; + + /* delayNumSamples is zeroed, and delayNumSamples_orig is updated only on first good frame, so need to re-fetch delay info */ + if ( ( error = IVAS_DEC_GetDelay( hIvasDec, fullDelayNumSamples, &delayTimeScale ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) ); + } +#endif if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } +#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT + delayMs = (float) ( fullDelayNumSamples[0] ) / (float) ( delayTimeScale ); + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta, &delayMs ) ) != IVAS_ERR_OK ) +#else if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); goto cleanup; -- GitLab