From 3a9743d05de925224ac0cda0453434498fd5b263 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 14 Jun 2023 07:11:37 +0200 Subject: [PATCH 01/66] 5ms API first step, not completely BE yet --- apps/decoder.c | 795 ++++++++++++++++--- lib_com/ivas_error.h | 5 + lib_com/options.h | 3 + lib_dec/ivas_binRenderer_internal.c | 8 + lib_dec/ivas_dirac_dec.c | 24 +- lib_dec/ivas_init_dec.c | 11 +- lib_dec/ivas_ism_dec.c | 5 +- lib_dec/ivas_ism_param_dec.c | 37 +- lib_dec/ivas_ism_renderer.c | 32 + lib_dec/ivas_jbm_dec.c | 76 +- lib_dec/ivas_masa_dec.c | 6 + lib_dec/ivas_mc_param_dec.c | 14 +- lib_dec/ivas_mct_dec.c | 5 +- lib_dec/ivas_objectRenderer_internal.c | 13 +- lib_dec/ivas_sba_dec.c | 6 +- lib_dec/ivas_spar_decoder.c | 4 + lib_dec/ivas_stat_dec.h | 4 + lib_dec/lib_dec.c | 691 ++++++++++++++-- lib_dec/lib_dec.h | 37 +- lib_rend/ivas_crend.c | 8 + lib_rend/ivas_dirac_dec_binaural_functions.c | 12 + lib_rend/ivas_objectRenderer.c | 4 + lib_rend/ivas_rotation.c | 14 + lib_rend/ivas_stat_rend.h | 5 + lib_rend/lib_rend.c | 14 +- 25 files changed, 1632 insertions(+), 201 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 7ceda8f6f3..5113b8e242 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -85,6 +85,9 @@ static #ifdef JBM_TSM_ON_TCS #define JBM_FRONTEND_FETCH_FRAMESIZE_MS 20 #endif +#ifdef API_5MS +#define HEADROTATION_FETCH_FRAMESIZE_MS 5 +#endif typedef struct { @@ -121,7 +124,9 @@ typedef struct bool renderConfigEnabled; char *renderConfigFilename; IVAS_DEC_COMPLEXITY_LEVEL complexityLevel; - +#ifdef API_5MS + bool tsmEnabled; +#endif #ifdef DEBUGGING IVAS_DEC_FORCED_REND_MODE forcedRendMode; #ifdef DEBUG_FOA_AGC @@ -131,7 +136,9 @@ typedef struct bool noBadFrameDelay; #endif #ifdef VARIABLE_SPEED_DECODING +#ifndef API_5MS bool variableSpeedMode; +#endif bool tsmScaleFileEnabled; char *tsmScaleFileName; uint16_t tsmScale; @@ -388,7 +395,11 @@ int main( *------------------------------------------------------------------------------------------*/ #ifdef FIX_356_ISM_METADATA_SYNC #ifdef FIX_439_OTR_PARAMS +#ifdef API_5MS + if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.tsmEnabled, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#endif #else if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) #endif @@ -412,12 +423,17 @@ int main( if ( arg.voipMode ) { +#ifdef API_5MS + if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, IVAS_DEC_VOIP_MODE_VOIP, 100, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nCould not enable VOIP: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } } +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING #ifdef DEBUGGING else if ( arg.variableSpeedMode ) @@ -431,6 +447,7 @@ int main( #endif #endif #endif +#endif #ifdef DEBUGGING /*-----------------------------------------------------------------* @@ -465,7 +482,11 @@ int main( #ifdef VARIABLE_SPEED_DECODING #ifdef DEBUGGING +#ifdef API_5MS + if ( arg.tsmEnabled ) +#else if ( arg.variableSpeedMode ) +#endif { if ( arg.tsmScaleFileEnabled ) { @@ -671,6 +692,7 @@ int main( #endif error = decodeVoIP( arg, hBsReader, hIvasDec ); } +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING #ifdef DEBUGGING else if ( arg.variableSpeedMode ) @@ -678,6 +700,7 @@ int main( error = decodeVariableSpeed( arg, hBsReader, headRotReader, refRotReader, referenceVectorReader, hIvasDec ); } #endif +#endif #endif else { @@ -913,10 +936,14 @@ static bool parseCmdlIVAS_dec( arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192; arg->Opt_non_diegetic_pan = 0; arg->non_diegetic_pan_gain = 0.f; - +#ifdef API_5MS + arg->tsmEnabled = false; +#endif #ifdef DEBUGGING #ifdef VARIABLE_SPEED_DECODING +#ifndef API_5MS arg->variableSpeedMode = false; +#endif arg->tsmScale = 100; arg->tsmScaleFileEnabled = false; arg->tsmScaleFileName = NULL; @@ -1067,7 +1094,11 @@ static bool parseCmdlIVAS_dec( { i++; int32_t tmp = 100; +#ifdef API_5MS + arg->tsmEnabled = true; +#else arg->variableSpeedMode = true; +#endif if ( i < argc - 3 ) { if ( !is_digits_only( argv[i] ) ) @@ -1626,7 +1657,7 @@ static ivas_error initOnFirstGoodFrame( * * Read G.192 bitstream and decode in regular decoder *---------------------------------------------------------------------*/ - +#ifdef API_5MS static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, @@ -1650,20 +1681,58 @@ static ivas_error decodeG192( int16_t numInitialBadFrames = 0; /* Number of bad frames received until first good frame is decoded */ int16_t nOutChannels = 0; int16_t delayNumSamples = -1; - int16_t delayNumSamples_orig[3]; /* stores: overall delay, dec+rend delay, and binauralization delay */ + int16_t delayNumSamples_orig[3]; int16_t nOutSamples = 0; int32_t delayTimeScale = 0; ivas_error error = IVAS_ERR_UNKNOWN; uint16_t numObj = 0; IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; - IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - + uint16_t nSamplesAvailableNext; + bool needNewFrame; + int16_t nSamplesRendered, nSamplesRendered_loop, nSamplesToRender; +#ifdef DEBUGGING +#ifdef VARIABLE_SPEED_DECODING + TsmScaleFileReader *tsmScaleFileReader = NULL; + int16_t scale; +#endif +#endif IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; + IVAS_VECTOR3 Pos; + int16_t vec_pos_update, vec_pos_len; + + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { ismWriters[i] = NULL; } + /* we always start with needing a new frame */ + needNewFrame = true; + +#ifdef DEBUGGING +#ifdef VARIABLE_SPEED_DECODING + /*------------------------------------------------------------------------------------------* + * Open TSM scale file or set global TSM scale + *------------------------------------------------------------------------------------------*/ + + if ( arg.tsmEnabled ) + { + if ( arg.tsmScaleFileEnabled ) + { + if ( ( tsmScaleFileReader = TsmScaleFileReader_open( arg.tsmScaleFileName ) ) == NULL ) + { + fprintf( stderr, "\nError: Can't open TSM scale file %s \n\n", arg.tsmScaleFileName ); + goto cleanup; + } + } + else + { + IVAS_DEC_VoIP_SetScale( hIvasDec, arg.tsmScale, arg.tsmScale ); + } + } +#endif +#endif + if ( !arg.quietModeEnabled ) { fprintf( stdout, "\n------ Running the decoder ------\n\n" ); @@ -1680,7 +1749,19 @@ static ivas_error decodeG192( reset_stack(); reset_wmops(); #endif + nSamplesAvailableNext = 0; + vec_pos_update = 0; + if ( arg.enableHeadRotation ) + { + nOutSamples = (int16_t) ( arg.output_Fs / 1000 * HEADROTATION_FETCH_FRAMESIZE_MS ); + vec_pos_len = IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; + } + else + { + nOutSamples = (int16_t) ( arg.output_Fs / 1000 * VARIABLE_SPEED_FETCH_FRAMESIZE_MS ); + vec_pos_len = 1; + } /*------------------------------------------------------------------------------------------* * Loop for every packet (frame) of bitstream data * - Read the bitstream packet @@ -1690,42 +1771,10 @@ static ivas_error decodeG192( while ( 1 ) { - /* Read next frame */ - if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) - { - if ( error == IVAS_ERR_END_OF_FILE ) - { - break; - } - fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); - goto cleanup; - } - -#ifdef DEBUGGING - /* Random FEC simulation */ - if ( arg.FER > 0.0f ) - { - float ftmp = (float) app_own_random( &fec_seed ) + 32768.0f; - if ( ftmp <= arg.FER / 100.0f * 65535.0f ) - { - bfi = 1; - } - else - { - bfi = 0; - } - } -#endif - - /* Feed into decoder */ - if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, bit_stream, num_bits, bfi ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError: could not feed frame to decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } + /* Read next frame if not enough samples availble */ /* reference vector */ - if ( arg.enableReferenceVectorTracking ) + if ( arg.enableReferenceVectorTracking && vec_pos_update == 0 ) { IVAS_VECTOR3 listenerPosition, referencePosition; if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPosition, &referencePosition ) ) != IVAS_ERR_OK ) @@ -1740,8 +1789,9 @@ static ivas_error decodeG192( goto cleanup; } } + /* Reference rotation */ - if ( arg.enableReferenceRotation ) + if ( arg.enableReferenceRotation && vec_pos_update == 0 ) { IVAS_QUATERNION quaternion; if ( ( error = HeadRotationFileReading( refRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) @@ -1756,31 +1806,95 @@ static ivas_error decodeG192( goto cleanup; } } + /* Head-tracking input simulation */ if ( arg.enableHeadRotation ) { - IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_QUATERNION Quaternion; - for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos ) ) != IVAS_ERR_OK ) { - 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 ), HeadRotationFileReader_getFilePath( headRotReader ) ); - goto cleanup; - } + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), HeadRotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; } - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos ) ) != IVAS_ERR_OK ) + + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } } - /* Run decoder for one frame (get rendered output) */ - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, pcmBuf, &nOutSamples ) ) != IVAS_ERR_OK ) + + /* decode and get samples */ + nSamplesRendered = 0; + nSamplesToRender = nOutSamples; + do { - fprintf( stderr, "\nError: could not get samples from decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; + if ( needNewFrame ) + { +#ifdef DEBUGGING +#ifdef VARIABLE_SPEED_DECODING + if ( arg.tsmScaleFileEnabled ) + { + if ( ( error = TsmScaleFileReader_readScale( tsmScaleFileReader, &scale ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); + goto cleanup; + } + IVAS_DEC_VoIP_SetScale( hIvasDec, scale, scale ); + } +#endif +#endif + + if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) + { + if ( error == IVAS_ERR_END_OF_FILE ) + { + break; + } + fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); + goto cleanup; + } + +#ifdef DEBUGGING + /* Random FEC simulation */ + if ( arg.FER > 0.0f ) + { + float ftmp = (float) app_own_random( &fec_seed ) + 32768.0f; + if ( ftmp <= arg.FER / 100.0f * 65535.0f ) + { + bfi = 1; + } + else + { + bfi = 0; + } + } +#endif + + /* Feed into decoder */ + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, bit_stream, num_bits, bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not feed frame to decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nOutChannels * nSamplesRendered, &nSamplesRendered_loop, &needNewFrame ); + nSamplesRendered += nSamplesRendered_loop; + nSamplesToRender -= nSamplesRendered_loop; + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + + } while ( nSamplesRendered < nOutSamples && error == IVAS_ERR_OK ); + + if ( error == IVAS_ERR_END_OF_FILE ) + { + break; } /* Continue checking for first good frame until it is found */ @@ -1838,7 +1952,7 @@ static ivas_error decodeG192( } } - /* Write ISM metadata to external file(s) */ + /* Write ISm metadata to external file(s) */ if ( decodedGoodFrame && arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) { if ( bsFormat == IVAS_DEC_BS_OBJ ) @@ -1884,6 +1998,7 @@ static ivas_error decodeG192( } frame++; + vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; if ( !arg.quietModeEnabled ) { fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); @@ -1895,77 +2010,552 @@ static ivas_error decodeG192( #endif } #ifdef WMOPS - update_mem(); update_wmops(); +#ifdef MEM_COUNT_DETAILS + export_mem( "mem_analysis.csv" ); +#endif #endif } - /*------------------------------------------------------------------------------------------* - * Add zeros at the end to have equal length of synthesized signals - *------------------------------------------------------------------------------------------*/ - - memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); - - if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); - goto cleanup; - } /*------------------------------------------------------------------------------------------* - * Printouts after decoding has finished + * Flush what is still left in the VoIP Buffers.... *------------------------------------------------------------------------------------------*/ - if ( !arg.quietModeEnabled ) + while ( nSamplesAvailableNext > 0 ) { - printf( "\n\nDecoder+renderer delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[1] / (float) delayTimeScale, delayNumSamples_orig[1], delayTimeScale ); + int16_t nSamplesFlushed; - if ( delayNumSamples_orig[2] > 0 ) - { - printf( "HRIR/BRIR delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[2] / (float) delayTimeScale, delayNumSamples_orig[2], delayTimeScale ); - printf( "Total delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * ( delayNumSamples_orig[1] + delayNumSamples_orig[2] ) / (float) delayTimeScale, delayNumSamples_orig[1] + delayNumSamples_orig[2], delayTimeScale ); - } - } + /* Feed into decoder */ - /* Print output metadata file name(s) */ - if ( arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) - { - if ( bsFormat == IVAS_DEC_BS_OBJ ) + /* reference vector */ + if ( arg.enableReferenceVectorTracking ) { - for ( i = 0; i < numObj; i++ ) + IVAS_VECTOR3 listenerPosition, referencePosition; + if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPosition, &referencePosition ) ) != IVAS_ERR_OK ) { - fprintf( stdout, "\nOutput metadata file: %s", IsmFileWriter_getFilePath( ismWriters[i] ) ); + 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; } - fprintf( stdout, "\n" ); } - else if ( bsFormat == IVAS_DEC_BS_MASA ) + /* Reference rotation */ + if ( arg.enableReferenceRotation ) { - fprintf( stdout, "\nOutput metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); - } - } + 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 ), HeadRotationFileReader_getFilePath( refRotReader ) ); + goto cleanup; + } - /*------------------------------------------------------------------------------------------* - * Close files and deallocate resources - *------------------------------------------------------------------------------------------*/ + 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; - decodingFailed = false; /* This will stay set to true if cleanup is reached via a goto due to an error */ -cleanup: + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), HeadRotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } - AudioFileWriter_close( &afWriter ); - MasaFileWriter_close( &masaWriter ); - for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) - { - IsmFileWriter_close( &ismWriters[i] ); - } - if ( decodingFailed && error == IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* decode and get samples */ + if ( ( error = IVAS_DEC_VoIP_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesAvailableNext, &nSamplesFlushed ) ) != IVAS_ERR_OK ) + { + 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.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + 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; + } + } + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != 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; + } + } + } + + 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 + } + } + + /*------------------------------------------------------------------------------------------* + * Printouts after decoding has finished + *------------------------------------------------------------------------------------------*/ + + if ( !arg.quietModeEnabled ) + { + printf( "\n\nDecoder+renderer delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[1] / (float) delayTimeScale, delayNumSamples_orig[1], delayTimeScale ); + + if ( delayNumSamples_orig[2] > 0 ) + { + printf( "HRIR/BRIR delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[2] / (float) delayTimeScale, delayNumSamples_orig[2], delayTimeScale ); + printf( "Total delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * ( delayNumSamples_orig[1] + delayNumSamples_orig[2] ) / (float) delayTimeScale, delayNumSamples_orig[1] + delayNumSamples_orig[2], delayTimeScale ); + } + } + + /* Print output metadata file name(s) */ + if ( arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + for ( i = 0; i < numObj; i++ ) + { + fprintf( stdout, "\nOutput metadata file: %s", IsmFileWriter_getFilePath( ismWriters[i] ) ); + } + fprintf( stdout, "\n" ); + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + fprintf( stdout, "\nOutput metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); + } + } + + /* add zeros at the end to have equal length of synthesized signals */ + memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } + + /*------------------------------------------------------------------------------------------* + * Close files and deallocate resources + *------------------------------------------------------------------------------------------*/ + + decodingFailed = false; /* This will stay set to true if cleanup is reached via a goto due to an error */ + +cleanup: + + AudioFileWriter_close( &afWriter ); + MasaFileWriter_close( &masaWriter ); + TsmScaleFileReader_close( &tsmScaleFileReader ); + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) + { + IsmFileWriter_close( &ismWriters[i] ); + } + + if ( decodingFailed && error == IVAS_ERR_OK ) + { + return IVAS_ERR_UNKNOWN; + } + + return error; +} +#else +static ivas_error decodeG192( + DecArguments arg, + BS_READER_HANDLE hBsReader, + HeadRotFileReader *headRotReader, + HeadRotFileReader *refRotReader, + Vector3PairFileReader *referenceVectorReader, + IVAS_DEC_HANDLE hIvasDec, + int16_t *pcmBuf ) + +{ + bool decodingFailed = true; /* Assume failure until cleanup is reached without errors */ + uint16_t bit_stream[IVAS_MAX_BITS_PER_FRAME + 4 * 8]; + int16_t i, num_bits; + int16_t bfi = 0; +#ifdef DEBUGGING + int16_t fec_seed = 12558; /* FEC_SEED */ +#endif + AudioFileWriter *afWriter = NULL; + MasaFileWriter *masaWriter = NULL; + bool decodedGoodFrame = false; + int16_t numInitialBadFrames = 0; /* Number of bad frames received until first good frame is decoded */ + int16_t nOutChannels = 0; + int16_t delayNumSamples = -1; + int16_t delayNumSamples_orig[3]; /* stores: overall delay, dec+rend delay, and binauralization delay */ + int16_t nOutSamples = 0; + int32_t delayTimeScale = 0; + ivas_error error = IVAS_ERR_UNKNOWN; + uint16_t numObj = 0; + IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + + IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) + { + ismWriters[i] = NULL; + } + + if ( !arg.quietModeEnabled ) + { + fprintf( stdout, "\n------ Running the decoder ------\n\n" ); + fprintf( stdout, "Frames processed: " ); + } + else + { + fprintf( stdout, "\n-- Start the decoder (quiet mode) --\n\n" ); + } + + delayNumSamples_orig[0] = -1; + +#ifdef WMOPS + reset_stack(); + reset_wmops(); +#endif + + /*------------------------------------------------------------------------------------------* + * Loop for every packet (frame) of bitstream data + * - Read the bitstream packet + * - Run the decoder + * - Write the synthesized signal into output file + *------------------------------------------------------------------------------------------*/ + + while ( 1 ) + { + /* Read next frame */ + if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) + { + if ( error == IVAS_ERR_END_OF_FILE ) + { + break; + } + fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); + goto cleanup; + } + +#ifdef DEBUGGING + /* Random FEC simulation */ + if ( arg.FER > 0.0f ) + { + float ftmp = (float) app_own_random( &fec_seed ) + 32768.0f; + if ( ftmp <= arg.FER / 100.0f * 65535.0f ) + { + bfi = 1; + } + else + { + bfi = 0; + } + } +#endif + + /* Feed into decoder */ + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, bit_stream, num_bits, bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not feed frame to decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + /* 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 ), HeadRotationFileReader_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 Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_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 ), HeadRotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + } + + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + /* Run decoder for one frame (get rendered output) */ + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, pcmBuf, &nOutSamples ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not get samples from decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + /* Continue checking for first good frame until it is found */ + if ( !decodedGoodFrame ) + { + if ( ( error = IVAS_DEC_HasDecodedFirstGoodFrame( hIvasDec, &decodedGoodFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_HasDecodedFirstGoodFrame, code: %d\n", error ); + goto cleanup; + } + + /* Once good frame decoded, catch up */ + if ( decodedGoodFrame ) + { + error = initOnFirstGoodFrame( + hIvasDec, + arg, + numInitialBadFrames, + nOutSamples, + delayNumSamples_orig, + &delayNumSamples, + &delayTimeScale, + &bsFormat, + &afWriter, + &masaWriter, + ismWriters, + &nOutChannels, + &numObj ); + if ( error != IVAS_ERR_OK ) + { + goto cleanup; + } + } + else + { + ++numInitialBadFrames; + } + } + + /* Write current frame */ + if ( decodedGoodFrame ) + { + if ( delayNumSamples < nOutSamples ) + { + if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + goto cleanup; + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= nOutSamples; + } + } + + /* Write ISM metadata to external file(s) */ + if ( decodedGoodFrame && arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + 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; + } + } + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != 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; + } + } + } + + 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 + } +#ifdef WMOPS + update_mem(); + update_wmops(); +#endif + } + + /*------------------------------------------------------------------------------------------* + * Add zeros at the end to have equal length of synthesized signals + *------------------------------------------------------------------------------------------*/ + + memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); + + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } + + /*------------------------------------------------------------------------------------------* + * Printouts after decoding has finished + *------------------------------------------------------------------------------------------*/ + + if ( !arg.quietModeEnabled ) + { + printf( "\n\nDecoder+renderer delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[1] / (float) delayTimeScale, delayNumSamples_orig[1], delayTimeScale ); + + if ( delayNumSamples_orig[2] > 0 ) + { + printf( "HRIR/BRIR delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[2] / (float) delayTimeScale, delayNumSamples_orig[2], delayTimeScale ); + printf( "Total delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * ( delayNumSamples_orig[1] + delayNumSamples_orig[2] ) / (float) delayTimeScale, delayNumSamples_orig[1] + delayNumSamples_orig[2], delayTimeScale ); + } + } + + /* Print output metadata file name(s) */ + if ( arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + for ( i = 0; i < numObj; i++ ) + { + fprintf( stdout, "\nOutput metadata file: %s", IsmFileWriter_getFilePath( ismWriters[i] ) ); + } + fprintf( stdout, "\n" ); + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + fprintf( stdout, "\nOutput metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); + } + } + + /*------------------------------------------------------------------------------------------* + * Close files and deallocate resources + *------------------------------------------------------------------------------------------*/ + + decodingFailed = false; /* This will stay set to true if cleanup is reached via a goto due to an error */ + +cleanup: + + AudioFileWriter_close( &afWriter ); + MasaFileWriter_close( &masaWriter ); + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) + { + IsmFileWriter_close( &ismWriters[i] ); + } + + if ( decodingFailed && error == IVAS_ERR_OK ) { return IVAS_ERR_UNKNOWN; } return error; } +#endif #ifdef DEBUGGING /*---------------------------------------------------------------------* @@ -2241,9 +2831,11 @@ static ivas_error decodeVoIP( while ( 1 ) { int16_t nOutSamples = 0; +#ifndef API_5MS #if defined( JBM_TSM_ON_TCS ) || defined( VARIABLE_SPEED_DECODING ) uint16_t nSamplesAvailableNext = 0; #endif +#endif #ifdef JBM_TSM_ON_TCS #ifdef DEBUG_JBM_CMD_OPTION nOutSamples = (int16_t) ( arg.output_Fs / 1000 * arg.frontendFetchSizeMs ); @@ -2309,10 +2901,12 @@ static ivas_error decodeVoIP( /* decode and get samples */ if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms +#ifndef API_5MS #if defined( JBM_TSM_ON_TCS ) || defined( VARIABLE_SPEED_DECODING ) , &nSamplesAvailableNext #endif +#endif #ifdef SUPPORT_JBM_TRACEFILE , writeJbmTraceFileFrameWrapper, @@ -2522,6 +3116,7 @@ cleanup: #ifdef DEBUGGING +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING /*---------------------------------------------------------------------* * decodeVariableSpeed() @@ -2694,7 +3289,7 @@ static ivas_error decodeVariableSpeed( fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); goto cleanup; } - IVAS_DEC_VoIP_SetScale( hIvasDec, scale ); + IVAS_DEC_VoIP_SetScale( hIvasDec, scale, scale ); } if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) @@ -3057,7 +3652,7 @@ cleanup: return error; } #endif - +#endif /*---------------------------------------------------------------------* * parseForcedRendModeDec() diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 56e09c558d..c444553021 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -93,6 +93,11 @@ typedef enum #ifdef VARIABLE_SPEED_DECODING IVAS_ERR_VS_FRAME_NEEDED, #endif +#ifdef API_5MS + IVAS_ERR_TSM_NOT_ENABLED, + IVAS_ERR_FETCH_SIZE_NO_MULTIPLE_OF_5MS, + IVAS_ERR_NEED_NEW_FRAME, +#endif #endif /*----------------------------------------* diff --git a/lib_com/options.h b/lib_com/options.h index 42d6a6a471..85195e86cc 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -227,6 +227,9 @@ #define FIX_170_DTX_MASA /* Nokia: Fix issue 170, relaxing the use of DTX in MASA format */ #define FIX_510 /* FhG: fix issue 510, misleading error message for invalid input format */ #define FIX_509 /* FhG: fix issue 509, too low number of bitsream indices in SBA */ +#define FIX_XXX_JITTER_SBA_BINAURAL_GAIN + +#define API_5MS /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 240205706f..2cea0226c5 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1221,14 +1221,22 @@ void ivas_binRenderer( } /* Head rotation in HOA3 or CICPx */ +#ifdef API_5MS + if ( hHeadTrackData && hBinRenderer->rotInCldfb ) +#else if ( hHeadTrackData && hHeadTrackData->num_quaternions >= 0 && hBinRenderer->rotInCldfb ) +#endif { if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) { /* Rotation in SHD (HOA3) */ if ( hHeadTrackData->shd_rot_max_order == -1 ) { +#ifdef API_5MS + QuatToRotMat( hHeadTrackData->Quaternion, hHeadTrackData->Rmat ); +#else QuatToRotMat( hHeadTrackData->Quaternions[hHeadTrackData->num_quaternions++], hHeadTrackData->Rmat ); +#endif #ifdef JBM_TSM_ON_TCS rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hHeadTrackData->Rmat, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); #else diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 502420781f..8ab712b762 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1166,7 +1166,11 @@ ivas_error ivas_dirac_dec_config( /* allocate transport channels*/ if ( flag_config == DIRAC_OPEN ) { +#ifdef API_5MS + if ( st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) +#endif { #ifndef SBA_MODE_CLEAN_UP if ( st_ivas->sba_mode == SBA_MODE_DIRAC ) @@ -2592,12 +2596,12 @@ void ivas_dirac_dec( *------------------------------------------------------------------------*/ void ivas_dirac_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t nchan_transport, /* i : number of transport channels */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ ) { int16_t slots_to_render, first_sf, last_sf, subframe_idx; @@ -2653,7 +2657,7 @@ void ivas_dirac_dec_render( } } - *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; + *nSamplesAvailableNext = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; return; } @@ -2888,7 +2892,11 @@ void ivas_dirac_dec_render_sf( if ( st_ivas->hHeadTrackData ) #endif { - QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[st_ivas->hHeadTrackData->num_quaternions++], st_ivas->hHeadTrackData->Rmat ); +#ifdef API_5MS + QuatToRotMat( st_ivas->hHeadTrackData->Quaternion, st_ivas->hHeadTrackData->Rmat ); +#else + QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[st_ivas->hHeadTrackData->num_quaternions++], st_ivas->hHeadTrackData->Rmat ); +#endif p_Rmat = &st_ivas->hHeadTrackData->Rmat[0][0]; diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index b232078417..d696217825 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1367,7 +1367,9 @@ ivas_error ivas_init_decoder( } #ifdef JBM_TSM_ON_TCS +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active ) +#endif { granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -1412,7 +1414,9 @@ ivas_error ivas_init_decoder( st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; #ifdef JBM_TSM_ON_TCS +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active ) +#endif { granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -1522,8 +1526,11 @@ ivas_error ivas_init_decoder( /*-----------------------------------------------------------------* * Allocate and initialize JBM struct + buffer *-----------------------------------------------------------------*/ - +#ifdef API_5MS + if ( st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hDecoderConfig->voip_active && st_ivas->hTcBuffer == NULL ) +#endif { /* no module has yet open the TC buffer, open a default one */ n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -1534,6 +1541,7 @@ ivas_error ivas_init_decoder( } } +#ifndef API_5MS if ( st_ivas->hTcBuffer == NULL ) { /* we need the handle anyway, but without the buffer*/ @@ -1542,6 +1550,7 @@ ivas_error ivas_init_decoder( return error; } } +#endif #endif return error; diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index fe98ca0dcb..59baa05d9b 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -130,7 +130,9 @@ static ivas_error ivas_ism_bitrate_switching( } #ifdef JBM_TSM_ON_TCS +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active ) +#endif { /* transfer subframe info from DirAC or ParamMC to central tc buffer */ if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hDirAC != NULL && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) ) @@ -331,8 +333,9 @@ static ivas_error ivas_ism_bitrate_switching( /*-----------------------------------------------------------------* * Reconfigure TC buffer *-----------------------------------------------------------------*/ - +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active == 1 ) +#endif { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index da4ce92107..f782e32460 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -648,7 +648,11 @@ ivas_error ivas_param_ism_dec_open( { /* Initialize Param ISM Rendering handle */ #ifdef JBM_TSM_ON_TCS +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) +#else if ( st_ivas->hDecoderConfig->voip_active ) +#endif { if ( ( error = ivas_param_ism_rendering_init( hDirAC->hParamIsmRendering, hOutSetup, st_ivas->nchan_transport, MAX_JBM_CLDFB_TIMESLOTS, output_config ) ) != IVAS_ERR_OK ) { @@ -710,7 +714,9 @@ ivas_error ivas_param_ism_dec_open( st_ivas->hDirAC = hDirAC; #ifdef JBM_TSM_ON_TCS +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active ) +#endif { if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) { @@ -724,7 +730,31 @@ ivas_error ivas_param_ism_dec_open( } else { +#ifdef API_5MS + int16_t n_slots_to_alloc; + if ( st_ivas->hDecoderConfig->tsm_active == 1 ) + { + n_slots_to_alloc = MAX_JBM_CLDFB_TIMESLOTS; + } + else + { + n_slots_to_alloc = CLDFB_SLOTS_PER_SUBFRAME * MAX_PARAM_SPATIAL_SUBFRAMES; + } + if ( ( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( n_slots_to_alloc * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL ) + + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) ); + } + set_zero( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc, n_slots_to_alloc * nchan_transport * hDirAC->num_freq_bands ); + + if ( ( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = (float *) malloc( n_slots_to_alloc * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) ); + } + set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, n_slots_to_alloc * nchan_transport * hDirAC->num_freq_bands ); +#else if ( ( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL ) + { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) ); } @@ -735,6 +765,7 @@ ivas_error ivas_param_ism_dec_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) ); } set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); +#endif } if ( st_ivas->hTcBuffer == NULL ) { @@ -758,11 +789,13 @@ ivas_error ivas_param_ism_dec_open( } } } +#ifndef API_5MS else { hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; } +#endif #endif pop_wmops(); @@ -1450,7 +1483,7 @@ void ivas_param_ism_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ float *output_f[] /* o : rendered time signal */ ) { @@ -1532,7 +1565,7 @@ void ivas_param_ism_dec_render( } } - *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; + *nSamplesAvailableNext = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; return; } diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 031c6cf18f..329f17e81e 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -87,7 +87,11 @@ ivas_error ivas_ism_renderer_open( } #ifdef JBM_TSM_ON_TCS +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) +#else if ( st_ivas->hDecoderConfig->voip_active ) +#endif { init_interpolator_length = NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_CLDFB_TIMESLOTS * CLDFB_SLOT_NS ); interpolator_length = (uint16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); @@ -159,10 +163,18 @@ void ivas_ism_render( set_f( output_f[i], 0.0f, output_frame ); } +#ifdef API_5MS + if ( st_ivas->hHeadTrackData != NULL ) +#else if ( st_ivas->hHeadTrackData != NULL && st_ivas->hHeadTrackData->num_quaternions >= 0 ) +#endif { /* Calculate rotation matrix from the quaternion */ +#ifdef API_5MS + QuatToRotMat( st_ivas->hHeadTrackData->Quaternion, Rmat ); +#else QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[st_ivas->hHeadTrackData->num_quaternions++], Rmat ); +#endif } for ( i = 0; i < nchan_ism; i++ ) @@ -177,7 +189,11 @@ void ivas_ism_render( else { /* Head rotation: rotate the object positions depending the head's orientation */ +#ifdef API_5MS + if ( st_ivas->hHeadTrackData != NULL && !st_ivas->hIsmMetaData[i]->non_diegetic_flag ) +#else if ( st_ivas->hHeadTrackData != NULL && st_ivas->hHeadTrackData->num_quaternions >= 0 && !st_ivas->hIsmMetaData[i]->non_diegetic_flag ) +#endif { rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, Rmat, st_ivas->hIntSetup.is_planar_setup ); } @@ -262,10 +278,18 @@ void ivas_ism_render_sf( set_f( output_f[i], 0.0f, n_samples_to_render ); } +#ifdef API_5MS + if ( st_ivas->hHeadTrackData != NULL ) +#else if ( st_ivas->hHeadTrackData != NULL && st_ivas->hHeadTrackData->num_quaternions >= 0 ) +#endif { /* Calculate rotation matrix from the quaternion */ +#ifdef API_5MS + QuatToRotMat( st_ivas->hHeadTrackData->Quaternion, Rmat ); +#else QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[st_ivas->hHeadTrackData->num_quaternions++], Rmat ); +#endif ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_to_render, n_samples_to_render, @@ -277,7 +301,11 @@ void ivas_ism_render_sf( { /* Head rotation: rotate the object positions depending the head's orientation */ #ifdef FIX_473_JITTER_NONDIEGETIC_PANNING +#ifdef API_5MS + if ( st_ivas->hHeadTrackData != NULL && !st_ivas->hIsmMetaData[i]->non_diegetic_flag ) +#else if ( st_ivas->hHeadTrackData != NULL && st_ivas->hHeadTrackData->num_quaternions >= 0 && !st_ivas->hIsmMetaData[i]->non_diegetic_flag ) +#endif #else if ( st_ivas->hHeadTrackData != NULL && st_ivas->hHeadTrackData->num_quaternions >= 0 ) #endif @@ -311,7 +339,11 @@ void ivas_ism_render_sf( } /* update here only in case of head rotation */ +#ifdef API_5MS + if ( st_ivas->hHeadTrackData != NULL ) +#else if ( st_ivas->hHeadTrackData != NULL && st_ivas->hHeadTrackData->num_quaternions >= 0 ) +#endif { st_ivas->hIsmRendererData->prev_gains[i][j] = gain; } diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 987c55f221..5a96069893 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -329,12 +329,30 @@ ivas_error ivas_jbm_dec_tc( } else if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { +#ifdef FIX_XXX_JITTER_SBA_BINAURAL_GAIN + float gain; + + if ( nchan_remapped == 1 ) + { + gain = 1.4454f; + } + else + { + gain = 1.3657f; + } + + for ( n = 0; n < nchan_remapped; n++ ) + { + v_multc( output[n], gain, output[n], output_frame ); + } +#else float gain = 0.8414f; /* Todo: Temporary gain for roughly matching the loudness. To be tuned later together with other outputs. */ for ( n = 0; n < nchan_remapped; n++ ) { v_multc( output[n], gain, output[n], output_frame ); } +#endif } } else if ( st_ivas->ivas_format == MC_FORMAT ) @@ -861,6 +879,12 @@ ivas_error ivas_jbm_dec_render( { ivas_param_mc_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); } +#ifdef API_5MS + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + return IVAS_ERR_NOT_IMPLEMENTED; + } +#endif else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { int16_t offset = st_ivas->hDirAC->slots_rendered * st_ivas->hDirAC->slot_size; @@ -1369,6 +1393,12 @@ int16_t ivas_jbm_dec_get_num_tc_channels( } } } +#ifdef API_5MS + else if ( st_ivas->ivas_format == MONO_FORMAT && st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) + { + num_tc = MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; + } +#endif return num_tc; } @@ -1522,9 +1552,26 @@ ivas_error ivas_jbm_dec_tc_buffer_open( } else { +#ifdef API_5MS + int16_t n_samp_full, n_samp_residual; +#else int16_t n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); int16_t n_samp_residual = hTcBuffer->n_samples_granularity - 1; +#endif int32_t offset; +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) + { + n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); + n_samp_residual = hTcBuffer->n_samples_granularity - 1; + } + else + { + n_samp_full = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + n_samp_residual = 0; + } +#endif + nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; nsamp_to_allocate += nchan_residual * n_samp_residual; @@ -1628,8 +1675,18 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( /* realloc buffers */ free( hTcBuffer->tc_buffer ); - n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); - n_samp_residual = hTcBuffer->n_samples_granularity - 1; +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) + { + n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); + n_samp_residual = hTcBuffer->n_samples_granularity - 1; + } + else + { + n_samp_full = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + n_samp_residual = 0; + } +#endif nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; nsamp_to_allocate += nchan_residual * n_samp_residual; @@ -1811,11 +1868,26 @@ TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( case RENDERER_PARAM_ISM: case RENDERER_BINAURAL_MIXER_CONV: case RENDERER_BINAURAL_MIXER_CONV_ROOM: +#ifdef API_5MS + buffer_mode = TC_BUFFER_MODE_RENDERER; + break; + case RENDERER_NON_DIEGETIC_DOWNMIX: + if ( st_ivas->ivas_format == MONO_FORMAT ) + { + buffer_mode = TC_BUFFER_MODE_BUFFER; + } + else + { + buffer_mode = TC_BUFFER_MODE_RENDERER; + } + break; +#else #ifdef FIX_473_JITTER_NONDIEGETIC_PANNING case RENDERER_NON_DIEGETIC_DOWNMIX: #endif buffer_mode = TC_BUFFER_MODE_RENDERER; break; +#endif case RENDERER_MC_PARAMMC: if ( st_ivas->hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) { diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 8d6cebe036..96502f3326 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -416,7 +416,11 @@ ivas_error ivas_masa_dec_open( #ifdef JBM_TSM_ON_TCS /* allocate transport channels*/ +#ifdef API_5MS + if ( st_ivas->hTcBuffer == NULL && st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) +#else if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL && st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) +#endif { int16_t nchan_to_allocate; TC_BUFFER_MODE buffer_mode; @@ -1300,7 +1304,9 @@ ivas_error ivas_masa_dec_reconfigure( ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp ); #ifdef JBM_TSM_ON_TCS +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active == 1 ) +#endif { int16_t tc_nchan_to_allocate; int16_t tc_nchan_transport; diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 4be35d188e..d058f4d5ba 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -479,7 +479,11 @@ ivas_error ivas_param_mc_dec_open( ivas_param_mc_dec_init( hParamMC, nchan_transport, nchan_out_cov ); #ifdef JBM_TSM_ON_TCS +#ifdef API_5MS + if ( hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) +#else if ( st_ivas->hDecoderConfig->voip_active && hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) +#endif { if ( ( hParamMC->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) { @@ -1576,7 +1580,7 @@ void ivas_param_mc_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ float *output_f[] /* o : rendered time signal */ ) { @@ -1840,7 +1844,7 @@ void ivas_param_mc_dec_render( param_mc_update_mixing_matrices( hParamMC, hParamMC->h_output_synthesis_cov_state.mixing_matrix, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, nchan_transport, nchan_out_cov ); } hParamMC->subframes_rendered = last_sf; - *nSamplesAvailable = ( hParamMC->num_slots - hParamMC->slots_rendered ) * NS2SA( output_Fs, CLDFB_SLOT_NS ); + *nSamplesAvailableNext = ( hParamMC->num_slots - hParamMC->slots_rendered ) * NS2SA( output_Fs, CLDFB_SLOT_NS ); pop_wmops(); return; @@ -1863,7 +1867,7 @@ void ivas_param_mc_dec( PARAM_MC_DEC_HANDLE hParamMC; float Cldfb_RealBuffer_in[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_NSLOTS * CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_in[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_NSLOTS * CLDFB_NO_CHANNELS_MAX]; - uint16_t nSamplesAsked, nSamplesAvailable, nSamplesRendered; + uint16_t nSamplesAsked, nSamplesAvailableNext, nSamplesRendered; hParamMC = st_ivas->hParamMC; assert( hParamMC ); @@ -1875,10 +1879,10 @@ void ivas_param_mc_dec( nSamplesAsked = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); ivas_param_mc_dec_digest_tc( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS, output_f ); - ivas_param_mc_dec_render( st_ivas, nSamplesAsked, &nSamplesRendered, &nSamplesAvailable, output_f ); + ivas_param_mc_dec_render( st_ivas, nSamplesAsked, &nSamplesRendered, &nSamplesAvailableNext, output_f ); #ifdef DEBUGGING assert( nSamplesRendered == nSamplesAsked ); - assert( nSamplesAvailable == 0 ); + assert( nSamplesAvailableNext == 0 ); #endif /* set handle pointers back to NULL */ diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 46c4343800..81eb631741 100755 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -750,7 +750,9 @@ static ivas_error ivas_mc_dec_reconfig( ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); #ifdef JBM_TSM_ON_TCS +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active ) +#endif { /* transfer subframe info from DirAC or ParamMC to central tc buffer */ if ( last_mc_mode == MC_MODE_PARAMMC ) @@ -1294,8 +1296,9 @@ static ivas_error ivas_mc_dec_reconfig( /*-----------------------------------------------------------------* * Reconfigure TC buffer *-----------------------------------------------------------------*/ - +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active == 1 ) +#endif { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index ba14104ed9..c1347b85d9 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -90,8 +90,13 @@ ivas_error ivas_td_binaural_renderer( st_ivas->hReverb, st_ivas->transport_config, st_ivas->hBinRendererTd, st_ivas->nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, +#ifdef API_5MS + st_ivas->hIsmMetaData, st_ivas->hDecoderConfig->Opt_Headrotation, ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternion : NULL, + ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Pos : NULL, ism_md_subframe_update, output, output_frame ); +#else st_ivas->hIsmMetaData, st_ivas->hDecoderConfig->Opt_Headrotation, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->Quaternions : NULL, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->Pos : NULL, ism_md_subframe_update, output, output_frame ); +#endif #else return ivas_td_binaural_renderer_unwrap( st_ivas->hReverb, @@ -195,9 +200,15 @@ ivas_error ivas_td_binaural_renderer_sf( #endif /* Update the listener's location/orientation */ +#ifdef API_5MS + TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, st_ivas->hDecoderConfig->Opt_Headrotation, + ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternion : NULL, + ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Pos : NULL ); +#else TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, st_ivas->hDecoderConfig->Opt_Headrotation, ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[0] : NULL, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->Pos : NULL ); +#endif if ( ( st_ivas->hRenderConfig != NULL ) && ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) { @@ -209,7 +220,7 @@ ivas_error ivas_td_binaural_renderer_sf( /* Render subframe */ #ifdef FIX_356_ISM_METADATA_SYNC - if ( ( error = TDREND_GetMix( st_ivas->hBinRendererTd, output_f_local, output_frame, 0, ism_md_subframe_update_jbm ) ) != IVAS_ERR_OK ) + if ( ( error = TDREND_GetMix( st_ivas->hBinRendererTd, output_f_local, output_frame, 0, ism_md_subframe_update_jbm != subframe_idx ) ) != IVAS_ERR_OK ) #else if ( ( error = TDREND_GetMix( st_ivas->hBinRendererTd, output_f_local, output_frame, 0 ) ) != IVAS_ERR_OK ) #endif diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 2d4c4cb2ab..d0e90ce9e2 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -377,7 +377,9 @@ ivas_error ivas_sba_dec_reconfigure( * JBM TC buffer *-----------------------------------------------------------------*/ +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active == 1 ) +#endif { int16_t tc_nchan_to_allocate; int16_t tc_nchan_tc; @@ -524,7 +526,7 @@ void ivas_sba_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ float *output_f[] /* o : rendered time signal */ ) { @@ -593,7 +595,7 @@ void ivas_sba_dec_render( } } - *nSamplesAvailable = ( hSpar->num_slots - hSpar->slots_rendered ) * slot_size; + *nSamplesAvailableNext = ( hSpar->num_slots - hSpar->slots_rendered ) * slot_size; return; } diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 0d028b2359..3b28fb77ee 100755 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -221,7 +221,11 @@ ivas_error ivas_spar_dec_open( } /* allocate transport channels*/ +#ifdef API_5MS + if ( st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) +#endif { int16_t nchan_to_allocate; int16_t nchan_tc; diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index aacaa7aa0f..8a53910080 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1224,9 +1224,13 @@ typedef struct decoder_config_structure #ifdef DEBUGGING int16_t force_rend; /* forced TD/CLDFB binaural renderer (for ISM and MC) */ #endif +#ifdef API_5MS + int16_t tsm_active; +#else #ifdef JBM_TSM_ON_TCS int16_t voip_active; #endif +#endif #ifdef FIX_356_ISM_METADATA_SYNC int16_t Opt_delay_comp; /* flag indicating delay compensation active */ #endif diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 69b6e127fd..a090d90621 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -53,20 +53,26 @@ struct IVAS_DEC_VOIP { uint16_t nSamplesFrame; /* Total number of samples in a frame (includes number of channels) */ JB4_HANDLE hJBM; +#ifndef API_5MS PCMDSP_APA_HANDLE hTimeScaler; +#endif uint16_t lastDecodedWasActive; +#ifndef API_5MS #ifdef JBM_TSM_ON_TCS float *apaExecBuffer; /* Buffer for APA scaling */ #else int16_t *apaExecBuffer; /* Buffer for APA scaling */ +#endif #endif JB4_DATAUNIT_HANDLE hCurrentDataUnit; /* Points to the currently processed data unit */ uint16_t *bs_conversion_buf; /* Buffer for bitstream conversion from packed to serial */ +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING IVAS_DEC_VOIP_MODE voipMode; uint16_t speedFac; bool needNewFrame; #endif + #ifdef JBM_TSM_ON_TCS JBM_RENDERER_TYPE rendererType; PCMDSP_FIFO_HANDLE hFifoOut; @@ -75,6 +81,7 @@ struct IVAS_DEC_VOIP #else PCMDSP_FIFO_HANDLE hFifoAfterTimeScaler; #endif +#endif #ifdef SUPPORT_JBM_TRACEFILE IVAS_JBM_TRACE_DATA JbmTraceData; #endif @@ -92,8 +99,20 @@ struct IVAS_DEC bool hasDecodedFirstGoodFrame; /* False on init. Gets set to true after first good frame has been decoded -> all bitstream information is known from that point on */ bool isInitialized; - int16_t bitstreamformat; /* Bitstream format flag (G.192/MIME/VOIP_G192_RTP/VOIP_RTPDUMP) */ - bool Opt_VOIP; /* flag indicating VOIP mode with JBM */ + int16_t bitstreamformat; /* Bitstream format flag (G.192/MIME/VOIP_G192_RTP/VOIP_RTPDUMP) */ + bool Opt_VOIP; /* flag indicating VOIP mode with JBM */ +#ifdef API_5MS + bool Opt_TSM; /* flag indicating TSM mode*/ + int16_t tsm_scale; /* scale for TSM operation */ + int16_t tsm_max_scaling; + float *apaExecBuffer; /* Buffer for APA scaling */ + PCMDSP_APA_HANDLE hTimeScaler; + bool needNewFrame; + bool hasBeenFedFrame; + uint16_t nSamplesAvailableNext; + int16_t nSamplesRendered; + int16_t nTransportChannelsOld; +#endif int16_t amrwb_rfc4867_flag; /* MIME from rfc4867 is used */ int16_t sdp_hf_only; /* RTP payload format parameter: only Header-Full format without zero padding for size collision avoidance */ int16_t prev_ft_speech; /* RXDTX handler: previous frametype flag for G.192 format AMRWB SID_FIRST detection */ @@ -123,7 +142,7 @@ static void init_decoder_config( DECODER_CONFIG_HANDLE hDecoderConfig, const int #ifdef JBM_TSM_ON_TCS static int16_t IVAS_DEC_VoIP_GetRenderGranularity( Decoder_Struct *st_ivas ); static JBM_RENDERER_TYPE IVAS_DEC_VoIP_GetRendererConfig( IVAS_DEC_HANDLE hIvasDec ); -static ivas_error IVAS_DEC_VoIP_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ); +static ivas_error IVAS_DEC_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ); static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels, uint8_t *nOutChannels, uint16_t *nSamplesRendered, int16_t *data ); static ivas_error IVAS_DEC_GetTcSamples( IVAS_DEC_HANDLE hIvasDec, float *pcmBuf, int16_t *nOutSamples ); static ivas_error IVAS_DEC_RendererFeedTcSamples( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesForRendering, int16_t *nSamplesResidual, float *pcmBuf ); @@ -165,6 +184,18 @@ ivas_error IVAS_DEC_Open( } hIvasDec = *phIvasDec; hIvasDec->hVoIP = NULL; +#ifdef API_5MS + hIvasDec->apaExecBuffer = NULL; + hIvasDec->hTimeScaler = NULL; + hIvasDec->Opt_TSM = false; + hIvasDec->tsm_scale = 100; + hIvasDec->needNewFrame = false; + hIvasDec->nTransportChannelsOld = 0; + hIvasDec->nSamplesAvailableNext = 0; + hIvasDec->nSamplesRendered = 0; + hIvasDec->nSamplesFrame = 0; + hIvasDec->hasBeenFedFrame = false; +#endif hIvasDec->hasBeenFedFirstGoodFrame = false; hIvasDec->hasDecodedFirstGoodFrame = false; hIvasDec->isInitialized = false; @@ -275,10 +306,13 @@ static void init_decoder_config( #endif hDecoderConfig->Opt_non_diegetic_pan = 0; hDecoderConfig->non_diegetic_pan_gain = 0; - +#ifdef API_5MS + hDecoderConfig->tsm_active = 0; +#else #ifdef JBM_TSM_ON_TCS hDecoderConfig->voip_active = 0; #endif +#endif #ifdef FIX_356_ISM_METADATA_SYNC hDecoderConfig->Opt_delay_comp = 0; @@ -316,6 +350,14 @@ void IVAS_DEC_Close( ( *phIvasDec )->st_ivas = NULL; } +#ifdef API_5MS + apa_exit( &( *phIvasDec )->hTimeScaler ); + + if ( ( *phIvasDec )->apaExecBuffer != NULL ) + { + free( ( *phIvasDec )->apaExecBuffer ); + } +#endif free( *phIvasDec ); *phIvasDec = NULL; phIvasDec = NULL; @@ -442,9 +484,12 @@ ivas_error IVAS_DEC_Configure( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const uint32_t sampleRate, /* i : output sampling frequency */ const IVAS_DEC_AUDIO_CONFIG outputFormat, /* i : output format */ - const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ - const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ - const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ +#ifdef API_5MS + const int16_t tsmEnabled, /* i : enable TSM */ +#endif + const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ + const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ + const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ #ifdef FIX_439_OTR_PARAMS const HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ #endif @@ -526,6 +571,16 @@ ivas_error IVAS_DEC_Configure( hIvasDec->st_ivas->ivas_format = MONO_FORMAT; } +#ifdef API_5MS + hDecoderConfig->tsm_active = tsmEnabled; + hIvasDec->Opt_TSM = tsmEnabled; + hIvasDec->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + hIvasDec->nSamplesAvailableNext = 0; + hIvasDec->nSamplesRendered = 0; + hIvasDec->tsm_scale = 100; + hIvasDec->tsm_max_scaling = 100; +#endif + return error; } @@ -540,9 +595,11 @@ ivas_error IVAS_DEC_Configure( ivas_error IVAS_DEC_EnableVoIP( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING const IVAS_DEC_VOIP_MODE voipMode, /* i : VoIP or variable speed */ const uint16_t speedFac, /* i : speed factor for variable speed */ +#endif #endif const int16_t jbmSafetyMargin, /* i : allowed delay reserve for JBM, in milliseconds */ const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ @@ -566,9 +623,14 @@ ivas_error IVAS_DEC_EnableVoIP( hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; hIvasDec->Opt_VOIP = 1; +#ifdef API_5MS + hIvasDec->Opt_TSM = 1; + hDecoderConfig->tsm_active = 1; +#else #ifdef JBM_TSM_ON_TCS hDecoderConfig->voip_active = 1; #endif +#endif #ifdef JBM_TSM_ON_TCS if ( hDecoderConfig->output_config != AUDIO_CONFIG_EXTERNAL ) @@ -602,25 +664,31 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->hVoIP->lastDecodedWasActive = 0; hIvasDec->hVoIP->hCurrentDataUnit = NULL; +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING hIvasDec->hVoIP->voipMode = voipMode; hIvasDec->hVoIP->speedFac = speedFac; hIvasDec->hVoIP->needNewFrame = false; #endif +#endif #ifdef JBM_TSM_ON_TCS hIvasDec->hVoIP->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); +#ifndef API_5MS hIvasDec->hVoIP->nSamplesAvailableNext = 0; hIvasDec->hVoIP->rendererType = JBM_RENDERER_NONE; hIvasDec->hVoIP->hFifoOut = NULL; +#endif #else hIvasDec->hVoIP->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs * hDecoderConfig->nchan_out / FRAMES_PER_SEC ); #endif +#ifndef API_5MS #ifdef JBM_TSM_ON_TCS /* postpone init of the buffers until we know the real number of TCs*/ hIvasDec->hVoIP->apaExecBuffer = NULL; hIvasDec->hVoIP->nTransportChannelsOld = 0; #else +#endif hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( int16_t ) * APA_BUF_PER_CHANNEL * hDecoderConfig->nchan_out ); if ( hIvasDec->hVoIP->apaExecBuffer == NULL ) @@ -640,10 +708,12 @@ ivas_error IVAS_DEC_EnableVoIP( } /* initialize JBM */ +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING hIvasDec->hVoIP->hJBM = NULL; if ( hIvasDec->hVoIP->voipMode == IVAS_DEC_VOIP_MODE_VOIP ) { +#endif #endif if ( ( error = JB4_Create( &hIvasDec->hVoIP->hJBM ) != IVAS_ERR_OK ) != IVAS_ERR_OK ) { @@ -653,9 +723,11 @@ ivas_error IVAS_DEC_EnableVoIP( { return IVAS_ERR_FAILED_ALLOC; } +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING } #endif +#endif #ifndef JBM_TSM_ON_TCS if ( hDecoderConfig->output_Fs == 8000 ) { @@ -683,6 +755,7 @@ ivas_error IVAS_DEC_EnableVoIP( } #endif +#ifndef API_5MS #ifdef JBM_TSM_ON_TCS /* postpone init of time scaler and output FIFO until we know the real number of TCs */ hIvasDec->hVoIP->hTimeScaler = NULL; @@ -721,6 +794,7 @@ ivas_error IVAS_DEC_EnableVoIP( return IVAS_ERR_INIT_ERROR; } #endif +#endif #endif return error; @@ -766,9 +840,13 @@ ivas_error IVAS_DEC_FeedFrame_Serial( { hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = ACELP_8k00; } +#ifdef API_5MS + hIvasDec->isInitialized = true; +#endif } - +#ifndef API_5MS hIvasDec->isInitialized = true; +#endif } if ( !bfi ) /* TODO(mcjbm): Is this ok for bfi == 2 (partial frame)? Is there enough info to fully configure decoder? */ @@ -810,11 +888,18 @@ ivas_error IVAS_DEC_FeedFrame_Serial( st->use_partial_copy = 1; } +#ifdef API_5MS + hIvasDec->needNewFrame = false; + hIvasDec->hasBeenFedFrame = true; + hIvasDec->nSamplesRendered = 0; + hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; +#else #ifdef VARIABLE_SPEED_DECODING if ( hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->voipMode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) { hIvasDec->hVoIP->needNewFrame = false; } +#endif #endif return error; @@ -826,7 +911,7 @@ ivas_error IVAS_DEC_FeedFrame_Serial( * * Main function to decode to PCM data *---------------------------------------------------------------------*/ - +#ifndef API_5MS ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ @@ -876,6 +961,136 @@ ivas_error IVAS_DEC_GetSamples( return error; } +#else +ivas_error IVAS_DEC_GetSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i: number of samples wanted by the caller */ + int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* indication that the decoder needs a new frame */ +) +{ + Decoder_Struct *st_ivas; + ivas_error error; + int16_t nOutSamplesElse, result, nSamplesToRender; + uint16_t nSamplesRendered, nSamplesRendered_loop, l_ts, nTimeScalerOutSamples; + uint8_t nTransportChannels, nOutChannels; + error = IVAS_ERR_OK; + nSamplesRendered = 0; + nOutChannels = 0; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; + + if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) + { + /* no frame was fed, do nothing but ask for a frame */ + *needNewFrame = true; + *nOutSamples = 0; + hIvasDec->needNewFrame = true; + return error; + } + + /* check if we are still at the beginning with bad frames, put out zeroes, keep track of subframes */ + if ( !hIvasDec->isInitialized && hIvasDec->st_ivas->bfi ) + { + hIvasDec->hasBeenFedFrame = false; + set_s( pcmBuf, 0, hIvasDec->st_ivas->hDecoderConfig->nchan_out * nSamplesAsked ); + hIvasDec->nSamplesRendered += nSamplesAsked; + *nOutSamples = nSamplesAsked; + hIvasDec->nSamplesAvailableNext -= nSamplesAsked; + if ( hIvasDec->nSamplesAvailableNext == 0 ) + { + hIvasDec->needNewFrame = true; + *needNewFrame = true; + } + } + else + { + /* check if we need to run the setup function, tc decoding and feeding the renderer */ + if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) + { + int16_t nResidualSamples, nSamplesTcsScaled; + /* setup */ + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &nSamplesRendered_loop, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + nSamplesRendered += nSamplesRendered_loop; + if ( nTransportChannels != hIvasDec->nTransportChannelsOld ) + { + IVAS_DEC_reconfigure( hIvasDec, nTransportChannels, l_ts ); + } + /* decode TCs only */ + if ( ( error = IVAS_DEC_GetTcSamples( hIvasDec, hIvasDec->apaExecBuffer, &nOutSamplesElse ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasDec->Opt_TSM ) + { + if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + result = apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ); + if ( result != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + assert( nTimeScalerOutSamples <= APA_BUF ); + } + else + { + nTimeScalerOutSamples = hIvasDec->nSamplesFrame * nTransportChannels; + } + nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; + + /* render IVAS frames */ + + + if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasDec->Opt_TSM ) + { + /* feed residual samples to TSM for the next call */ + if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + hIvasDec->hasBeenFedFrame = false; + } + /* render IVAS frames directly to the output buffer */ + nSamplesToRender = nSamplesAsked - nSamplesRendered; + if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + nSamplesRendered += nSamplesRendered_loop; + nSamplesToRender -= nSamplesRendered_loop; + if ( hIvasDec->nSamplesAvailableNext == 0 ) + { + *needNewFrame = true; + hIvasDec->needNewFrame = true; + } + else + { + *needNewFrame = false; + } + } + + *nOutSamples = nSamplesRendered; + + return error; +} +#endif #ifdef JBM_TSM_ON_TCS @@ -1265,15 +1480,26 @@ ivas_error IVAS_DEC_GetMasaMetadata( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_FeedHeadTrackData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef API_5MS + IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ + IVAS_VECTOR3 Pos /* i : listener position */ +#else IVAS_QUATERNION *orientation, /* i : head-tracking data, listener orientation */ IVAS_VECTOR3 *Pos /* i : listener position */ +#endif ) { HEAD_TRACK_DATA_HANDLE hHeadTrackData; +#ifndef API_5MS int16_t i; +#endif +#ifdef API_5MS + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) +#else if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || orientation == NULL ) +#endif { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1286,6 +1512,18 @@ ivas_error IVAS_DEC_FeedHeadTrackData( } /* Move head-tracking data to the decoder handle */ +#ifdef API_5MS + /* check for Euler angle signaling */ + if ( orientation.w == -3.0f ) + { + Euler2Quat( deg2rad( orientation.x ), deg2rad( orientation.y ), deg2rad( orientation.z ), &orientation ); + } + + ivas_orient_trk_Process( hHeadTrackData->OrientationTracker, orientation, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &hHeadTrackData->Quaternion ); + hHeadTrackData->Pos.x = Pos.x; + hHeadTrackData->Pos.y = Pos.y; + hHeadTrackData->Pos.z = Pos.z; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { /* check for Euler angle signaling */ @@ -1301,6 +1539,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( } hIvasDec->st_ivas->hHeadTrackData->num_quaternions = 0; +#endif return IVAS_ERR_OK; } @@ -1824,7 +2063,6 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( } #ifdef VARIABLE_SPEED_DECODING -#ifdef DEBUGGING /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_SetScale( ) * @@ -1833,20 +2071,220 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( ivas_error IVAS_DEC_VoIP_SetScale( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t scale /* i : TSM scale to set */ +#ifdef API_5MS + const int16_t maxScaling, +#endif + const int16_t scale /* i : TSM scale to set */ ) { ivas_error error; error = IVAS_ERR_OK; +#ifdef API_5MS + if ( hIvasDec->Opt_TSM == false ) + { + return IVAS_ERR_TSM_NOT_ENABLED; + } + else + { + hIvasDec->tsm_scale = scale; + hIvasDec->tsm_max_scaling = maxScaling; + } +#else hIvasDec->hVoIP->speedFac = scale; +#endif return error; } #endif + + +#ifdef API_5MS +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_GetSamples( ) + * + * Main function to decode one frame in VoIP + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_VoIP_GetSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ +#ifdef SUPPORT_JBM_TRACEFILE + , + JbmTraceFileWriterFn jbmWriterFn, + void *jbmWriter +#endif + +) +{ + Decoder_Struct *st_ivas; + DECODER_CONFIG_HANDLE hDecoderConfig; + IVAS_DEC_VOIP *hVoIP; + uint32_t extBufferedTime_ms, scale, maxScaling; +#ifndef API_5MS + uint16_t nTimeScalerOutSamples; +#endif + JB4_DATAUNIT_HANDLE dataUnit; +#ifndef API_5MS + int16_t nOutSamplesElse; +#endif + uint16_t extBufferedSamples; + int16_t timeScalingDone; + int16_t result; + ivas_error error; +#ifdef JBM_TSM_ON_TCS + int16_t nSamplesRendered; + uint16_t nSamplesTcsScaled; + uint8_t nTransportChannels; + uint8_t nOutChannels; #endif + error = IVAS_ERR_OK; + + st_ivas = hIvasDec->st_ivas; + hDecoderConfig = st_ivas->hDecoderConfig; + hVoIP = hIvasDec->hVoIP; + timeScalingDone = 0; + + nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + nTransportChannels = 0; + nSamplesTcsScaled = hVoIP->nSamplesFrame; + nSamplesRendered = 0; + + if ( nSamplesPerChannel == 0 ) + { + return IVAS_ERR_WRONG_PARAMS; + } + + /* make sure that the FIFO after decoder/scaler contains at least one sound card frame (i.e. 20ms) */ + while ( nSamplesRendered < nSamplesPerChannel ) + { + if ( hIvasDec->nSamplesAvailableNext == 0 ) + { + int16_t nSamplesBuffered; + nSamplesBuffered = 0; + if ( hIvasDec->hasBeenFedFirstGoodFrame ) + { + IVAS_DEC_GetBufferedNumberOfSamples( hIvasDec, &nSamplesBuffered ); + } + extBufferedSamples = nSamplesRendered + nSamplesBuffered; + + 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 ) + { + return IVAS_ERR_UNKNOWN; + } + + + maxScaling = maxScaling * hDecoderConfig->output_Fs / 1000; + /* avoid time scaling multiple times in one sound card slot */ + if ( scale != 100U ) + { + if ( timeScalingDone ) + { + scale = 100; + } + else + { + timeScalingDone = 1; + } + } + + /* limit scale to range supported by time scaler */ + if ( scale < APA_MIN_SCALE ) + { + scale = APA_MIN_SCALE; + } + else if ( scale > APA_MAX_SCALE ) + { + scale = APA_MAX_SCALE; + } + + IVAS_DEC_VoIP_SetScale( hIvasDec, (int16_t) maxScaling, (int16_t) scale ); + + /* copy bitstream into decoder state */ + if ( dataUnit ) + { + hIvasDec->hVoIP->hCurrentDataUnit = dataUnit; + + bsCompactToSerial( dataUnit->data, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize ); + IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 ); + } + else if ( hIvasDec->hasDecodedFirstGoodFrame ) + { + /* Decoder has been initialized with first good frame - do PLC */ + IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 ); + } + +#ifdef SUPPORT_JBM_TRACEFILE + /* jbmWriterFn and jbmWriter may be NULL if tracefile writing was not requested on CLI */ + if ( jbmWriterFn != NULL && jbmWriter != NULL ) + { + /* write JBM trace data entry */ + store_JbmData( hVoIP, dataUnit, systemTimestamp_ms, extBufferedSamples, hDecoderConfig->output_Fs ); + if ( ( jbmWriterFn( &hVoIP->JbmTraceData, jbmWriter ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing JBM Trace data to file\n" ); + return IVAS_ERR_UNKNOWN; + } + } +#endif + if ( dataUnit ) + { + if ( dataUnit->partial_frame != 0 ) + { + hVoIP->lastDecodedWasActive = 1; + } + else + { + hVoIP->lastDecodedWasActive = !dataUnit->silenceIndicator; + } + /* data unit memory is no longer used */ + JB4_FreeDataUnit( hVoIP->hJBM, dataUnit ); + } + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; + hIvasDec->nSamplesRendered = 0; + } + } + /* decode */ + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + /* codec mode to use not known yet - simply output silence */ + /* directly set output zero */ + int16_t nSamplesToZero = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); + set_s( pcmBuf + nSamplesRendered * nOutChannels, 0, nSamplesToZero * nOutChannels ); + nSamplesRendered += nSamplesToZero; + hIvasDec->nSamplesRendered += nSamplesToZero; + hIvasDec->nSamplesAvailableNext -= nSamplesToZero; + } + else + { + int16_t nSamplesToRender, nSamplesRendered_loop; + bool tmp; + nSamplesToRender = nSamplesPerChannel - nSamplesRendered; + + /* render IVAS frames directly to the output buffer */ + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nSamplesRendered * nOutChannels, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) + { + return error; + } + nSamplesRendered += nSamplesRendered_loop; + } + } + return error; +} +#else /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_GetSamples( ) * @@ -2076,7 +2514,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( nSamplesRendered += nSamplesRendered_loop; if ( nTransportChannels != hVoIP->nTransportChannelsOld ) { - IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ); + IVAS_DEC_reconfigure( hIvasDec, nTransportChannels, l_ts ); } /* decode TCs only */ @@ -2159,8 +2597,8 @@ ivas_error IVAS_DEC_VoIP_GetSamples( #ifdef VARIABLE_SPEED_DECODING if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) { - int16_t nSamplesAvailable = pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ); - if ( nSamplesAvailable < nSamplesPerChannel ) + int16_t nSamplesAvailableNext = pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ); + if ( nSamplesAvailableNext < nSamplesPerChannel ) { hVoIP->needNewFrame = true; } @@ -2312,6 +2750,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( return error; } +#endif /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_Flush( ) @@ -2331,7 +2770,9 @@ ivas_error IVAS_DEC_VoIP_Flush( ivas_error error; IVAS_DEC_VOIP *hVoIP; #ifdef JBM_TSM_ON_TCS +#ifndef API_5MS int16_t rendererPcmBuf[( MAX_OUTPUT_CHANNELS * L_FRAME_MAX * APA_MAX_SCALE ) / 100]; +#endif uint16_t nSamplesToRender; uint16_t nSamplesFlushedLocal; #endif @@ -2340,11 +2781,16 @@ ivas_error IVAS_DEC_VoIP_Flush( hVoIP = hIvasDec->hVoIP; #if defined( JBM_TSM_ON_TCS ) +#ifdef API_5MS + *nSamplesFlushed = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); +#else *nSamplesFlushed = min( nSamplesPerChannel, hVoIP->nSamplesAvailableNext ); +#endif #else *nSamplesFlushed = min( nSamplesPerChannel, pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ) ); #endif +#ifndef API_5MS #ifdef JBM_TSM_ON_TCS if ( hVoIP->rendererType == JBM_RENDERER_NONE ) { @@ -2368,6 +2814,7 @@ ivas_error IVAS_DEC_VoIP_Flush( } else { + nSamplesToRender = (uint16_t) *nSamplesFlushed; /* render IVAS frames */ if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hVoIP->nSamplesAvailableNext, rendererPcmBuf ) ) != IVAS_ERR_OK ) @@ -2389,7 +2836,15 @@ ivas_error IVAS_DEC_VoIP_Flush( *nSamplesFlushed = (int16_t) nSamplesFlushedLocal; } #endif +#else + nSamplesToRender = (uint16_t) *nSamplesFlushed; + /* render IVAS frames */ + if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmBuf ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif return error; } #endif @@ -2410,7 +2865,11 @@ bool IVAS_DEC_VoIP_IsEmpty( ) { #ifdef JBM_TSM_ON_TCS +#ifdef API_5MS + return ( ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->nSamplesAvailableNext < nSamplesAsked ) ); +#else return ( ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->hVoIP->nSamplesAvailableNext < nSamplesAsked ) ); +#endif #else return JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0; #endif @@ -2452,6 +2911,7 @@ static void IVAS_DEC_Close_VoIP( { JB4_Destroy( &hVoIP->hJBM ); +#ifndef API_5MS apa_exit( &hVoIP->hTimeScaler ); #ifdef JBM_TSM_ON_TCS @@ -2464,7 +2924,7 @@ static void IVAS_DEC_Close_VoIP( { free( hVoIP->apaExecBuffer ); } - +#endif if ( hVoIP->bs_conversion_buf != NULL ) { #define WMC_TOOL_SKIP @@ -2805,17 +3265,25 @@ static ivas_error printConfigInfo_dec( } } +#ifdef API_5MS + /*-----------------------------------------------------------------* + * Print VoIP mode info + *-----------------------------------------------------------------*/ + if ( st_ivas->hDecoderConfig->tsm_active ) + { + fprintf( stdout, "TSM mode: ON\n" ); + } +#else #ifdef JBM_TSM_ON_TCS /*-----------------------------------------------------------------* * Print VoIP mode info *-----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->voip_active ) { fprintf( stdout, "VoIP mode: ON\n" ); } #endif - +#endif return IVAS_ERR_OK; } @@ -3269,64 +3737,103 @@ static JBM_RENDERER_TYPE IVAS_DEC_VoIP_GetRendererConfig( * *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_VoIP_reconfigure( +ivas_error IVAS_DEC_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ) { IVAS_DEC_VOIP *hVoIP; +#ifdef API_5MS + int16_t apa_buffer_size; +#endif + ivas_error error; + hVoIP = hIvasDec->hVoIP; +#ifdef API_5MS + apa_buffer_size = hIvasDec->nSamplesFrame; +#endif +#ifdef API_5MS + if ( hIvasDec->apaExecBuffer == NULL ) +#else if ( hIvasDec->hVoIP->hTimeScaler == NULL ) +#endif { - +#ifndef API_5MS uint16_t wss, css; float startQuality; +#endif DECODER_CONFIG_HANDLE hDecoderConfig; +#ifdef API_5MS + if ( hIvasDec->Opt_TSM ) + { + uint16_t wss, css; + float startQuality; + + startQuality = 1.0f; + apa_buffer_size = APA_BUF_PER_CHANNEL; +#else #ifdef VARIABLE_SPEED_DECODING startQuality = hVoIP->voipMode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ? -2.0f : 1.0f; #else startQuality = 1.0f; +#endif #endif - /* get current renderer type*/ - hVoIP->rendererType = IVAS_DEC_VoIP_GetRendererConfig( hIvasDec ); - hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; - if ( hDecoderConfig->output_Fs == 8000 ) - { - wss = 1; - css = 1; - } - else if ( hDecoderConfig->output_Fs == 16000 ) - { - wss = 2; - css = 1; - } - else if ( hDecoderConfig->output_Fs == 32000 ) - { - wss = 4; - css = 2; - } - else if ( hDecoderConfig->output_Fs == 48000 ) - { - wss = 6; - css = 3; - } - else - { - return IVAS_ERR_INIT_ERROR; - } + /* get current renderer type*/ +#ifndef API_5MS + hVoIP->rendererType = IVAS_DEC_VoIP_GetRendererConfig( hIvasDec ); +#endif + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; - if ( ( hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); - } - set_zero( hIvasDec->hVoIP->apaExecBuffer, APA_BUF_PER_CHANNEL * nTransportChannels ); + if ( hDecoderConfig->output_Fs == 8000 ) + { + wss = 1; + css = 1; + } + else if ( hDecoderConfig->output_Fs == 16000 ) + { + wss = 2; + css = 1; + } + else if ( hDecoderConfig->output_Fs == 32000 ) + { + wss = 4; + css = 2; + } + else if ( hDecoderConfig->output_Fs == 48000 ) + { + wss = 6; + css = 3; + } + else + { + return IVAS_ERR_INIT_ERROR; + } +#ifndef API_5MS + if ( ( hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ) ) == NULL ) + + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } + set_zero( hIvasDec->hVoIP->apaExecBuffer, APA_BUF_PER_CHANNEL * nTransportChannels ); +#endif +#ifdef API_5MS + if ( apa_init( &hIvasDec->hTimeScaler, + nTransportChannels ) != IVAS_ERR_OK || + apa_set_rate( hIvasDec->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || + apa_set_complexity_options( hIvasDec->hTimeScaler, wss, css ) != 0 || + apa_set_quality( hIvasDec->hTimeScaler, startQuality, 4, 4 ) != 0 || + apa_set_renderer_granularity( hIvasDec->hTimeScaler, l_ts ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } +#else if ( apa_init( &hIvasDec->hVoIP->hTimeScaler, nTransportChannels ) != IVAS_ERR_OK || apa_set_rate( hIvasDec->hVoIP->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || @@ -3336,51 +3843,91 @@ ivas_error IVAS_DEC_VoIP_reconfigure( { return IVAS_ERR_INIT_ERROR; } +#endif - if ( hVoIP->hFifoOut == NULL && hVoIP->rendererType == JBM_RENDERER_NONE ) - { - /* we still need the FIFO out buffer */ - if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || - pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) +#ifndef API_5MS + if ( hVoIP->hFifoOut == NULL && hVoIP->rendererType == JBM_RENDERER_NONE ) { - return IVAS_ERR_INIT_ERROR; + /* we still need the FIFO out buffer */ + if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || + pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } } - } #ifdef VARIABLE_SPEED_DECODING - else if ( hIvasDec->hVoIP->voipMode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) - { - if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || - pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) + else if ( hIvasDec->hVoIP->voipMode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) { - return IVAS_ERR_INIT_ERROR; + if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || + pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } } - } +#endif #endif - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - if ( apa_set_evs_compat_mode( hIvasDec->hVoIP->hTimeScaler, true ) != 0 ) + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { - return IVAS_ERR_INIT_ERROR; +#ifdef API_5MS + if ( apa_set_evs_compat_mode( hIvasDec->hTimeScaler, true ) != 0 ) +#else + if ( apa_set_evs_compat_mode( hIvasDec->hVoIP->hTimeScaler, true ) != 0 ) +#endif + { + return IVAS_ERR_INIT_ERROR; + } } +#ifdef API_5MS } +#endif + if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) + + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } + + set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); } else { - if ( apa_reconfigure( hVoIP->hTimeScaler, nTransportChannels, l_ts ) != 0 ) +#ifdef API_5MS + if ( hIvasDec->Opt_TSM ) { - return IVAS_ERR_INIT_ERROR; + if ( apa_reconfigure( hIvasDec->hTimeScaler, nTransportChannels, l_ts ) != 0 ) +#else + if ( apa_reconfigure( hVoIP->hTimeScaler, nTransportChannels, l_ts ) != 0 ) +#endif + { + return IVAS_ERR_INIT_ERROR; + } +#ifdef API_5MS + apa_buffer_size = APA_BUF_PER_CHANNEL; } - +#endif /* realloc apa_exe_buffer */ +#ifdef API_5MS + free( hIvasDec->apaExecBuffer ); + if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } + set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); +#else free( hIvasDec->hVoIP->apaExecBuffer ); if ( ( hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); } set_zero( hIvasDec->hVoIP->apaExecBuffer, APA_BUF_PER_CHANNEL * nTransportChannels ); +#endif } + +#ifdef API_5MS + hIvasDec->nTransportChannelsOld = nTransportChannels; +#else hIvasDec->hVoIP->nTransportChannelsOld = (uint8_t) nTransportChannels; +#endif error = IVAS_ERR_OK; diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 0539d75188..50d899e8f6 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -83,7 +83,7 @@ typedef enum _IVAS_DEC_COMPLEXITY_LEVEL IVAS_DEC_COMPLEXITY_LEVEL_THREE = 3 } IVAS_DEC_COMPLEXITY_LEVEL; - +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING typedef enum { @@ -91,6 +91,7 @@ typedef enum IVAS_DEC_VOIP_MODE_VARIABLE_SPEED = 1 } IVAS_DEC_VOIP_MODE; #endif +#endif #ifdef DEBUGGING typedef enum _IVAS_DEC_FORCED_REND_MODE @@ -144,11 +145,14 @@ ivas_error IVAS_DEC_Configure( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const uint32_t sampleRate, /* i : output sampling frequency */ const IVAS_DEC_AUDIO_CONFIG outputFormat, /* i : output format */ +#ifdef API_5MS + const int16_t tsmEnabled, /* i : enable TSM */ +#endif const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ #ifdef FIX_439_OTR_PARAMS - const HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ + const HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ #endif const int16_t renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ const int16_t Opt_non_diegetic_pan, /* i : diegetic or not */ @@ -177,9 +181,17 @@ ivas_error IVAS_DEC_FeedFrame_Serial( /*! r: decoder error code */ ivas_error IVAS_DEC_GetSamples( +#ifdef API_5MS + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i: number of samples wanted by the caller */ + int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* indication that the decoder needs a new frame */ +#else IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ +#endif ); /*! r: error code */ @@ -199,8 +211,13 @@ ivas_error IVAS_DEC_GetMasaMetadata( /*! r: error code */ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION *orientation, /* i : head-tracking data */ - IVAS_VECTOR3 *Pos /* i : listener position */ +#ifdef API_5MS + IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ + IVAS_VECTOR3 Pos /* i : listener position */ +#else + IVAS_QUATERNION *orientation, /* i : head-tracking data, listener orientation */ + IVAS_VECTOR3 *Pos /* i : listener position */ +#endif ); /*! r: error code */ @@ -226,6 +243,13 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( const bool qBit /* i : Q bit for AMR-WB IO */ ); +#ifdef API_5MS +ivas_error IVAS_DEC_VoIP_SetScale( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t maxScaling, /* i : maximum allowed TSM scale */ + const int16_t scale /* i : TSM scale to set */ +); +#else #ifdef VARIABLE_SPEED_DECODING #ifdef DEBUGGING /*! r: error code */ @@ -235,6 +259,7 @@ ivas_error IVAS_DEC_VoIP_SetScale( ); #endif #endif +#endif /*! r: error code */ ivas_error IVAS_DEC_VoIP_GetSamples( @@ -242,10 +267,12 @@ ivas_error IVAS_DEC_VoIP_GetSamples( uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ const uint32_t systemTimestamp_ms /* i : current system timestamp */ +#ifndef API_5MS #if defined( JBM_TSM_ON_TCS ) || defined(VARIABLE_SPEED_DECODING ) , uint16_t *sampleAvailableNext /* o : samples available for the next call */ #endif +#endif #ifdef SUPPORT_JBM_TRACEFILE , JbmTraceFileWriterFn jbmWriterFn, void* jbmWriter @@ -267,9 +294,11 @@ ivas_error IVAS_DEC_VoIP_Flush( /*! r: error code */ ivas_error IVAS_DEC_EnableVoIP( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING const IVAS_DEC_VOIP_MODE voipMode, /* i : VoIP or variable speed */ const uint16_t speedFac, /* i : speed factor for variable speed */ +#endif #endif const int16_t jbmSafetyMargin, /* i : allowed delay reserve for JBM, in milliseconds */ const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 76af4a17c8..4fa4a61760 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1517,7 +1517,11 @@ ivas_error ivas_rend_crendProcess( for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { +#ifdef API_5MS + if ( hDecoderConfig && hDecoderConfig->Opt_Headrotation && hHeadTrackData ) +#else if ( hDecoderConfig && hDecoderConfig->Opt_Headrotation && hHeadTrackData && hHeadTrackData->num_quaternions >= 0 ) +#endif { /* Orientation tracking */ @@ -1656,7 +1660,11 @@ ivas_error ivas_rend_crendProcessSubframe( { subframe_len = hTcBuffer->subframe_nbslots[subframe_idx] * hTcBuffer->n_samples_granularity; +#ifdef API_5MS + if ( hDecoderConfig && hDecoderConfig->Opt_Headrotation && hHeadTrackData ) +#else if ( hDecoderConfig && hDecoderConfig->Opt_Headrotation && hHeadTrackData && hHeadTrackData->num_quaternions >= 0 ) +#endif { /* Rotation in SHD for: MC with elevation (5_1_2 / 5_1_4 / 7_1_4) -> BINAURAL diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index c3e76e7306..0791d274f3 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -236,7 +236,11 @@ ivas_error ivas_dirac_dec_init_binaural_data( #ifdef JBM_TSM_ON_TCS /* allocate transport channels*/ +#ifdef API_5MS + if ( st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) +#endif { int16_t nchan_to_allocate; @@ -688,9 +692,17 @@ static void ivas_dirac_dec_binaural_internal( ivas_sba_prototype_renderer( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe ); } +#ifdef API_5MS + if ( st_ivas->hHeadTrackData ) +#else if ( st_ivas->hHeadTrackData && st_ivas->hHeadTrackData->num_quaternions >= 0 ) +#endif { +#ifdef API_5MS + QuatToRotMat( st_ivas->hHeadTrackData->Quaternion, Rmat ); +#else QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[subframe], Rmat ); +#endif if ( nchan_transport == 2 ) { diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 2f5b406c66..9636f58bbb 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -319,7 +319,11 @@ ivas_error ivas_td_binaural_renderer_unwrap( } #endif /* Update the listener's location/orientation */ +#ifdef API_5MS + TDREND_Update_listener_orientation( hBinRendererTd, Opt_Headrotation, ( Quaternions != NULL ) ? Quaternions : NULL, ( Pos != NULL ) ? Pos : NULL ); +#else TDREND_Update_listener_orientation( hBinRendererTd, Opt_Headrotation, ( Quaternions != NULL ) ? &Quaternions[subframe_idx] : NULL, ( Pos != NULL ) ? &Pos[subframe_idx] : NULL ); +#endif if ( hReverb != NULL && hReverb->pConfig.roomAcoustics.late_reverb_on ) { diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 79ef75e470..649e387c0a 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -64,7 +64,9 @@ ivas_error ivas_headTrack_open( } /* Initialization */ +#ifndef API_5MS ( *hHeadTrackData )->num_quaternions = 0; +#endif ( *hHeadTrackData )->lrSwitchInterpVal = 0.0f; ( *hHeadTrackData )->lrSwitchedCurrent = 0; ( *hHeadTrackData )->lrSwitchedNext = 0; @@ -286,7 +288,11 @@ void rotateFrame_shd( } /* get next quaternion */ +#ifdef API_5MS + QuatToRotMat( hHeadTrackData->Quaternion, hHeadTrackData->Rmat ); +#else QuatToRotMat( hHeadTrackData->Quaternions[hHeadTrackData->num_quaternions++], hHeadTrackData->Rmat ); +#endif /* calculate ambisonics rotation matrices for the previous and current frames */ SHrotmatgen( SHrotmat_prev, hHeadTrackData->Rmat_prev, shd_rot_max_order ); @@ -392,7 +398,11 @@ void rotateFrame_sd( } /* Get next quaternion and calculate rotation matrix */ +#ifdef API_5MS + QuatToRotMat( hHeadTrackData->Quaternion, hHeadTrackData->Rmat ); +#else QuatToRotMat( hHeadTrackData->Quaternions[hHeadTrackData->num_quaternions++], hHeadTrackData->Rmat ); +#endif for ( ch_in = 0; ch_in < nchan; ch_in++ ) { @@ -632,7 +642,11 @@ void rotateFrame_sd_cldfb( } /* Get next quaternion and calculate rotation matrix */ +#ifdef API_5MS + QuatToRotMat( hHeadTrackData->Quaternion, Rmat ); +#else QuatToRotMat( hHeadTrackData->Quaternions[hHeadTrackData->num_quaternions++], Rmat ); +#endif /* rotation of Euler angles */ for ( n = 0; n < nInChannels; n++ ) diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 877076db9a..e7acc00e97 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -260,9 +260,14 @@ typedef struct typedef struct ivas_binaural_head_track_struct { +#ifdef API_5MS + IVAS_QUATERNION Quaternion; + IVAS_VECTOR3 Pos; +#else int16_t num_quaternions; IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_VECTOR3 Pos[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif float Rmat[3][3]; float Rmat_prev[3][3]; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index cd4f16aaa7..f53cbd5695 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2473,10 +2473,13 @@ static DecoderDummy *initDecoderDummy( decDummy->hDecoderConfig->output_Fs = sampleRate; decDummy->hDecoderConfig->nchan_out = numOutChannels; decDummy->hDecoderConfig->Opt_Headrotation = 0; +#ifdef API_5MS + decDummy->hDecoderConfig->tsm_active = 0; +#else #ifdef JBM_TSM_ON_TCS decDummy->hDecoderConfig->voip_active = 0; #endif - +#endif decDummy->hBinRenderer = NULL; decDummy->hEFAPdata = NULL; decDummy->hCrendWrapper = NULL; @@ -2513,6 +2516,12 @@ static DecoderDummy *initDecoderDummy( set_zero( decDummy->hHeadTrackData->chEneIIR[1], MASA_FREQUENCY_BANDS ); set_zero( decDummy->hHeadTrackData->procChEneIIR[0], MASA_FREQUENCY_BANDS ); set_zero( decDummy->hHeadTrackData->procChEneIIR[1], MASA_FREQUENCY_BANDS ); +#ifdef API_5MS + decDummy->hHeadTrackData->Quaternion.w = 1.0f; + decDummy->hHeadTrackData->Quaternion.x = 0.0f; + decDummy->hHeadTrackData->Quaternion.y = 0.0f; + decDummy->hHeadTrackData->Quaternion.z = 0.0f; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { decDummy->hHeadTrackData->Quaternions[i].w = 1.0f; @@ -2520,8 +2529,9 @@ static DecoderDummy *initDecoderDummy( decDummy->hHeadTrackData->Quaternions[i].y = 0.0f; decDummy->hHeadTrackData->Quaternions[i].z = 0.0f; } -#endif decDummy->hHeadTrackData->num_quaternions = 0; +#endif +#endif decDummy->hHeadTrackData->lrSwitchInterpVal = 0.0f; decDummy->hHeadTrackData->lrSwitchedCurrent = 0; decDummy->hHeadTrackData->lrSwitchedNext = 0; -- GitLab From fde3a29385ef0720a21fb9ba897eada28c736ca9 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 15 Jun 2023 08:07:25 +0200 Subject: [PATCH 02/66] temp fix for orientation tracking init --- lib_com/options.h | 2 +- lib_dec/ivas_init_dec.c | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 85195e86cc..11128d2641 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -228,7 +228,7 @@ #define FIX_510 /* FhG: fix issue 510, misleading error message for invalid input format */ #define FIX_509 /* FhG: fix issue 509, too low number of bitsream indices in SBA */ #define FIX_XXX_JITTER_SBA_BINAURAL_GAIN - +#define FIX_XXX_HEADTRACKER_INIT #define API_5MS /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index d696217825..57eac86767 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -631,6 +631,12 @@ ivas_error ivas_init_decoder_front( { return error; } +#ifdef FIX_XXX_HEADTRACKER_INIT + if ( ( error = ivas_orient_trk_SetTrackingType( st_ivas->hHeadTrackData->OrientationTracker, st_ivas->hDecoderConfig->orientation_tracking ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif } /*-------------------------------------------------------------------* @@ -781,6 +787,7 @@ ivas_error ivas_init_decoder( } } +#ifndef FIX_XXX_HEADTRACKER_INIT /*-----------------------------------------------------------------* * Set head/orientation tracking *-----------------------------------------------------------------*/ @@ -834,7 +841,7 @@ ivas_error ivas_init_decoder( } #endif } - +#endif /*-----------------------------------------------------------------* * Allocate and initialize SCE/CPE and other handles *-----------------------------------------------------------------*/ -- GitLab From 8d73b36a1595651fbf1f967b8ea516103181b76b Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 15 Jun 2023 13:06:03 +0200 Subject: [PATCH 03/66] fix compiling, re-add all 5ms API stuff that got lost in the latest merge from main --- apps/decoder.c | 46 ++- lib_com/ivas_prot.h | 2 + lib_dec/ivas_binRenderer_internal.c | 35 ++- lib_dec/ivas_dirac_dec.c | 24 +- lib_dec/ivas_ism_renderer.c | 21 ++ lib_dec/ivas_mc_param_dec.c | 15 +- lib_dec/ivas_objectRenderer_internal.c | 12 + lib_dec/ivas_stat_dec.h | 2 +- lib_dec/lib_dec.c | 91 +++--- lib_dec/lib_dec.h | 24 +- lib_rend/ivas_crend.c | 14 + lib_rend/ivas_dirac_dec_binaural_functions.c | 12 + lib_rend/ivas_objectRenderer.c | 11 +- lib_rend/ivas_prot_rend.h | 9 +- lib_rend/ivas_rotation.c | 288 ++++++++++++++++++- lib_rend/ivas_stat_rend.h | 27 +- lib_rend/lib_rend.c | 107 +++++++ 17 files changed, 637 insertions(+), 103 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 3f8be70cbd..d8f16e7768 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -403,8 +403,8 @@ int main( * Configure the decoder *------------------------------------------------------------------------------------------*/ #ifdef API_5MS - if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.tsmEnabled, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) -#else + if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.tsmEnabled, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) #endif { @@ -1635,8 +1635,9 @@ static ivas_error initOnFirstGoodFrame( static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, - HeadRotFileReader *headRotReader, - HeadRotFileReader *refRotReader, + RotFileReader *headRotReader, + RotFileReader *externalOrientationFileReader, + RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ) @@ -1770,7 +1771,7 @@ static ivas_error decodeG192( 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 ), HeadRotationFileReader_getFilePath( refRotReader ) ); + fprintf( stderr, "\nError %s while reading reference rotation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( refRotReader ) ); goto cleanup; } @@ -1781,6 +1782,30 @@ static ivas_error decodeG192( } } + if ( arg.enableExternalOrientation ) + { + IVAS_QUATERNION Quaternion; + int8_t enableHeadRotation; + int8_t enableExternalOrientation; + int8_t enableRotationInterpolation; + int16_t numFramesToTargetOrientation; + + + if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &Quaternion, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading external orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), + RotationFileReader_getFilePath( externalOrientationFileReader ) ); + goto cleanup; + } + + + if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternion, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + /* Head-tracking input simulation */ if ( arg.enableHeadRotation ) { @@ -1788,7 +1813,7 @@ static ivas_error decodeG192( if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), HeadRotationFileReader_getFilePath( headRotReader ) ); + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); goto cleanup; } @@ -2024,7 +2049,7 @@ static ivas_error decodeG192( 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 ), HeadRotationFileReader_getFilePath( refRotReader ) ); + fprintf( stderr, "\nError %s while reading reference rotation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( refRotReader ) ); goto cleanup; } @@ -2042,7 +2067,7 @@ static ivas_error decodeG192( if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), HeadRotationFileReader_getFilePath( headRotReader ) ); + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); goto cleanup; } @@ -2055,7 +2080,7 @@ static ivas_error decodeG192( } /* decode and get samples */ - if ( ( error = IVAS_DEC_VoIP_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesAvailableNext, &nSamplesFlushed ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2833,7 +2858,8 @@ static ivas_error decodeVoIP( int16_t nOutSamples = 0; #ifndef API_5MS uint16_t nSamplesAvailableNext = 0; -#endif#ifdef DEBUG_JBM_CMD_OPTION +#endif +#ifdef DEBUG_JBM_CMD_OPTION nOutSamples = (int16_t) ( arg.output_Fs / 1000 * arg.frontendFetchSizeMs ); #else nOutSamples = (int16_t) ( arg.output_Fs / 1000 * JBM_FRONTEND_FETCH_FRAMESIZE_MS ); diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 646d025ec3..7d3042d861 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5148,7 +5148,9 @@ void ivas_binaural_cldfb_sf( void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ +#ifndef API_5MS int16_t subframe_idx, /* i : subframe index */ +#endif const int16_t numTimeSlots, /* i: : number of time slots to process */ float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 48eda8b313..eb2e33b80a 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -994,7 +994,11 @@ void ivas_binaural_cldfb( } /* Implement binaural rendering */ +#ifdef API_5MS + ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, JBM_CLDFB_SLOTS_IN_SUBFRAME, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#else ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, subframeIdx, JBM_CLDFB_SLOTS_IN_SUBFRAME, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#endif /* Implement CLDFB synthesis */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) @@ -1086,8 +1090,11 @@ void ivas_binaural_cldfb_sf( } /* Implement binaural rendering */ +#ifdef API_5MS + ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#else ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, subframeIdx, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); - +#endif /* Implement CLDFB synthesis */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { @@ -1120,9 +1127,11 @@ void ivas_binaural_cldfb_sf( *-------------------------------------------------------------------------*/ void ivas_binRenderer( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ - int16_t subframe_idx, /* i : subframe index */ + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ +#ifndef API_5MS + int16_t subframe_idx, /* i : subframe index */ +#endif const int16_t numTimeSlots, /* i : number of time slots to render*/ float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ @@ -1146,8 +1155,10 @@ void ivas_binRenderer( } /* Head rotation in HOA3 or CICPx */ - if ( - hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && hBinRenderer->rotInCldfb ) +#ifdef API_5MS + if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation && hBinRenderer->rotInCldfb ) +#else + if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && hBinRenderer->rotInCldfb ) #endif { if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) @@ -1155,17 +1166,29 @@ void ivas_binRenderer( /* Rotation in SHD (HOA3) */ if ( hCombinedOrientationData->shd_rot_max_order == -1 ) { +#ifdef API_5MS + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); +#else rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); +#endif } else if ( hCombinedOrientationData->shd_rot_max_order > 0 ) { +#ifdef API_5MS + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); +#else rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); +#endif } } else { /* Rotation in SD (CICPx) */ +#ifdef API_5MS + rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat, RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); +#else rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); +#endif } } diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index e7c3b7c371..19f99cad4e 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2456,9 +2456,17 @@ void ivas_dirac_dec_render_sf( set_zero( onset_filter_subframe, hDirAC->num_freq_bands ); } +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation ) +#else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] ) +#endif { +#ifdef API_5MS + p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[0][0]; +#else p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[subframe_idx][0][0]; +#endif if ( st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) { @@ -2522,7 +2530,11 @@ void ivas_dirac_dec_render_sf( set_zero( surCohRatio, hDirAC->num_freq_bands ); } } +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) +#else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) +#endif { ivas_dirac_dec_compute_directional_responses( hDirAC, st_ivas->hVBAPdata, @@ -2615,7 +2627,11 @@ void ivas_dirac_dec_render_sf( if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) +#else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) +#endif { protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, @@ -2848,8 +2864,12 @@ void ivas_dirac_dec_render_sf( ivas_dirac_dec_compute_diffuse_proto( hDirAC, slot_idx ); } - /*Compute PSDs*/ +/*Compute PSDs*/ +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) +#else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) +#endif { ivas_dirac_dec_output_synthesis_process_slot( reference_power, p_onset_filter, @@ -2942,7 +2962,9 @@ void ivas_dirac_dec_render_sf( /* Perform binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, +#ifndef API_5MS subframe_idx, +#endif hDirAC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 6dcc6dcd15..037f4a8b50 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -159,10 +159,17 @@ void ivas_ism_render( else { /* Combined rotation: rotate the object positions depending the head and external orientations */ +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation == 1 ) +#else if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) #endif { +#ifdef API_5MS + rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat, 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 } else { @@ -243,6 +250,9 @@ void ivas_ism_render_sf( set_f( output_f[i], 0.0f, n_samples_to_render ); } +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation ) +#else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] ) #endif { @@ -256,9 +266,17 @@ void ivas_ism_render_sf( { /* Combined rotation: rotate the object positions depending the head and external orientations */ +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation == 1 ) +#else if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) +#endif { +#ifdef API_5MS + rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat, 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 ); @@ -287,6 +305,9 @@ void ivas_ism_render_sf( } /* update here only in case of head rotation */ +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation == 1 ) +#else if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) #endif { diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index a8a5f0c944..16159ad005 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1541,11 +1541,11 @@ void ivas_param_mc_dec_digest_tc( *------------------------------------------------------------------------*/ void ivas_param_mc_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ ) { PARAM_MC_DEC_HANDLE hParamMC; @@ -1755,7 +1755,10 @@ void ivas_param_mc_dec_render( if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { ivas_binRenderer( st_ivas->hBinRenderer, - st_ivas->hCombinedOrientationData, subframe_idx, + st_ivas->hCombinedOrientationData, +#ifndef API_5MS + subframe_idx, +#endif hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); } diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index a4c23b6110..3802c4fc09 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -86,9 +86,15 @@ ivas_error ivas_td_binaural_renderer( st_ivas->transport_config, st_ivas->hBinRendererTd, st_ivas->nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, +#ifdef API_5MS + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->enableCombinedOrientation : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->Quaternion : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->listenerPos : NULL, +#else ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation : NULL, ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->listenerPos : NULL, +#endif ism_md_subframe_update, output, output_frame ); } @@ -178,6 +184,12 @@ ivas_error ivas_td_binaural_renderer_sf( } /* Update the listener's location/orientation */ +#ifdef API_5MS + TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, + ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation : 0, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->Quaternion : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->listenerPos : NULL ); +#else TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] : 0, ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index c31389ddf9..18fedf54aa 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1197,8 +1197,8 @@ typedef struct decoder_config_structure #ifdef API_5MS int16_t tsm_active; #else - int16_t voip_active; +#endif int16_t Opt_delay_comp; /* flag indicating delay compensation active */ } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 841250b0c9..351ddf8722 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -445,9 +445,9 @@ static IVAS_DEC_BS_FORMAT mapIvasFormat( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_Configure( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const uint32_t sampleRate, /* i : output sampling frequency */ - const IVAS_DEC_AUDIO_CONFIG outputFormat, /* i : output format */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const uint32_t sampleRate, /* i : output sampling frequency */ + const IVAS_DEC_AUDIO_CONFIG outputFormat, /* i : output format */ #ifdef API_5MS const int16_t tsmEnabled, /* i : enable TSM */ #endif @@ -611,6 +611,7 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->hVoIP->voipMode = voipMode; hIvasDec->hVoIP->speedFac = speedFac; hIvasDec->hVoIP->needNewFrame = false; +#endif #endif hIvasDec->hVoIP->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); #ifndef API_5MS @@ -654,35 +655,8 @@ ivas_error IVAS_DEC_EnableVoIP( } #endif #endif -#ifndef JBM_TSM_ON_TCS - if ( hDecoderConfig->output_Fs == 8000 ) - { - wss = 1; - css = 1; - } - else if ( hDecoderConfig->output_Fs == 16000 ) - { - wss = 2; - css = 1; - } - else if ( hDecoderConfig->output_Fs == 32000 ) - { - wss = 4; - css = 2; - } - else if ( hDecoderConfig->output_Fs == 48000 ) - { - wss = 6; - css = 3; - } - else - { - return IVAS_ERR_INIT_ERROR; - } -#endif #ifndef API_5MS -#ifdef JBM_TSM_ON_TCS /* postpone init of time scaler and output FIFO until we know the real number of TCs */ hIvasDec->hVoIP->hTimeScaler = NULL; #ifdef VARIABLE_SPEED_DECODING @@ -692,7 +666,6 @@ ivas_error IVAS_DEC_EnableVoIP( } #endif #endif - return error; } @@ -1493,18 +1466,32 @@ ivas_error IVAS_DEC_FeedRefVectorData( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_FeedExternalOrientationData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef API_5MS + IVAS_QUATERNION orientation, /* i : external orientation data */ + int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#else IVAS_QUATERNION *orientation, /* i : external orientation data */ int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#endif ) { EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; +#ifndef API_5MS int16_t i; +#endif +#ifdef API_5MS + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) +#else if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || orientation == NULL ) +#endif { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1517,6 +1504,14 @@ ivas_error IVAS_DEC_FeedExternalOrientationData( } /* Move external orientation data to the decoder handle (invert orientations) */ +#ifdef API_5MS + QuaternionInverse( orientation, &hExternalOrientationData->Quaternion ); + + hExternalOrientationData->enableHeadRotation = enableHeadRotation; + hExternalOrientationData->enableExternalOrientation = enableExternalOrientation; + hExternalOrientationData->enableRotationInterpolation = enableRotationInterpolation; + hExternalOrientationData->numFramesToTargetOrientation = numFramesToTargetOrientation; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { QuaternionInverse( orientation[i], &hExternalOrientationData->Quaternions[i] ); @@ -1526,6 +1521,7 @@ ivas_error IVAS_DEC_FeedExternalOrientationData( hExternalOrientationData->enableRotationInterpolation[i] = enableRotationInterpolation[i]; hExternalOrientationData->numFramesToTargetOrientation[i] = numFramesToTargetOrientation[i]; } +#endif return IVAS_ERR_OK; } @@ -2062,12 +2058,10 @@ ivas_error IVAS_DEC_VoIP_GetSamples( int16_t timeScalingDone; int16_t result; ivas_error error; -#ifdef JBM_TSM_ON_TCS int16_t nSamplesRendered; uint16_t nSamplesTcsScaled; uint8_t nTransportChannels; uint8_t nOutChannels; -#endif error = IVAS_ERR_OK; @@ -2477,23 +2471,6 @@ ivas_error IVAS_DEC_VoIP_GetSamples( assert( nTimeScalerOutSamples <= APA_BUF ); nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; -#else - /* append scaled samples to FIFO */ - if ( pcmdsp_fifo_write( hVoIP->hFifoAfterTimeScaler, (uint8_t *) hVoIP->apaExecBuffer, (uint16_t) ( nTimeScalerOutSamples / hDecoderConfig->nchan_out ) ) != 0 ) - { - return IVAS_ERR_UNKNOWN; - } -#ifdef VARIABLE_SPEED_DECODING - if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) - { - int16_t nSamplesAvailableNext = pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ); - if ( nSamplesAvailableNext < nSamplesPerChannel ) - { - hVoIP->needNewFrame = true; - } - } -#endif -#endif if ( hIvasDec->hasBeenFedFirstGoodFrame && hVoIP->rendererType != JBM_RENDERER_NONE ) { @@ -2622,12 +2599,14 @@ ivas_error IVAS_DEC_VoIP_GetSamples( * Function to flush remaining audio in VoIP *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_VoIP_Flush( +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 */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ - uint16_t *nSamplesAvailableNext, /* o : number of samples still available */ - int16_t *nSamplesFlushed /* o : number of samples flushed */ +#ifndef API_5MS + uint16_t *nSamplesAvailableNext, /* o : number of samples still available */ +#endif + int16_t *nSamplesFlushed /* o : number of samples flushed */ ) { ivas_error error; @@ -2645,6 +2624,7 @@ ivas_error IVAS_DEC_VoIP_Flush( *nSamplesFlushed = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); #else *nSamplesFlushed = min( nSamplesPerChannel, hVoIP->nSamplesAvailableNext ); +#endif #ifndef API_5MS if ( hVoIP->rendererType == JBM_RENDERER_NONE ) @@ -2707,7 +2687,8 @@ bool IVAS_DEC_VoIP_IsEmpty( return ( ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->nSamplesAvailableNext < nSamplesAsked ) ); #else return ( ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->hVoIP->nSamplesAvailableNext < nSamplesAsked ) ); -#endif} +#endif +} /*---------------------------------------------------------------------* diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index f17b6b6835..24d0bf1b57 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -227,11 +227,19 @@ ivas_error IVAS_DEC_FeedRefVectorData( /*! r: error code */ ivas_error IVAS_DEC_FeedExternalOrientationData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION *orientation, /* i : external orientation data */ - int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ - int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ - int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ - int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#ifdef API_5MS + IVAS_QUATERNION orientation, /* i : external orientation data */ + int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#else + IVAS_QUATERNION *orientation, /* i : external orientation data */ + int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#endif ); /*! r: error code */ @@ -279,11 +287,13 @@ ivas_error IVAS_DEC_VoIP_GetSamples( #endif ); -ivas_error IVAS_DEC_VoIP_Flush( +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 */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ - uint16_t *nSamplesAvailableNext, /* o : number of samples still available */ +#ifndef API_5MS + uint16_t *nSamplesAvailableNext, /* o : number of samples still available */ +#endif int16_t *nSamplesFlushed /* o : number of samples flushed */ ); diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index b2b4887499..e5bdd05ed1 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1348,6 +1348,12 @@ ivas_error ivas_rend_crendProcess( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + if ( hCombinedOrientationData->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( hCombinedOrientationData->enableCombinedOrientation[subframe_idx] != 0 ) @@ -1356,6 +1362,7 @@ ivas_error ivas_rend_crendProcess( break; } } +#endif } push_wmops( "ivas_rend_crendProcess" ); @@ -1470,6 +1477,12 @@ ivas_error ivas_rend_crendProcessSubframe( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + if ( hCombinedOrientationData->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( hCombinedOrientationData->enableCombinedOrientation[subframe_idx] != 0 ) @@ -1478,6 +1491,7 @@ ivas_error ivas_rend_crendProcessSubframe( break; } } +#endif } push_wmops( "ivas_rend_crendProcessSubframe" ); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 41605cb678..c698ad1d3f 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -656,7 +656,11 @@ static void ivas_dirac_dec_binaural_internal( { for ( j = 0; j < 3; j++ ) { +#ifdef API_5MS + Rmat[i][j] = hCombinedOrientationData->Rmat[i][j]; +#else Rmat[i][j] = hCombinedOrientationData->Rmat[subframe][i][j]; +#endif } } @@ -669,7 +673,11 @@ static void ivas_dirac_dec_binaural_internal( } ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, +#ifdef API_5MS + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation > 0 ); +#else hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0 ); +#endif if ( st_ivas->ivas_format == ISM_FORMAT ) { @@ -685,7 +693,11 @@ static void ivas_dirac_dec_binaural_internal( } ivas_dirac_dec_binaural_determine_processing_matrices( st_ivas, max_band_decorr, Rmat, +#ifdef API_5MS + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation > 0 ); +#else hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0 ); +#endif ivas_dirac_dec_binaural_process_output( st_ivas, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, subframe ); st_ivas->hDirAC->hDiffuseDist = NULL; diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 86ec0125d5..842925d11a 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -302,8 +302,11 @@ ivas_error ivas_td_binaural_renderer_unwrap( TDREND_Update_object_positions( hBinRendererTd, num_src, ivas_format, hIsmMetaData ); } /* Update the listener's location/orientation */ +#ifdef API_5MS + TDREND_Update_listener_orientation( hBinRendererTd, ( enableCombinedOrientation != NULL ) ? *enableCombinedOrientation : 0, ( Quaternions != NULL ) ? Quaternions : NULL, ( Pos != NULL ) ? Pos : NULL ); +#else TDREND_Update_listener_orientation( hBinRendererTd, ( enableCombinedOrientation != NULL ) ? enableCombinedOrientation[subframe_idx] : 0, ( Quaternions != NULL ) ? &Quaternions[subframe_idx] : NULL, ( Pos != NULL ) ? &Pos[subframe_idx] : NULL ); - +#endif if ( hReverb != NULL ) { if ( ( error = ivas_reverb_process( hReverb, transport_config, 0, output, p_reverb_signal, subframe_idx ) ) != IVAS_ERR_OK ) @@ -676,9 +679,15 @@ ivas_error ivas_td_binaural_renderer_ext( } if ( ( error = ivas_td_binaural_renderer_unwrap( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, +#ifdef API_5MS + ( hCombinedOrientationData != NULL ) ? &( *hCombinedOrientationData )->enableCombinedOrientation : NULL, + ( hCombinedOrientationData != NULL ) ? &( *hCombinedOrientationData )->Quaternion : NULL, + ( hCombinedOrientationData != NULL ) ? &( *hCombinedOrientationData )->listenerPos : NULL, +#else ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->enableCombinedOrientation : NULL, ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->Quaternions : NULL, ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->listenerPos : NULL, +#endif ism_md_subframe_update_ext, p_output, output_frame ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 4ea5cb4484..29a5ace8f4 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -859,15 +859,20 @@ ivas_error combine_external_and_head_orientations_rend( ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ IVAS_VECTOR3 *listenerPos, /* i : listener position */ - int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ +#ifndef API_5MS + int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ +#endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ); void external_target_interpolation( EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ +#ifndef API_5MS + , const int16_t i +#endif ); bool are_orientations_same( diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index dbeda48727..184f382ee8 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -286,7 +286,11 @@ void rotateFrame_shd( /* calculate ambisonics rotation matrices for the previous and current frames */ SHrotmatgen( SHrotmat_prev, hCombinedOrientationData->Rmat_prev, shd_rot_max_order ); +#ifdef API_5MS + SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat, shd_rot_max_order ); +#else SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat[subframe_idx], shd_rot_max_order ); +#endif for ( i = 0; i < subframe_len; i++ ) { @@ -338,7 +342,11 @@ void rotateFrame_shd( /* move Rmat to Rmat_prev */ for ( i = 0; i < 3; i++ ) { +#ifdef API_5MS + mvr2r( hCombinedOrientationData->Rmat[i], hCombinedOrientationData->Rmat_prev[i], 3 ); +#else mvr2r( hCombinedOrientationData->Rmat[subframe_idx][i], hCombinedOrientationData->Rmat_prev[i], 3 ); +#endif } return; @@ -426,7 +434,11 @@ void rotateFrame_sd( /* gains for current subframe rotation */ +#ifdef API_5MS + rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat, hTransSetup.is_planar_setup ); +#else rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat[subframe_idx], hTransSetup.is_planar_setup ); +#endif if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { efap_determine_gains( hEFAPdata, tmp_gains, azimuth, elevation, EFAP_MODE_EFAP ); @@ -463,7 +475,11 @@ void rotateFrame_sd( /* move Rmat to Rmat_prev */ for ( i = 0; i < 3; i++ ) { +#ifdef API_5MS + mvr2r( hCombinedOrientationData->Rmat[i], hCombinedOrientationData->Rmat_prev[i], 3 ); +#else mvr2r( hCombinedOrientationData->Rmat[subframe_idx][i], hCombinedOrientationData->Rmat_prev[i], 3 ); +#endif } /* copy to output */ @@ -692,7 +708,9 @@ ivas_error ivas_external_orientation_open( EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData /* o : external orientation handle */ ) { +#ifndef API_5MS int16_t i; +#endif IVAS_QUATERNION identity; identity.w = 1.0f; @@ -705,6 +723,13 @@ ivas_error ivas_external_orientation_open( } /* Enable head rotation and disable external orientation as default */ +#ifdef API_5MS + ( *hExtOrientationData )->enableHeadRotation = 1; + ( *hExtOrientationData )->enableExternalOrientation = 0; + ( *hExtOrientationData )->enableRotationInterpolation = 0; + ( *hExtOrientationData )->numFramesToTargetOrientation = 0; + ( *hExtOrientationData )->Quaternion = identity; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { ( *hExtOrientationData )->enableHeadRotation[i] = 1; @@ -713,7 +738,7 @@ ivas_error ivas_external_orientation_open( ( *hExtOrientationData )->numFramesToTargetOrientation[i] = 0; ( *hExtOrientationData )->Quaternions[i] = identity; } - +#endif return IVAS_ERR_OK; } @@ -750,7 +775,10 @@ ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData /* o : combined orientation handle */ ) { - int16_t i, j; +#ifndef API_5MS + int16_t i; +#endif + int16_t j; IVAS_QUATERNION identity; IVAS_VECTOR3 origo; @@ -775,6 +803,19 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->Quaternions_ext_interpolation_start = identity; ( *hCombinedOrientationData )->Quaternions_ext_interpolation_target = identity; +#ifdef API_5MS + ( *hCombinedOrientationData )->enableCombinedOrientation = 0; + ( *hCombinedOrientationData )->Quaternion = identity; + ( *hCombinedOrientationData )->Quaternion_prev_headRot = identity; + ( *hCombinedOrientationData )->Quaternion_prev_extOrientation = identity; + ( *hCombinedOrientationData )->listenerPos = origo; + + for ( j = 0; j < 3; j++ ) + { + set_zero( ( *hCombinedOrientationData )->Rmat[j], 3 ); + ( *hCombinedOrientationData )->Rmat[j][j] = 1.0f; + } +#else /* Initialise orientations to identity */ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { @@ -790,7 +831,7 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->Rmat[i][j][j] = 1.0f; } } - +#endif for ( j = 0; j < 3; j++ ) { set_zero( ( *hCombinedOrientationData )->Rmat_prev[j], 3 ); @@ -842,19 +883,29 @@ ivas_error combine_external_and_head_orientations_dec( { IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; +#ifndef API_5MS int16_t numHeadRotQuaternions = 0; +#endif if ( hHeadTrackData != NULL ) { +#ifdef API_5MS + headRotQuaternions = &hHeadTrackData->Quaternion; + listenerPos = &hHeadTrackData->Pos; +#else numHeadRotQuaternions = hHeadTrackData->num_quaternions; if ( hHeadTrackData->num_quaternions >= 0 ) { headRotQuaternions = hHeadTrackData->Quaternions; listenerPos = hHeadTrackData->Pos; } +#endif } - +#ifdef API_5MS + return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); +#else return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); +#endif } @@ -872,8 +923,10 @@ ivas_error combine_external_and_head_orientations_rend( { IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; +#ifndef API_5MS int16_t numHeadRotQuaternions = 0; int16_t i; +#endif if ( hHeadTrackData != NULL ) { @@ -886,6 +939,13 @@ ivas_error combine_external_and_head_orientations_rend( else if ( hExtOrientationData != NULL ) { /* Head rotation data not available, use the freezed value or disable */ +#ifdef API_5MS + if ( hExtOrientationData->enableHeadRotation != 2 ) + { + hExtOrientationData->enableHeadRotation = 0; + } + +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData->enableHeadRotation[i] != 2 ) @@ -893,9 +953,13 @@ ivas_error combine_external_and_head_orientations_rend( hExtOrientationData->enableHeadRotation[i] = 0; } } +#endif } - +#ifdef API_5MS + return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); +#else return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); +#endif } @@ -907,14 +971,19 @@ ivas_error combine_external_and_head_orientations_rend( *------------------------------------------------------------------------*/ ivas_error combine_external_and_head_orientations( - IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ - IVAS_VECTOR3 *listenerPos, /* i : listener position */ - int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ + IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ + IVAS_VECTOR3 *listenerPos, /* i : listener position */ +#ifndef API_5MS + int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ +#endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { - int16_t i, j; +#ifndef API_5MS + int16_t i; +#endif + int16_t j; IVAS_QUATERNION identity; IVAS_VECTOR3 origo; @@ -942,6 +1011,18 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->interpolationIncrement = 1.0f; hCombinedOrientationData->Quaternions_ext_interpolation_start = identity; hCombinedOrientationData->Quaternions_ext_interpolation_target = identity; +#ifdef API_5MS + + hCombinedOrientationData->enableCombinedOrientation = 0; + hCombinedOrientationData->Quaternion = identity; + hCombinedOrientationData->listenerPos = origo; + + for ( j = 0; j < 3; j++ ) + { + set_zero( hCombinedOrientationData->Rmat[j], 3 ); + hCombinedOrientationData->Rmat[j][j] = 1.0f; + } +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { hCombinedOrientationData->enableCombinedOrientation[i] = 0; @@ -954,10 +1035,15 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Rmat[i][j][j] = 1.0f; } } +#endif } else if ( hExtOrientationData == NULL && headRotQuaternions != NULL ) { /* Head rotation only */ +#ifdef API_5MS + hCombinedOrientationData->Quaternion = *headRotQuaternions; + +#else if ( numHeadRotQuaternions >= 0 ) { for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) @@ -965,11 +1051,47 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; } } +#endif } if ( hExtOrientationData != NULL ) { /* External orientations */ +#ifdef API_5MS + + if ( hExtOrientationData->enableRotationInterpolation == 1 && hExtOrientationData->enableExternalOrientation > 0 ) + { + if ( hCombinedOrientationData->isInterpolationOngoing == TRUE && hCombinedOrientationData->interpolationCoefficient <= 1.0f && are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternion ) == true ) + { + /* Continue interpolation */ + QuaternionSlerp( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternion ); + hCombinedOrientationData->interpolationCoefficient += hCombinedOrientationData->interpolationIncrement; + } + else + { + /* Stop interpolation or check for new interpolation */ + hCombinedOrientationData->isInterpolationOngoing = FALSE; + hCombinedOrientationData->interpolationCoefficient = 1.0f; + hCombinedOrientationData->interpolationIncrement = 1.0f; + external_target_interpolation( hExtOrientationData, hCombinedOrientationData ); + } + } + else + { + /* Interpolation disabled, use the current orientation values */ + + /* Use the most recent external orientation */ + if ( hExtOrientationData->enableExternalOrientation == 1 ) + { + hCombinedOrientationData->Quaternion = hExtOrientationData->Quaternion; + } + /* Use the freezed external orientation */ + else if ( hExtOrientationData->enableExternalOrientation == 2 ) + { + hCombinedOrientationData->Quaternion = hCombinedOrientationData->Quaternion_prev_extOrientation; + } + } +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData->enableRotationInterpolation[i] == 1 && hExtOrientationData->enableExternalOrientation[i] > 0 ) @@ -1005,11 +1127,46 @@ ivas_error combine_external_and_head_orientations( } } } +#endif } if ( hExtOrientationData != NULL && headRotQuaternions != NULL ) { /* Combine head and external orientations */ +#ifdef API_5MS + + /* Use the most recent head rotation */ + if ( hExtOrientationData->enableHeadRotation == 1 ) + { + if ( hExtOrientationData->enableExternalOrientation > 0 ) + { + QuaternionProduct( hCombinedOrientationData->Quaternion, *headRotQuaternions, &hCombinedOrientationData->Quaternion ); + } + else + { + hCombinedOrientationData->Quaternion = *headRotQuaternions; + } + } + /* Use the freezed head rotation */ + else if ( hExtOrientationData->enableHeadRotation == 2 ) + { + if ( hExtOrientationData->enableExternalOrientation > 0 ) + { + QuaternionProduct( hCombinedOrientationData->Quaternion, hCombinedOrientationData->Quaternion_prev_headRot, &hCombinedOrientationData->Quaternion ); + } + else + { + hCombinedOrientationData->Quaternion = hCombinedOrientationData->Quaternion_prev_headRot; + } + } + + /* Reset the combined orientations to identity */ + if ( hExtOrientationData->enableHeadRotation == 0 && hExtOrientationData->enableExternalOrientation == 0 ) + { + hCombinedOrientationData->Quaternion = identity; + } + +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { /* Use the most recent head rotation */ @@ -1043,20 +1200,36 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternions[i] = identity; } } +#endif } if ( headRotQuaternions != NULL || hExtOrientationData != NULL ) { /* Calculate the combined rotation matrix */ +#ifdef API_5MS + QuatToRotMat( hCombinedOrientationData->Quaternion, hCombinedOrientationData->Rmat ); +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { QuatToRotMat( hCombinedOrientationData->Quaternions[i], hCombinedOrientationData->Rmat[i] ); } +#endif } /* Save the current orientations */ if ( hExtOrientationData != NULL ) { +#ifdef API_5MS + if ( hExtOrientationData->enableExternalOrientation > 0 ) + { + hCombinedOrientationData->Quaternion_prev_extOrientation = hCombinedOrientationData->Quaternion; + } + else + { + hCombinedOrientationData->Quaternion_prev_extOrientation = identity; + } + +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData->enableExternalOrientation[i] > 0 ) @@ -1068,9 +1241,29 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternions_prev_extOrientation[i] = identity; } } +#endif } if ( headRotQuaternions != NULL ) { +#ifdef API_5MS + if ( hExtOrientationData != NULL ) + { + if ( hExtOrientationData->enableHeadRotation > 0 ) + { + hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternions; + } + else + { + hCombinedOrientationData->Quaternion_prev_headRot = identity; + } + } + else + { + hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternions; + } + hCombinedOrientationData->listenerPos = *listenerPos; + +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData != NULL ) @@ -1097,11 +1290,16 @@ ivas_error combine_external_and_head_orientations( } hCombinedOrientationData->listenerPos[i] = listenerPos[i]; } +#endif } /* Check if combined orientation is enabled */ if ( headRotQuaternions != NULL && hExtOrientationData == NULL ) { +#ifdef API_5MS + hCombinedOrientationData->enableCombinedOrientation = 1; + +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( numHeadRotQuaternions >= 0 ) @@ -1113,9 +1311,20 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->enableCombinedOrientation[i] = 0; } } +#endif } else if ( headRotQuaternions == NULL && hExtOrientationData != NULL ) { +#ifdef API_5MS + if ( hExtOrientationData->enableExternalOrientation > 0 ) + { + hCombinedOrientationData->enableCombinedOrientation = 1; + } + else + { + hCombinedOrientationData->enableCombinedOrientation = 0; + } +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData->enableExternalOrientation[i] > 0 ) @@ -1127,9 +1336,20 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->enableCombinedOrientation[i] = 0; } } +#endif } else if ( headRotQuaternions != NULL && hExtOrientationData != NULL ) { +#ifdef API_5MS + if ( hExtOrientationData->enableExternalOrientation > 0 || hExtOrientationData->enableHeadRotation > 0 ) + { + hCombinedOrientationData->enableCombinedOrientation = 1; + } + else + { + hCombinedOrientationData->enableCombinedOrientation = 0; + } +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData->enableExternalOrientation[i] > 0 || ( hExtOrientationData->enableHeadRotation[i] > 0 && numHeadRotQuaternions >= 0 ) ) @@ -1141,13 +1361,18 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->enableCombinedOrientation[i] = 0; } } +#endif } else { +#ifdef API_5MS + hCombinedOrientationData->enableCombinedOrientation = 0; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { hCombinedOrientationData->enableCombinedOrientation[i] = 0; } +#endif } return IVAS_ERR_OK; @@ -1161,35 +1386,68 @@ ivas_error combine_external_and_head_orientations( *------------------------------------------------------------------------*/ void external_target_interpolation( - EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ - const int16_t i ) + EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ +#ifndef API_5MS + , + const int16_t i +#endif +) { /* Sanity check for number of frames */ +#ifdef API_5MS + hExtOrientationData->numFramesToTargetOrientation = min( hExtOrientationData->numFramesToTargetOrientation, hCombinedOrientationData->maximumFramesToTargetOrientation ); + hExtOrientationData->numFramesToTargetOrientation = max( hExtOrientationData->numFramesToTargetOrientation, 0 ); +#else hExtOrientationData->numFramesToTargetOrientation[i] = min( hExtOrientationData->numFramesToTargetOrientation[i], hCombinedOrientationData->maximumFramesToTargetOrientation ); hExtOrientationData->numFramesToTargetOrientation[i] = max( hExtOrientationData->numFramesToTargetOrientation[i], 0 ); +#endif /* Interpolate from the current orientation to the target orientation */ +#ifdef API_5MS + if ( hExtOrientationData->numFramesToTargetOrientation > 0 ) +#else if ( hExtOrientationData->numFramesToTargetOrientation[i] > 0 ) +#endif { - if ( are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternions[i] ) == false ) +#ifdef API_5MS + if ( are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternion ) == false ) +#else + if ( are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternion ) == false ) +#endif { /* Target orientation is different from the previous target, update the values */ /* Set the received orientation as the target */ +#ifdef API_5MS + hCombinedOrientationData->Quaternions_ext_interpolation_target = hExtOrientationData->Quaternion; +#else hCombinedOrientationData->Quaternions_ext_interpolation_target = hExtOrientationData->Quaternions[i]; +#endif /* Use the most recent external orientation as the starting orientation */ +#ifdef API_5MS + hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternion_prev_extOrientation; +#else hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternions_prev_extOrientation[i]; +#endif /* Calculate the interpolation increment and coefficient */ +#ifdef API_5MS + hCombinedOrientationData->interpolationIncrement = 1.0f / ( (float) hExtOrientationData->numFramesToTargetOrientation * (float) MAX_PARAM_SPATIAL_SUBFRAMES ); +#else hCombinedOrientationData->interpolationIncrement = 1.0f / ( (float) hExtOrientationData->numFramesToTargetOrientation[i] * (float) MAX_PARAM_SPATIAL_SUBFRAMES ); +#endif hCombinedOrientationData->interpolationCoefficient = hCombinedOrientationData->interpolationIncrement; } /* Interpolate */ hCombinedOrientationData->isInterpolationOngoing = TRUE; +#ifdef API_5MS + QuaternionSlerp( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternion ); +#else QuaternionSlerp( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i] ); +#endif hCombinedOrientationData->interpolationCoefficient += hCombinedOrientationData->interpolationIncrement; } else @@ -1198,7 +1456,11 @@ void external_target_interpolation( hCombinedOrientationData->isInterpolationOngoing = FALSE; hCombinedOrientationData->interpolationCoefficient = 1.0f; hCombinedOrientationData->interpolationIncrement = 1.0f; +#ifdef API_5MS + hCombinedOrientationData->Quaternion = hExtOrientationData->Quaternion; +#else hCombinedOrientationData->Quaternions[i] = hExtOrientationData->Quaternions[i]; +#endif } } diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 3dde2563f2..14de5e7d55 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -286,12 +286,19 @@ typedef struct ivas_binaural_head_track_struct typedef struct ivas_external_orientation_struct { +#ifdef API_5MS + int8_t enableHeadRotation; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ + int8_t enableExternalOrientation; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ + int8_t enableRotationInterpolation; /* 0 - disable, 1 - enable */ + int16_t numFramesToTargetOrientation; /* Number of frames until target orientation is reached */ + IVAS_QUATERNION Quaternion; /* External orientation in quaternions */ +#else int8_t enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ int8_t enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ int8_t enableRotationInterpolation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable */ int16_t numFramesToTargetOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Number of frames until target orientation is reached */ IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */ - +#endif } EXTERNAL_ORIENTATION_DATA, *EXTERNAL_ORIENTATION_HANDLE; /*----------------------------------------------------------------------------------* @@ -300,7 +307,11 @@ typedef struct ivas_external_orientation_struct typedef struct ivas_combined_orientation_struct { +#ifdef API_5MS + int16_t enableCombinedOrientation; +#else int16_t enableCombinedOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif float interpolationCoefficient; float interpolationIncrement; int16_t maximumFramesToTargetOrientation; @@ -308,17 +319,31 @@ typedef struct ivas_combined_orientation_struct uint8_t lrSwitchedCurrent; float lrSwitchInterpVal; bool isInterpolationOngoing; +#ifdef API_5MS + IVAS_QUATERNION Quaternion; + IVAS_QUATERNION Quaternion_prev_headRot; + IVAS_QUATERNION Quaternion_prev_extOrientation; +#else IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_QUATERNION Quaternions_prev_headRot[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_QUATERNION Quaternions_prev_extOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif IVAS_QUATERNION Quaternions_ext_interpolation_start; IVAS_QUATERNION Quaternions_ext_interpolation_target; +#ifdef API_5MS + float Rmat[3][3]; +#else float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; +#endif float Rmat_prev[3][3]; float chEneIIR[2][MASA_FREQUENCY_BANDS]; /* independent of the format. MASA bands are suitable for the task and readily available in ROM. */ float procChEneIIR[2][MASA_FREQUENCY_BANDS]; int16_t shd_rot_max_order; +#ifdef API_5MS + IVAS_VECTOR3 listenerPos; +#else IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index c1963fa031..89b51e7745 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2632,6 +2632,7 @@ static DecoderDummy *initDecoderDummy( decDummy->hHeadTrackData->Quaternions[i].y = 0.0f; decDummy->hHeadTrackData->Quaternions[i].z = 0.0f; } +#endif decDummy->hHeadTrackData->lrSwitchInterpVal = 0.0f; decDummy->hHeadTrackData->lrSwitchedCurrent = 0; decDummy->hHeadTrackData->lrSwitchedNext = 0; @@ -4254,21 +4255,35 @@ ivas_error IVAS_REND_SetExternalOrientation( if ( orientation == NULL ) { +#ifdef API_5MS + hIvasRend->hExternalOrientationData->enableExternalOrientation = 0; +#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { hIvasRend->hExternalOrientationData->enableExternalOrientation[i] = 0; } +#endif } else { for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { +#ifdef API_5MS + /* just fix compilation issues, ToDo: change ext renderer also to 5ms */ + QuaternionInverse( orientation[i], &hIvasRend->hExternalOrientationData->Quaternion ); + + hIvasRend->hExternalOrientationData->enableHeadRotation = enableHeadRotation[i]; + hIvasRend->hExternalOrientationData->enableExternalOrientation = enableExternalOrientation[i]; + hIvasRend->hExternalOrientationData->enableRotationInterpolation = enableRotationInterpolation[i]; + hIvasRend->hExternalOrientationData->numFramesToTargetOrientation = numFramesToTargetOrientation[i]; +#else QuaternionInverse( orientation[i], &hIvasRend->hExternalOrientationData->Quaternions[i] ); hIvasRend->hExternalOrientationData->enableHeadRotation[i] = enableHeadRotation[i]; hIvasRend->hExternalOrientationData->enableExternalOrientation[i] = enableExternalOrientation[i]; hIvasRend->hExternalOrientationData->enableRotationInterpolation[i] = enableRotationInterpolation[i]; hIvasRend->hExternalOrientationData->numFramesToTargetOrientation[i] = numFramesToTargetOrientation[i]; +#endif } } @@ -4317,7 +4332,12 @@ ivas_error IVAS_REND_GetCombinedOrientation( { for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { +#ifdef API_5MS + /* fix compilation only,ToDo adapt ext renderer to 5ms , this functions looks stale anyway */ + pOrientation[i] = hIvasRend->hCombinedOrientationData->Quaternion; +#else pOrientation[i] = hIvasRend->hCombinedOrientationData->Quaternions[i]; +#endif } } @@ -4476,7 +4496,12 @@ static ivas_error rotateFrameMc( { for ( j = 0; j < 3; j++ ) { +#ifdef API_5MS + /* fix compiling only, ToDo adapt ext renderer to 5ms */ + Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[i][j]; +#else Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][j]; +#endif } } else @@ -4593,7 +4618,12 @@ static ivas_error rotateFrameSba( { for ( l = 0; l < 3; l++ ) { +#ifdef API_5MS + /* fix compilation only, ToDo adapt ext renderer to 5ms */ + Rmat[i][l] = ( *hCombinedOrientationData )->Rmat[i][l]; +#else Rmat[i][l] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][l]; +#endif } } else @@ -4731,14 +4761,23 @@ static ivas_error renderIsmToBinauralRoom( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compilation only, ToDo adapt ext renderer to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { + if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) { combinedOrientationEnabled = 1; break; } } +#endif } @@ -4750,6 +4789,16 @@ static ivas_error renderIsmToBinauralRoom( { for ( i = 0; i < 3; i++ ) { +#ifdef API_5MS + /* at least this looks like it is adapted to 5ms already since it "loops" only over the first subframe, ToDo needs to be checked */ + if ( hCombinedOrientationData != NULL && ( *hCombinedOrientationData )->enableCombinedOrientation ) + { + for ( j = 0; j < 3; j++ ) + { + Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[i][j]; + } + } +#else if ( hCombinedOrientationData != NULL && ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] ) { for ( j = 0; j < 3; j++ ) @@ -4757,6 +4806,7 @@ static ivas_error renderIsmToBinauralRoom( Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][j]; } } +#endif else { /* Set to identity */ @@ -5156,7 +5206,9 @@ static ivas_error renderMcToBinaural( IVAS_REND_AudioBuffer tmpRotBuffer; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; +#ifndef API_5MS int16_t subframe_idx; +#endif float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; int16_t i; @@ -5173,6 +5225,14 @@ static ivas_error renderMcToBinaural( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compiling only, ToDo ext renderer needs to adapted to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } + +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) @@ -5181,6 +5241,7 @@ static ivas_error renderMcToBinaural( break; } } +#endif } if ( ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) || ( combinedOrientationEnabled @@ -5254,7 +5315,9 @@ static ivas_error renderMcToBinauralRoom( int16_t i; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; +#ifndef API_5MS int16_t subframe_idx; +#endif for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { @@ -5269,6 +5332,13 @@ static ivas_error renderMcToBinauralRoom( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compiling only, ToDo ext renderer needs to adapted to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) @@ -5277,6 +5347,7 @@ static ivas_error renderMcToBinauralRoom( break; } } +#endif } if ( ( mcInput->hReverb != NULL && outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && ( ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) || ( combinedOrientationEnabled && ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1 || inConfig == IVAS_REND_AUDIO_CONFIG_7_1 ) ) ) ) @@ -5349,7 +5420,9 @@ static ivas_error renderMcCustomLsToBinauralRoom( float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; +#ifndef API_5MS int16_t subframe_idx; +#endif push_wmops( "renderMcCustomLsToBinauralRoom" ); @@ -5364,6 +5437,13 @@ static ivas_error renderMcCustomLsToBinauralRoom( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compilin only, ToDo adapt renderer to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) @@ -5372,6 +5452,7 @@ static ivas_error renderMcCustomLsToBinauralRoom( break; } } +#endif } /* apply rotation */ @@ -5635,7 +5716,9 @@ static ivas_error renderSbaToBinaural( int16_t i; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; +#ifndef API_5MS int16_t subframe_idx; +#endif push_wmops( "renderSbaToBinaural" ); @@ -5648,6 +5731,13 @@ static ivas_error renderSbaToBinaural( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compiling only, ToDo ext renderer needs to adapted to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) @@ -5656,6 +5746,7 @@ static ivas_error renderSbaToBinaural( break; } } +#endif } /* apply rotation */ @@ -5711,7 +5802,9 @@ static ivas_error renderSbaToBinauralRoom( float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; +#ifndef API_5MS int16_t subframe_idx; +#endif tmpRotBuffer = outAudio; /* avoid compilation warning */ @@ -5726,6 +5819,13 @@ static ivas_error renderSbaToBinauralRoom( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compiling only, ToDo ext renderer needs to adapted to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) @@ -5734,6 +5834,7 @@ static ivas_error renderSbaToBinauralRoom( break; } } +#endif } /* apply rotation */ @@ -6201,8 +6302,14 @@ static ivas_error renderActiveInputsMasa( { for ( sf_idx = 0; sf_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; ++sf_idx ) { +#ifdef API_5MS + /* fix compilation only, ToDo adapt ext renderer to 5ms */ + pCurrentInput->decDummy->hHeadTrackData->Quaternion = hIvasRend->headRotData.headPositions[sf_idx]; + pCurrentInput->decDummy->hHeadTrackData->Pos = hIvasRend->headRotData.Pos[sf_idx]; +#else pCurrentInput->decDummy->hHeadTrackData->Quaternions[sf_idx] = hIvasRend->headRotData.headPositions[sf_idx]; pCurrentInput->decDummy->hHeadTrackData->Pos[sf_idx] = hIvasRend->headRotData.Pos[sf_idx]; +#endif } } -- GitLab From 167aafc1b91d5e80f17084f9579de437b2483e75 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 15 Jun 2023 13:46:31 +0200 Subject: [PATCH 04/66] Add tests for 5ms renderer framing The feature is not implemented yet so they will fail --- tests/renderer/constants.py | 3 ++ tests/renderer/test_renderer.py | 68 ++++++++++++++++++++++----------- tests/renderer/utils.py | 4 ++ 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index 877a1454c2..5780ee964b 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -200,6 +200,9 @@ HR_TRAJECTORIES_TO_TEST = [ "rotate_yaw_pitch_roll1", ] +""" 5ms framing """ +FRAMING_5MS_TO_TEST = [True, False] + """ Per-testcase xfail SNR thresholds (dB) """ pass_snr = dict() # not relevant for tests anymore, should be deprecated soon _pass_snr = { diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index 22f439c8b1..beed8e897b 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -35,24 +35,28 @@ from .utils import * @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:]) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) -def test_ambisonics(test_info, in_fmt, out_fmt): - run_renderer(in_fmt, out_fmt) +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_ambisonics(test_info, in_fmt, out_fmt, framing_5ms): + run_renderer(in_fmt, out_fmt, framing_5ms=framing_5ms) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) -def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt): - run_renderer(in_fmt, out_fmt) +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt, framing_5ms): + run_renderer(in_fmt, out_fmt, framing_5ms=framing_5ms) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) -def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file, framing_5ms): run_renderer( in_fmt, out_fmt, trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + framing_5ms=framing_5ms, ) @@ -250,23 +254,26 @@ def test_ambisonics_binaural_headrotation_refveclev_vs_refvec( @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:]) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) -def test_multichannel(test_info, in_fmt, out_fmt): - run_renderer(in_fmt, out_fmt) +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_multichannel(test_info, in_fmt, out_fmt, framing_5ms): + run_renderer(in_fmt, out_fmt, framing_5ms=framing_5ms) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) -def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_multichannel_binaural_static(test_info, in_fmt, out_fmt, framing_5ms): if in_fmt in ["MONO", "STEREO"]: pytest.skip("MONO or STEREO to Binaural rendering unsupported") - run_renderer(in_fmt, out_fmt) + run_renderer(in_fmt, out_fmt, framing_5ms=framing_5ms) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) -def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file, framing_5ms): if in_fmt in ["MONO", "STEREO"]: pytest.skip("MONO or STEREO to Binaural rendering unsupported") @@ -275,12 +282,14 @@ def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file in_fmt, out_fmt, trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + framing_5ms=framing_5ms, ) else: run_renderer( in_fmt, out_fmt, trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + framing_5ms=framing_5ms, ) @@ -318,28 +327,31 @@ def test_multichannel_binaural_headrotation_refvec_rotating(test_info, in_fmt, o @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:]) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) -def test_ism(test_info, in_fmt, out_fmt): - run_renderer(in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt]) +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_ism(test_info, in_fmt, out_fmt, framing_5ms): + run_renderer(in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], framing_5ms=framing_5ms) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) -def test_ism_binaural_static(test_info, in_fmt, out_fmt): +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_ism_binaural_static(test_info, in_fmt, out_fmt, framing_5ms): try: in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] except: in_meta_files = None if out_fmt == "BINAURAL": - run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) + run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files, framing_5ms=framing_5ms) else: - run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) + run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files, framing_5ms=framing_5ms) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) -def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file, framing_5ms): try: in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] except: @@ -351,6 +363,7 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): out_fmt, trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), in_meta_files=in_meta_files, + framing_5ms=framing_5ms, ) else: run_renderer( @@ -358,6 +371,7 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): out_fmt, trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), in_meta_files=in_meta_files, + framing_5ms=framing_5ms, ) @@ -399,8 +413,9 @@ def test_ism_binaural_headrotation_refvec_rotating(test_info, in_fmt, out_fmt): @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) -def test_masa(test_info, in_fmt, out_fmt): - run_renderer(in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt]) +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_masa(test_info, in_fmt, out_fmt, framing_5ms): + run_renderer(in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], framing_5ms=framing_5ms) """ Custom loudspeaker layouts """ @@ -408,8 +423,9 @@ def test_masa(test_info, in_fmt, out_fmt): @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:]) @pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) -def test_custom_ls_input(test_info, in_layout, out_fmt): - run_renderer(CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt) +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_custom_ls_input(test_info, in_layout, out_fmt, framing_5ms): + run_renderer(CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt, framing_5ms=framing_5ms) @pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) @@ -432,21 +448,25 @@ def test_custom_ls_input_output(test_info, in_fmt, out_fmt): @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) -def test_custom_ls_input_binaural(test_info, in_layout, out_fmt): +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_custom_ls_input_binaural(test_info, in_layout, out_fmt, framing_5ms): run_renderer( CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt, + framing_5ms=framing_5ms, ) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) -def test_custom_ls_input_binaural_headrotation(test_info, in_layout, out_fmt, trj_file): +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_custom_ls_input_binaural_headrotation(test_info, in_layout, out_fmt, trj_file, framing_5ms): run_renderer( CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt, trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + framing_5ms=framing_5ms, ) @@ -455,11 +475,13 @@ def test_custom_ls_input_binaural_headrotation(test_info, in_layout, out_fmt, tr @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS[2:]) @pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST) -def test_metadata(test_info, in_fmt, out_fmt): +@pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) +def test_metadata(test_info, in_fmt, out_fmt, framing_5ms): run_renderer( "META", out_fmt, metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), + framing_5ms=framing_5ms, ) diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index 356902ff47..ac5c57695a 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -114,6 +114,7 @@ def run_renderer( output_path_base: str = OUTPUT_PATH_CUT, binary_suffix: str = "", is_comparetest: Optional[bool] = False, + framing_5ms: Optional[bool] = False, ) -> Tuple[np.ndarray, int]: """CuT creation with standalone renderer""" if trj_file is not None: @@ -200,6 +201,9 @@ def run_renderer( if config_file is not None: cmd.extend(["-rc", str(config_file)]) + if framing_5ms: + cmd.extend(["-fr5"]) + run_cmd(cmd) return pyaudio3dtools.audiofile.readfile(out_file) -- GitLab From 52b5489763af0a72c31f3febebe5dcc6d9dcad83 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 15 Jun 2023 13:55:13 +0200 Subject: [PATCH 05/66] fix compiling issues with API_5MS inactive --- apps/decoder.c | 10 +++++++--- lib_com/options.h | 1 + lib_dec/ivas_jbm_dec.c | 3 +++ lib_dec/lib_dec.c | 10 ++++++++++ lib_rend/ivas_objectRenderer.c | 8 ++++++++ lib_rend/ivas_objectRenderer_hrFilt.c | 3 ++- lib_rend/ivas_rotation.c | 2 +- 7 files changed, 32 insertions(+), 5 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index d8f16e7768..d8229ce705 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -2080,7 +2080,7 @@ static ivas_error decodeG192( } /* decode and get samples */ - if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2858,7 +2858,7 @@ static ivas_error decodeVoIP( int16_t nOutSamples = 0; #ifndef API_5MS uint16_t nSamplesAvailableNext = 0; -#endif +#endif #ifdef DEBUG_JBM_CMD_OPTION nOutSamples = (int16_t) ( arg.output_Fs / 1000 * arg.frontendFetchSizeMs ); #else @@ -3325,7 +3325,11 @@ static ivas_error decodeVariableSpeed( fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); goto cleanup; } +#ifdef API_5MS IVAS_DEC_VoIP_SetScale( hIvasDec, scale, scale ); +#else + IVAS_DEC_VoIP_SetScale( hIvasDec, scale ); +#endif } if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) @@ -3581,7 +3585,7 @@ static ivas_error decodeVariableSpeed( } /* decode and get samples */ - if ( ( error = IVAS_DEC_VoIP_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesAvailableNext, &nSamplesFlushed ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesAvailableNext, &nSamplesFlushed ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; diff --git a/lib_com/options.h b/lib_com/options.h index bee9901a56..9caeda123a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -156,6 +156,7 @@ #define FIX_XXX_JITTER_SBA_BINAURAL_GAIN #define FIX_XXX_HEADTRACKER_INIT +#define FIX_XXX_TDOBJRENDERER_INPUT #define API_5MS /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 2c0a05465c..8e6b0541db 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -1645,6 +1645,9 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( n_samp_full = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); n_samp_residual = 0; } +#else + n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); + n_samp_residual = hTcBuffer->n_samples_granularity - 1; #endif nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; nsamp_to_allocate += nchan_residual * n_samp_residual; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 351ddf8722..86d46fe2b0 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3655,6 +3655,7 @@ ivas_error IVAS_DEC_reconfigure( #ifdef API_5MS } #endif +#ifdef API_5MS if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) { @@ -3662,6 +3663,15 @@ ivas_error IVAS_DEC_reconfigure( } set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); +#else + if ( ( hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ) ) == NULL ) + + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } + + set_zero( hVoIP->apaExecBuffer, APA_BUF_PER_CHANNEL * nTransportChannels ); +#endif } else { diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 842925d11a..9f39aa8b93 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -397,9 +397,17 @@ ivas_error TDREND_GetMix( { pan_left = ( SrcSpatial_p->Pos_p[1] + 1.f ) * 0.5f; pan_right = 1.f - pan_left; +#ifdef FIX_XXX_TDOBJRENDERER_INPUT + v_multc_acc( Src_p->InputFrame_p, pan_left, output_buf[0], subframe_length ); + v_multc_acc( Src_p->InputFrame_p, pan_right, output_buf[1], subframe_length ); +#else v_multc_acc( &Src_p->InputFrame_p[subframe_idx * subframe_length], pan_left, output_buf[0], subframe_length ); v_multc_acc( &Src_p->InputFrame_p[subframe_idx * subframe_length], pan_right, output_buf[1], subframe_length ); +#endif } +#ifdef FIX_XXX_TDOBJRENDERER_INPUT + Src_p->InputFrame_p += subframe_length; +#endif } /* Populate output variable */ diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index 6463261ec4..084da6550c 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -79,8 +79,9 @@ ivas_error TDREND_REND_RenderSourceHRFilt( v_add( LeftOutputFrame, output_buf[0], output_buf[0], subframe_length ); v_add( RightOutputFrame, output_buf[1], output_buf[1], subframe_length ); +#ifndef FIX_XXX_TDOBJRENDERER_INPUT Src_p->InputFrame_p += subframe_length; /* Increment input pointer */ - +#endif return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 184f382ee8..0997626bbb 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -1413,7 +1413,7 @@ void external_target_interpolation( #ifdef API_5MS if ( are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternion ) == false ) #else - if ( are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternion ) == false ) + if ( are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternions[i] ) == false ) #endif { /* Target orientation is different from the previous target, update the values */ -- GitLab From c0f7678d6bb651ce2b856a32b854929c395f6664 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 15 Jun 2023 14:07:16 +0200 Subject: [PATCH 06/66] Copy CI yml from from other repo for easier editing --- .gitlab-ci-custom.yml | 1092 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1088 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index 86c1f487e0..bef4bdb69e 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -1,4 +1,1088 @@ -include: - - project: $CUSTOM_CI_PROJECT - ref: $CUSTOM_CI_REF - file: $CUSTOM_CI_FILE +# include: +# - project: $CUSTOM_CI_PROJECT +# ref: $CUSTOM_CI_REF +# file: $CUSTOM_CI_FILE + +# Copied from ivas-ci:main + +variables: + # Variables as used in external repo (may be altered in value, see comments) + TESTV_DIR: "/usr/local/testv" + LTV_DIR: "/usr/local/ltv" + BUILD_OUTPUT: "build_output.txt" + EVS_BE_TEST_DIR: "/usr/local/be_2_evs_test" + SANITIZER_TESTS: "CLANG1 CLANG2" + OUT_FORMATS_CHANNEL_BASED: "stereo mono 5_1 5_1_2 5_1_4 7_1 7_1_4" + OUT_FORMATS_SCENE_BASED: "FOA HOA2 HOA3" + OUT_FORMATS_BINAURAL: "BINAURAL BINAURAL_ROOM_IR BINAURAL_ROOM_REVERB" + EXIT_CODE_NON_BE: 123 + EXIT_CODE_FAIL: 1 + # Variables for FhG internal jobs + UPSTREAM_URL: "https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/" + INTERNAL_TESTV_DIR: "/testv" + INTERNAL_CI_REPO_CLONE_DIR: "ivas-internal-ci" + + +# This sets when pipelines are created. Jobs have more specific rules to restrict them. +workflow: + rules: + # see https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" + when: never + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' # Runs for merge requests + - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Pushes to main + - if: $CI_PIPELINE_SOURCE == 'schedule' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Scheduled in main + - if: $CI_PIPELINE_SOURCE == 'web' # Scheduled in main + + +stages: + - mirroring-pre-test + - build + - test + - compare + - validate + - mirroring-post-test + +# --------------------------------------------------------------- +# Generic script anchors +# --------------------------------------------------------------- + +# These can be used later on to do common tasks + +# Prints useful information for every job and should be used at the beginning of each job +.print-common-info: &print-common-info + - | + echo "Printing common information for build job." + echo "Current job is run on commit $CI_COMMIT_SHA" + echo "Commit time was $CI_COMMIT_TIMESTAMP" + date | xargs echo "System time is" + +.get-previous-merge-commit-sha: &get-previous-merge-commit-sha + - previous_merge_commit=$(git --no-pager log --merges HEAD~1 -n 1 --pretty=format:%H) + +.mr-fetch-target-branch: &mr-fetch-target-branch + # first delete local target branch to avoid conflicts when branch is cached and there are merge conflicts during fetching + # depending on chaching, the branch may not be there, so prevent failure of this command -> should maybe be done smarter later + - git branch -D $CI_MERGE_REQUEST_TARGET_BRANCH_NAME || true + # needed when depth is lower than the number of commits in the branch + - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:$CI_MERGE_REQUEST_TARGET_BRANCH_NAME + +.mr-get-target-commit: &mr-get-target-commit + # compare to last target branch commit before pipeline was created + - target_commit=$(git log $CI_MERGE_REQUEST_TARGET_BRANCH_NAME -1 --oneline --before=${CI_PIPELINE_CREATED_AT} --format=%H) + +# [INTERNAL] clone the ivas-internal-ci repo +.get-ivas-internal-ci-repo: &get-ivas-internal-ci-repo + - git clone --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@$CI_SERVER_HOST/$CUSTOM_CI_PROJECT $INTERNAL_CI_REPO_CLONE_DIR + +# [INTERNAL] use this anchor to copy over the "old" internal testv/ files +.overwrite-testv-with-internal-ones: &overwrite-testv-with-internal-ones + - cp $INTERNAL_CI_REPO_CLONE_DIR/internal-testv/* scripts/testv/ + +# [INTERNAL] use for getting the sanitizer testvectors from ivas-internal-ci +.get-internal-ltv-signals: &get-internal-ltv-signals + # overwrite config + - cp $INTERNAL_CI_REPO_CLONE_DIR/scripts/ci_sanitizers_fhg_testv.json scripts/config/ci_linux_ltv.json + # copy files + - if [ ! -d "$LTV_DIR" ]; then mkdir -p $LTV_DIR; fi + - cp $INTERNAL_CI_REPO_CLONE_DIR/internal-ltv/* $LTV_DIR/ + +# --------------------------------------------------------------- +# Job templates +# --------------------------------------------------------------- + +# When designing templates, try not to use too much inheritance and +# if multiple templates and extended on, remember that on conflict, +# latest overwrites the parameter. + +# templates for rules +.rules-basis: + rules: + - if: $MIRROR_ACCESS_TOKEN # Don't run in the mirror update pipeline (only then MIRROR_ACCESS_TOKEN is defined) + when: never + - when: on_success + - if: $CI_PIPELINE_SOURCE == 'schedule' # Don't run in any scheduled pipelines by default (use schedule templates below to enable again for certain conditions) + when: never + - when: on_success + +.rules-merge-request: + extends: .rules-basis + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + +.rules-main-push: + extends: .rules-basis + rules: + - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + +.rules-main-scheduled: + extends: .rules-basis + rules: + - if: $CI_PIPELINE_SOURCE == 'schedule' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + + +# templates to define stages and platforms + +# differs from forge -> we use docker image here +.test-job-linux: + tags: + - exec::docker + image: $CUSTOM_CI_REGISTRY/ubuntu_22.04:latest + +# differs from forge -> we use docker image here +.build-job-linux: + stage: build + # more time internally to accomodate for the shared runners + timeout: "4 minutes" + tags: + - exec::docker + image: $CUSTOM_CI_REGISTRY/ubuntu_22.04:latest + + +# template for test jobs on linux that need the TESTV_DIR +.test-job-linux-needs-testv-dir: + extends: .test-job-linux + tags: + - exec::docker + - res::ivas-testv + before_script: + - if [ ! -d "$TESTV_DIR" ]; then mkdir -p $TESTV_DIR; fi + - cp -r scripts/testv/* $TESTV_DIR/ + +# [INTERNAL] use the internal testvectors for self_test.prm items +.test-job-linux-needs-internal-testv-dir: + extends: .test-job-linux + tags: + - exec::docker + - res::ivas-testv + before_script: + - if [ ! -d "$TESTV_DIR" ]; then mkdir -p $TESTV_DIR; fi + # first copy external testvectors, then overwrite with internal ones + # this way, newly added vectors that have no internal pendent are not missing + - cp -r scripts/testv/* $TESTV_DIR/ + - cp -r $INTERNAL_TESTV_DIR/* $TESTV_DIR/ + +# [INTERNAL] copy "old" internal testvectors to scripts/testv to use them in self_test.prm-based test +.test-job-linux-with-internal-selftest-vectors: + extends: .test-job-linux + tags: + - exec::docker + - res::ivas-testv + before_script: + - cp -r $INTERNAL_TESTV_DIR/* ./scripts/testv/ + +# template for build jobs to include the check for warnings +.build-job-with-check-for-warnings: + extends: .build-job-linux + stage: build + allow_failure: + exit_codes: + - 123 + + +# --------------------------------------------------------------- +# Build jobs +# --------------------------------------------------------------- + +build-codec-linux-make: + extends: + - .build-job-with-check-for-warnings + - .rules-basis + script: + - *print-common-info + - make -j 2>&1 | tee $BUILD_OUTPUT + # need to use the "|| exit $?" suffix to get the allowed_failure return code, otherwise the job fails with code 1...< + - ci/check_for_warnings.py $BUILD_OUTPUT || exit $? + +build-codec-linux-cmake: + extends: + - .build-job-with-check-for-warnings + - .rules-basis + script: + - *print-common-info + - mkdir build + - cd build + - cmake .. + - cd .. + - make -C build -j 2>&1 | tee $BUILD_OUTPUT + # need to use the "|| exit $?" suffix to get the allowed_failure return code, otherwise the job fails with code 1...< + - ci/check_for_warnings.py $BUILD_OUTPUT || exit $? + +build-codec-instrumented-linux: + extends: + - .build-job-linux + - .rules-basis + script: + - *print-common-info + - bash ci/build_codec_instrumented_linux.sh + +# make sure that the codec builds with msan, asan and usan +build-codec-sanitizers-linux: + extends: + - .build-job-linux + - .rules-basis + script: + - *print-common-info + - bash ci/build_codec_sanitizers_linux.sh + + +# --------------------------------------------------------------- +# Test jobs for merge requests +# --------------------------------------------------------------- + +# test that runs all modes with 1s input signals +codec-smoke-test: + extends: + - .test-job-linux-needs-internal-testv-dir + - .rules-merge-request + timeout: "5 minutes" + stage: test + needs: [ "build-codec-linux-cmake" ] + script: + - *print-common-info + - bash ci/smoke_test.sh + ### analyze for failures + - if cat smoke_test_output.txt | grep -c "failed"; then echo "Smoke test without PLC failed"; exit 1; fi + - if cat smoke_test_output_plc.txt | grep -c "failed"; then echo "Smoke test with PLC failed"; exit 1; fi + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + when: always + paths: + - out/logs/ + - smoke_test_output.txt + - smoke_test_output_plc.txt + expose_as: 'Smoke test results' + + +# code selftest testvectors with memory-sanitizer binaries +msan-on-merge-request-linux: + extends: + - .test-job-linux + - .rules-merge-request + stage: test + needs: [ "build-codec-sanitizers-linux" ] + script: + - *print-common-info + - make clean + - make -j CLANG=1 + - python3 scripts/self_test.py --create | tee test_output.txt + - run_errors=$(cat test_output.txt | grep -ic "run errors") || true + - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py with Clang memory-sanitizer"; exit 1; fi + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + paths: + - scripts/ref/logs/ + - test_output.txt + expose_as: 'Msan selftest results' + + +# code selftest testvectors with address-sanitizer binaries +asan-on-merge-request-linux: + extends: + - .test-job-linux + - .rules-merge-request + stage: test + needs: [ "build-codec-sanitizers-linux" ] + script: + - *print-common-info + - make clean + - make -j CLANG=2 + - python3 scripts/self_test.py --create | tee test_output.txt + - run_errors=$(cat test_output.txt | grep -ic "run errors") || true + - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py with Clang address-sanitizer"; exit 1; fi + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + paths: + - scripts/ref/logs/ + - test_output.txt + expose_as: 'Asan selftest results' + +# test renderer executable +renderer-smoke-test: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-make"] + stage: test + script: + - make -j IVAS_rend + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + when: always + paths: + - report-junit.xml + expose_as: "renderer make pytest results" + reports: + junit: + - report-junit.xml + +# test renderer executable with cmake + asan +renderer-asan: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-cmake"] + stage: test + script: + - python3 ci/disable_ram_counting.py + - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true + - cmake --build cmake-build -- -j + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + when: always + paths: + - report-junit.xml + expose_as: "renderer asan pytest results" + reports: + junit: + - report-junit.xml + +# test renderer executable with cmake + msan +renderer-msan: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-cmake"] + stage: test + script: + - python3 ci/disable_ram_counting.py + - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true + - cmake --build cmake-build -- -j + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + when: always + paths: + - report-junit.xml + expose_as: "renderer msan pytest results" + reports: + junit: + - report-junit.xml + + +.merge-request-comparison-setup-codec: + &merge-request-comparison-setup-codec ### build test binaries, initial clean for paranoia reasons + - make clean + - mkdir build + - cd build + - cmake .. + - make -j + - mv IVAS_cod ../IVAS_cod_test + - mv IVAS_dec ../IVAS_dec_test + - mv IVAS_rend .. + - cd .. + - rm -rf build/* + + ### store the current commit hash + - source_branch_commit_sha=$(git rev-parse HEAD) + + ### checkout version to compare against + - *mr-fetch-target-branch + + - *mr-get-target-commit + - git checkout $target_commit + + ### build reference binaries + - cd build + - cmake .. + - make -j + - mv IVAS_cod ../IVAS_cod_ref + - mv IVAS_dec ../IVAS_dec_ref + - cd .. + + # rename test binaries back + - mv IVAS_cod_test IVAS_cod + - mv IVAS_dec_test IVAS_dec + +.merge-request-comparison-check: &merge-request-comparison-check + - if [ $zero_errors != 1 ]; then echo "Run errors encountered!"; exit $EXIT_CODE_FAIL; fi + - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "Non-bitexact cases without non-BE tag encountered!"; exit $EXIT_CODE_FAIL; fi + - if [ $exit_code -eq 1 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; exit $EXIT_CODE_NON_BE; fi + - exit 0 + +# compare renderer bitexactness between target and source branch +renderer-pytest-on-merge-request: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-make"] + # TODO: set reasonable timeout, will most likely take less + timeout: "20 minutes" + stage: compare + script: + - *print-common-info + + # some helper variables - "|| true" to prevent failures from grep not finding anything + - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend\(erer\)*[ -]*non[ -]*be\]") || true + # TODO: needs splitting the test between reference and cut generation + #- ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true + + # store the current commit hash + - source_branch_commit_sha=$(git rev-parse HEAD) + + - *mr-fetch-target-branch + - *mr-get-target-commit + - git checkout $target_commit + + # build reference binaries + - make -j IVAS_rend + - mv IVAS_rend IVAS_rend_ref + + # back to source branch + - git checkout $source_branch_commit_sha + - make clean + - make -j IVAS_rend + + # run test + - exit_code=0 + - python3 -m pytest -q --log-level ERROR -n auto -rA --html=report.html --self-contained-html --junit-xml=report-junit.xml tests/renderer/test_renderer_be_comparison.py || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + when: always + paths: + - report-junit.xml + - report.html + expose_as: "pytest renderer results" + reports: + junit: + - report-junit.xml + +# compare bit exactness between target and source branch +# [INTERNAL] this uses our own testvectors internally! +ivas-pytest-on-merge-request: + extends: + - .test-job-linux + - .rules-merge-request + stage: compare + needs: ["build-codec-linux-cmake", "codec-smoke-test"] + timeout: "10 minutes" + script: + - *print-common-info + - *merge-request-comparison-setup-codec + - *get-ivas-internal-ci-repo + - *overwrite-testv-with-internal-ones + + # some helper variables - "|| true" to prevent failures from grep not finding anything + - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[non[ -]*be\]") || true + - ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true + + ### If ref_using_main is not set, checkoug the source branch to use scripts and input from there + - if [ $ref_using_main == 0 ]; then git checkout $source_branch_commit_sha; fi + + ### prepare pytest + # create short test vectors + - python3 tests/create_short_testvectors.py + # create references + - python3 -m pytest tests -v --update_ref 1 -m create_ref + - python3 -m pytest tests -v --update_ref 1 -m create_ref_part2 + + ### Run test using branch scripts and input + - if [ $ref_using_main == 1 ]; then git checkout $source_branch_commit_sha; fi + + ### run pytest + - exit_code=0 + - python3 -m pytest tests -v --junit-xml=report-junit.xml || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + when: always + paths: + - report-junit.xml + expose_as: "pytest ivas results" + reports: + junit: + - report-junit.xml + +# compare external renderer bitexactness between target and source branch +external-renderer-pytest-on-merge-request: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-make"] + # TODO: set reasonable timeout, will most likely take less + timeout: "20 minutes" + stage: compare + script: + - *print-common-info + + # some helper variables - "|| true" to prevent failures from grep not finding anything + - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend\(erer\)*[ -]*non[ -]*be\]") || true + # TODO: needs splitting the test between reference and cut generation + #- ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true + + # store the current commit hash + - source_branch_commit_sha=$(git rev-parse HEAD) + + - *mr-fetch-target-branch + - *mr-get-target-commit + - git checkout $target_commit + + # build reference binaries + - make -j IVAS_rend + - mv IVAS_rend IVAS_rend_ref + + # back to source branch + - git checkout $source_branch_commit_sha + - make clean + - make -j IVAS_rend + + # run test + - exit_code=0 + - python3 -m pytest -q --log-level ERROR -n auto -rA --html=report.html --self-contained-html --junit-xml=report-junit.xml tests/renderer/test_renderer_be_comparison.py || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + when: always + paths: + - report-junit.xml + - report.html + expose_as: "pytest external renderer results" + reports: + junit: + - report-junit.xml + +evs-pytest-on-merge-request: + extends: + - .test-job-linux + - .rules-merge-request + stage: compare + needs: ["build-codec-linux-cmake", "codec-smoke-test"] + timeout: "10 minutes" + script: + - *print-common-info + - *merge-request-comparison-setup-codec + - *get-ivas-internal-ci-repo + - *overwrite-testv-with-internal-ones + + # some helper variables - "|| true" to prevent failures from grep not finding anything + - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[evs[ -]*non[ -]*be\]") || true + - ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true + + ### If ref_using_main is not set, checkoug the source branch to use scripts and input from there + - if [ $ref_using_main == 0 ]; then git checkout $source_branch_commit_sha; fi + + ### prepare pytest + # create references + - python3 -m pytest tests/test_param_file.py -v --update_ref 1 -m create_ref --param_file scripts/config/self_test_evs.prm + + ### Run test using branch scripts and input + - if [ $ref_using_main == 1 ]; then git checkout $source_branch_commit_sha; fi + + ### run pytest for EVS cases + - exit_code=0 + - python3 -m pytest tests/test_param_file.py -v --param_file scripts/config/self_test_evs.prm --junit-xml=report-junit-evs.xml || exit_code=$? + - zero_errors=$(cat report-junit-evs.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + when: always + paths: + - report-junit-evs.xml + expose_as: "pytest evs results" + reports: + junit: + - report-junit-evs.xml + +clang-format-check: + extends: + - .test-job-linux + - .rules-merge-request + variables: + ARTIFACT_BASE_NAME: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--formatting-fix" + stage: validate + needs: [] + timeout: "5 minutes" + script: + # Set up variables. This can't be done in the "variables" section because variables are not expanded properly there + - PATCH_FILE_NAME="$ARTIFACT_BASE_NAME".patch + - > + INSTRUCTIONS_GITLAB="To fix formatting issues:\n + - download the diff patch available as artifact of this job\n + - unzip the artifact and place the patch file in the root directory of your local IVAS repo\n + - run: git apply $PATCH_FILE_NAME\n + - commit new changes" + - > + INSTRUCTIONS_README="To fix formatting issues:\n + - place the patch file in the root directory of your local IVAS repo\n + - run: git apply $PATCH_FILE_NAME\n + - commit new changes" + + - scripts/check-format.sh -af -p 8 || format_problems=$? + - if [ $format_problems == 0 ] ; then exit 0; fi + + - mkdir tmp-formatting-fix + - git diff > "tmp-formatting-fix/$PATCH_FILE_NAME" + + # Print instructions to job output + - echo -e "$INSTRUCTIONS_GITLAB" + + # Include readme in the artifact, in case someone misses the job printout (e.g. getting the artifact via MR interface) + - echo -e "$INSTRUCTIONS_README" > "tmp-formatting-fix/readme.txt" + + - exit $format_problems + artifacts: + paths: + - tmp-formatting-fix/ + when: on_failure + name: "$ARTIFACT_BASE_NAME" + expose_as: 'formatting patch' + + +# --------------------------------------------------------------- +# Test jobs for main branch +# --------------------------------------------------------------- + +# check bitexactness to EVS +# difference to forge: on the forge, this job runs only on pushes to main +# those are mirrored to our repo anyway, so no push-to-main triggers exist in +# our internal repo. Testing BE to EVS is probably only useful before moving a +# feature branch from internal to external repo. Therefore, this job internally +# runs on MR pipelines +be-2-evs-linux: + extends: + - .test-job-linux + # manual rules here to have .rules-main-push + run on MR + rules: + - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + # this is different from the forge repo -> allow manual run of the EVS-BE test + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + when: manual + allow_failure: true + tags: + - be-2-evs-temp + stage: test + needs: [ "build-codec-linux-cmake" ] + timeout: "20 minutes" + script: + - *print-common-info + + - mkdir build + - cd build + - cmake .. + - make -j + - cd .. + + # copy over to never change the testvector dir + - cp -r $EVS_BE_TEST_DIR ./evs_be_test + - cp build/IVAS_cod ./evs_be_test/bin/EVS_cod + - cp build/IVAS_dec ./evs_be_test/bin/EVS_dec + + - cd evs_be_test + - python3 ../ci/run_evs_be_test.py + +codec-comparison-on-main-push: + extends: + - .test-job-linux + - .rules-main-push + stage: compare + needs: [ "build-codec-linux-cmake" ] + timeout: "30 minutes" # To be revisited + script: + - *print-common-info + - latest_commit=$(git rev-parse HEAD) # Latest commit + - *get-previous-merge-commit-sha # Stored in previous_merge_commit shell variable now + - echo "Comparing changes from $previous_merge_commit to $latest_commit" + - git --no-pager diff --stat $previous_merge_commit..$latest_commit + + # Rest is more or less placeholder adapted from MR self test. This should be replaced with more complex tests. + + ### build test binaries, initial clean for paranoia reasons + - make clean + - mkdir build + - cd build + - cmake .. + - make -j + - mv IVAS_cod ../IVAS_cod_test + - mv IVAS_dec ../IVAS_dec_test + - cd .. + - rm -rf build/* + + ### compare to the previous merge commit in the main branch + - git fetch origin main + - git checkout $previous_merge_commit + + ### build reference binaries + - cd build + - cmake .. + - make -j + - mv IVAS_cod ../IVAS_cod_ref + - mv IVAS_dec ../IVAS_dec_ref + - cd .. + + ### re-checkout the latest commit in the main branch + - git checkout $latest_commit + + # helper variable - "|| true" to prevent failures from grep not finding anything + - non_be_flag=$(echo $CI_COMMIT_MESSAGE | grep -c --ignore-case "\[non[ -]*be\]") || true + + ### prepare pytest + # create short test vectors + - python3 tests/create_short_testvectors.py + # rename test binaries back + - mv IVAS_cod_test IVAS_cod + - mv IVAS_dec_test IVAS_dec + # create references + - python3 -m pytest tests -v --update_ref 1 -m create_ref + - python3 -m pytest tests -v --update_ref 1 -m create_ref_part2 + + ### run pytest + - exit_code=0 + - python3 -m pytest tests -v --junit-xml=report-junit.xml || exit_code=$? + - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures and non-BE flag not present"; exit $EXIT_CODE_FAIL; fi + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + - if [ $exit_code -eq 1 ] && [ $zero_errors == 1 ]; then echo "pytest run had failures, but no errors and non-BE flag present"; exit $EXIT_CODE_NON_BE; fi + - if [ $exit_code -ne 0 ]; then echo "pytest run had errors"; exit $EXIT_CODE_FAIL; fi; + allow_failure: + exit_codes: + - 123 + artifacts: + name: "main-push--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + when: always + paths: + - report-junit.xml + expose_as: 'Results of comparison to previous merge commit' + reports: + junit: report-junit.xml + + +# --------------------------------------------------------------- +# Scheduled jobs on main +# --------------------------------------------------------------- +.sanitizer-test-template: + extends: + - .test-job-linux + tags: + - sanitizer_test_main + stage: test + artifacts: + name: "$CI_JOB_NAME--main--sha-$CI_COMMIT_SHORT_SHA" + when: always + paths: + - ep_015.g192 + - ./LOGS_PLC + - ./LOGS_noPLC + +sanitizer-test-mono: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_MONO + timeout: "2 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py mono mono --tests $SANITIZER_TESTS + +sanitizer-test-stereo: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_STEREO + timeout: "2 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py stereo $OUT_FORMATS_CHANNEL_BASED --tests $SANITIZER_TESTS + +sanitizer-test-stereodmxevs: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_STEREODMXEVS + timeout: "2 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py StereoDmxEVS mono --tests $SANITIZER_TESTS + +sanitizer-test-ism1: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_ISM1 + timeout: "2 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +sanitizer-test-ism2: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_ISM2 + timeout: "2 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +sanitizer-test-ism3: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_ISM3 + timeout: "3 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +sanitizer-test-ism4: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_ISM4 + timeout: "4 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +sanitizer-test-masa: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_MASA + timeout: "2 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py MASA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +sanitizer-test-mc-5_1: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_MC51 + timeout: "3 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py 5_1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-mc-5_1_2: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_MC512 + timeout: "3 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py 5_1_2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-mc-5_1_4: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_MC514 + timeout: "3 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py 5_1_4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-mc-7_1: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_MC71 + timeout: "3 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py 7_1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-mc-7_1_4: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_MC714 + timeout: "3 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py 7_1_4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-sba: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_SBA + timeout: "4 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py SBA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-planarsba: + extends: .sanitizer-test-template + rules: + - if: $SANITIZER_TEST_PLANARSBA + timeout: "3 hours" + script: + - *get-ivas-internal-ci-repo + - *get-internal-ltv-signals + - ls -altr $LTV_DIR + - ls -altr + - cat scripts/config/ci_linux_ltv.json + - python3 ci/run_scheduled_sanitizer_test.py PlanarSBA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + + +# GCOV/LCOV coverage analysis of self_test suite +coverage-test-on-main-scheduled: + extends: + - .test-job-linux-needs-internal-testv-dir + - .rules-main-scheduled + tags: + - coverage-test + stage: test + rules: + # only run in scheduled pipeline that passes this env vars + - if: $COVERAGE_TEST + script: + - *print-common-info + - make GCOV=1 -j + - python3 tests/create_short_testvectors.py + - python3 -m pytest tests -v -n 0 --update_ref 1 -m create_ref --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec + - python3 -m pytest tests -v -n 0 --update_ref 1 -m create_ref_part2 --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec + - python3 -m pytest tests/test_param_file.py -v -n 0 --update_ref 1 -m create_ref --param_file scripts/config/self_test_evs.prm --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec + - lcov -c -d obj -o coverage.info + - genhtml coverage.info -o coverage + artifacts: + name: "main-coverage-sha-$CI_COMMIT_SHORT_SHA" + when: always + paths: + - coverage.info + - coverage + +# --------------------------------------------------------------- +# FhG internal - mirroring +# --------------------------------------------------------------- + +# Pull state of a branch on 3GPP repo, push to a mirror repo +.mirror-update: + extends: .test-job-linux + tags: + - host::r10499 + script: + # Set up git LFS for mirroring (see: https://github.com/git-lfs/git-lfs/issues/1762) + - git lfs install --skip-smudge --local + + # Select target branch: + # * if mirroring without testing, push to $CI_COMMIT_BRANCH at mirroring-pre-test stage + # * if mirroring with testing, push to: + # * $CI_COMMIT_BRANCH-mirror-untested at mirroring-pre-test stage + # * $CI_COMMIT_BRANCH at mirroring-post-test stage + - MIRROR_TARGET_BRANCH=$CI_COMMIT_BRANCH + - if [[ $MIRROR_TESTING == 'true' && $CI_JOB_STAGE == 'mirroring-pre-test' ]]; then MIRROR_TARGET_BRANCH="${CI_COMMIT_BRANCH}-mirror-untested"; fi + + # Check out or create mirror target branch - by default the runner checks out by commit hash, which results in detached head state + - git checkout -B $MIRROR_TARGET_BRANCH + + # Pull commits from upstream + - git pull --ff-only $UPSTREAM_URL $MIRROR_SOURCE_BRANCH + - git lfs fetch --all $UPSTREAM_URL $MIRROR_SOURCE_BRANCH + + # Push to mirror. Option `-o ci.skip` tells GitLab to skip CI for the pushed commits (testing already done in current pipeline if enabled) + - git push -o ci.skip "https://${GITLAB_USER_LOGIN}:${MIRROR_ACCESS_TOKEN}@${CI_REPOSITORY_URL#*@}" "HEAD:${MIRROR_TARGET_BRANCH}" + +mirror-update-untested: + rules: + - if: $MIRROR_ACCESS_TOKEN + extends: + - .mirror-update + stage: mirroring-pre-test + +mirror-update-tested: + rules: + - if: $MIRROR_ACCESS_TOKEN && $MIRROR_TESTING == 'true' + extends: + - .mirror-update + stage: mirroring-post-test + + +# --------------------------------------------------------------- +# FhG internal - tests +# --------------------------------------------------------------- + +build-codec-debug-windows-vs2017: + extends: + - .rules-basis + tags: + - os::windows + stage: build + script: + - $ENV:PATH + - MSBuild.exe .\Workspace_msvc\Workspace_msvc.sln /property:Configuration=Debug | tee $BUILD_OUTPUT + - python ci/check_for_warnings.py $BUILD_OUTPUT + +build-codec-release-windows-vs2017: + extends: + - .rules-basis + tags: + - os::windows + stage: build + script: + - $ENV:PATH + - MSBuild.exe .\Workspace_msvc\Workspace_msvc.sln /property:Configuration=Release | tee $BUILD_OUTPUT + - python ci/check_for_warnings.py $BUILD_OUTPUT -- GitLab From 426deb6a6d2599cd385df3e88559dcb9170b632c Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 15 Jun 2023 14:11:08 +0200 Subject: [PATCH 07/66] Allow less importnat CI jobs to fail (for now) --- .gitlab-ci-custom.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index bef4bdb69e..84aa4f65ba 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -217,6 +217,7 @@ build-codec-instrumented-linux: script: - *print-common-info - bash ci/build_codec_instrumented_linux.sh + allow_failure: true # TODO(sgi): Remove # make sure that the codec builds with msan, asan and usan build-codec-sanitizers-linux: @@ -254,6 +255,7 @@ codec-smoke-test: - smoke_test_output.txt - smoke_test_output_plc.txt expose_as: 'Smoke test results' + allow_failure: true # TODO(sgi): Remove # code selftest testvectors with memory-sanitizer binaries @@ -656,6 +658,7 @@ clang-format-check: when: on_failure name: "$ARTIFACT_BASE_NAME" expose_as: 'formatting patch' + allow_failure: true # TODO(sgi): Remove # --------------------------------------------------------------- -- GitLab From f104d3bbe0976522dd25f4d1232248ec8f3a1f2d Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 15 Jun 2023 14:30:43 +0200 Subject: [PATCH 08/66] fix asan, put out at least zeroes for ParamUpmix in the JBM path --- lib_com/options.h | 1 + lib_dec/ivas_jbm_dec.c | 8 +++++++- lib_dec/ivas_sba_rendering_internal.c | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 9caeda123a..6e3e1010c2 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -157,6 +157,7 @@ #define FIX_XXX_JITTER_SBA_BINAURAL_GAIN #define FIX_XXX_HEADTRACKER_INIT #define FIX_XXX_TDOBJRENDERER_INPUT +#define FIX_XXX_ISM_SBA_ASAN #define API_5MS /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 8e6b0541db..310e787511 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -846,7 +846,13 @@ ivas_error ivas_jbm_dec_render( #ifdef API_5MS else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) { - return IVAS_ERR_NOT_IMPLEMENTED; + /* zero output for now, not yet implemented... */ + int16_t ch; + *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); + for ( ch = 0; ch < nchan_out; ch++ ) + { + set_zero( p_output[ch], *nSamplesRendered ); + } } #endif else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index 6f3dd13b7a..8e92a1f622 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -365,15 +365,22 @@ void ivas_ism2sba_sf( for ( j = 0; j < sba_num_chans; j++ ) { g2 = hIsmRendererData->interpolator + offset; +#ifndef FIX_XXX_ISM_SBA_ASAN g1 = 1 - *g2; +#endif tc = buffer_in[i] + offset; out = buffer_out[j]; gain = hIsmRendererData->gains[i][j]; prev_gain = hIsmRendererData->prev_gains[i][j]; for ( k = 0; k < n_samples_to_render; k++ ) { +#ifdef FIX_XXX_ISM_SBA_ASAN + g1 = 1.0f - *g2; +#endif *( out++ ) += ( ( *( g2++ ) ) * gain + g1 * prev_gain ) * ( *( tc++ ) ); +#ifndef FIX_XXX_ISM_SBA_ASAN g1 = 1.0f - *g2; +#endif } } } -- GitLab From d4c03c2e3af4ef2360acd80400b16df8b161476c Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 15 Jun 2023 15:08:55 +0200 Subject: [PATCH 09/66] make sure 7.1.4 br does not crash any longer, still ParamUpmix needs to be fully implemented in the JBM path --- apps/decoder.c | 7 ++++++- lib_dec/ivas_jbm_dec.c | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/apps/decoder.c b/apps/decoder.c index d8229ce705..a8093c7a71 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -86,6 +86,7 @@ static #define JBM_FRONTEND_FETCH_FRAMESIZE_MS 20 #ifdef API_5MS #define HEADROTATION_FETCH_FRAMESIZE_MS 5 +#define DEFAULT_FETCH_FRAMESIZE_MS 20 #endif typedef struct @@ -1734,7 +1735,7 @@ static ivas_error decodeG192( } else { - nOutSamples = (int16_t) ( arg.output_Fs / 1000 * VARIABLE_SPEED_FETCH_FRAMESIZE_MS ); + nOutSamples = (int16_t) ( arg.output_Fs / 1000 * DEFAULT_FETCH_FRAMESIZE_MS ); vec_pos_len = 1; } /*------------------------------------------------------------------------------------------* @@ -2201,7 +2202,11 @@ cleanup: AudioFileWriter_close( &afWriter ); MasaFileWriter_close( &masaWriter ); +#ifdef DEBUGGING +#ifdef VARIABLE_SPEED_DECODING TsmScaleFileReader_close( &tsmScaleFileReader ); +#endif +#endif for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) { IsmFileWriter_close( &ismWriters[i] ); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 310e787511..c7d9996aab 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -477,6 +477,21 @@ ivas_error ivas_jbm_dec_tc( ivas_mono_stereo_downmix_mcmasa( st_ivas, output, output_frame ); } } +#ifdef API_5MS + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + + /* at least decode everything here, the rest is ToDo, for this we just output zeroes atm */ + ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, output_lfe_ch ); + + ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] ); + + if ( ( error = ivas_mct_dec( st_ivas, output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif } -- GitLab From de03fd1e6595cc31021a4988dc827a9210142ffe Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 15 Jun 2023 15:41:27 +0200 Subject: [PATCH 10/66] fix external orientation update rate --- apps/decoder.c | 34 +++++++++++++++++----------------- lib_rend/ivas_rotation.c | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index a8093c7a71..34527b8c82 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1783,45 +1783,45 @@ static ivas_error decodeG192( } } - if ( arg.enableExternalOrientation ) + /* Head-tracking input simulation */ + if ( arg.enableHeadRotation ) { IVAS_QUATERNION Quaternion; - int8_t enableHeadRotation; - int8_t enableExternalOrientation; - int8_t enableRotationInterpolation; - int16_t numFramesToTargetOrientation; - - if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &Quaternion, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nError %s while reading external orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), - RotationFileReader_getFilePath( externalOrientationFileReader ) ); + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); goto cleanup; } - if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternion, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } } - /* Head-tracking input simulation */ - if ( arg.enableHeadRotation ) + if ( arg.enableExternalOrientation ) { IVAS_QUATERNION Quaternion; + int8_t enableHeadRotation; + int8_t enableExternalOrientation; + int8_t enableRotationInterpolation; + int16_t numFramesToTargetOrientation; - if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos ) ) != IVAS_ERR_OK ) + + if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &Quaternion, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); + fprintf( stderr, "\nError %s while reading external orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), + RotationFileReader_getFilePath( externalOrientationFileReader ) ); goto cleanup; } - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternion, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } } diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 0997626bbb..efd281ce84 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -1434,7 +1434,7 @@ void external_target_interpolation( /* Calculate the interpolation increment and coefficient */ #ifdef API_5MS - hCombinedOrientationData->interpolationIncrement = 1.0f / ( (float) hExtOrientationData->numFramesToTargetOrientation * (float) MAX_PARAM_SPATIAL_SUBFRAMES ); + hCombinedOrientationData->interpolationIncrement = 1.0f / ( (float) hExtOrientationData->numFramesToTargetOrientation ); #else hCombinedOrientationData->interpolationIncrement = 1.0f / ( (float) hExtOrientationData->numFramesToTargetOrientation[i] * (float) MAX_PARAM_SPATIAL_SUBFRAMES ); #endif -- GitLab From b61cb8986ce97d473c30c3ce8eb1bca94ffcf33a Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 15 Jun 2023 16:12:09 +0200 Subject: [PATCH 11/66] disable unused code --- lib_com/ivas_prot.h | 2 ++ lib_dec/ivas_dec.c | 2 ++ lib_dec/jbm_jb4sb.h | 4 ++-- lib_dec/jbm_pcmdsp_fifo.c | 2 ++ lib_dec/jbm_pcmdsp_fifo.h | 4 ++-- lib_dec/lib_dec.c | 7 +++++-- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 7d3042d861..0a56c5081e 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -308,10 +308,12 @@ void stereo_dmx_evs_close_encoder( STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS /* i/o: Stereo downmix for EVS encoder handle */ ); +#ifndef API_5MS ivas_error ivas_dec( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ int16_t *data /* o : output synthesis signal */ ); +#endif ivas_error ivas_dec_setup( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index fd0bf5b530..3287ebbb47 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -32,6 +32,7 @@ #include #include "options.h" +#ifndef API_5MS #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" @@ -755,3 +756,4 @@ ivas_error ivas_dec( pop_wmops(); return error; } +#endif \ No newline at end of file diff --git a/lib_dec/jbm_jb4sb.h b/lib_dec/jbm_jb4sb.h index 00f5ccbb40..599730975d 100644 --- a/lib_dec/jbm_jb4sb.h +++ b/lib_dec/jbm_jb4sb.h @@ -77,13 +77,13 @@ struct JB4_DATAUNIT int16_t partialCopyOffset; int16_t nextCoderType; }; - +#ifndef API_5MS typedef enum { JBM_RENDERER_NONE, JBM_RENDERER_IVAS, } JBM_RENDERER_TYPE; - +#endif typedef struct JB4_DATAUNIT *JB4_DATAUNIT_HANDLE; diff --git a/lib_dec/jbm_pcmdsp_fifo.c b/lib_dec/jbm_pcmdsp_fifo.c index a3e8936464..d3c93679fe 100644 --- a/lib_dec/jbm_pcmdsp_fifo.c +++ b/lib_dec/jbm_pcmdsp_fifo.c @@ -38,6 +38,7 @@ #include #include "options.h" +#ifndef API_5MS #include "prot.h" #include "ivas_prot.h" #ifdef DEBUGGING @@ -267,3 +268,4 @@ uint16_t pcmdsp_fifo_nReadableSamplesPerChannel( { return h->size; } +#endif \ No newline at end of file diff --git a/lib_dec/jbm_pcmdsp_fifo.h b/lib_dec/jbm_pcmdsp_fifo.h index b601cc2e0e..62ebc15d08 100644 --- a/lib_dec/jbm_pcmdsp_fifo.h +++ b/lib_dec/jbm_pcmdsp_fifo.h @@ -41,7 +41,7 @@ #include #include "options.h" - +#ifndef API_5MS /** Ringbuffer (FIFO) with fixed capacity for audio samples. */ struct PCMDSP_FIFO @@ -81,5 +81,5 @@ int16_t pcmdsp_fifo_write_zero( PCMDSP_FIFO_HANDLE h, uint16_t nSamplesPerChanne int16_t pcmdsp_fifo_read( PCMDSP_FIFO_HANDLE h, uint16_t nSamplesPerChannel, uint8_t *samples ); uint16_t pcmdsp_fifo_nReadableSamplesPerChannel( const PCMDSP_FIFO_HANDLE h ); - +#endif #endif /* JBM_PCMDSP_FIFO_H */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 86d46fe2b0..0def4c244d 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -123,7 +123,9 @@ static ivas_error evs_dec_main( Decoder_Struct *st_ivas, const int16_t nOutSampl static ivas_error input_format_API_to_internal( IVAS_DEC_INPUT_FORMAT input_format, int16_t *bitstream_format_internal, int16_t *sdp_hf_only, const bool is_voip_enabled ); static void init_decoder_config( DECODER_CONFIG_HANDLE hDecoderConfig ); static int16_t IVAS_DEC_VoIP_GetRenderGranularity( Decoder_Struct *st_ivas ); +#ifndef API_5MS static JBM_RENDERER_TYPE IVAS_DEC_VoIP_GetRendererConfig( IVAS_DEC_HANDLE hIvasDec ); +#endif static ivas_error IVAS_DEC_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ); static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels, uint8_t *nOutChannels, uint16_t *nSamplesRendered, int16_t *data ); static ivas_error IVAS_DEC_GetTcSamples( IVAS_DEC_HANDLE hIvasDec, float *pcmBuf, int16_t *nOutSamples ); @@ -1985,7 +1987,7 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( return IVAS_ERR_OK; } -#ifdef VARIABLE_SPEED_DECODING +#if defined( VARIABLE_SPEED_DECODING ) || defined( API_5MS ) /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_SetScale( ) * @@ -3480,6 +3482,7 @@ static int16_t IVAS_DEC_VoIP_GetRenderGranularity( } +#ifndef API_5MS /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_GetRendererConfig() * @@ -3503,7 +3506,7 @@ static JBM_RENDERER_TYPE IVAS_DEC_VoIP_GetRendererConfig( return rendererType; } - +#endif /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_reconfigure() -- GitLab From 7fb10d40a051ab031a939821cb5bfdbd1dfddb40 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 15 Jun 2023 17:49:42 +0200 Subject: [PATCH 12/66] Remove RENDERER_HEAD_POSITIONS_PER_FRAME - code compiles, but untested --- apps/renderer.c | 170 +++++++++++++++++++++++++++++------ lib_com/common_api_types.h | 2 + lib_com/options.h | 1 + lib_rend/ivas_prot_rend.h | 4 + lib_rend/ivas_rotation.c | 69 +++++++++++++++ lib_rend/ivas_stat_rend.h | 7 ++ lib_rend/lib_rend.c | 175 ++++++++++++++++++++++++++++++++++++- lib_rend/lib_rend.h | 21 ++++- 8 files changed, 418 insertions(+), 31 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 760065be91..9be54daca5 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -157,6 +157,9 @@ typedef struct float lfeConfigElevation; bool lfeCustomRoutingEnabled; char inLfePanningMatrixFile[RENDERER_MAX_CLI_ARG_LENGTH]; +#ifdef LIB_REND_API_5MS + bool framing_5ms; +#endif } CmdlnArgs; typedef enum @@ -181,6 +184,9 @@ typedef enum CmdLnOptionId_inputGain, CmdLnOptionId_referenceVectorFile, CmdLnOptionId_exteriorOrientationFile, +#ifdef LIB_REND_API_5MS + CmdLnOptionId_framing5ms, +#endif } CmdLnOptionId; static const CmdLnParser_Option cliOptions[] = { @@ -302,6 +308,14 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "exof", .description = "External orientation trajectory file for simulation of external orientations", }, +#ifdef LIB_REND_API_5MS + { + .id = CmdLnOptionId_framing5ms, + .match = "framing_5ms", + .matchShort = "fr5", + .description = "Process audio with 5 ms framing. Time resolution of metadata (e.g. ISM positions) remains unchanged w.r.t. 20 ms framing", + }, +#endif }; @@ -560,7 +574,9 @@ int main( int32_t delayTimeScale = 0; int16_t i, numChannels; ivas_error error = IVAS_ERR_OK; +#ifndef LIB_REND_API_5MS IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME]; +#endif #ifdef WMOPS reset_wmops(); @@ -733,7 +749,13 @@ int main( fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 ); + const int16_t frameSize_smpls = (int16_t) ( +#ifdef LIB_REND_API_5MS + ( args.framing_5ms ? 5 : 20 ) +#else + 20 +#endif + * args.sampleRate / 1000 ); IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 }; IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS] = { 0 }; @@ -1019,10 +1041,17 @@ int main( fprintf( stdout, "\n\n-- Start the renderer (quiet mode) --\n\n" ); } +#ifdef LIB_REND_API_5MS + ObjectPositionBuffer mtdBuffer; +#endif + while ( 1 ) { int16_t num_in_channels; num_in_channels = inBuffer.config.numChannels; +#ifdef LIB_REND_API_5MS + const bool isCurrentFrameMultipleOf20ms = !args.framing_5ms || frame % 4 == 0; +#endif /* Read the input data */ if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) @@ -1040,50 +1069,85 @@ int main( /* Convert from int to float and from interleaved to packed */ convertInputBuffer( inpInt16Buffer, numSamplesRead, frameSize_smpls, num_in_channels, inFloatBuffer ); - +#ifdef LIB_REND_API_5MS + if ( isCurrentFrameMultipleOf20ms ) + { +#else ObjectPositionBuffer mtdBuffer; - IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); +#endif + IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); - if ( referenceVectorReader != NULL ) - { - IVAS_VECTOR3 listenerPos, refPos; - if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPos, &refPos ) ) != IVAS_ERR_OK ) + if ( referenceVectorReader != NULL ) { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); + IVAS_VECTOR3 listenerPos, refPos; + if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPos, &refPos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + if ( ( error = IVAS_REND_SetReferenceVector( hIvasRend, listenerPos, refPos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } } - if ( ( error = IVAS_REND_SetReferenceVector( hIvasRend, listenerPos, refPos ) ) != IVAS_ERR_OK ) + /* Read from reference rotation trajectory file if specified */ + if ( referenceRotReader != NULL ) { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); + IVAS_QUATERNION quaternion; + if ( ( error = HeadRotationFileReading( referenceRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_SetReferenceRotation( hIvasRend, quaternion ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error setting Reference Rotation: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } } +#ifdef LIB_REND_API_5MS } - /* Read from reference rotation trajectory file if specified */ - if ( referenceRotReader != NULL ) +#endif + + /* Read from head rotation trajectory file if specified */ + if ( headRotReader != NULL ) { - IVAS_QUATERNION quaternion; - if ( ( error = HeadRotationFileReading( referenceRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) +#ifdef LIB_REND_API_5MS + IVAS_QUATERNION headRot; + IVAS_VECTOR3 Pos; + + if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - - if ( ( error = IVAS_REND_SetReferenceRotation( hIvasRend, quaternion ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "Error setting Reference Rotation: %s\n", ivas_error_to_string( error ) ); + fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - } - /* Read from head rotation trajectory file if specified */ - if ( headRotReader != NULL ) - { - IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; - - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + if ( !args.framing_5ms ) { - if ( ( error = HeadRotationFileReading( headRotReader, &quatBuffer[i], &Pos[i] ) ) != IVAS_ERR_OK ) + /* Skip over 3 following head positions - they are given on 5ms grid */ + for ( int16_t i = 0; i < 3; ++i ) + { + if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } +#else + IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; + + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { + if ( ( error = HeadRotationFileReading( headRotReader, &quatBuffer[i], &Pos[i] ) ) != IVAS_ERR_OK ) + { fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } @@ -1093,20 +1157,61 @@ int main( fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } +#endif } else { +#ifdef LIB_REND_API_5MS + if ( ( error = IVAS_REND_DisableHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error disabling head rotation: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } +#else error = IVAS_REND_SetHeadRotation( hIvasRend, NULL, NULL ); if ( error != IVAS_ERR_OK && error != IVAS_ERR_INVALID_OUTPUT_FORMAT ) { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } +#endif } /* Read from external orientation file if specified */ if ( externalOrientationFileReader != NULL ) { +#ifdef LIB_REND_API_5MS + IVAS_QUATERNION quat; + int8_t enableHeadRotation; + int8_t enableExternalOrientation; + int8_t enableRotationInterpolation; + int16_t numFramesToTargetOrientation; + + if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &quat, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in External Orientation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_SetExternalOrientation( hIvasRend, &quat, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error setting External Orientation: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( !args.framing_5ms ) + { + /* Skip over 3 following entries in file - they are given on 5ms grid */ + for ( int16_t i = 0; i < 3; ++i ) + { + if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &quat, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in External Orientation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } +#else IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; int8_t enableHeadRotation[RENDERER_HEAD_POSITIONS_PER_FRAME]; int8_t enableExternalOrientation[RENDERER_HEAD_POSITIONS_PER_FRAME]; @@ -1127,6 +1232,7 @@ int main( fprintf( stderr, "Error setting External Orientation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } +#endif } /* Combine external orientations and head rotation */ @@ -1281,6 +1387,7 @@ int main( delayNumSamples -= (int16_t) outBufferSize; } + /* TODO(sgi): Masa output most likely broken with 5ms framing */ /* Write MASA metadata for MASA outputs */ if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_MASA1 || args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_MASA2 ) { @@ -1900,6 +2007,9 @@ static CmdlnArgs defaultArgs( args.lfeCustomRoutingEnabled = false; clearString( args.inLfePanningMatrixFile ); +#ifdef LIB_REND_API_5MS + args.framing_5ms = false; +#endif return args; } @@ -2029,6 +2139,12 @@ static void parseOption( exit( -1 ); } break; +#ifdef LIB_REND_API_5MS + case CmdLnOptionId_framing5ms: + assert( numOptionValues == 0 ); + args->framing_5ms = false; + break; +#endif default: assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); break; diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 2dc926dfc2..49c6f395fd 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -50,7 +50,9 @@ #define IVAS_CLDFB_NO_CHANNELS_MAX ( 60 ) #define IVAS_MAX_INPUT_LFE_CHANNELS 4 +#ifndef LIB_REND_API_5MS #define RENDERER_HEAD_POSITIONS_PER_FRAME 4 +#endif /*----------------------------------------------------------------------------------* diff --git a/lib_com/options.h b/lib_com/options.h index bee9901a56..4a88b47d83 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -157,6 +157,7 @@ #define FIX_XXX_JITTER_SBA_BINAURAL_GAIN #define FIX_XXX_HEADTRACKER_INIT #define API_5MS +#define LIB_REND_API_5MS /* FhG: Adds 5ms framing capability to lib_rend */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 29a5ace8f4..8d987a3f3c 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -857,7 +857,11 @@ ivas_error combine_external_and_head_orientations_rend( ); ivas_error combine_external_and_head_orientations( +#ifdef LIB_REND_API_5MS + IVAS_QUATERNION *headRotQuaternion, /* i : quaternion for head rotation */ +#else IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ +#endif IVAS_VECTOR3 *listenerPos, /* i : listener position */ #ifndef API_5MS int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 184f382ee8..468d28b026 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -902,7 +902,11 @@ ivas_error combine_external_and_head_orientations_dec( #endif } #ifdef API_5MS +#ifdef LIB_REND_API_5MS return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); +#else + return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); +#endif #else return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); #endif @@ -932,8 +936,13 @@ ivas_error combine_external_and_head_orientations_rend( { if ( hHeadTrackData->headRotEnabled ) { +#ifdef LIB_REND_API_5MS + headRotQuaternions = &hHeadTrackData->headPosition; + listenerPos = &hHeadTrackData->Pos; +#else headRotQuaternions = hHeadTrackData->headPositions; listenerPos = hHeadTrackData->Pos; +#endif } } else if ( hExtOrientationData != NULL ) @@ -971,7 +980,11 @@ ivas_error combine_external_and_head_orientations_rend( *------------------------------------------------------------------------*/ ivas_error combine_external_and_head_orientations( +#ifdef LIB_REND_API_5MS + IVAS_QUATERNION *headRotQuaternion, /* i : quaternion for head rotation */ +#else IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ +#endif IVAS_VECTOR3 *listenerPos, /* i : listener position */ #ifndef API_5MS int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ @@ -994,7 +1007,11 @@ ivas_error combine_external_and_head_orientations( /* Form combined orientations or return if no data available */ if ( hCombinedOrientationData == NULL ) { +#ifdef LIB_REND_API_5MS + if ( headRotQuaternion != NULL || hExtOrientationData != NULL ) +#else if ( headRotQuaternions != NULL || hExtOrientationData != NULL ) +#endif { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1003,7 +1020,11 @@ ivas_error combine_external_and_head_orientations( return IVAS_ERR_OK; } } +#ifdef LIB_REND_API_5MS + else if ( headRotQuaternion == NULL && hExtOrientationData == NULL ) +#else else if ( headRotQuaternions == NULL && hExtOrientationData == NULL ) +#endif { /* Reset the combined orientations and rotations */ hCombinedOrientationData->isInterpolationOngoing = FALSE; @@ -1037,11 +1058,19 @@ ivas_error combine_external_and_head_orientations( } #endif } +#ifdef LIB_REND_API_5MS + else if ( hExtOrientationData == NULL && headRotQuaternion != NULL ) +#else else if ( hExtOrientationData == NULL && headRotQuaternions != NULL ) +#endif { /* Head rotation only */ #ifdef API_5MS +#ifdef LIB_REND_API_5MS + hCombinedOrientationData->Quaternion = *headRotQuaternion; +#else hCombinedOrientationData->Quaternion = *headRotQuaternions; +#endif #else if ( numHeadRotQuaternions >= 0 ) @@ -1130,7 +1159,11 @@ ivas_error combine_external_and_head_orientations( #endif } +#ifdef LIB_REND_API_5MS + if ( hExtOrientationData != NULL && headRotQuaternion != NULL ) +#else if ( hExtOrientationData != NULL && headRotQuaternions != NULL ) +#endif { /* Combine head and external orientations */ #ifdef API_5MS @@ -1140,11 +1173,19 @@ ivas_error combine_external_and_head_orientations( { if ( hExtOrientationData->enableExternalOrientation > 0 ) { +#ifdef LIB_REND_API_5MS + QuaternionProduct( hCombinedOrientationData->Quaternion, *headRotQuaternion, &hCombinedOrientationData->Quaternion ); +#else QuaternionProduct( hCombinedOrientationData->Quaternion, *headRotQuaternions, &hCombinedOrientationData->Quaternion ); +#endif } else { +#ifdef LIB_REND_API_5MS + hCombinedOrientationData->Quaternion = *headRotQuaternion; +#else hCombinedOrientationData->Quaternion = *headRotQuaternions; +#endif } } /* Use the freezed head rotation */ @@ -1203,7 +1244,11 @@ ivas_error combine_external_and_head_orientations( #endif } +#ifdef LIB_REND_API_5MS + if ( headRotQuaternion != NULL || hExtOrientationData != NULL ) +#else if ( headRotQuaternions != NULL || hExtOrientationData != NULL ) +#endif { /* Calculate the combined rotation matrix */ #ifdef API_5MS @@ -1243,14 +1288,22 @@ ivas_error combine_external_and_head_orientations( } #endif } +#ifdef LIB_REND_API_5MS + if ( headRotQuaternion != NULL ) +#else if ( headRotQuaternions != NULL ) +#endif { #ifdef API_5MS if ( hExtOrientationData != NULL ) { if ( hExtOrientationData->enableHeadRotation > 0 ) { +#ifdef LIB_REND_API_5MS + hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternion; +#else hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternions; +#endif } else { @@ -1259,7 +1312,11 @@ ivas_error combine_external_and_head_orientations( } else { +#ifdef LIB_REND_API_5MS + hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternion; +#else hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternions; +#endif } hCombinedOrientationData->listenerPos = *listenerPos; @@ -1294,7 +1351,11 @@ ivas_error combine_external_and_head_orientations( } /* Check if combined orientation is enabled */ +#ifdef LIB_REND_API_5MS + if ( headRotQuaternion != NULL && hExtOrientationData == NULL ) +#else if ( headRotQuaternions != NULL && hExtOrientationData == NULL ) +#endif { #ifdef API_5MS hCombinedOrientationData->enableCombinedOrientation = 1; @@ -1313,7 +1374,11 @@ ivas_error combine_external_and_head_orientations( } #endif } +#ifdef LIB_REND_API_5MS + else if ( headRotQuaternion == NULL && hExtOrientationData != NULL ) +#else else if ( headRotQuaternions == NULL && hExtOrientationData != NULL ) +#endif { #ifdef API_5MS if ( hExtOrientationData->enableExternalOrientation > 0 ) @@ -1338,7 +1403,11 @@ ivas_error combine_external_and_head_orientations( } #endif } +#ifdef LIB_REND_API_5MS + else if ( headRotQuaternion != NULL && hExtOrientationData != NULL ) +#else else if ( headRotQuaternions != NULL && hExtOrientationData != NULL ) +#endif { #ifdef API_5MS if ( hExtOrientationData->enableExternalOrientation > 0 || hExtOrientationData->enableHeadRotation > 0 ) diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 14de5e7d55..7306c45e99 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -248,9 +248,16 @@ typedef struct ivas_orient_trk_state_t typedef struct { int8_t headRotEnabled; +#ifdef LIB_REND_API_5MS + IVAS_QUATERNION headPosition; + IVAS_VECTOR3 Pos; + float crossfade_5ms[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + float crossfade_20ms[L_FRAME48k]; +#else IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME]; IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME]; float crossfade[L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME]; +#endif ivas_orient_trk_state_t *hOrientationTracker; } IVAS_REND_HeadRotData; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 89b51e7745..6f6b32de1b 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -930,6 +930,25 @@ static ivas_error initHeadRotation( /* Head rotation is enabled by default */ hIvasRend->headRotData.headRotEnabled = 1; +#ifdef LIB_REND_API_5MS + /* Initialize 5ms crossfade */ + crossfade_len = L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES; /* TODO(sgi): @tmu why do we assume 48 kHz here? */ + tmp = 1.f / ( crossfade_len - 1 ); + for ( i = 0; i < crossfade_len; i++ ) + { + hIvasRend->headRotData.crossfade_5ms[i] = i * tmp; + } + /* Initialize 20ms crossfade */ + crossfade_len = L_FRAME48k; /* TODO(sgi): @tmu why do we assume 48 kHz here? */ + tmp = 1.f / ( crossfade_len - 1 ); + for ( i = 0; i < crossfade_len; i++ ) + { + hIvasRend->headRotData.crossfade_20ms[i] = i * tmp; + } + + /* Initialize with unit quaternion */ + hIvasRend->headRotData.headPosition = quaternionInit(); +#else /* Initialize 5ms crossfade */ crossfade_len = L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME; tmp = 1.f / ( crossfade_len - 1 ); @@ -943,6 +962,7 @@ static ivas_error initHeadRotation( { hIvasRend->headRotData.headPositions[i] = quaternionInit(); } +#endif if ( ( hIvasRend->headRotData.hOrientationTracker = (ivas_orient_trk_state_t *) malloc( sizeof( ivas_orient_trk_state_t ) ) ) == NULL ) { @@ -4063,12 +4083,19 @@ int16_t IVAS_REND_FeedRenderConfig( *-------------------------------------------------------------------*/ ivas_error IVAS_REND_SetHeadRotation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ +#ifdef LIB_REND_API_5MS + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos /* i : listener positions for next rendering call */ +#else const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ +#endif ) { +#ifndef LIB_REND_API_5MS int16_t i; +#endif IVAS_QUATERNION rotQuat; /* Validate function arguments */ @@ -4083,6 +4110,20 @@ ivas_error IVAS_REND_SetHeadRotation( return IVAS_ERR_INVALID_OUTPUT_FORMAT; } +#ifdef LIB_REND_API_5MS + /* check for Euler angle signaling */ + if ( headRot.w == -3.0f ) + { + Euler2Quat( deg2rad( headRot.x ), deg2rad( headRot.y ), deg2rad( headRot.z ), &rotQuat ); + } + else + { + rotQuat = headRot; + } + + ivas_orient_trk_Process( hIvasRend->headRotData.hOrientationTracker, rotQuat, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &hIvasRend->headRotData.headPosition ); + hIvasRend->headRotData.Pos = Pos; +#else if ( headRot == NULL ) { hIvasRend->headRotData.headRotEnabled = 0; @@ -4106,10 +4147,27 @@ ivas_error IVAS_REND_SetHeadRotation( hIvasRend->headRotData.Pos[i] = Pos[i]; } } +#endif return IVAS_ERR_OK; } +#ifdef LIB_REND_API_5MS +ivas_error IVAS_REND_DisableHeadRotation( + IVAS_REND_HANDLE hIvasRend /* i/o: Renderer handle */ +) +{ + /* Validate function arguments */ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hIvasRend->headRotData.headRotEnabled = 0; + return IVAS_ERR_OK; +} +#endif + /*-------------------------------------------------------------------* * IVAS_REND_SetOrientationTrackingMode() @@ -4237,15 +4295,24 @@ ivas_error IVAS_REND_SetReferenceVector( *---------------------------------------------------------------------*/ ivas_error IVAS_REND_SetExternalOrientation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_QUATERNION *orientation, /* i : external orientation data */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_QUATERNION *orientation, /* i : external orientation data */ +#ifdef LIB_REND_API_5MS + int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ /* TODO(sgi): make independent of framing */ +#else int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#endif ) { +#ifndef LIB_REND_API_5MS int16_t i; +#endif /* Validate function arguments */ if ( hIvasRend == NULL || hIvasRend->hExternalOrientationData == NULL ) @@ -4266,6 +4333,14 @@ ivas_error IVAS_REND_SetExternalOrientation( } else { +#ifdef LIB_REND_API_5MS + QuaternionInverse( *orientation, &hIvasRend->hExternalOrientationData->Quaternion ); + + hIvasRend->hExternalOrientationData->enableHeadRotation = enableHeadRotation; + hIvasRend->hExternalOrientationData->enableExternalOrientation = enableExternalOrientation; + hIvasRend->hExternalOrientationData->enableRotationInterpolation = enableRotationInterpolation; + hIvasRend->hExternalOrientationData->numFramesToTargetOrientation = numFramesToTargetOrientation; +#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { #ifdef API_5MS @@ -4285,6 +4360,7 @@ ivas_error IVAS_REND_SetExternalOrientation( hIvasRend->hExternalOrientationData->numFramesToTargetOrientation[i] = numFramesToTargetOrientation[i]; #endif } +#endif } return IVAS_ERR_OK; @@ -4321,7 +4397,9 @@ ivas_error IVAS_REND_GetCombinedOrientation( IVAS_QUATERNION *pOrientation /* i/o: Quaternion pointer processed orientation */ ) { +#ifndef LIB_REND_API_5MS int16_t i; +#endif if ( hIvasRend == NULL || pOrientation == NULL ) { @@ -4330,6 +4408,9 @@ ivas_error IVAS_REND_GetCombinedOrientation( if ( hIvasRend->hCombinedOrientationData != NULL ) { +#ifdef LIB_REND_API_5MS + *pOrientation = hIvasRend->hCombinedOrientationData->Quaternion; +#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { #ifdef API_5MS @@ -4339,6 +4420,7 @@ ivas_error IVAS_REND_GetCombinedOrientation( pOrientation[i] = hIvasRend->hCombinedOrientationData->Quaternions[i]; #endif } +#endif } return IVAS_ERR_OK; @@ -4447,7 +4529,11 @@ static ivas_error rotateFrameMc( { int16_t i; int16_t j; +#ifdef LIB_REND_API_5MS + const float *crossfade; +#else int16_t subframe_idx, subframe_len; +#endif int16_t azimuth, elevation; int16_t is_planar_setup, lfe_idx; int16_t nchan; @@ -4462,6 +4548,21 @@ static ivas_error rotateFrameMc( push_wmops( "rotateFrameMc" ); +#ifdef LIB_REND_API_5MS + if ( inAudio.config.numSamplesPerChannel == L_FRAME48k ) + { + crossfade = headRotData->crossfade_20ms; + } + else if ( inAudio.config.numSamplesPerChannel == L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) + { + crossfade = headRotData->crossfade_5ms; + } + else + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Only 5 and 20 ms framing is supported" ); + } +#endif + if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { if ( ( error = getAudioConfigNumChannels( inConfig, &nchan ) ) != IVAS_ERR_OK ) @@ -4486,10 +4587,13 @@ static ivas_error rotateFrameMc( gains[ch_in][ch_in] = 1.f; } +#ifndef LIB_REND_API_5MS + /* TODO(sgi): @tmu please review changes in this function */ /* subframe loop */ subframe_len = inAudio.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) { +#endif for ( i = 0; i < 3; i++ ) { if ( hCombinedOrientationData != NULL ) @@ -4551,6 +4655,18 @@ static ivas_error rotateFrameMc( { for ( ch_in = 0; ch_in < nchan; ch_in++ ) { +#ifdef LIB_REND_API_5MS + writePtr = getSmplPtr( outAudio, ch_out, 0 ); + readPtr = getSmplPtr( inAudio, ch_in, 0 ); + /* crossfade with previous rotation gains */ + for ( i = 0; i < inAudio.config.numSamplesPerChannel; i++ ) + { + *writePtr++ += + ( *readPtr ) * ( ( 1 - crossfade[i] ) * gains_prev[ch_in][ch_out] ) + + ( *readPtr ) * ( crossfade[i] * gains[ch_in][ch_out] ); + readPtr++; + } +#else writePtr = getSmplPtr( outAudio, ch_out, subframe_idx * subframe_len ); readPtr = getSmplPtr( inAudio, ch_in, subframe_idx * subframe_len ); /* crossfade with previous rotation gains */ @@ -4561,6 +4677,7 @@ static ivas_error rotateFrameMc( ( *readPtr ) * ( headRotData->crossfade[i] * gains[ch_in][ch_out] ); readPtr++; } +#endif } } @@ -4569,7 +4686,9 @@ static ivas_error rotateFrameMc( { mvr2r( gains[i], gains_prev[i], nchan ); } +#ifndef LIB_REND_API_5MS } +#endif pop_wmops(); @@ -4588,7 +4707,11 @@ static ivas_error rotateFrameSba( int16_t i, l, n, m; int16_t m1, m2; int16_t shd_rot_max_order; +#ifdef LIB_REND_API_5MS + const float *crossfade; +#else int16_t subframe_idx, subframe_len; +#endif float *readPtr, *writePtr; rotation_matrix Rmat; float tmpRot[2 * HEADROT_ORDER + 1]; @@ -4597,15 +4720,33 @@ static ivas_error rotateFrameSba( push_wmops( "rotateFrameSba" ); +#ifdef LIB_REND_API_5MS + if ( inAudio.config.numSamplesPerChannel == L_FRAME48k ) + { + crossfade = headRotData->crossfade_20ms; + } + else if ( inAudio.config.numSamplesPerChannel == L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) + { + crossfade = headRotData->crossfade_5ms; + } + else + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Only 5 and 20 ms framing is supported" ); + } +#endif + if ( ( error = getAmbisonicsOrder( inConfig, &shd_rot_max_order ) ) != IVAS_ERR_OK ) { return error; } +#ifndef LIB_REND_API_5MS + /* TODO(sgi): @tmu please review changes in this function */ /* subframe loop */ subframe_len = inAudio.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) { +#endif /* initialize rotation matrices with zeros */ for ( i = 0; i < HEADROT_SHMAT_DIM; i++ ) { @@ -4637,7 +4778,11 @@ static ivas_error rotateFrameSba( /* calculate ambisonics rotation matrices for the previous and current frames */ SHrotmatgen( gains, Rmat, shd_rot_max_order ); +#ifdef LIB_REND_API_5MS + for ( i = 0; i < inAudio.config.numSamplesPerChannel; i++ ) +#else for ( i = 0; i < subframe_len; i++ ) +#endif { /* As the rotation matrix becomes block diagonal in a SH basis, we can*/ /* apply each angular-momentum block individually to save complexity. */ @@ -4654,16 +4799,27 @@ static ivas_error rotateFrameSba( for ( m = m1; m < m2; m++ ) { +#ifdef LIB_REND_API_5MS + readPtr = getSmplPtr( inAudio, m, i ); + /* crossfade with previous rotation gains */ + tmpRot[n - m1] += crossfade[i] * gains[n][m] * ( *readPtr ) + + ( 1 - crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); +#else readPtr = getSmplPtr( inAudio, m, subframe_idx * subframe_len + i ); /* crossfade with previous rotation gains */ tmpRot[n - m1] += headRotData->crossfade[i] * gains[n][m] * ( *readPtr ) + ( 1 - headRotData->crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); +#endif } } /* write back the result */ for ( n = m1; n < m2; n++ ) { +#ifdef LIB_REND_API_5MS + writePtr = getSmplPtr( outAudio, n, i ); +#else writePtr = getSmplPtr( outAudio, n, subframe_idx * subframe_len + i ); +#endif ( *writePtr ) = tmpRot[n - m1]; } m1 = m2; @@ -4691,7 +4847,9 @@ static ivas_error rotateFrameSba( { mvr2r( gains[i], gains_prev[i], HEADROT_SHMAT_DIM ); } +#ifndef LIB_REND_API_5MS } +#endif pop_wmops(); @@ -4734,7 +4892,9 @@ static ivas_error renderIsmToBinauralRoom( { int16_t i; int16_t azi_rot, ele_rot; +#ifndef LIB_REND_API_5MS int16_t subframe_idx, subframe_len; +#endif int16_t tmp; rotation_matrix Rmat; float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; @@ -4783,10 +4943,12 @@ static ivas_error renderIsmToBinauralRoom( if ( combinedOrientationEnabled ) { +#ifndef LIB_REND_API_5MS subframe_len = ismInput->base.inputBuffer.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; // for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) for ( subframe_idx = 0; subframe_idx < 1; subframe_idx++ ) { +#endif for ( i = 0; i < 3; i++ ) { #ifdef API_5MS @@ -4814,8 +4976,10 @@ static ivas_error renderIsmToBinauralRoom( Rmat[i][i] = 1.0f; } } +#ifndef LIB_REND_API_5MS } (void) subframe_len; // avoid warning +#endif } /* TODO tmu : see issue #518 */ @@ -6300,6 +6464,10 @@ static ivas_error renderActiveInputsMasa( if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && pCurrentInput->decDummy->hHeadTrackData != NULL ) { +#ifdef LIB_REND_API_5MS + pCurrentInput->decDummy->hHeadTrackData->Quaternion = hIvasRend->headRotData.headPosition; + pCurrentInput->decDummy->hHeadTrackData->Pos = hIvasRend->headRotData.Pos; +#else for ( sf_idx = 0; sf_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; ++sf_idx ) { #ifdef API_5MS @@ -6311,6 +6479,7 @@ static ivas_error renderActiveInputsMasa( pCurrentInput->decDummy->hHeadTrackData->Pos[sf_idx] = hIvasRend->headRotData.Pos[sf_idx]; #endif } +#endif } if ( ( error = renderInputMasa( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index d8d6127b20..701e0d5062 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -247,9 +247,21 @@ int16_t IVAS_REND_FeedRenderConfig( ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ +#ifdef LIB_REND_API_5MS + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos /* i : listener positions for next rendering call */ +#else const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ +#endif +); + +#ifdef LIB_REND_API_5MS +/* Head rotation becomes enabled by calling IVAS_REND_SetHeadRotation. Use this to disable. */ +ivas_error IVAS_REND_DisableHeadRotation( + IVAS_REND_HANDLE hIvasRend /* i/o: Renderer handle */ ); +#endif ivas_error IVAS_REND_SetOrientationTrackingMode( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ @@ -280,10 +292,17 @@ ivas_error IVAS_REND_SetReferenceVector( ivas_error IVAS_REND_SetExternalOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_QUATERNION *orientation, /* i : external orientation data */ +#ifdef LIB_REND_API_5MS + int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#else int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#endif ); ivas_error IVAS_REND_CombineHeadAndExternalOrientation( @@ -292,7 +311,7 @@ ivas_error IVAS_REND_CombineHeadAndExternalOrientation( ivas_error IVAS_REND_GetCombinedOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_QUATERNION *pRotation /* i/o: Quaternion pointer processed orientation */ + IVAS_QUATERNION *pOrientation /* i/o: Quaternion pointer processed orientation */ ); ivas_error IVAS_REND_GetMasaMetadata( -- GitLab From 6e1fe92ff2cf0a510017bb86ab4b6f72b3ffd7cd Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 16 Jun 2023 09:37:32 +0200 Subject: [PATCH 13/66] [tmp] Revert "Remove RENDERER_HEAD_POSITIONS_PER_FRAME - code compiles, but untested" This reverts commit 7fb10d40a051ab031a939821cb5bfdbd1dfddb40. --- apps/renderer.c | 170 ++++++----------------------------- lib_com/common_api_types.h | 2 - lib_com/options.h | 1 - lib_rend/ivas_prot_rend.h | 4 - lib_rend/ivas_rotation.c | 69 --------------- lib_rend/ivas_stat_rend.h | 7 -- lib_rend/lib_rend.c | 175 +------------------------------------ lib_rend/lib_rend.h | 21 +---- 8 files changed, 31 insertions(+), 418 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 9be54daca5..760065be91 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -157,9 +157,6 @@ typedef struct float lfeConfigElevation; bool lfeCustomRoutingEnabled; char inLfePanningMatrixFile[RENDERER_MAX_CLI_ARG_LENGTH]; -#ifdef LIB_REND_API_5MS - bool framing_5ms; -#endif } CmdlnArgs; typedef enum @@ -184,9 +181,6 @@ typedef enum CmdLnOptionId_inputGain, CmdLnOptionId_referenceVectorFile, CmdLnOptionId_exteriorOrientationFile, -#ifdef LIB_REND_API_5MS - CmdLnOptionId_framing5ms, -#endif } CmdLnOptionId; static const CmdLnParser_Option cliOptions[] = { @@ -308,14 +302,6 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "exof", .description = "External orientation trajectory file for simulation of external orientations", }, -#ifdef LIB_REND_API_5MS - { - .id = CmdLnOptionId_framing5ms, - .match = "framing_5ms", - .matchShort = "fr5", - .description = "Process audio with 5 ms framing. Time resolution of metadata (e.g. ISM positions) remains unchanged w.r.t. 20 ms framing", - }, -#endif }; @@ -574,9 +560,7 @@ int main( int32_t delayTimeScale = 0; int16_t i, numChannels; ivas_error error = IVAS_ERR_OK; -#ifndef LIB_REND_API_5MS IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME]; -#endif #ifdef WMOPS reset_wmops(); @@ -749,13 +733,7 @@ int main( fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - const int16_t frameSize_smpls = (int16_t) ( -#ifdef LIB_REND_API_5MS - ( args.framing_5ms ? 5 : 20 ) -#else - 20 -#endif - * args.sampleRate / 1000 ); + const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 ); IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 }; IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS] = { 0 }; @@ -1041,17 +1019,10 @@ int main( fprintf( stdout, "\n\n-- Start the renderer (quiet mode) --\n\n" ); } -#ifdef LIB_REND_API_5MS - ObjectPositionBuffer mtdBuffer; -#endif - while ( 1 ) { int16_t num_in_channels; num_in_channels = inBuffer.config.numChannels; -#ifdef LIB_REND_API_5MS - const bool isCurrentFrameMultipleOf20ms = !args.framing_5ms || frame % 4 == 0; -#endif /* Read the input data */ if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) @@ -1069,85 +1040,50 @@ int main( /* Convert from int to float and from interleaved to packed */ convertInputBuffer( inpInt16Buffer, numSamplesRead, frameSize_smpls, num_in_channels, inFloatBuffer ); -#ifdef LIB_REND_API_5MS - if ( isCurrentFrameMultipleOf20ms ) - { -#else + ObjectPositionBuffer mtdBuffer; -#endif - IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); + IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); - if ( referenceVectorReader != NULL ) + if ( referenceVectorReader != NULL ) + { + IVAS_VECTOR3 listenerPos, refPos; + if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPos, &refPos ) ) != IVAS_ERR_OK ) { - IVAS_VECTOR3 listenerPos, refPos; - if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPos, &refPos ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - if ( ( error = IVAS_REND_SetReferenceVector( hIvasRend, listenerPos, refPos ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); } - /* Read from reference rotation trajectory file if specified */ - if ( referenceRotReader != NULL ) + if ( ( error = IVAS_REND_SetReferenceVector( hIvasRend, listenerPos, refPos ) ) != IVAS_ERR_OK ) { - IVAS_QUATERNION quaternion; - if ( ( error = HeadRotationFileReading( referenceRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - - if ( ( error = IVAS_REND_SetReferenceRotation( hIvasRend, quaternion ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error setting Reference Rotation: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); } -#ifdef LIB_REND_API_5MS } -#endif - - /* Read from head rotation trajectory file if specified */ - if ( headRotReader != NULL ) + /* Read from reference rotation trajectory file if specified */ + if ( referenceRotReader != NULL ) { -#ifdef LIB_REND_API_5MS - IVAS_QUATERNION headRot; - IVAS_VECTOR3 Pos; - - if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) + IVAS_QUATERNION quaternion; + if ( ( error = HeadRotationFileReading( referenceRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos ) ) != IVAS_ERR_OK ) + + if ( ( error = IVAS_REND_SetReferenceRotation( hIvasRend, quaternion ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); + fprintf( stderr, "Error setting Reference Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } + } - if ( !args.framing_5ms ) - { - /* Skip over 3 following head positions - they are given on 5ms grid */ - for ( int16_t i = 0; i < 3; ++i ) - { - if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } - } -#else - IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; + /* Read from head rotation trajectory file if specified */ + if ( headRotReader != NULL ) + { + IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + if ( ( error = HeadRotationFileReading( headRotReader, &quatBuffer[i], &Pos[i] ) ) != IVAS_ERR_OK ) { - if ( ( error = HeadRotationFileReading( headRotReader, &quatBuffer[i], &Pos[i] ) ) != IVAS_ERR_OK ) - { fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } @@ -1157,61 +1093,20 @@ int main( fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } -#endif } else { -#ifdef LIB_REND_API_5MS - if ( ( error = IVAS_REND_DisableHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error disabling head rotation: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } -#else error = IVAS_REND_SetHeadRotation( hIvasRend, NULL, NULL ); if ( error != IVAS_ERR_OK && error != IVAS_ERR_INVALID_OUTPUT_FORMAT ) { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } -#endif } /* Read from external orientation file if specified */ if ( externalOrientationFileReader != NULL ) { -#ifdef LIB_REND_API_5MS - IVAS_QUATERNION quat; - int8_t enableHeadRotation; - int8_t enableExternalOrientation; - int8_t enableRotationInterpolation; - int16_t numFramesToTargetOrientation; - - if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &quat, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error in External Orientation File Reading: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - - if ( ( error = IVAS_REND_SetExternalOrientation( hIvasRend, &quat, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error setting External Orientation: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - - if ( !args.framing_5ms ) - { - /* Skip over 3 following entries in file - they are given on 5ms grid */ - for ( int16_t i = 0; i < 3; ++i ) - { - if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &quat, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error in External Orientation File Reading: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } - } -#else IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; int8_t enableHeadRotation[RENDERER_HEAD_POSITIONS_PER_FRAME]; int8_t enableExternalOrientation[RENDERER_HEAD_POSITIONS_PER_FRAME]; @@ -1232,7 +1127,6 @@ int main( fprintf( stderr, "Error setting External Orientation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } -#endif } /* Combine external orientations and head rotation */ @@ -1387,7 +1281,6 @@ int main( delayNumSamples -= (int16_t) outBufferSize; } - /* TODO(sgi): Masa output most likely broken with 5ms framing */ /* Write MASA metadata for MASA outputs */ if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_MASA1 || args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_MASA2 ) { @@ -2007,9 +1900,6 @@ static CmdlnArgs defaultArgs( args.lfeCustomRoutingEnabled = false; clearString( args.inLfePanningMatrixFile ); -#ifdef LIB_REND_API_5MS - args.framing_5ms = false; -#endif return args; } @@ -2139,12 +2029,6 @@ static void parseOption( exit( -1 ); } break; -#ifdef LIB_REND_API_5MS - case CmdLnOptionId_framing5ms: - assert( numOptionValues == 0 ); - args->framing_5ms = false; - break; -#endif default: assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); break; diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 49c6f395fd..2dc926dfc2 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -50,9 +50,7 @@ #define IVAS_CLDFB_NO_CHANNELS_MAX ( 60 ) #define IVAS_MAX_INPUT_LFE_CHANNELS 4 -#ifndef LIB_REND_API_5MS #define RENDERER_HEAD_POSITIONS_PER_FRAME 4 -#endif /*----------------------------------------------------------------------------------* diff --git a/lib_com/options.h b/lib_com/options.h index 4a88b47d83..bee9901a56 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -157,7 +157,6 @@ #define FIX_XXX_JITTER_SBA_BINAURAL_GAIN #define FIX_XXX_HEADTRACKER_INIT #define API_5MS -#define LIB_REND_API_5MS /* FhG: Adds 5ms framing capability to lib_rend */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 8d987a3f3c..29a5ace8f4 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -857,11 +857,7 @@ ivas_error combine_external_and_head_orientations_rend( ); ivas_error combine_external_and_head_orientations( -#ifdef LIB_REND_API_5MS - IVAS_QUATERNION *headRotQuaternion, /* i : quaternion for head rotation */ -#else IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ -#endif IVAS_VECTOR3 *listenerPos, /* i : listener position */ #ifndef API_5MS int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 468d28b026..184f382ee8 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -902,11 +902,7 @@ ivas_error combine_external_and_head_orientations_dec( #endif } #ifdef API_5MS -#ifdef LIB_REND_API_5MS return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); -#else - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); -#endif #else return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); #endif @@ -936,13 +932,8 @@ ivas_error combine_external_and_head_orientations_rend( { if ( hHeadTrackData->headRotEnabled ) { -#ifdef LIB_REND_API_5MS - headRotQuaternions = &hHeadTrackData->headPosition; - listenerPos = &hHeadTrackData->Pos; -#else headRotQuaternions = hHeadTrackData->headPositions; listenerPos = hHeadTrackData->Pos; -#endif } } else if ( hExtOrientationData != NULL ) @@ -980,11 +971,7 @@ ivas_error combine_external_and_head_orientations_rend( *------------------------------------------------------------------------*/ ivas_error combine_external_and_head_orientations( -#ifdef LIB_REND_API_5MS - IVAS_QUATERNION *headRotQuaternion, /* i : quaternion for head rotation */ -#else IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ -#endif IVAS_VECTOR3 *listenerPos, /* i : listener position */ #ifndef API_5MS int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ @@ -1007,11 +994,7 @@ ivas_error combine_external_and_head_orientations( /* Form combined orientations or return if no data available */ if ( hCombinedOrientationData == NULL ) { -#ifdef LIB_REND_API_5MS - if ( headRotQuaternion != NULL || hExtOrientationData != NULL ) -#else if ( headRotQuaternions != NULL || hExtOrientationData != NULL ) -#endif { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1020,11 +1003,7 @@ ivas_error combine_external_and_head_orientations( return IVAS_ERR_OK; } } -#ifdef LIB_REND_API_5MS - else if ( headRotQuaternion == NULL && hExtOrientationData == NULL ) -#else else if ( headRotQuaternions == NULL && hExtOrientationData == NULL ) -#endif { /* Reset the combined orientations and rotations */ hCombinedOrientationData->isInterpolationOngoing = FALSE; @@ -1058,19 +1037,11 @@ ivas_error combine_external_and_head_orientations( } #endif } -#ifdef LIB_REND_API_5MS - else if ( hExtOrientationData == NULL && headRotQuaternion != NULL ) -#else else if ( hExtOrientationData == NULL && headRotQuaternions != NULL ) -#endif { /* Head rotation only */ #ifdef API_5MS -#ifdef LIB_REND_API_5MS - hCombinedOrientationData->Quaternion = *headRotQuaternion; -#else hCombinedOrientationData->Quaternion = *headRotQuaternions; -#endif #else if ( numHeadRotQuaternions >= 0 ) @@ -1159,11 +1130,7 @@ ivas_error combine_external_and_head_orientations( #endif } -#ifdef LIB_REND_API_5MS - if ( hExtOrientationData != NULL && headRotQuaternion != NULL ) -#else if ( hExtOrientationData != NULL && headRotQuaternions != NULL ) -#endif { /* Combine head and external orientations */ #ifdef API_5MS @@ -1173,19 +1140,11 @@ ivas_error combine_external_and_head_orientations( { if ( hExtOrientationData->enableExternalOrientation > 0 ) { -#ifdef LIB_REND_API_5MS - QuaternionProduct( hCombinedOrientationData->Quaternion, *headRotQuaternion, &hCombinedOrientationData->Quaternion ); -#else QuaternionProduct( hCombinedOrientationData->Quaternion, *headRotQuaternions, &hCombinedOrientationData->Quaternion ); -#endif } else { -#ifdef LIB_REND_API_5MS - hCombinedOrientationData->Quaternion = *headRotQuaternion; -#else hCombinedOrientationData->Quaternion = *headRotQuaternions; -#endif } } /* Use the freezed head rotation */ @@ -1244,11 +1203,7 @@ ivas_error combine_external_and_head_orientations( #endif } -#ifdef LIB_REND_API_5MS - if ( headRotQuaternion != NULL || hExtOrientationData != NULL ) -#else if ( headRotQuaternions != NULL || hExtOrientationData != NULL ) -#endif { /* Calculate the combined rotation matrix */ #ifdef API_5MS @@ -1288,22 +1243,14 @@ ivas_error combine_external_and_head_orientations( } #endif } -#ifdef LIB_REND_API_5MS - if ( headRotQuaternion != NULL ) -#else if ( headRotQuaternions != NULL ) -#endif { #ifdef API_5MS if ( hExtOrientationData != NULL ) { if ( hExtOrientationData->enableHeadRotation > 0 ) { -#ifdef LIB_REND_API_5MS - hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternion; -#else hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternions; -#endif } else { @@ -1312,11 +1259,7 @@ ivas_error combine_external_and_head_orientations( } else { -#ifdef LIB_REND_API_5MS - hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternion; -#else hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternions; -#endif } hCombinedOrientationData->listenerPos = *listenerPos; @@ -1351,11 +1294,7 @@ ivas_error combine_external_and_head_orientations( } /* Check if combined orientation is enabled */ -#ifdef LIB_REND_API_5MS - if ( headRotQuaternion != NULL && hExtOrientationData == NULL ) -#else if ( headRotQuaternions != NULL && hExtOrientationData == NULL ) -#endif { #ifdef API_5MS hCombinedOrientationData->enableCombinedOrientation = 1; @@ -1374,11 +1313,7 @@ ivas_error combine_external_and_head_orientations( } #endif } -#ifdef LIB_REND_API_5MS - else if ( headRotQuaternion == NULL && hExtOrientationData != NULL ) -#else else if ( headRotQuaternions == NULL && hExtOrientationData != NULL ) -#endif { #ifdef API_5MS if ( hExtOrientationData->enableExternalOrientation > 0 ) @@ -1403,11 +1338,7 @@ ivas_error combine_external_and_head_orientations( } #endif } -#ifdef LIB_REND_API_5MS - else if ( headRotQuaternion != NULL && hExtOrientationData != NULL ) -#else else if ( headRotQuaternions != NULL && hExtOrientationData != NULL ) -#endif { #ifdef API_5MS if ( hExtOrientationData->enableExternalOrientation > 0 || hExtOrientationData->enableHeadRotation > 0 ) diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 7306c45e99..14de5e7d55 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -248,16 +248,9 @@ typedef struct ivas_orient_trk_state_t typedef struct { int8_t headRotEnabled; -#ifdef LIB_REND_API_5MS - IVAS_QUATERNION headPosition; - IVAS_VECTOR3 Pos; - float crossfade_5ms[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; - float crossfade_20ms[L_FRAME48k]; -#else IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME]; IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME]; float crossfade[L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME]; -#endif ivas_orient_trk_state_t *hOrientationTracker; } IVAS_REND_HeadRotData; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 6f6b32de1b..89b51e7745 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -930,25 +930,6 @@ static ivas_error initHeadRotation( /* Head rotation is enabled by default */ hIvasRend->headRotData.headRotEnabled = 1; -#ifdef LIB_REND_API_5MS - /* Initialize 5ms crossfade */ - crossfade_len = L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES; /* TODO(sgi): @tmu why do we assume 48 kHz here? */ - tmp = 1.f / ( crossfade_len - 1 ); - for ( i = 0; i < crossfade_len; i++ ) - { - hIvasRend->headRotData.crossfade_5ms[i] = i * tmp; - } - /* Initialize 20ms crossfade */ - crossfade_len = L_FRAME48k; /* TODO(sgi): @tmu why do we assume 48 kHz here? */ - tmp = 1.f / ( crossfade_len - 1 ); - for ( i = 0; i < crossfade_len; i++ ) - { - hIvasRend->headRotData.crossfade_20ms[i] = i * tmp; - } - - /* Initialize with unit quaternion */ - hIvasRend->headRotData.headPosition = quaternionInit(); -#else /* Initialize 5ms crossfade */ crossfade_len = L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME; tmp = 1.f / ( crossfade_len - 1 ); @@ -962,7 +943,6 @@ static ivas_error initHeadRotation( { hIvasRend->headRotData.headPositions[i] = quaternionInit(); } -#endif if ( ( hIvasRend->headRotData.hOrientationTracker = (ivas_orient_trk_state_t *) malloc( sizeof( ivas_orient_trk_state_t ) ) ) == NULL ) { @@ -4083,19 +4063,12 @@ int16_t IVAS_REND_FeedRenderConfig( *-------------------------------------------------------------------*/ ivas_error IVAS_REND_SetHeadRotation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ -#ifdef LIB_REND_API_5MS - const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ - const IVAS_VECTOR3 Pos /* i : listener positions for next rendering call */ -#else + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ -#endif ) { -#ifndef LIB_REND_API_5MS int16_t i; -#endif IVAS_QUATERNION rotQuat; /* Validate function arguments */ @@ -4110,20 +4083,6 @@ ivas_error IVAS_REND_SetHeadRotation( return IVAS_ERR_INVALID_OUTPUT_FORMAT; } -#ifdef LIB_REND_API_5MS - /* check for Euler angle signaling */ - if ( headRot.w == -3.0f ) - { - Euler2Quat( deg2rad( headRot.x ), deg2rad( headRot.y ), deg2rad( headRot.z ), &rotQuat ); - } - else - { - rotQuat = headRot; - } - - ivas_orient_trk_Process( hIvasRend->headRotData.hOrientationTracker, rotQuat, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &hIvasRend->headRotData.headPosition ); - hIvasRend->headRotData.Pos = Pos; -#else if ( headRot == NULL ) { hIvasRend->headRotData.headRotEnabled = 0; @@ -4147,27 +4106,10 @@ ivas_error IVAS_REND_SetHeadRotation( hIvasRend->headRotData.Pos[i] = Pos[i]; } } -#endif return IVAS_ERR_OK; } -#ifdef LIB_REND_API_5MS -ivas_error IVAS_REND_DisableHeadRotation( - IVAS_REND_HANDLE hIvasRend /* i/o: Renderer handle */ -) -{ - /* Validate function arguments */ - if ( hIvasRend == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - hIvasRend->headRotData.headRotEnabled = 0; - return IVAS_ERR_OK; -} -#endif - /*-------------------------------------------------------------------* * IVAS_REND_SetOrientationTrackingMode() @@ -4295,24 +4237,15 @@ ivas_error IVAS_REND_SetReferenceVector( *---------------------------------------------------------------------*/ ivas_error IVAS_REND_SetExternalOrientation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_QUATERNION *orientation, /* i : external orientation data */ -#ifdef LIB_REND_API_5MS - int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ - int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ - int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ - int16_t numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ /* TODO(sgi): make independent of framing */ -#else + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_QUATERNION *orientation, /* i : external orientation data */ int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ -#endif ) { -#ifndef LIB_REND_API_5MS int16_t i; -#endif /* Validate function arguments */ if ( hIvasRend == NULL || hIvasRend->hExternalOrientationData == NULL ) @@ -4333,14 +4266,6 @@ ivas_error IVAS_REND_SetExternalOrientation( } else { -#ifdef LIB_REND_API_5MS - QuaternionInverse( *orientation, &hIvasRend->hExternalOrientationData->Quaternion ); - - hIvasRend->hExternalOrientationData->enableHeadRotation = enableHeadRotation; - hIvasRend->hExternalOrientationData->enableExternalOrientation = enableExternalOrientation; - hIvasRend->hExternalOrientationData->enableRotationInterpolation = enableRotationInterpolation; - hIvasRend->hExternalOrientationData->numFramesToTargetOrientation = numFramesToTargetOrientation; -#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { #ifdef API_5MS @@ -4360,7 +4285,6 @@ ivas_error IVAS_REND_SetExternalOrientation( hIvasRend->hExternalOrientationData->numFramesToTargetOrientation[i] = numFramesToTargetOrientation[i]; #endif } -#endif } return IVAS_ERR_OK; @@ -4397,9 +4321,7 @@ ivas_error IVAS_REND_GetCombinedOrientation( IVAS_QUATERNION *pOrientation /* i/o: Quaternion pointer processed orientation */ ) { -#ifndef LIB_REND_API_5MS int16_t i; -#endif if ( hIvasRend == NULL || pOrientation == NULL ) { @@ -4408,9 +4330,6 @@ ivas_error IVAS_REND_GetCombinedOrientation( if ( hIvasRend->hCombinedOrientationData != NULL ) { -#ifdef LIB_REND_API_5MS - *pOrientation = hIvasRend->hCombinedOrientationData->Quaternion; -#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { #ifdef API_5MS @@ -4420,7 +4339,6 @@ ivas_error IVAS_REND_GetCombinedOrientation( pOrientation[i] = hIvasRend->hCombinedOrientationData->Quaternions[i]; #endif } -#endif } return IVAS_ERR_OK; @@ -4529,11 +4447,7 @@ static ivas_error rotateFrameMc( { int16_t i; int16_t j; -#ifdef LIB_REND_API_5MS - const float *crossfade; -#else int16_t subframe_idx, subframe_len; -#endif int16_t azimuth, elevation; int16_t is_planar_setup, lfe_idx; int16_t nchan; @@ -4548,21 +4462,6 @@ static ivas_error rotateFrameMc( push_wmops( "rotateFrameMc" ); -#ifdef LIB_REND_API_5MS - if ( inAudio.config.numSamplesPerChannel == L_FRAME48k ) - { - crossfade = headRotData->crossfade_20ms; - } - else if ( inAudio.config.numSamplesPerChannel == L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) - { - crossfade = headRotData->crossfade_5ms; - } - else - { - return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Only 5 and 20 ms framing is supported" ); - } -#endif - if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { if ( ( error = getAudioConfigNumChannels( inConfig, &nchan ) ) != IVAS_ERR_OK ) @@ -4587,13 +4486,10 @@ static ivas_error rotateFrameMc( gains[ch_in][ch_in] = 1.f; } -#ifndef LIB_REND_API_5MS - /* TODO(sgi): @tmu please review changes in this function */ /* subframe loop */ subframe_len = inAudio.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) { -#endif for ( i = 0; i < 3; i++ ) { if ( hCombinedOrientationData != NULL ) @@ -4655,18 +4551,6 @@ static ivas_error rotateFrameMc( { for ( ch_in = 0; ch_in < nchan; ch_in++ ) { -#ifdef LIB_REND_API_5MS - writePtr = getSmplPtr( outAudio, ch_out, 0 ); - readPtr = getSmplPtr( inAudio, ch_in, 0 ); - /* crossfade with previous rotation gains */ - for ( i = 0; i < inAudio.config.numSamplesPerChannel; i++ ) - { - *writePtr++ += - ( *readPtr ) * ( ( 1 - crossfade[i] ) * gains_prev[ch_in][ch_out] ) + - ( *readPtr ) * ( crossfade[i] * gains[ch_in][ch_out] ); - readPtr++; - } -#else writePtr = getSmplPtr( outAudio, ch_out, subframe_idx * subframe_len ); readPtr = getSmplPtr( inAudio, ch_in, subframe_idx * subframe_len ); /* crossfade with previous rotation gains */ @@ -4677,7 +4561,6 @@ static ivas_error rotateFrameMc( ( *readPtr ) * ( headRotData->crossfade[i] * gains[ch_in][ch_out] ); readPtr++; } -#endif } } @@ -4686,9 +4569,7 @@ static ivas_error rotateFrameMc( { mvr2r( gains[i], gains_prev[i], nchan ); } -#ifndef LIB_REND_API_5MS } -#endif pop_wmops(); @@ -4707,11 +4588,7 @@ static ivas_error rotateFrameSba( int16_t i, l, n, m; int16_t m1, m2; int16_t shd_rot_max_order; -#ifdef LIB_REND_API_5MS - const float *crossfade; -#else int16_t subframe_idx, subframe_len; -#endif float *readPtr, *writePtr; rotation_matrix Rmat; float tmpRot[2 * HEADROT_ORDER + 1]; @@ -4720,33 +4597,15 @@ static ivas_error rotateFrameSba( push_wmops( "rotateFrameSba" ); -#ifdef LIB_REND_API_5MS - if ( inAudio.config.numSamplesPerChannel == L_FRAME48k ) - { - crossfade = headRotData->crossfade_20ms; - } - else if ( inAudio.config.numSamplesPerChannel == L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) - { - crossfade = headRotData->crossfade_5ms; - } - else - { - return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Only 5 and 20 ms framing is supported" ); - } -#endif - if ( ( error = getAmbisonicsOrder( inConfig, &shd_rot_max_order ) ) != IVAS_ERR_OK ) { return error; } -#ifndef LIB_REND_API_5MS - /* TODO(sgi): @tmu please review changes in this function */ /* subframe loop */ subframe_len = inAudio.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) { -#endif /* initialize rotation matrices with zeros */ for ( i = 0; i < HEADROT_SHMAT_DIM; i++ ) { @@ -4778,11 +4637,7 @@ static ivas_error rotateFrameSba( /* calculate ambisonics rotation matrices for the previous and current frames */ SHrotmatgen( gains, Rmat, shd_rot_max_order ); -#ifdef LIB_REND_API_5MS - for ( i = 0; i < inAudio.config.numSamplesPerChannel; i++ ) -#else for ( i = 0; i < subframe_len; i++ ) -#endif { /* As the rotation matrix becomes block diagonal in a SH basis, we can*/ /* apply each angular-momentum block individually to save complexity. */ @@ -4799,27 +4654,16 @@ static ivas_error rotateFrameSba( for ( m = m1; m < m2; m++ ) { -#ifdef LIB_REND_API_5MS - readPtr = getSmplPtr( inAudio, m, i ); - /* crossfade with previous rotation gains */ - tmpRot[n - m1] += crossfade[i] * gains[n][m] * ( *readPtr ) + - ( 1 - crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); -#else readPtr = getSmplPtr( inAudio, m, subframe_idx * subframe_len + i ); /* crossfade with previous rotation gains */ tmpRot[n - m1] += headRotData->crossfade[i] * gains[n][m] * ( *readPtr ) + ( 1 - headRotData->crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); -#endif } } /* write back the result */ for ( n = m1; n < m2; n++ ) { -#ifdef LIB_REND_API_5MS - writePtr = getSmplPtr( outAudio, n, i ); -#else writePtr = getSmplPtr( outAudio, n, subframe_idx * subframe_len + i ); -#endif ( *writePtr ) = tmpRot[n - m1]; } m1 = m2; @@ -4847,9 +4691,7 @@ static ivas_error rotateFrameSba( { mvr2r( gains[i], gains_prev[i], HEADROT_SHMAT_DIM ); } -#ifndef LIB_REND_API_5MS } -#endif pop_wmops(); @@ -4892,9 +4734,7 @@ static ivas_error renderIsmToBinauralRoom( { int16_t i; int16_t azi_rot, ele_rot; -#ifndef LIB_REND_API_5MS int16_t subframe_idx, subframe_len; -#endif int16_t tmp; rotation_matrix Rmat; float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; @@ -4943,12 +4783,10 @@ static ivas_error renderIsmToBinauralRoom( if ( combinedOrientationEnabled ) { -#ifndef LIB_REND_API_5MS subframe_len = ismInput->base.inputBuffer.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; // for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) for ( subframe_idx = 0; subframe_idx < 1; subframe_idx++ ) { -#endif for ( i = 0; i < 3; i++ ) { #ifdef API_5MS @@ -4976,10 +4814,8 @@ static ivas_error renderIsmToBinauralRoom( Rmat[i][i] = 1.0f; } } -#ifndef LIB_REND_API_5MS } (void) subframe_len; // avoid warning -#endif } /* TODO tmu : see issue #518 */ @@ -6464,10 +6300,6 @@ static ivas_error renderActiveInputsMasa( if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && pCurrentInput->decDummy->hHeadTrackData != NULL ) { -#ifdef LIB_REND_API_5MS - pCurrentInput->decDummy->hHeadTrackData->Quaternion = hIvasRend->headRotData.headPosition; - pCurrentInput->decDummy->hHeadTrackData->Pos = hIvasRend->headRotData.Pos; -#else for ( sf_idx = 0; sf_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; ++sf_idx ) { #ifdef API_5MS @@ -6479,7 +6311,6 @@ static ivas_error renderActiveInputsMasa( pCurrentInput->decDummy->hHeadTrackData->Pos[sf_idx] = hIvasRend->headRotData.Pos[sf_idx]; #endif } -#endif } if ( ( error = renderInputMasa( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 701e0d5062..d8d6127b20 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -247,21 +247,9 @@ int16_t IVAS_REND_FeedRenderConfig( ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ -#ifdef LIB_REND_API_5MS - const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ - const IVAS_VECTOR3 Pos /* i : listener positions for next rendering call */ -#else const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ -#endif -); - -#ifdef LIB_REND_API_5MS -/* Head rotation becomes enabled by calling IVAS_REND_SetHeadRotation. Use this to disable. */ -ivas_error IVAS_REND_DisableHeadRotation( - IVAS_REND_HANDLE hIvasRend /* i/o: Renderer handle */ ); -#endif ivas_error IVAS_REND_SetOrientationTrackingMode( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ @@ -292,17 +280,10 @@ ivas_error IVAS_REND_SetReferenceVector( ivas_error IVAS_REND_SetExternalOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_QUATERNION *orientation, /* i : external orientation data */ -#ifdef LIB_REND_API_5MS - int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ - int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ - int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ - int16_t numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ -#else int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ -#endif ); ivas_error IVAS_REND_CombineHeadAndExternalOrientation( @@ -311,7 +292,7 @@ ivas_error IVAS_REND_CombineHeadAndExternalOrientation( ivas_error IVAS_REND_GetCombinedOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_QUATERNION *pOrientation /* i/o: Quaternion pointer processed orientation */ + IVAS_QUATERNION *pRotation /* i/o: Quaternion pointer processed orientation */ ); ivas_error IVAS_REND_GetMasaMetadata( -- GitLab From ffc8eb1a0f76e13a734dbe9056582957bf588105 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 16 Jun 2023 09:39:16 +0200 Subject: [PATCH 14/66] Revert "[tmp] Revert "Remove RENDERER_HEAD_POSITIONS_PER_FRAME - code compiles, but untested"" This reverts commit 6e1fe92ff2cf0a510017bb86ab4b6f72b3ffd7cd. --- apps/renderer.c | 170 +++++++++++++++++++++++++++++------ lib_com/common_api_types.h | 2 + lib_com/options.h | 1 + lib_rend/ivas_prot_rend.h | 4 + lib_rend/ivas_rotation.c | 69 +++++++++++++++ lib_rend/ivas_stat_rend.h | 7 ++ lib_rend/lib_rend.c | 175 ++++++++++++++++++++++++++++++++++++- lib_rend/lib_rend.h | 21 ++++- 8 files changed, 418 insertions(+), 31 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 760065be91..9be54daca5 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -157,6 +157,9 @@ typedef struct float lfeConfigElevation; bool lfeCustomRoutingEnabled; char inLfePanningMatrixFile[RENDERER_MAX_CLI_ARG_LENGTH]; +#ifdef LIB_REND_API_5MS + bool framing_5ms; +#endif } CmdlnArgs; typedef enum @@ -181,6 +184,9 @@ typedef enum CmdLnOptionId_inputGain, CmdLnOptionId_referenceVectorFile, CmdLnOptionId_exteriorOrientationFile, +#ifdef LIB_REND_API_5MS + CmdLnOptionId_framing5ms, +#endif } CmdLnOptionId; static const CmdLnParser_Option cliOptions[] = { @@ -302,6 +308,14 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "exof", .description = "External orientation trajectory file for simulation of external orientations", }, +#ifdef LIB_REND_API_5MS + { + .id = CmdLnOptionId_framing5ms, + .match = "framing_5ms", + .matchShort = "fr5", + .description = "Process audio with 5 ms framing. Time resolution of metadata (e.g. ISM positions) remains unchanged w.r.t. 20 ms framing", + }, +#endif }; @@ -560,7 +574,9 @@ int main( int32_t delayTimeScale = 0; int16_t i, numChannels; ivas_error error = IVAS_ERR_OK; +#ifndef LIB_REND_API_5MS IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME]; +#endif #ifdef WMOPS reset_wmops(); @@ -733,7 +749,13 @@ int main( fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 ); + const int16_t frameSize_smpls = (int16_t) ( +#ifdef LIB_REND_API_5MS + ( args.framing_5ms ? 5 : 20 ) +#else + 20 +#endif + * args.sampleRate / 1000 ); IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 }; IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS] = { 0 }; @@ -1019,10 +1041,17 @@ int main( fprintf( stdout, "\n\n-- Start the renderer (quiet mode) --\n\n" ); } +#ifdef LIB_REND_API_5MS + ObjectPositionBuffer mtdBuffer; +#endif + while ( 1 ) { int16_t num_in_channels; num_in_channels = inBuffer.config.numChannels; +#ifdef LIB_REND_API_5MS + const bool isCurrentFrameMultipleOf20ms = !args.framing_5ms || frame % 4 == 0; +#endif /* Read the input data */ if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) @@ -1040,50 +1069,85 @@ int main( /* Convert from int to float and from interleaved to packed */ convertInputBuffer( inpInt16Buffer, numSamplesRead, frameSize_smpls, num_in_channels, inFloatBuffer ); - +#ifdef LIB_REND_API_5MS + if ( isCurrentFrameMultipleOf20ms ) + { +#else ObjectPositionBuffer mtdBuffer; - IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); +#endif + IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); - if ( referenceVectorReader != NULL ) - { - IVAS_VECTOR3 listenerPos, refPos; - if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPos, &refPos ) ) != IVAS_ERR_OK ) + if ( referenceVectorReader != NULL ) { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); + IVAS_VECTOR3 listenerPos, refPos; + if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPos, &refPos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + if ( ( error = IVAS_REND_SetReferenceVector( hIvasRend, listenerPos, refPos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } } - if ( ( error = IVAS_REND_SetReferenceVector( hIvasRend, listenerPos, refPos ) ) != IVAS_ERR_OK ) + /* Read from reference rotation trajectory file if specified */ + if ( referenceRotReader != NULL ) { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); + IVAS_QUATERNION quaternion; + if ( ( error = HeadRotationFileReading( referenceRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_SetReferenceRotation( hIvasRend, quaternion ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error setting Reference Rotation: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } } +#ifdef LIB_REND_API_5MS } - /* Read from reference rotation trajectory file if specified */ - if ( referenceRotReader != NULL ) +#endif + + /* Read from head rotation trajectory file if specified */ + if ( headRotReader != NULL ) { - IVAS_QUATERNION quaternion; - if ( ( error = HeadRotationFileReading( referenceRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) +#ifdef LIB_REND_API_5MS + IVAS_QUATERNION headRot; + IVAS_VECTOR3 Pos; + + if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - - if ( ( error = IVAS_REND_SetReferenceRotation( hIvasRend, quaternion ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "Error setting Reference Rotation: %s\n", ivas_error_to_string( error ) ); + fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - } - /* Read from head rotation trajectory file if specified */ - if ( headRotReader != NULL ) - { - IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; - - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + if ( !args.framing_5ms ) { - if ( ( error = HeadRotationFileReading( headRotReader, &quatBuffer[i], &Pos[i] ) ) != IVAS_ERR_OK ) + /* Skip over 3 following head positions - they are given on 5ms grid */ + for ( int16_t i = 0; i < 3; ++i ) + { + if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } +#else + IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; + + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { + if ( ( error = HeadRotationFileReading( headRotReader, &quatBuffer[i], &Pos[i] ) ) != IVAS_ERR_OK ) + { fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } @@ -1093,20 +1157,61 @@ int main( fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } +#endif } else { +#ifdef LIB_REND_API_5MS + if ( ( error = IVAS_REND_DisableHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error disabling head rotation: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } +#else error = IVAS_REND_SetHeadRotation( hIvasRend, NULL, NULL ); if ( error != IVAS_ERR_OK && error != IVAS_ERR_INVALID_OUTPUT_FORMAT ) { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } +#endif } /* Read from external orientation file if specified */ if ( externalOrientationFileReader != NULL ) { +#ifdef LIB_REND_API_5MS + IVAS_QUATERNION quat; + int8_t enableHeadRotation; + int8_t enableExternalOrientation; + int8_t enableRotationInterpolation; + int16_t numFramesToTargetOrientation; + + if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &quat, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in External Orientation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_SetExternalOrientation( hIvasRend, &quat, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error setting External Orientation: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( !args.framing_5ms ) + { + /* Skip over 3 following entries in file - they are given on 5ms grid */ + for ( int16_t i = 0; i < 3; ++i ) + { + if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &quat, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in External Orientation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } +#else IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; int8_t enableHeadRotation[RENDERER_HEAD_POSITIONS_PER_FRAME]; int8_t enableExternalOrientation[RENDERER_HEAD_POSITIONS_PER_FRAME]; @@ -1127,6 +1232,7 @@ int main( fprintf( stderr, "Error setting External Orientation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } +#endif } /* Combine external orientations and head rotation */ @@ -1281,6 +1387,7 @@ int main( delayNumSamples -= (int16_t) outBufferSize; } + /* TODO(sgi): Masa output most likely broken with 5ms framing */ /* Write MASA metadata for MASA outputs */ if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_MASA1 || args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_MASA2 ) { @@ -1900,6 +2007,9 @@ static CmdlnArgs defaultArgs( args.lfeCustomRoutingEnabled = false; clearString( args.inLfePanningMatrixFile ); +#ifdef LIB_REND_API_5MS + args.framing_5ms = false; +#endif return args; } @@ -2029,6 +2139,12 @@ static void parseOption( exit( -1 ); } break; +#ifdef LIB_REND_API_5MS + case CmdLnOptionId_framing5ms: + assert( numOptionValues == 0 ); + args->framing_5ms = false; + break; +#endif default: assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); break; diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 2dc926dfc2..49c6f395fd 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -50,7 +50,9 @@ #define IVAS_CLDFB_NO_CHANNELS_MAX ( 60 ) #define IVAS_MAX_INPUT_LFE_CHANNELS 4 +#ifndef LIB_REND_API_5MS #define RENDERER_HEAD_POSITIONS_PER_FRAME 4 +#endif /*----------------------------------------------------------------------------------* diff --git a/lib_com/options.h b/lib_com/options.h index 6e3e1010c2..544100fb35 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -159,6 +159,7 @@ #define FIX_XXX_TDOBJRENDERER_INPUT #define FIX_XXX_ISM_SBA_ASAN #define API_5MS +#define LIB_REND_API_5MS /* FhG: Adds 5ms framing capability to lib_rend */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 29a5ace8f4..8d987a3f3c 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -857,7 +857,11 @@ ivas_error combine_external_and_head_orientations_rend( ); ivas_error combine_external_and_head_orientations( +#ifdef LIB_REND_API_5MS + IVAS_QUATERNION *headRotQuaternion, /* i : quaternion for head rotation */ +#else IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ +#endif IVAS_VECTOR3 *listenerPos, /* i : listener position */ #ifndef API_5MS int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index efd281ce84..f01120ddc0 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -902,7 +902,11 @@ ivas_error combine_external_and_head_orientations_dec( #endif } #ifdef API_5MS +#ifdef LIB_REND_API_5MS return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); +#else + return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); +#endif #else return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); #endif @@ -932,8 +936,13 @@ ivas_error combine_external_and_head_orientations_rend( { if ( hHeadTrackData->headRotEnabled ) { +#ifdef LIB_REND_API_5MS + headRotQuaternions = &hHeadTrackData->headPosition; + listenerPos = &hHeadTrackData->Pos; +#else headRotQuaternions = hHeadTrackData->headPositions; listenerPos = hHeadTrackData->Pos; +#endif } } else if ( hExtOrientationData != NULL ) @@ -971,7 +980,11 @@ ivas_error combine_external_and_head_orientations_rend( *------------------------------------------------------------------------*/ ivas_error combine_external_and_head_orientations( +#ifdef LIB_REND_API_5MS + IVAS_QUATERNION *headRotQuaternion, /* i : quaternion for head rotation */ +#else IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ +#endif IVAS_VECTOR3 *listenerPos, /* i : listener position */ #ifndef API_5MS int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ @@ -994,7 +1007,11 @@ ivas_error combine_external_and_head_orientations( /* Form combined orientations or return if no data available */ if ( hCombinedOrientationData == NULL ) { +#ifdef LIB_REND_API_5MS + if ( headRotQuaternion != NULL || hExtOrientationData != NULL ) +#else if ( headRotQuaternions != NULL || hExtOrientationData != NULL ) +#endif { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1003,7 +1020,11 @@ ivas_error combine_external_and_head_orientations( return IVAS_ERR_OK; } } +#ifdef LIB_REND_API_5MS + else if ( headRotQuaternion == NULL && hExtOrientationData == NULL ) +#else else if ( headRotQuaternions == NULL && hExtOrientationData == NULL ) +#endif { /* Reset the combined orientations and rotations */ hCombinedOrientationData->isInterpolationOngoing = FALSE; @@ -1037,11 +1058,19 @@ ivas_error combine_external_and_head_orientations( } #endif } +#ifdef LIB_REND_API_5MS + else if ( hExtOrientationData == NULL && headRotQuaternion != NULL ) +#else else if ( hExtOrientationData == NULL && headRotQuaternions != NULL ) +#endif { /* Head rotation only */ #ifdef API_5MS +#ifdef LIB_REND_API_5MS + hCombinedOrientationData->Quaternion = *headRotQuaternion; +#else hCombinedOrientationData->Quaternion = *headRotQuaternions; +#endif #else if ( numHeadRotQuaternions >= 0 ) @@ -1130,7 +1159,11 @@ ivas_error combine_external_and_head_orientations( #endif } +#ifdef LIB_REND_API_5MS + if ( hExtOrientationData != NULL && headRotQuaternion != NULL ) +#else if ( hExtOrientationData != NULL && headRotQuaternions != NULL ) +#endif { /* Combine head and external orientations */ #ifdef API_5MS @@ -1140,11 +1173,19 @@ ivas_error combine_external_and_head_orientations( { if ( hExtOrientationData->enableExternalOrientation > 0 ) { +#ifdef LIB_REND_API_5MS + QuaternionProduct( hCombinedOrientationData->Quaternion, *headRotQuaternion, &hCombinedOrientationData->Quaternion ); +#else QuaternionProduct( hCombinedOrientationData->Quaternion, *headRotQuaternions, &hCombinedOrientationData->Quaternion ); +#endif } else { +#ifdef LIB_REND_API_5MS + hCombinedOrientationData->Quaternion = *headRotQuaternion; +#else hCombinedOrientationData->Quaternion = *headRotQuaternions; +#endif } } /* Use the freezed head rotation */ @@ -1203,7 +1244,11 @@ ivas_error combine_external_and_head_orientations( #endif } +#ifdef LIB_REND_API_5MS + if ( headRotQuaternion != NULL || hExtOrientationData != NULL ) +#else if ( headRotQuaternions != NULL || hExtOrientationData != NULL ) +#endif { /* Calculate the combined rotation matrix */ #ifdef API_5MS @@ -1243,14 +1288,22 @@ ivas_error combine_external_and_head_orientations( } #endif } +#ifdef LIB_REND_API_5MS + if ( headRotQuaternion != NULL ) +#else if ( headRotQuaternions != NULL ) +#endif { #ifdef API_5MS if ( hExtOrientationData != NULL ) { if ( hExtOrientationData->enableHeadRotation > 0 ) { +#ifdef LIB_REND_API_5MS + hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternion; +#else hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternions; +#endif } else { @@ -1259,7 +1312,11 @@ ivas_error combine_external_and_head_orientations( } else { +#ifdef LIB_REND_API_5MS + hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternion; +#else hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternions; +#endif } hCombinedOrientationData->listenerPos = *listenerPos; @@ -1294,7 +1351,11 @@ ivas_error combine_external_and_head_orientations( } /* Check if combined orientation is enabled */ +#ifdef LIB_REND_API_5MS + if ( headRotQuaternion != NULL && hExtOrientationData == NULL ) +#else if ( headRotQuaternions != NULL && hExtOrientationData == NULL ) +#endif { #ifdef API_5MS hCombinedOrientationData->enableCombinedOrientation = 1; @@ -1313,7 +1374,11 @@ ivas_error combine_external_and_head_orientations( } #endif } +#ifdef LIB_REND_API_5MS + else if ( headRotQuaternion == NULL && hExtOrientationData != NULL ) +#else else if ( headRotQuaternions == NULL && hExtOrientationData != NULL ) +#endif { #ifdef API_5MS if ( hExtOrientationData->enableExternalOrientation > 0 ) @@ -1338,7 +1403,11 @@ ivas_error combine_external_and_head_orientations( } #endif } +#ifdef LIB_REND_API_5MS + else if ( headRotQuaternion != NULL && hExtOrientationData != NULL ) +#else else if ( headRotQuaternions != NULL && hExtOrientationData != NULL ) +#endif { #ifdef API_5MS if ( hExtOrientationData->enableExternalOrientation > 0 || hExtOrientationData->enableHeadRotation > 0 ) diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 14de5e7d55..7306c45e99 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -248,9 +248,16 @@ typedef struct ivas_orient_trk_state_t typedef struct { int8_t headRotEnabled; +#ifdef LIB_REND_API_5MS + IVAS_QUATERNION headPosition; + IVAS_VECTOR3 Pos; + float crossfade_5ms[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + float crossfade_20ms[L_FRAME48k]; +#else IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME]; IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME]; float crossfade[L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME]; +#endif ivas_orient_trk_state_t *hOrientationTracker; } IVAS_REND_HeadRotData; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 89b51e7745..6f6b32de1b 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -930,6 +930,25 @@ static ivas_error initHeadRotation( /* Head rotation is enabled by default */ hIvasRend->headRotData.headRotEnabled = 1; +#ifdef LIB_REND_API_5MS + /* Initialize 5ms crossfade */ + crossfade_len = L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES; /* TODO(sgi): @tmu why do we assume 48 kHz here? */ + tmp = 1.f / ( crossfade_len - 1 ); + for ( i = 0; i < crossfade_len; i++ ) + { + hIvasRend->headRotData.crossfade_5ms[i] = i * tmp; + } + /* Initialize 20ms crossfade */ + crossfade_len = L_FRAME48k; /* TODO(sgi): @tmu why do we assume 48 kHz here? */ + tmp = 1.f / ( crossfade_len - 1 ); + for ( i = 0; i < crossfade_len; i++ ) + { + hIvasRend->headRotData.crossfade_20ms[i] = i * tmp; + } + + /* Initialize with unit quaternion */ + hIvasRend->headRotData.headPosition = quaternionInit(); +#else /* Initialize 5ms crossfade */ crossfade_len = L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME; tmp = 1.f / ( crossfade_len - 1 ); @@ -943,6 +962,7 @@ static ivas_error initHeadRotation( { hIvasRend->headRotData.headPositions[i] = quaternionInit(); } +#endif if ( ( hIvasRend->headRotData.hOrientationTracker = (ivas_orient_trk_state_t *) malloc( sizeof( ivas_orient_trk_state_t ) ) ) == NULL ) { @@ -4063,12 +4083,19 @@ int16_t IVAS_REND_FeedRenderConfig( *-------------------------------------------------------------------*/ ivas_error IVAS_REND_SetHeadRotation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ +#ifdef LIB_REND_API_5MS + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos /* i : listener positions for next rendering call */ +#else const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ +#endif ) { +#ifndef LIB_REND_API_5MS int16_t i; +#endif IVAS_QUATERNION rotQuat; /* Validate function arguments */ @@ -4083,6 +4110,20 @@ ivas_error IVAS_REND_SetHeadRotation( return IVAS_ERR_INVALID_OUTPUT_FORMAT; } +#ifdef LIB_REND_API_5MS + /* check for Euler angle signaling */ + if ( headRot.w == -3.0f ) + { + Euler2Quat( deg2rad( headRot.x ), deg2rad( headRot.y ), deg2rad( headRot.z ), &rotQuat ); + } + else + { + rotQuat = headRot; + } + + ivas_orient_trk_Process( hIvasRend->headRotData.hOrientationTracker, rotQuat, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &hIvasRend->headRotData.headPosition ); + hIvasRend->headRotData.Pos = Pos; +#else if ( headRot == NULL ) { hIvasRend->headRotData.headRotEnabled = 0; @@ -4106,10 +4147,27 @@ ivas_error IVAS_REND_SetHeadRotation( hIvasRend->headRotData.Pos[i] = Pos[i]; } } +#endif return IVAS_ERR_OK; } +#ifdef LIB_REND_API_5MS +ivas_error IVAS_REND_DisableHeadRotation( + IVAS_REND_HANDLE hIvasRend /* i/o: Renderer handle */ +) +{ + /* Validate function arguments */ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hIvasRend->headRotData.headRotEnabled = 0; + return IVAS_ERR_OK; +} +#endif + /*-------------------------------------------------------------------* * IVAS_REND_SetOrientationTrackingMode() @@ -4237,15 +4295,24 @@ ivas_error IVAS_REND_SetReferenceVector( *---------------------------------------------------------------------*/ ivas_error IVAS_REND_SetExternalOrientation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_QUATERNION *orientation, /* i : external orientation data */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_QUATERNION *orientation, /* i : external orientation data */ +#ifdef LIB_REND_API_5MS + int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ /* TODO(sgi): make independent of framing */ +#else int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#endif ) { +#ifndef LIB_REND_API_5MS int16_t i; +#endif /* Validate function arguments */ if ( hIvasRend == NULL || hIvasRend->hExternalOrientationData == NULL ) @@ -4266,6 +4333,14 @@ ivas_error IVAS_REND_SetExternalOrientation( } else { +#ifdef LIB_REND_API_5MS + QuaternionInverse( *orientation, &hIvasRend->hExternalOrientationData->Quaternion ); + + hIvasRend->hExternalOrientationData->enableHeadRotation = enableHeadRotation; + hIvasRend->hExternalOrientationData->enableExternalOrientation = enableExternalOrientation; + hIvasRend->hExternalOrientationData->enableRotationInterpolation = enableRotationInterpolation; + hIvasRend->hExternalOrientationData->numFramesToTargetOrientation = numFramesToTargetOrientation; +#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { #ifdef API_5MS @@ -4285,6 +4360,7 @@ ivas_error IVAS_REND_SetExternalOrientation( hIvasRend->hExternalOrientationData->numFramesToTargetOrientation[i] = numFramesToTargetOrientation[i]; #endif } +#endif } return IVAS_ERR_OK; @@ -4321,7 +4397,9 @@ ivas_error IVAS_REND_GetCombinedOrientation( IVAS_QUATERNION *pOrientation /* i/o: Quaternion pointer processed orientation */ ) { +#ifndef LIB_REND_API_5MS int16_t i; +#endif if ( hIvasRend == NULL || pOrientation == NULL ) { @@ -4330,6 +4408,9 @@ ivas_error IVAS_REND_GetCombinedOrientation( if ( hIvasRend->hCombinedOrientationData != NULL ) { +#ifdef LIB_REND_API_5MS + *pOrientation = hIvasRend->hCombinedOrientationData->Quaternion; +#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { #ifdef API_5MS @@ -4339,6 +4420,7 @@ ivas_error IVAS_REND_GetCombinedOrientation( pOrientation[i] = hIvasRend->hCombinedOrientationData->Quaternions[i]; #endif } +#endif } return IVAS_ERR_OK; @@ -4447,7 +4529,11 @@ static ivas_error rotateFrameMc( { int16_t i; int16_t j; +#ifdef LIB_REND_API_5MS + const float *crossfade; +#else int16_t subframe_idx, subframe_len; +#endif int16_t azimuth, elevation; int16_t is_planar_setup, lfe_idx; int16_t nchan; @@ -4462,6 +4548,21 @@ static ivas_error rotateFrameMc( push_wmops( "rotateFrameMc" ); +#ifdef LIB_REND_API_5MS + if ( inAudio.config.numSamplesPerChannel == L_FRAME48k ) + { + crossfade = headRotData->crossfade_20ms; + } + else if ( inAudio.config.numSamplesPerChannel == L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) + { + crossfade = headRotData->crossfade_5ms; + } + else + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Only 5 and 20 ms framing is supported" ); + } +#endif + if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { if ( ( error = getAudioConfigNumChannels( inConfig, &nchan ) ) != IVAS_ERR_OK ) @@ -4486,10 +4587,13 @@ static ivas_error rotateFrameMc( gains[ch_in][ch_in] = 1.f; } +#ifndef LIB_REND_API_5MS + /* TODO(sgi): @tmu please review changes in this function */ /* subframe loop */ subframe_len = inAudio.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) { +#endif for ( i = 0; i < 3; i++ ) { if ( hCombinedOrientationData != NULL ) @@ -4551,6 +4655,18 @@ static ivas_error rotateFrameMc( { for ( ch_in = 0; ch_in < nchan; ch_in++ ) { +#ifdef LIB_REND_API_5MS + writePtr = getSmplPtr( outAudio, ch_out, 0 ); + readPtr = getSmplPtr( inAudio, ch_in, 0 ); + /* crossfade with previous rotation gains */ + for ( i = 0; i < inAudio.config.numSamplesPerChannel; i++ ) + { + *writePtr++ += + ( *readPtr ) * ( ( 1 - crossfade[i] ) * gains_prev[ch_in][ch_out] ) + + ( *readPtr ) * ( crossfade[i] * gains[ch_in][ch_out] ); + readPtr++; + } +#else writePtr = getSmplPtr( outAudio, ch_out, subframe_idx * subframe_len ); readPtr = getSmplPtr( inAudio, ch_in, subframe_idx * subframe_len ); /* crossfade with previous rotation gains */ @@ -4561,6 +4677,7 @@ static ivas_error rotateFrameMc( ( *readPtr ) * ( headRotData->crossfade[i] * gains[ch_in][ch_out] ); readPtr++; } +#endif } } @@ -4569,7 +4686,9 @@ static ivas_error rotateFrameMc( { mvr2r( gains[i], gains_prev[i], nchan ); } +#ifndef LIB_REND_API_5MS } +#endif pop_wmops(); @@ -4588,7 +4707,11 @@ static ivas_error rotateFrameSba( int16_t i, l, n, m; int16_t m1, m2; int16_t shd_rot_max_order; +#ifdef LIB_REND_API_5MS + const float *crossfade; +#else int16_t subframe_idx, subframe_len; +#endif float *readPtr, *writePtr; rotation_matrix Rmat; float tmpRot[2 * HEADROT_ORDER + 1]; @@ -4597,15 +4720,33 @@ static ivas_error rotateFrameSba( push_wmops( "rotateFrameSba" ); +#ifdef LIB_REND_API_5MS + if ( inAudio.config.numSamplesPerChannel == L_FRAME48k ) + { + crossfade = headRotData->crossfade_20ms; + } + else if ( inAudio.config.numSamplesPerChannel == L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) + { + crossfade = headRotData->crossfade_5ms; + } + else + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Only 5 and 20 ms framing is supported" ); + } +#endif + if ( ( error = getAmbisonicsOrder( inConfig, &shd_rot_max_order ) ) != IVAS_ERR_OK ) { return error; } +#ifndef LIB_REND_API_5MS + /* TODO(sgi): @tmu please review changes in this function */ /* subframe loop */ subframe_len = inAudio.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) { +#endif /* initialize rotation matrices with zeros */ for ( i = 0; i < HEADROT_SHMAT_DIM; i++ ) { @@ -4637,7 +4778,11 @@ static ivas_error rotateFrameSba( /* calculate ambisonics rotation matrices for the previous and current frames */ SHrotmatgen( gains, Rmat, shd_rot_max_order ); +#ifdef LIB_REND_API_5MS + for ( i = 0; i < inAudio.config.numSamplesPerChannel; i++ ) +#else for ( i = 0; i < subframe_len; i++ ) +#endif { /* As the rotation matrix becomes block diagonal in a SH basis, we can*/ /* apply each angular-momentum block individually to save complexity. */ @@ -4654,16 +4799,27 @@ static ivas_error rotateFrameSba( for ( m = m1; m < m2; m++ ) { +#ifdef LIB_REND_API_5MS + readPtr = getSmplPtr( inAudio, m, i ); + /* crossfade with previous rotation gains */ + tmpRot[n - m1] += crossfade[i] * gains[n][m] * ( *readPtr ) + + ( 1 - crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); +#else readPtr = getSmplPtr( inAudio, m, subframe_idx * subframe_len + i ); /* crossfade with previous rotation gains */ tmpRot[n - m1] += headRotData->crossfade[i] * gains[n][m] * ( *readPtr ) + ( 1 - headRotData->crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); +#endif } } /* write back the result */ for ( n = m1; n < m2; n++ ) { +#ifdef LIB_REND_API_5MS + writePtr = getSmplPtr( outAudio, n, i ); +#else writePtr = getSmplPtr( outAudio, n, subframe_idx * subframe_len + i ); +#endif ( *writePtr ) = tmpRot[n - m1]; } m1 = m2; @@ -4691,7 +4847,9 @@ static ivas_error rotateFrameSba( { mvr2r( gains[i], gains_prev[i], HEADROT_SHMAT_DIM ); } +#ifndef LIB_REND_API_5MS } +#endif pop_wmops(); @@ -4734,7 +4892,9 @@ static ivas_error renderIsmToBinauralRoom( { int16_t i; int16_t azi_rot, ele_rot; +#ifndef LIB_REND_API_5MS int16_t subframe_idx, subframe_len; +#endif int16_t tmp; rotation_matrix Rmat; float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; @@ -4783,10 +4943,12 @@ static ivas_error renderIsmToBinauralRoom( if ( combinedOrientationEnabled ) { +#ifndef LIB_REND_API_5MS subframe_len = ismInput->base.inputBuffer.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; // for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) for ( subframe_idx = 0; subframe_idx < 1; subframe_idx++ ) { +#endif for ( i = 0; i < 3; i++ ) { #ifdef API_5MS @@ -4814,8 +4976,10 @@ static ivas_error renderIsmToBinauralRoom( Rmat[i][i] = 1.0f; } } +#ifndef LIB_REND_API_5MS } (void) subframe_len; // avoid warning +#endif } /* TODO tmu : see issue #518 */ @@ -6300,6 +6464,10 @@ static ivas_error renderActiveInputsMasa( if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && pCurrentInput->decDummy->hHeadTrackData != NULL ) { +#ifdef LIB_REND_API_5MS + pCurrentInput->decDummy->hHeadTrackData->Quaternion = hIvasRend->headRotData.headPosition; + pCurrentInput->decDummy->hHeadTrackData->Pos = hIvasRend->headRotData.Pos; +#else for ( sf_idx = 0; sf_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; ++sf_idx ) { #ifdef API_5MS @@ -6311,6 +6479,7 @@ static ivas_error renderActiveInputsMasa( pCurrentInput->decDummy->hHeadTrackData->Pos[sf_idx] = hIvasRend->headRotData.Pos[sf_idx]; #endif } +#endif } if ( ( error = renderInputMasa( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index d8d6127b20..701e0d5062 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -247,9 +247,21 @@ int16_t IVAS_REND_FeedRenderConfig( ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ +#ifdef LIB_REND_API_5MS + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos /* i : listener positions for next rendering call */ +#else const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ +#endif +); + +#ifdef LIB_REND_API_5MS +/* Head rotation becomes enabled by calling IVAS_REND_SetHeadRotation. Use this to disable. */ +ivas_error IVAS_REND_DisableHeadRotation( + IVAS_REND_HANDLE hIvasRend /* i/o: Renderer handle */ ); +#endif ivas_error IVAS_REND_SetOrientationTrackingMode( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ @@ -280,10 +292,17 @@ ivas_error IVAS_REND_SetReferenceVector( ivas_error IVAS_REND_SetExternalOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_QUATERNION *orientation, /* i : external orientation data */ +#ifdef LIB_REND_API_5MS + int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#else int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#endif ); ivas_error IVAS_REND_CombineHeadAndExternalOrientation( @@ -292,7 +311,7 @@ ivas_error IVAS_REND_CombineHeadAndExternalOrientation( ivas_error IVAS_REND_GetCombinedOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_QUATERNION *pRotation /* i/o: Quaternion pointer processed orientation */ + IVAS_QUATERNION *pOrientation /* i/o: Quaternion pointer processed orientation */ ); ivas_error IVAS_REND_GetMasaMetadata( -- GitLab From 2cc42c0ad07941392da5a305308df7f6d11c509f Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 16 Jun 2023 09:48:27 +0200 Subject: [PATCH 15/66] Fix concurrent access to the same file from different test cases --- tests/renderer/utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index ac5c57695a..ebad130ca2 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -142,6 +142,10 @@ def run_renderer( else: config_name = "" + if framing_5ms: + framing_name = "_5ms_framing" + else: + framing_name = "" if not isinstance(out_fmt, str): @@ -166,7 +170,7 @@ def run_renderer( out_file = str( output_path_base.joinpath( - f"{in_name}_to_{out_name}{trj_name}{non_diegetic_pan}{refrot_name}{refvec_name}{refveclev_name}{config_name}{name_extension}.wav" + f"{in_name}_to_{out_name}{trj_name}{non_diegetic_pan}{refrot_name}{refvec_name}{refveclev_name}{config_name}{framing_name}{name_extension}.wav" ) ) -- GitLab From bc55845248974ad25b0a883544d30849e1be61a7 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 16 Jun 2023 09:53:42 +0200 Subject: [PATCH 16/66] Allow warnings in Visual Studio build jobs --- .gitlab-ci-custom.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index 84aa4f65ba..f3453eedff 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -1078,6 +1078,8 @@ build-codec-debug-windows-vs2017: - $ENV:PATH - MSBuild.exe .\Workspace_msvc\Workspace_msvc.sln /property:Configuration=Debug | tee $BUILD_OUTPUT - python ci/check_for_warnings.py $BUILD_OUTPUT + allow_failure: + exit_codes: 123 build-codec-release-windows-vs2017: extends: @@ -1089,3 +1091,5 @@ build-codec-release-windows-vs2017: - $ENV:PATH - MSBuild.exe .\Workspace_msvc\Workspace_msvc.sln /property:Configuration=Release | tee $BUILD_OUTPUT - python ci/check_for_warnings.py $BUILD_OUTPUT + allow_failure: + exit_codes: 123 \ No newline at end of file -- GitLab From 11685f61025044c7ba7f342c3a0a91dd545a782f Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 16 Jun 2023 10:23:27 +0200 Subject: [PATCH 17/66] Fix stack-use-after-scope in rotateFrameMc --- lib_rend/lib_rend.c | 67 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 6f6b32de1b..b0472c96fc 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -741,7 +741,11 @@ static ivas_error getNumNonLfeChannelsInSpeakerLayout( static ivas_error getMcConfigValues( IVAS_REND_AudioConfig inConfig, +#ifdef LIB_REND_API_5MS + const LSSETUP_CUSTOM_STRUCT *pInCustomLs, +#else LSSETUP_CUSTOM_STRUCT inCustomLs, +#endif const float **azimuth, const float **elevation, int16_t *lfe_idx, @@ -754,6 +758,22 @@ static ivas_error getMcConfigValues( switch ( inConfig ) { case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: +#ifdef LIB_REND_API_5MS + *azimuth = (const float *) &pInCustomLs->ls_azimuth; + *elevation = (const float *) &pInCustomLs->ls_elevation; + if ( pInCustomLs->num_lfe > 0 ) + { + *lfe_idx = pInCustomLs->lfe_idx[0]; + } + for ( i = 0; i < pInCustomLs->num_spk; i++ ) + { + if ( pInCustomLs->ls_elevation[i] != 0 ) + { + *is_planar = 0; + break; + } + } +#else *azimuth = (const float *) &inCustomLs.ls_azimuth; *elevation = (const float *) &inCustomLs.ls_elevation; if ( inCustomLs.num_lfe > 0 ) @@ -768,6 +788,7 @@ static ivas_error getMcConfigValues( break; } } +#endif break; case IVAS_REND_AUDIO_CONFIG_MONO: case IVAS_REND_AUDIO_CONFIG_STEREO: @@ -4517,9 +4538,13 @@ static void renderBufferChannel( } static ivas_error rotateFrameMc( - IVAS_REND_AudioBuffer inAudio, /* i : Input Audio buffer */ - IVAS_REND_AudioConfig inConfig, /* i : Input Audio config */ - LSSETUP_CUSTOM_STRUCT inCustomLs, /* i : Input Custom LS setup */ + IVAS_REND_AudioBuffer inAudio, /* i : Input Audio buffer */ + IVAS_REND_AudioConfig inConfig, /* i : Input Audio config */ +#ifdef LIB_REND_API_5MS + const LSSETUP_CUSTOM_STRUCT *pInCustomLs, /* i : Input Custom LS setup */ +#else + LSSETUP_CUSTOM_STRUCT inCustomLs, /* i : Input Custom LS setup */ +#endif const IVAS_REND_HeadRotData *headRotData, /* i : Head rotation data */ const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* i : Combined head and external orientations */ rotation_gains gains_prev, /* i/o: Previous frame rotation gains */ @@ -4572,10 +4597,20 @@ static ivas_error rotateFrameMc( } else { +#ifdef LIB_REND_API_5MS + nchan = pInCustomLs->num_spk + pInCustomLs->num_lfe; +#else nchan = inCustomLs.num_spk + inCustomLs.num_lfe; +#endif } - if ( ( error = getMcConfigValues( inConfig, inCustomLs, &ls_azimuth, &ls_elevation, &lfe_idx, &is_planar_setup ) ) != IVAS_ERR_OK ) + if ( ( error = getMcConfigValues( inConfig, +#ifdef LIB_REND_API_5MS + pInCustomLs, +#else + inCustomLs, +#endif + &ls_azimuth, &ls_elevation, &lfe_idx, &is_planar_setup ) ) != IVAS_ERR_OK ) { return error; } @@ -5431,7 +5466,13 @@ static ivas_error renderMcToBinaural( tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); - if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, +#ifdef LIB_REND_API_5MS + &mcInput->customLsInput, +#else + mcInput->customLsInput, +#endif + mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev, mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) { @@ -5534,7 +5575,13 @@ static ivas_error renderMcToBinauralRoom( tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); - if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, +#ifdef LIB_REND_API_5MS + &mcInput->customLsInput, +#else + mcInput->customLsInput, +#endif + mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev, mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) { @@ -5626,7 +5673,13 @@ static ivas_error renderMcCustomLsToBinauralRoom( tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); - if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, +#ifdef LIB_REND_API_5MS + &mcInput->customLsInput, +#else + mcInput->customLsInput, +#endif + mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev, mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) { -- GitLab From ae80a29f3fd9691895257d905c4227992898e1ec Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 16 Jun 2023 20:27:02 +0200 Subject: [PATCH 18/66] Add IVAS_rend_ref to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a2f6a6b95f..1829cde3a7 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ scripts/testv/*_cut*.pcm # default reference binary name IVAS_cod_ref IVAS_dec_ref +IVAS_rend_ref # Python files that pop up when running scripts __pycache__/ -- GitLab From b7b09e85d6fc2fa437905c1bd92fee1b069f77a1 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Mon, 19 Jun 2023 09:56:03 +0200 Subject: [PATCH 19/66] Actually enable 5ms mode when flag is set --- apps/renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/renderer.c b/apps/renderer.c index 9be54daca5..73125900c1 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -2142,7 +2142,7 @@ static void parseOption( #ifdef LIB_REND_API_5MS case CmdLnOptionId_framing5ms: assert( numOptionValues == 0 ); - args->framing_5ms = false; + args->framing_5ms = true; break; #endif default: -- GitLab From 03cc1fe55b6ee8b09ed6feff6e7379696c79642c Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Mon, 19 Jun 2023 11:22:36 +0200 Subject: [PATCH 20/66] Fix rendering too many subframes in TD rend --- lib_dec/ivas_objectRenderer_internal.c | 7 ++++++- lib_rend/ivas_objectRenderer.c | 19 ++++++++++++++++++- lib_rend/ivas_prot_rend.h | 3 +++ lib_rend/lib_rend.c | 4 ++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 3802c4fc09..567a91f4fb 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -95,7 +95,12 @@ ivas_error ivas_td_binaural_renderer( ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->listenerPos : NULL, #endif - ism_md_subframe_update, output, output_frame ); + ism_md_subframe_update, output, output_frame +#ifdef LIB_REND_API_5MS + , + MAX_PARAM_SPATIAL_SUBFRAMES +#endif + ); } diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 9f39aa8b93..346dbc695c 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -266,6 +266,10 @@ ivas_error ivas_td_binaural_renderer_unwrap( const int16_t ism_md_subframe_update, /* i: Number of subframes to delay ism metadata to sync with audio */ float *output[], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame /* i : output frame length */ +#ifdef LIB_REND_API_5MS + , + const int16_t num_subframes /* i : number of subframes to render */ +#endif ) { int16_t subframe_length; @@ -281,7 +285,11 @@ ivas_error ivas_td_binaural_renderer_unwrap( p_reverb_signal[ch] = reverb_signal[ch]; } +#ifdef LIB_REND_API_5MS + subframe_length = output_frame / num_subframes; +#else subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; +#endif c_indx = 0; for ( nS = 0; nS < num_src; nS++ ) @@ -294,7 +302,11 @@ ivas_error ivas_td_binaural_renderer_unwrap( } } +#ifdef LIB_REND_API_5MS + for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) +#endif { if ( subframe_idx == ism_md_subframe_update ) { @@ -696,7 +708,12 @@ ivas_error ivas_td_binaural_renderer_ext( ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->Quaternions : NULL, ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->listenerPos : NULL, #endif - ism_md_subframe_update_ext, p_output, output_frame ) ) != IVAS_ERR_OK ) + ism_md_subframe_update_ext, p_output, output_frame +#ifdef LIB_REND_API_5MS + , + 1 +#endif + ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 8d987a3f3c..d96f5228f2 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -234,6 +234,9 @@ ivas_error ivas_td_binaural_renderer_unwrap( const int16_t ism_md_subframe_update, float *output[], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame /* i : output frame length */ +#ifdef LIB_REND_API_5MS + ,const int16_t num_subframes /* i : number of subframes to render */ +#endif ); ivas_error ivas_td_binaural_renderer_ext( diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index b0472c96fc..158110012f 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -56,7 +56,11 @@ #define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) /* Frame size required when rendering to binaural */ +#ifdef LIB_REND_API_5MS +#define BINAURAL_RENDERING_FRAME_SIZE_MS 5 +#else #define BINAURAL_RENDERING_FRAME_SIZE_MS 20 +#endif /*-------------------------------------------------------------------* -- GitLab From 1a5757ea6813d98bc56276fcd797e854558b3f0e Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Tue, 20 Jun 2023 08:26:50 +0200 Subject: [PATCH 21/66] try to fix BE for the external orientation, did not succeed, seems to be a deeper problem. Make self test summary more verbous --- apps/decoder.c | 2 +- lib_rend/ivas_rotation.c | 4 ++++ scripts/self_test.py | 23 +++++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/apps/decoder.c b/apps/decoder.c index 34527b8c82..2d33228a3b 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1819,7 +1819,7 @@ static ivas_error decodeG192( } - if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternion, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternion, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation * vec_pos_len ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index efd281ce84..faee209b70 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -795,7 +795,11 @@ ivas_error ivas_combined_orientation_open( /* Initialization */ ( *hCombinedOrientationData )->interpolationCoefficient = 1.0f; ( *hCombinedOrientationData )->interpolationIncrement = 1.0f; +#ifdef API_5MS + ( *hCombinedOrientationData )->maximumFramesToTargetOrientation = 2000; +#else ( *hCombinedOrientationData )->maximumFramesToTargetOrientation = 500; +#endif ( *hCombinedOrientationData )->lrSwitchedNext = 0; ( *hCombinedOrientationData )->lrSwitchedCurrent = 0; ( *hCombinedOrientationData )->lrSwitchInterpVal = 0.0f; diff --git a/scripts/self_test.py b/scripts/self_test.py index d7118832db..321f83419b 100755 --- a/scripts/self_test.py +++ b/scripts/self_test.py @@ -186,6 +186,13 @@ class SelfTest(IvasScriptsCommon.IvasScript): "--dectest", help="Test decoder binary (default:{})".format(default_dec_test), ) + self.parser.add_argument( + "--list_conditions", + "-l", + help="List all comditions in the parameter file", + action="store_true", + default=False, + ) if shutil.which("valgrind"): self.valgrind = [ "valgrind", @@ -858,6 +865,7 @@ class SelfTest(IvasScriptsCommon.IvasScript): # add the detailed results for this condition self.fail_results["detailedResults"].append(result_str) + self.fail_results["failed_modes"].append(mode) self.logger.progress( "Comparing conditions: {}/{} ({} running), {} failed ".format( self.stat["num_tests_done"], @@ -1140,6 +1148,11 @@ class SelfTest(IvasScriptsCommon.IvasScript): self.parse_args() + if self.args["list_conditions"] is True: + run_dict = self.parse_self_test_prm(self.args["test_prm"]) + for mode in run_dict.keys(): + self.logger.console(f"- {run_dict[mode]['cmd']['table_name']}") + return # create/update test vectors (export from SVN server if not existing) svn_action = None if not os.path.exists(TESTV_DIR): @@ -1540,6 +1553,7 @@ class SelfTest(IvasScriptsCommon.IvasScript): "corrupt_test_conditions": {"cnt": 0, "conditions": []}, "diff_nsamples_conditions": {"cnt": 0, "conditions": []}, "detailedResults": [], + "failed_modes":[], } self.run_pesq = self.args["pesq"] failed_ref_conditions = {} @@ -1948,6 +1962,15 @@ class SelfTest(IvasScriptsCommon.IvasScript): for l in r: self.logger.info(l) + self.logger.info("\n\n") + self.logger.info("Summary of all tests") + self.logger.info("---------------------\n") + for mode in run_dict.keys(): + if mode in self.fail_results["failed_modes"]: + self.logger.info(f"[FAIL] {run_dict[mode]['cmd']['table_name']}") + else: + self.logger.info(f"[OK] {run_dict[mode]['cmd']['table_name']}") + if __name__ == "__main__": if sys.version_info[0] < 3 or sys.version_info[1] < 7: -- GitLab From 5f0f350b3761ef3ab6b232506ae1c6b270a883b8 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Tue, 20 Jun 2023 08:54:06 +0200 Subject: [PATCH 22/66] 5ms API Squashed commit of the following: commit a019f87f21a295491b97c43a1c3122339d07bb27 Merge: 1a5757ea daca8536 Author: Stefan Bayer Date: Tue Jun 20 08:39:14 2023 +0200 Merge remote-tracking branch 'remotes/origin/main' into b_20230601_API_5ms_rendering_bay commit 1a5757ea6813d98bc56276fcd797e854558b3f0e Author: Stefan Bayer Date: Tue Jun 20 08:26:50 2023 +0200 try to fix BE for the external orientation, did not succeed, seems to be a deeper problem. Make self test summary more verbous commit b61cb8986ce97d473c30c3ce8eb1bca94ffcf33a Author: Stefan Bayer Date: Thu Jun 15 16:12:09 2023 +0200 disable unused code commit de03fd1e6595cc31021a4988dc827a9210142ffe Author: Stefan Bayer Date: Thu Jun 15 15:41:27 2023 +0200 fix external orientation update rate commit d4c03c2e3af4ef2360acd80400b16df8b161476c Author: Stefan Bayer Date: Thu Jun 15 15:08:55 2023 +0200 make sure 7.1.4 br does not crash any longer, still ParamUpmix needs to be fully implemented in the JBM path commit f104d3bbe0976522dd25f4d1232248ec8f3a1f2d Author: Stefan Bayer Date: Thu Jun 15 14:30:43 2023 +0200 fix asan, put out at least zeroes for ParamUpmix in the JBM path commit 52b5489763af0a72c31f3febebe5dcc6d9dcad83 Author: Stefan Bayer Date: Thu Jun 15 13:55:13 2023 +0200 fix compiling issues with API_5MS inactive commit 8d73b36a1595651fbf1f967b8ea516103181b76b Author: Stefan Bayer Date: Thu Jun 15 13:06:03 2023 +0200 fix compiling, re-add all 5ms API stuff that got lost in the latest merge from main commit 612455369970bcf8fe4192aedd3efd85ade44308 Merge: fde3a293 96ad022e Author: Stefan Bayer Date: Thu Jun 15 08:38:42 2023 +0200 Merge remote-tracking branch 'remotes/origin/main' into b_20230601_API_5ms_rendering_bay commit fde3a29385ef0720a21fb9ba897eada28c736ca9 Author: Stefan Bayer Date: Thu Jun 15 08:07:25 2023 +0200 temp fix for orientation tracking init commit 3a9743d05de925224ac0cda0453434498fd5b263 Author: Stefan Bayer Date: Wed Jun 14 07:11:37 2023 +0200 5ms API first step, not completely BE yet --- apps/decoder.c | 862 ++++++++++++++++--- lib_com/ivas_error.h | 5 + lib_com/ivas_prot.h | 6 +- lib_com/options.h | 5 + lib_dec/ivas_binRenderer_internal.c | 30 +- lib_dec/ivas_dec.c | 2 + lib_dec/ivas_dirac_dec.c | 42 +- lib_dec/ivas_init_dec.c | 20 +- lib_dec/ivas_ism_dec.c | 5 +- lib_dec/ivas_ism_param_dec.c | 37 +- lib_dec/ivas_ism_renderer.c | 28 + lib_dec/ivas_jbm_dec.c | 78 ++ lib_dec/ivas_masa_dec.c | 6 + lib_dec/ivas_mc_param_dec.c | 27 +- lib_dec/ivas_mct_dec.c | 5 +- lib_dec/ivas_objectRenderer_internal.c | 15 +- lib_dec/ivas_sba_dec.c | 6 +- lib_dec/ivas_sba_rendering_internal.c | 7 + lib_dec/ivas_spar_decoder.c | 4 + lib_dec/ivas_stat_dec.h | 4 + lib_dec/jbm_jb4sb.h | 4 +- lib_dec/jbm_pcmdsp_fifo.c | 2 + lib_dec/jbm_pcmdsp_fifo.h | 4 +- lib_dec/lib_dec.c | 735 ++++++++++++++-- lib_dec/lib_dec.h | 64 +- lib_rend/ivas_crend.c | 14 + lib_rend/ivas_dirac_dec_binaural_functions.c | 16 + lib_rend/ivas_objectRenderer.c | 19 +- lib_rend/ivas_objectRenderer_hrFilt.c | 3 +- lib_rend/ivas_rotation.c | 307 ++++++- lib_rend/ivas_stat_rend.h | 32 +- lib_rend/lib_rend.c | 119 ++- scripts/self_test.py | 23 + 33 files changed, 2275 insertions(+), 261 deletions(-) mode change 100755 => 100644 lib_com/options.h diff --git a/apps/decoder.c b/apps/decoder.c index e210ebe95e..71a296ed00 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -84,6 +84,10 @@ static #define VARIABLE_SPEED_FETCH_FRAMESIZE_MS 20 #endif #define JBM_FRONTEND_FETCH_FRAMESIZE_MS 20 +#ifdef API_5MS +#define HEADROTATION_FETCH_FRAMESIZE_MS 5 +#define DEFAULT_FETCH_FRAMESIZE_MS 20 +#endif typedef struct { @@ -122,7 +126,9 @@ typedef struct bool renderConfigEnabled; char *renderConfigFilename; IVAS_DEC_COMPLEXITY_LEVEL complexityLevel; - +#ifdef API_5MS + bool tsmEnabled; +#endif #ifdef DEBUGGING IVAS_DEC_FORCED_REND_MODE forcedRendMode; #ifdef DEBUG_FOA_AGC @@ -132,7 +138,9 @@ typedef struct bool noBadFrameDelay; #endif #ifdef VARIABLE_SPEED_DECODING +#ifndef API_5MS bool variableSpeedMode; +#endif bool tsmScaleFileEnabled; char *tsmScaleFileName; uint16_t tsmScale; @@ -395,8 +403,11 @@ int main( /*------------------------------------------------------------------------------------------* * Configure the decoder *------------------------------------------------------------------------------------------*/ +#ifdef API_5MS + if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.tsmEnabled, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) - +#endif { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -408,16 +419,17 @@ int main( if ( arg.voipMode ) { -#ifdef VARIABLE_SPEED_DECODING - if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, IVAS_DEC_VOIP_MODE_VOIP, 100, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) -#else +#ifdef API_5MS if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, IVAS_DEC_VOIP_MODE_VOIP, 100, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) #endif { fprintf( stderr, "\nCould not enable VOIP: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } } +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING else if ( arg.variableSpeedMode ) { @@ -428,6 +440,7 @@ int main( } } #endif +#endif #ifdef DEBUGGING /*-----------------------------------------------------------------* @@ -461,7 +474,11 @@ int main( IVAS_DEC_PrintConfigWithBitstream( hIvasDec, arg.quietModeEnabled, bit_stream, num_bits ); #ifdef VARIABLE_SPEED_DECODING +#ifdef API_5MS + if ( arg.tsmEnabled ) +#else if ( arg.variableSpeedMode ) +#endif { if ( arg.tsmScaleFileEnabled ) { @@ -639,6 +656,7 @@ int main( { error = decodeVoIP( arg, hBsReader, hIvasDec ); } +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING else if ( arg.variableSpeedMode ) { @@ -646,6 +664,7 @@ int main( externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec ); } +#endif #endif else { @@ -882,10 +901,14 @@ static bool parseCmdlIVAS_dec( arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192; arg->Opt_non_diegetic_pan = 0; arg->non_diegetic_pan_gain = 0.f; - +#ifdef API_5MS + arg->tsmEnabled = false; +#endif #ifdef DEBUGGING #ifdef VARIABLE_SPEED_DECODING +#ifndef API_5MS arg->variableSpeedMode = false; +#endif arg->tsmScale = 100; arg->tsmScaleFileEnabled = false; arg->tsmScaleFileName = NULL; @@ -1034,7 +1057,11 @@ static bool parseCmdlIVAS_dec( { i++; int32_t tmp = 100; +#ifdef API_5MS + arg->tsmEnabled = true; +#else arg->variableSpeedMode = true; +#endif if ( i < argc - 3 ) { if ( !is_digits_only( argv[i] ) ) @@ -1609,7 +1636,7 @@ static ivas_error initOnFirstGoodFrame( * * Read G.192 bitstream and decode in regular decoder *---------------------------------------------------------------------*/ - +#ifdef API_5MS static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, @@ -1634,20 +1661,58 @@ static ivas_error decodeG192( int16_t numInitialBadFrames = 0; /* Number of bad frames received until first good frame is decoded */ int16_t nOutChannels = 0; int16_t delayNumSamples = -1; - int16_t delayNumSamples_orig[3]; /* stores: overall delay, dec+rend delay, and binauralization delay */ + int16_t delayNumSamples_orig[3]; int16_t nOutSamples = 0; int32_t delayTimeScale = 0; ivas_error error = IVAS_ERR_UNKNOWN; uint16_t numObj = 0; IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; - IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - + uint16_t nSamplesAvailableNext; + bool needNewFrame; + int16_t nSamplesRendered, nSamplesRendered_loop, nSamplesToRender; +#ifdef DEBUGGING +#ifdef VARIABLE_SPEED_DECODING + TsmScaleFileReader *tsmScaleFileReader = NULL; + int16_t scale; +#endif +#endif IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; + IVAS_VECTOR3 Pos; + int16_t vec_pos_update, vec_pos_len; + + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { ismWriters[i] = NULL; } + /* we always start with needing a new frame */ + needNewFrame = true; + +#ifdef DEBUGGING +#ifdef VARIABLE_SPEED_DECODING + /*------------------------------------------------------------------------------------------* + * Open TSM scale file or set global TSM scale + *------------------------------------------------------------------------------------------*/ + + if ( arg.tsmEnabled ) + { + if ( arg.tsmScaleFileEnabled ) + { + if ( ( tsmScaleFileReader = TsmScaleFileReader_open( arg.tsmScaleFileName ) ) == NULL ) + { + fprintf( stderr, "\nError: Can't open TSM scale file %s \n\n", arg.tsmScaleFileName ); + goto cleanup; + } + } + else + { + IVAS_DEC_VoIP_SetScale( hIvasDec, arg.tsmScale, arg.tsmScale ); + } + } +#endif +#endif + if ( !arg.quietModeEnabled ) { fprintf( stdout, "\n------ Running the decoder ------\n\n" ); @@ -1664,7 +1729,19 @@ static ivas_error decodeG192( reset_stack(); reset_wmops(); #endif + nSamplesAvailableNext = 0; + vec_pos_update = 0; + if ( arg.enableHeadRotation ) + { + nOutSamples = (int16_t) ( arg.output_Fs / 1000 * HEADROTATION_FETCH_FRAMESIZE_MS ); + vec_pos_len = IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; + } + else + { + nOutSamples = (int16_t) ( arg.output_Fs / 1000 * DEFAULT_FETCH_FRAMESIZE_MS ); + vec_pos_len = 1; + } /*------------------------------------------------------------------------------------------* * Loop for every packet (frame) of bitstream data * - Read the bitstream packet @@ -1674,42 +1751,10 @@ static ivas_error decodeG192( while ( 1 ) { - /* Read next frame */ - if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) - { - if ( error == IVAS_ERR_END_OF_FILE ) - { - break; - } - fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); - goto cleanup; - } - -#ifdef DEBUGGING - /* Random FEC simulation */ - if ( arg.FER > 0.0f ) - { - float ftmp = (float) app_own_random( &fec_seed ) + 32768.0f; - if ( ftmp <= arg.FER / 100.0f * 65535.0f ) - { - bfi = 1; - } - else - { - bfi = 0; - } - } -#endif - - /* Feed into decoder */ - if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, bit_stream, num_bits, bfi ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError: could not feed frame to decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } + /* Read next frame if not enough samples availble */ /* reference vector */ - if ( arg.enableReferenceVectorTracking ) + if ( arg.enableReferenceVectorTracking && vec_pos_update == 0 ) { IVAS_VECTOR3 listenerPosition, referencePosition; if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPosition, &referencePosition ) ) != IVAS_ERR_OK ) @@ -1724,14 +1769,14 @@ static ivas_error decodeG192( goto cleanup; } } + /* Reference rotation */ - if ( arg.enableReferenceRotation ) + 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 ) ); + fprintf( stderr, "\nError %s while reading reference rotation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( refRotReader ) ); goto cleanup; } @@ -1741,22 +1786,20 @@ static ivas_error decodeG192( goto cleanup; } } + /* Head-tracking input simulation */ if ( arg.enableHeadRotation ) { - IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_QUATERNION Quaternion; - for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos ) ) != IVAS_ERR_OK ) { - 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; - } + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; } - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos ) ) != IVAS_ERR_OK ) + + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -1765,35 +1808,97 @@ static ivas_error decodeG192( 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]; + IVAS_QUATERNION Quaternion; + int8_t enableHeadRotation; + int8_t enableExternalOrientation; + int8_t enableRotationInterpolation; + int16_t numFramesToTargetOrientation; - for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + + if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &Quaternion, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) { + fprintf( stderr, "\nError %s while reading external orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), + RotationFileReader_getFilePath( externalOrientationFileReader ) ); + goto cleanup; + } - if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &Quaternions[i], &enableHeadRotation[i], &enableExternalOrientation[i], &enableRotationInterpolation[i], &numFramesToTargetOrientation[i] ) ) != IVAS_ERR_OK ) + + if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternion, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation * vec_pos_len ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* decode and get samples */ + nSamplesRendered = 0; + nSamplesToRender = nOutSamples; + do + { + if ( needNewFrame ) + { +#ifdef DEBUGGING +#ifdef VARIABLE_SPEED_DECODING + if ( arg.tsmScaleFileEnabled ) { - fprintf( stderr, "\nError %s while reading external orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), - RotationFileReader_getFilePath( externalOrientationFileReader ) ); + if ( ( error = TsmScaleFileReader_readScale( tsmScaleFileReader, &scale ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); + goto cleanup; + } + IVAS_DEC_VoIP_SetScale( hIvasDec, scale, scale ); + } +#endif +#endif + + if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) + { + if ( error == IVAS_ERR_END_OF_FILE ) + { + break; + } + fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); goto cleanup; } - } - if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternions, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) +#ifdef DEBUGGING + /* Random FEC simulation */ + if ( arg.FER > 0.0f ) + { + float ftmp = (float) app_own_random( &fec_seed ) + 32768.0f; + if ( ftmp <= arg.FER / 100.0f * 65535.0f ) + { + bfi = 1; + } + else + { + bfi = 0; + } + } +#endif + + /* Feed into decoder */ + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, bit_stream, num_bits, bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not feed frame to decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nOutChannels * nSamplesRendered, &nSamplesRendered_loop, &needNewFrame ); + nSamplesRendered += nSamplesRendered_loop; + nSamplesToRender -= nSamplesRendered_loop; + if ( error != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } - } - /* Run decoder for one frame (get rendered output) */ - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, pcmBuf, &nOutSamples ) ) != IVAS_ERR_OK ) + + } while ( nSamplesRendered < nOutSamples && error == IVAS_ERR_OK ); + + if ( error == IVAS_ERR_END_OF_FILE ) { - fprintf( stderr, "\nError: could not get samples from decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; + break; } /* Continue checking for first good frame until it is found */ @@ -1851,7 +1956,7 @@ static ivas_error decodeG192( } } - /* Write ISM metadata to external file(s) */ + /* Write ISm metadata to external file(s) */ if ( decodedGoodFrame && arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) { if ( bsFormat == IVAS_DEC_BS_OBJ ) @@ -1901,6 +2006,7 @@ static ivas_error decodeG192( } frame++; + vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; if ( !arg.quietModeEnabled ) { fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); @@ -1912,60 +2018,576 @@ static ivas_error decodeG192( #endif } #ifdef WMOPS - update_mem(); update_wmops(); +#ifdef MEM_COUNT_DETAILS + export_mem( "mem_analysis.csv" ); +#endif #endif } - /*------------------------------------------------------------------------------------------* - * Add zeros at the end to have equal length of synthesized signals - *------------------------------------------------------------------------------------------*/ - - memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); - - if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); - goto cleanup; - } /*------------------------------------------------------------------------------------------* - * Printouts after decoding has finished + * Flush what is still left in the VoIP Buffers.... *------------------------------------------------------------------------------------------*/ - if ( !arg.quietModeEnabled ) + while ( nSamplesAvailableNext > 0 ) { - printf( "\n\nDecoder+renderer delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[1] / (float) delayTimeScale, delayNumSamples_orig[1], delayTimeScale ); + int16_t nSamplesFlushed; - if ( delayNumSamples_orig[2] > 0 ) - { - printf( "HRIR/BRIR delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[2] / (float) delayTimeScale, delayNumSamples_orig[2], delayTimeScale ); - printf( "Total delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * ( delayNumSamples_orig[1] + delayNumSamples_orig[2] ) / (float) delayTimeScale, delayNumSamples_orig[1] + delayNumSamples_orig[2], delayTimeScale ); - } - } + /* Feed into decoder */ - /* Print output metadata file name(s) */ - if ( arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) - { - if ( bsFormat == IVAS_DEC_BS_OBJ ) + /* reference vector */ + if ( arg.enableReferenceVectorTracking ) { - for ( i = 0; i < numObj; i++ ) + IVAS_VECTOR3 listenerPosition, referencePosition; + if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPosition, &referencePosition ) ) != IVAS_ERR_OK ) { - fprintf( stdout, "\nOutput metadata file: %s", IsmFileWriter_getFilePath( ismWriters[i] ) ); + 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; } - fprintf( stdout, "\n" ); } - else if ( bsFormat == IVAS_DEC_BS_MASA ) + /* Reference rotation */ + if ( arg.enableReferenceRotation ) { - fprintf( stdout, "\nOutput metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); - } - } - - /*------------------------------------------------------------------------------------------* - * Close files and deallocate resources - *------------------------------------------------------------------------------------------*/ + 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; + } - decodingFailed = false; /* This will stay set to true if cleanup is reached via a goto due to an error */ + 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 ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + + + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* decode and get samples */ + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) + { + 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.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + 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; + } + } + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; +#ifdef FIX_470_MASA_JBM_EXT + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#endif + { + 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; + } + } + } + + 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 + } + } + + /*------------------------------------------------------------------------------------------* + * Printouts after decoding has finished + *------------------------------------------------------------------------------------------*/ + + if ( !arg.quietModeEnabled ) + { + printf( "\n\nDecoder+renderer delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[1] / (float) delayTimeScale, delayNumSamples_orig[1], delayTimeScale ); + + if ( delayNumSamples_orig[2] > 0 ) + { + printf( "HRIR/BRIR delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[2] / (float) delayTimeScale, delayNumSamples_orig[2], delayTimeScale ); + printf( "Total delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * ( delayNumSamples_orig[1] + delayNumSamples_orig[2] ) / (float) delayTimeScale, delayNumSamples_orig[1] + delayNumSamples_orig[2], delayTimeScale ); + } + } + + /* Print output metadata file name(s) */ + if ( arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + for ( i = 0; i < numObj; i++ ) + { + fprintf( stdout, "\nOutput metadata file: %s", IsmFileWriter_getFilePath( ismWriters[i] ) ); + } + fprintf( stdout, "\n" ); + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + fprintf( stdout, "\nOutput metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); + } + } + + /* add zeros at the end to have equal length of synthesized signals */ + memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } + + /*------------------------------------------------------------------------------------------* + * Close files and deallocate resources + *------------------------------------------------------------------------------------------*/ + + decodingFailed = false; /* This will stay set to true if cleanup is reached via a goto due to an error */ + +cleanup: + + AudioFileWriter_close( &afWriter ); + MasaFileWriter_close( &masaWriter ); +#ifdef DEBUGGING +#ifdef VARIABLE_SPEED_DECODING + TsmScaleFileReader_close( &tsmScaleFileReader ); +#endif +#endif + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) + { + IsmFileWriter_close( &ismWriters[i] ); + } + + if ( decodingFailed && error == IVAS_ERR_OK ) + { + return IVAS_ERR_UNKNOWN; + } + + return error; +} +#else +static ivas_error decodeG192( + DecArguments arg, + BS_READER_HANDLE hBsReader, + RotFileReader *headRotReader, + RotFileReader *externalOrientationFileReader, + RotFileReader *refRotReader, + Vector3PairFileReader *referenceVectorReader, + IVAS_DEC_HANDLE hIvasDec, + int16_t *pcmBuf ) + +{ + bool decodingFailed = true; /* Assume failure until cleanup is reached without errors */ + uint16_t bit_stream[IVAS_MAX_BITS_PER_FRAME + 4 * 8]; + int16_t i, num_bits; + int16_t bfi = 0; +#ifdef DEBUGGING + int16_t fec_seed = 12558; /* FEC_SEED */ +#endif + AudioFileWriter *afWriter = NULL; + MasaFileWriter *masaWriter = NULL; + bool decodedGoodFrame = false; + int16_t numInitialBadFrames = 0; /* Number of bad frames received until first good frame is decoded */ + int16_t nOutChannels = 0; + int16_t delayNumSamples = -1; + int16_t delayNumSamples_orig[3]; /* stores: overall delay, dec+rend delay, and binauralization delay */ + int16_t nOutSamples = 0; + int32_t delayTimeScale = 0; + ivas_error error = IVAS_ERR_UNKNOWN; + uint16_t numObj = 0; + IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + + IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) + { + ismWriters[i] = NULL; + } + + if ( !arg.quietModeEnabled ) + { + fprintf( stdout, "\n------ Running the decoder ------\n\n" ); + fprintf( stdout, "Frames processed: " ); + } + else + { + fprintf( stdout, "\n-- Start the decoder (quiet mode) --\n\n" ); + } + + delayNumSamples_orig[0] = -1; + +#ifdef WMOPS + reset_stack(); + reset_wmops(); +#endif + + /*------------------------------------------------------------------------------------------* + * Loop for every packet (frame) of bitstream data + * - Read the bitstream packet + * - Run the decoder + * - Write the synthesized signal into output file + *------------------------------------------------------------------------------------------*/ + + while ( 1 ) + { + /* Read next frame */ + if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) + { + if ( error == IVAS_ERR_END_OF_FILE ) + { + break; + } + fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); + goto cleanup; + } + +#ifdef DEBUGGING + /* Random FEC simulation */ + if ( arg.FER > 0.0f ) + { + float ftmp = (float) app_own_random( &fec_seed ) + 32768.0f; + if ( ftmp <= arg.FER / 100.0f * 65535.0f ) + { + bfi = 1; + } + else + { + bfi = 0; + } + } +#endif + + /* Feed into decoder */ + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, bit_stream, num_bits, bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not feed frame to decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + /* 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 Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_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; + } + } + + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos ) ) != 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 < IVAS_MAX_PARAM_SPATIAL_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; + } + } + + if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternions, enableHeadRotation, enableExternalOrientation, enableRotationInterpolation, numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* Run decoder for one frame (get rendered output) */ + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, pcmBuf, &nOutSamples ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not get samples from decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + /* Continue checking for first good frame until it is found */ + if ( !decodedGoodFrame ) + { + if ( ( error = IVAS_DEC_HasDecodedFirstGoodFrame( hIvasDec, &decodedGoodFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_HasDecodedFirstGoodFrame, code: %d\n", error ); + goto cleanup; + } + + /* Once good frame decoded, catch up */ + if ( decodedGoodFrame ) + { + error = initOnFirstGoodFrame( + hIvasDec, + arg, + numInitialBadFrames, + nOutSamples, + delayNumSamples_orig, + &delayNumSamples, + &delayTimeScale, + &bsFormat, + &afWriter, + &masaWriter, + ismWriters, + &nOutChannels, + &numObj ); + if ( error != IVAS_ERR_OK ) + { + goto cleanup; + } + } + else + { + ++numInitialBadFrames; + } + } + + /* Write current frame */ + if ( decodedGoodFrame ) + { + if ( delayNumSamples < nOutSamples ) + { + if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + goto cleanup; + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= nOutSamples; + } + } + + /* Write ISM metadata to external file(s) */ + if ( decodedGoodFrame && arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + 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; + } + } + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; +#ifdef FIX_470_MASA_JBM_EXT + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#endif + { + 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; + } + } + } + + 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 + } +#ifdef WMOPS + update_mem(); + update_wmops(); +#endif + } + + /*------------------------------------------------------------------------------------------* + * Add zeros at the end to have equal length of synthesized signals + *------------------------------------------------------------------------------------------*/ + + memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); + + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } + + /*------------------------------------------------------------------------------------------* + * Printouts after decoding has finished + *------------------------------------------------------------------------------------------*/ + + if ( !arg.quietModeEnabled ) + { + printf( "\n\nDecoder+renderer delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[1] / (float) delayTimeScale, delayNumSamples_orig[1], delayTimeScale ); + + if ( delayNumSamples_orig[2] > 0 ) + { + printf( "HRIR/BRIR delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[2] / (float) delayTimeScale, delayNumSamples_orig[2], delayTimeScale ); + printf( "Total delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * ( delayNumSamples_orig[1] + delayNumSamples_orig[2] ) / (float) delayTimeScale, delayNumSamples_orig[1] + delayNumSamples_orig[2], delayTimeScale ); + } + } + + /* Print output metadata file name(s) */ + if ( arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + for ( i = 0; i < numObj; i++ ) + { + fprintf( stdout, "\nOutput metadata file: %s", IsmFileWriter_getFilePath( ismWriters[i] ) ); + } + fprintf( stdout, "\n" ); + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + fprintf( stdout, "\nOutput metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); + } + } + + /*------------------------------------------------------------------------------------------* + * Close files and deallocate resources + *------------------------------------------------------------------------------------------*/ + + decodingFailed = false; /* This will stay set to true if cleanup is reached via a goto due to an error */ cleanup: @@ -1983,6 +2605,7 @@ cleanup: return error; } +#endif #ifdef DEBUGGING /*---------------------------------------------------------------------* @@ -2254,7 +2877,9 @@ static ivas_error decodeVoIP( while ( 1 ) { int16_t nOutSamples = 0; +#ifndef API_5MS uint16_t nSamplesAvailableNext = 0; +#endif #ifdef DEBUG_JBM_CMD_OPTION nOutSamples = (int16_t) ( arg.output_Fs / 1000 * arg.frontendFetchSizeMs ); #else @@ -2311,7 +2936,11 @@ static ivas_error decodeVoIP( /* decode and get samples */ - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms, &nSamplesAvailableNext + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms +#ifndef API_5MS + , + &nSamplesAvailableNext +#endif #ifdef SUPPORT_JBM_TRACEFILE , writeJbmTraceFileFrameWrapper, @@ -2519,6 +3148,7 @@ cleanup: #ifdef DEBUGGING +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING /*---------------------------------------------------------------------* * decodeVariableSpeed() @@ -2720,7 +3350,11 @@ static ivas_error decodeVariableSpeed( fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); goto cleanup; } +#ifdef API_5MS + IVAS_DEC_VoIP_SetScale( hIvasDec, scale, scale ); +#else IVAS_DEC_VoIP_SetScale( hIvasDec, scale ); +#endif } if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) @@ -2980,7 +3614,7 @@ static ivas_error decodeVariableSpeed( } /* decode and get samples */ - if ( ( error = IVAS_DEC_VoIP_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesAvailableNext, &nSamplesFlushed ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesAvailableNext, &nSamplesFlushed ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -3119,7 +3753,7 @@ cleanup: return error; } #endif - +#endif /*---------------------------------------------------------------------* * parseForcedRendModeDec() diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index c86d947125..251be0d38a 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -94,6 +94,11 @@ typedef enum #ifdef VARIABLE_SPEED_DECODING IVAS_ERR_VS_FRAME_NEEDED, #endif +#ifdef API_5MS + IVAS_ERR_TSM_NOT_ENABLED, + IVAS_ERR_FETCH_SIZE_NO_MULTIPLE_OF_5MS, + IVAS_ERR_NEED_NEW_FRAME, +#endif #endif /*----------------------------------------* diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index ba48326231..9d7e6b5806 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -311,10 +311,12 @@ void stereo_dmx_evs_close_encoder( STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS /* i/o: Stereo downmix for EVS encoder handle */ ); +#ifndef API_5MS ivas_error ivas_dec( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ int16_t *data /* o : output synthesis signal */ ); +#endif ivas_error ivas_dec_setup( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -5172,8 +5174,10 @@ void ivas_binaural_cldfb_sf( void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ +#ifndef API_5MS int16_t subframe_idx, /* i : subframe index */ - const int16_t numTimeSlots, /* i : number of time slots to process */ +#endif + const int16_t numTimeSlots, /* i: : number of time slots to process */ float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ diff --git a/lib_com/options.h b/lib_com/options.h old mode 100755 new mode 100644 index 8a4dc67706..c6d3a9c108 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -166,6 +166,11 @@ #define FIX_558_PLC_DISCONT /* FhG: issue 558: fix discontinuities in DFT Stereo when switching from TCX concealment to ACELP */ #define FIX_564 /* Nokia: Issue 564: Fix gains in JBM path for SBA with parametric binaural renderer */ #define FIX_566_2DIR_MASA_384K /* Nokia: Issued 566: Bugfix in 384k MASA metadata encoding of second direction */ +#define FIX_XXX_JITTER_SBA_BINAURAL_GAIN +#define FIX_XXX_HEADTRACKER_INIT +#define FIX_XXX_TDOBJRENDERER_INPUT +#define FIX_XXX_ISM_SBA_ASAN +#define API_5MS /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 5bd09236e0..efc3b11215 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -994,7 +994,11 @@ void ivas_binaural_cldfb( } /* Implement binaural rendering */ +#ifdef API_5MS + ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, JBM_CLDFB_SLOTS_IN_SUBFRAME, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#else ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, subframeIdx, JBM_CLDFB_SLOTS_IN_SUBFRAME, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#endif /* Implement CLDFB synthesis */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) @@ -1086,8 +1090,11 @@ void ivas_binaural_cldfb_sf( } /* Implement binaural rendering */ +#ifdef API_5MS + ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#else ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, subframeIdx, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); - +#endif /* Implement CLDFB synthesis */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { @@ -1122,7 +1129,9 @@ void ivas_binaural_cldfb_sf( void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ +#ifndef API_5MS int16_t subframe_idx, /* i : subframe index */ +#endif const int16_t numTimeSlots, /* i : number of time slots to render */ float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ @@ -1146,25 +1155,40 @@ void ivas_binRenderer( } /* Head rotation in HOA3 or CICPx */ - if ( - hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && hBinRenderer->rotInCldfb ) +#ifdef API_5MS + if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation && hBinRenderer->rotInCldfb ) +#else + if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && hBinRenderer->rotInCldfb ) +#endif { if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) { /* Rotation in SHD (HOA3) */ if ( hCombinedOrientationData->shd_rot_max_order == -1 ) { +#ifdef API_5MS + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); +#else rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); +#endif } else if ( hCombinedOrientationData->shd_rot_max_order > 0 ) { +#ifdef API_5MS + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); +#else rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); +#endif } } else { /* Rotation in SD (CICPx) */ +#ifdef API_5MS + rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat, RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); +#else rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); +#endif } } diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 02c74efa37..1f588ac2cc 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -32,6 +32,7 @@ #include #include "options.h" +#ifndef API_5MS #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" @@ -760,3 +761,4 @@ ivas_error ivas_dec( pop_wmops(); return error; } +#endif \ No newline at end of file diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index fc24c8bdef..f692ef1931 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1053,7 +1053,11 @@ ivas_error ivas_dirac_dec_config( /* allocate transport channels*/ if ( flag_config == DIRAC_OPEN ) { +#ifdef API_5MS + if ( st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) +#endif { if ( st_ivas->ivas_format == SBA_FORMAT ) { @@ -2261,12 +2265,12 @@ void ivas_dirac_dec( *------------------------------------------------------------------------*/ void ivas_dirac_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t nchan_transport, /* i : number of transport channels */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ ) { int16_t slots_to_render, first_sf, last_sf, subframe_idx; @@ -2323,7 +2327,7 @@ void ivas_dirac_dec_render( } } - *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; + *nSamplesAvailableNext = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; return; } @@ -2447,9 +2451,17 @@ void ivas_dirac_dec_render_sf( set_zero( onset_filter_subframe, hDirAC->num_freq_bands ); } +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation ) +#else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] ) +#endif { +#ifdef API_5MS + p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[0][0]; +#else p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[subframe_idx][0][0]; +#endif if ( st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) { @@ -2513,7 +2525,11 @@ void ivas_dirac_dec_render_sf( set_zero( surCohRatio, hDirAC->num_freq_bands ); } } +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) +#else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) +#endif { ivas_dirac_dec_compute_directional_responses( hDirAC, st_ivas->hVBAPdata, @@ -2606,7 +2622,11 @@ void ivas_dirac_dec_render_sf( if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) +#else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) +#endif { protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, @@ -2837,8 +2857,12 @@ void ivas_dirac_dec_render_sf( ivas_dirac_dec_compute_diffuse_proto( hDirAC, slot_idx ); } - /*Compute PSDs*/ +/*Compute PSDs*/ +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) +#else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) +#endif { ivas_dirac_dec_output_synthesis_process_slot( reference_power, p_onset_filter, @@ -2929,7 +2953,9 @@ void ivas_dirac_dec_render_sf( /* Perform binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, +#ifndef API_5MS subframe_idx, +#endif hDirAC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 3c0370c880..f23bac7367 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -618,6 +618,12 @@ ivas_error ivas_init_decoder_front( { return error; } +#ifdef FIX_XXX_HEADTRACKER_INIT + if ( ( error = ivas_orient_trk_SetTrackingType( st_ivas->hHeadTrackData->OrientationTracker, st_ivas->hDecoderConfig->orientation_tracking ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif } /*-------------------------------------------------------------------* @@ -786,6 +792,7 @@ ivas_error ivas_init_decoder( } } +#ifndef FIX_XXX_HEADTRACKER_INIT /*-----------------------------------------------------------------* * Set head/orientation tracking *-----------------------------------------------------------------*/ @@ -797,7 +804,7 @@ ivas_error ivas_init_decoder( return error; } } - +#endif /*-----------------------------------------------------------------* * Allocate and initialize SCE/CPE and other handles *-----------------------------------------------------------------*/ @@ -1289,7 +1296,9 @@ ivas_error ivas_init_decoder( } } +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active ) +#endif { granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -1332,7 +1341,9 @@ ivas_error ivas_init_decoder( st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active ) +#endif { granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -1436,8 +1447,11 @@ ivas_error ivas_init_decoder( /*-----------------------------------------------------------------* * Allocate and initialize JBM struct + buffer *-----------------------------------------------------------------*/ - +#ifdef API_5MS + if ( st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hDecoderConfig->voip_active && st_ivas->hTcBuffer == NULL ) +#endif { /* no module has yet open the TC buffer, open a default one */ n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -1448,6 +1462,7 @@ ivas_error ivas_init_decoder( } } +#ifndef API_5MS if ( st_ivas->hTcBuffer == NULL ) { /* we need the handle anyway, but without the buffer*/ @@ -1456,6 +1471,7 @@ ivas_error ivas_init_decoder( return error; } } +#endif #ifdef FIX_470_MASA_JBM_EXT if ( st_ivas->hJbmMetadata == NULL ) diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 6da3c05e75..64c00effb7 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -119,7 +119,9 @@ static ivas_error ivas_ism_bitrate_switching( ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->hDecoderConfig->output_config ); } +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active ) +#endif { /* transfer subframe info from DirAC or ParamMC to central tc buffer */ if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hDirAC != NULL && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) ) @@ -290,8 +292,9 @@ static ivas_error ivas_ism_bitrate_switching( /*-----------------------------------------------------------------* * Reconfigure TC buffer *-----------------------------------------------------------------*/ - +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active == 1 ) +#endif { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 2497f5ab98..f73b40b666 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -516,7 +516,11 @@ ivas_error ivas_param_ism_dec_open( if ( !( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) ) { /* Initialize Param ISM Rendering handle */ +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) +#else if ( st_ivas->hDecoderConfig->voip_active ) +#endif { if ( ( error = ivas_param_ism_rendering_init( hDirAC->hParamIsmRendering, hOutSetup, st_ivas->nchan_transport, MAX_JBM_CLDFB_TIMESLOTS, output_config ) ) != IVAS_ERR_OK ) { @@ -568,7 +572,9 @@ ivas_error ivas_param_ism_dec_open( st_ivas->hDirAC = hDirAC; +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active ) +#endif { if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) { @@ -582,7 +588,31 @@ ivas_error ivas_param_ism_dec_open( } else { +#ifdef API_5MS + int16_t n_slots_to_alloc; + if ( st_ivas->hDecoderConfig->tsm_active == 1 ) + { + n_slots_to_alloc = MAX_JBM_CLDFB_TIMESLOTS; + } + else + { + n_slots_to_alloc = CLDFB_SLOTS_PER_SUBFRAME * MAX_PARAM_SPATIAL_SUBFRAMES; + } + if ( ( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( n_slots_to_alloc * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL ) + + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) ); + } + set_zero( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc, n_slots_to_alloc * nchan_transport * hDirAC->num_freq_bands ); + + if ( ( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = (float *) malloc( n_slots_to_alloc * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) ); + } + set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, n_slots_to_alloc * nchan_transport * hDirAC->num_freq_bands ); +#else if ( ( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL ) + { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) ); } @@ -593,6 +623,7 @@ ivas_error ivas_param_ism_dec_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) ); } set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); +#endif } if ( st_ivas->hTcBuffer == NULL ) { @@ -616,11 +647,13 @@ ivas_error ivas_param_ism_dec_open( } } } +#ifndef API_5MS else { hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; } +#endif pop_wmops(); return error; @@ -1362,7 +1395,7 @@ void ivas_param_ism_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ float *output_f[] /* o : rendered time signal */ ) { @@ -1444,7 +1477,7 @@ void ivas_param_ism_dec_render( } } - *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; + *nSamplesAvailableNext = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; return; } diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 77563629ae..037f4a8b50 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -82,7 +82,11 @@ ivas_error ivas_ism_renderer_open( set_f( st_ivas->hIsmRendererData->gains[i], 0.0f, MAX_OUTPUT_CHANNELS ); } +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) +#else if ( st_ivas->hDecoderConfig->voip_active ) +#endif { init_interpolator_length = NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_CLDFB_TIMESLOTS * CLDFB_SLOT_NS ); interpolator_length = (uint16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); @@ -155,9 +159,17 @@ void ivas_ism_render( else { /* Combined rotation: rotate the object positions depending the head and external orientations */ +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation == 1 ) +#else if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) +#endif { +#ifdef API_5MS + rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat, 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 } else { @@ -238,7 +250,11 @@ void ivas_ism_render_sf( set_f( output_f[i], 0.0f, n_samples_to_render ); } +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation ) +#else if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] ) +#endif { ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_to_render, n_samples_to_render, @@ -250,9 +266,17 @@ void ivas_ism_render_sf( { /* Combined rotation: rotate the object positions depending the head and external orientations */ +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation == 1 ) +#else if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) +#endif { +#ifdef API_5MS + rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat, 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 ); @@ -281,7 +305,11 @@ void ivas_ism_render_sf( } /* update here only in case of head rotation */ +#ifdef API_5MS + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation == 1 ) +#else if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) +#endif { st_ivas->hIsmRendererData->prev_gains[i][j] = gain; } diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 858d78ab28..42c834c70f 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -476,6 +476,21 @@ ivas_error ivas_jbm_dec_tc( ivas_mono_stereo_downmix_mcmasa( st_ivas, output, output_frame ); } } +#ifdef API_5MS + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + + /* at least decode everything here, the rest is ToDo, for this we just output zeroes atm */ + ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, output_lfe_ch ); + + ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] ); + + if ( ( error = ivas_mct_dec( st_ivas, output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif } @@ -848,6 +863,18 @@ ivas_error ivas_jbm_dec_render( { ivas_param_mc_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); } +#ifdef API_5MS + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + /* zero output for now, not yet implemented... */ + int16_t ch; + *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); + for ( ch = 0; ch < nchan_out; ch++ ) + { + set_zero( p_output[ch], *nSamplesRendered ); + } + } +#endif else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { int16_t offset = st_ivas->hDirAC->slots_rendered * st_ivas->hDirAC->slot_size; @@ -1417,6 +1444,12 @@ int16_t ivas_jbm_dec_get_num_tc_channels( } } } +#ifdef API_5MS + else if ( st_ivas->ivas_format == MONO_FORMAT && st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) + { + num_tc = MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; + } +#endif return num_tc; } @@ -1570,9 +1603,26 @@ ivas_error ivas_jbm_dec_tc_buffer_open( } else { +#ifdef API_5MS + int16_t n_samp_full, n_samp_residual; +#else int16_t n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); int16_t n_samp_residual = hTcBuffer->n_samples_granularity - 1; +#endif int32_t offset; +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) + { + n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); + n_samp_residual = hTcBuffer->n_samples_granularity - 1; + } + else + { + n_samp_full = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + n_samp_residual = 0; + } +#endif + nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; nsamp_to_allocate += nchan_residual * n_samp_residual; @@ -1676,8 +1726,21 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( /* realloc buffers */ free( hTcBuffer->tc_buffer ); +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) + { + n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); + n_samp_residual = hTcBuffer->n_samples_granularity - 1; + } + else + { + n_samp_full = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + n_samp_residual = 0; + } +#else n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); n_samp_residual = hTcBuffer->n_samples_granularity - 1; +#endif nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; nsamp_to_allocate += nchan_residual * n_samp_residual; @@ -1859,9 +1922,24 @@ TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( case RENDERER_PARAM_ISM: case RENDERER_BINAURAL_MIXER_CONV: case RENDERER_BINAURAL_MIXER_CONV_ROOM: +#ifdef API_5MS + buffer_mode = TC_BUFFER_MODE_RENDERER; + break; + case RENDERER_NON_DIEGETIC_DOWNMIX: + if ( st_ivas->ivas_format == MONO_FORMAT ) + { + buffer_mode = TC_BUFFER_MODE_BUFFER; + } + else + { + buffer_mode = TC_BUFFER_MODE_RENDERER; + } + break; +#else case RENDERER_NON_DIEGETIC_DOWNMIX: buffer_mode = TC_BUFFER_MODE_RENDERER; break; +#endif case RENDERER_MC_PARAMMC: if ( st_ivas->hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) { diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 0576fe8121..bc519c5766 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -384,7 +384,11 @@ ivas_error ivas_masa_dec_open( st_ivas->hMasa = hMasa; /* allocate transport channels*/ +#ifdef API_5MS + if ( st_ivas->hTcBuffer == NULL && st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) +#else if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL && st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) +#endif { int16_t nchan_to_allocate; TC_BUFFER_MODE buffer_mode; @@ -1076,7 +1080,9 @@ ivas_error ivas_masa_dec_reconfigure( ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp ); +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active == 1 ) +#endif { int16_t tc_nchan_to_allocate; int16_t tc_nchan_transport; diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 32fbf135ba..16159ad005 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -459,7 +459,11 @@ ivas_error ivas_param_mc_dec_open( ivas_param_mc_dec_init( hParamMC, nchan_transport, nchan_out_cov ); +#ifdef API_5MS + if ( hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) +#else if ( st_ivas->hDecoderConfig->voip_active && hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) +#endif { if ( ( hParamMC->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) { @@ -1537,11 +1541,11 @@ void ivas_param_mc_dec_digest_tc( *------------------------------------------------------------------------*/ void ivas_param_mc_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ ) { PARAM_MC_DEC_HANDLE hParamMC; @@ -1751,7 +1755,10 @@ void ivas_param_mc_dec_render( if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { ivas_binRenderer( st_ivas->hBinRenderer, - st_ivas->hCombinedOrientationData, subframe_idx, + st_ivas->hCombinedOrientationData, +#ifndef API_5MS + subframe_idx, +#endif hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); } @@ -1807,7 +1814,7 @@ void ivas_param_mc_dec_render( param_mc_update_mixing_matrices( hParamMC, hParamMC->h_output_synthesis_cov_state.mixing_matrix, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, nchan_transport, nchan_out_cov ); } hParamMC->subframes_rendered = last_sf; - *nSamplesAvailable = ( hParamMC->num_slots - hParamMC->slots_rendered ) * NS2SA( output_Fs, CLDFB_SLOT_NS ); + *nSamplesAvailableNext = ( hParamMC->num_slots - hParamMC->slots_rendered ) * NS2SA( output_Fs, CLDFB_SLOT_NS ); pop_wmops(); return; @@ -1828,7 +1835,7 @@ void ivas_param_mc_dec( PARAM_MC_DEC_HANDLE hParamMC; float Cldfb_RealBuffer_in[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_NSLOTS * CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_in[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_NSLOTS * CLDFB_NO_CHANNELS_MAX]; - uint16_t nSamplesAsked, nSamplesAvailable, nSamplesRendered; + uint16_t nSamplesAsked, nSamplesAvailableNext, nSamplesRendered; hParamMC = st_ivas->hParamMC; assert( hParamMC ); @@ -1840,10 +1847,10 @@ void ivas_param_mc_dec( nSamplesAsked = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); ivas_param_mc_dec_digest_tc( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS, output_f ); - ivas_param_mc_dec_render( st_ivas, nSamplesAsked, &nSamplesRendered, &nSamplesAvailable, output_f ); + ivas_param_mc_dec_render( st_ivas, nSamplesAsked, &nSamplesRendered, &nSamplesAvailableNext, output_f ); #ifdef DEBUGGING assert( nSamplesRendered == nSamplesAsked ); - assert( nSamplesAvailable == 0 ); + assert( nSamplesAvailableNext == 0 ); #endif /* set handle pointers back to NULL */ diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 51d6856987..e52f30e9d0 100755 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -726,7 +726,9 @@ static ivas_error ivas_mc_dec_reconfig( /* side effect of the renderer selection can be a changed internal config */ ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active ) +#endif { /* transfer subframe info from DirAC or ParamMC to central tc buffer */ if ( last_mc_mode == MC_MODE_PARAMMC ) @@ -1259,8 +1261,9 @@ static ivas_error ivas_mc_dec_reconfig( /*-----------------------------------------------------------------* * Reconfigure TC buffer *-----------------------------------------------------------------*/ - +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active == 1 ) +#endif { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 3be8a2c62e..3802c4fc09 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -86,9 +86,15 @@ ivas_error ivas_td_binaural_renderer( st_ivas->transport_config, st_ivas->hBinRendererTd, st_ivas->nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, +#ifdef API_5MS + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->enableCombinedOrientation : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->Quaternion : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->listenerPos : NULL, +#else ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation : NULL, ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->listenerPos : NULL, +#endif ism_md_subframe_update, output, output_frame ); } @@ -178,10 +184,17 @@ ivas_error ivas_td_binaural_renderer_sf( } /* Update the listener's location/orientation */ +#ifdef API_5MS + TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, + ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation : 0, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->Quaternion : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->listenerPos : NULL ); +#else TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] : 0, ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->listenerPos : NULL ); +#endif if ( st_ivas->hRenderConfig != NULL && st_ivas->hIntSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { @@ -192,7 +205,7 @@ ivas_error ivas_td_binaural_renderer_sf( } /* Render subframe */ - if ( ( error = TDREND_GetMix( st_ivas->hBinRendererTd, output_f_local, output_frame, 0, ism_md_subframe_update_jbm ) ) != IVAS_ERR_OK ) + if ( ( error = TDREND_GetMix( st_ivas->hBinRendererTd, output_f_local, output_frame, 0, ism_md_subframe_update_jbm != subframe_idx ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 22258a9365..50bb1b3ddf 100755 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -348,7 +348,9 @@ ivas_error ivas_sba_dec_reconfigure( * JBM TC buffer *-----------------------------------------------------------------*/ +#ifndef API_5MS if ( st_ivas->hDecoderConfig->voip_active == 1 ) +#endif { int16_t tc_nchan_to_allocate; int16_t tc_nchan_tc; @@ -472,7 +474,7 @@ void ivas_sba_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ float *output_f[] /* o : rendered time signal */ ) { @@ -539,7 +541,7 @@ void ivas_sba_dec_render( } } - *nSamplesAvailable = ( hSpar->num_slots - hSpar->slots_rendered ) * slot_size; + *nSamplesAvailableNext = ( hSpar->num_slots - hSpar->slots_rendered ) * slot_size; return; } diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index 6f3dd13b7a..8e92a1f622 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -365,15 +365,22 @@ void ivas_ism2sba_sf( for ( j = 0; j < sba_num_chans; j++ ) { g2 = hIsmRendererData->interpolator + offset; +#ifndef FIX_XXX_ISM_SBA_ASAN g1 = 1 - *g2; +#endif tc = buffer_in[i] + offset; out = buffer_out[j]; gain = hIsmRendererData->gains[i][j]; prev_gain = hIsmRendererData->prev_gains[i][j]; for ( k = 0; k < n_samples_to_render; k++ ) { +#ifdef FIX_XXX_ISM_SBA_ASAN + g1 = 1.0f - *g2; +#endif *( out++ ) += ( ( *( g2++ ) ) * gain + g1 * prev_gain ) * ( *( tc++ ) ); +#ifndef FIX_XXX_ISM_SBA_ASAN g1 = 1.0f - *g2; +#endif } } } diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 9d4d67393f..df60891a58 100755 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -213,7 +213,11 @@ ivas_error ivas_spar_dec_open( } /* allocate transport channels*/ +#ifdef API_5MS + if ( st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) +#endif { int16_t nchan_to_allocate; int16_t nchan_tc; diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 315cfbad66..941ff4e6d4 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1194,7 +1194,11 @@ typedef struct decoder_config_structure #ifdef DEBUGGING int16_t force_rend; /* forced TD/CLDFB binaural renderer (for ISM and MC) */ #endif +#ifdef API_5MS + int16_t tsm_active; +#else int16_t voip_active; +#endif int16_t Opt_delay_comp; /* flag indicating delay compensation active */ } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; diff --git a/lib_dec/jbm_jb4sb.h b/lib_dec/jbm_jb4sb.h index 00f5ccbb40..599730975d 100644 --- a/lib_dec/jbm_jb4sb.h +++ b/lib_dec/jbm_jb4sb.h @@ -77,13 +77,13 @@ struct JB4_DATAUNIT int16_t partialCopyOffset; int16_t nextCoderType; }; - +#ifndef API_5MS typedef enum { JBM_RENDERER_NONE, JBM_RENDERER_IVAS, } JBM_RENDERER_TYPE; - +#endif typedef struct JB4_DATAUNIT *JB4_DATAUNIT_HANDLE; diff --git a/lib_dec/jbm_pcmdsp_fifo.c b/lib_dec/jbm_pcmdsp_fifo.c index a3e8936464..d3c93679fe 100644 --- a/lib_dec/jbm_pcmdsp_fifo.c +++ b/lib_dec/jbm_pcmdsp_fifo.c @@ -38,6 +38,7 @@ #include #include "options.h" +#ifndef API_5MS #include "prot.h" #include "ivas_prot.h" #ifdef DEBUGGING @@ -267,3 +268,4 @@ uint16_t pcmdsp_fifo_nReadableSamplesPerChannel( { return h->size; } +#endif \ No newline at end of file diff --git a/lib_dec/jbm_pcmdsp_fifo.h b/lib_dec/jbm_pcmdsp_fifo.h index b601cc2e0e..62ebc15d08 100644 --- a/lib_dec/jbm_pcmdsp_fifo.h +++ b/lib_dec/jbm_pcmdsp_fifo.h @@ -41,7 +41,7 @@ #include #include "options.h" - +#ifndef API_5MS /** Ringbuffer (FIFO) with fixed capacity for audio samples. */ struct PCMDSP_FIFO @@ -81,5 +81,5 @@ int16_t pcmdsp_fifo_write_zero( PCMDSP_FIFO_HANDLE h, uint16_t nSamplesPerChanne int16_t pcmdsp_fifo_read( PCMDSP_FIFO_HANDLE h, uint16_t nSamplesPerChannel, uint8_t *samples ); uint16_t pcmdsp_fifo_nReadableSamplesPerChannel( const PCMDSP_FIFO_HANDLE h ); - +#endif #endif /* JBM_PCMDSP_FIFO_H */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 5cc4bdd9b9..1e4dd48a60 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -53,11 +53,16 @@ struct IVAS_DEC_VOIP { uint16_t nSamplesFrame; /* Total number of samples in a frame (includes number of channels) */ JB4_HANDLE hJBM; +#ifndef API_5MS PCMDSP_APA_HANDLE hTimeScaler; +#endif uint16_t lastDecodedWasActive; - float *apaExecBuffer; /* Buffer for APA scaling */ +#ifndef API_5MS + float *apaExecBuffer; /* Buffer for APA scaling */ +#endif JB4_DATAUNIT_HANDLE hCurrentDataUnit; /* Points to the currently processed data unit */ uint16_t *bs_conversion_buf; /* Buffer for bitstream conversion from packed to serial */ +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING IVAS_DEC_VOIP_MODE voipMode; uint16_t speedFac; @@ -67,6 +72,7 @@ struct IVAS_DEC_VOIP PCMDSP_FIFO_HANDLE hFifoOut; uint8_t nTransportChannelsOld; uint16_t nSamplesAvailableNext; +#endif #ifdef SUPPORT_JBM_TRACEFILE IVAS_JBM_TRACE_DATA JbmTraceData; #endif @@ -84,8 +90,20 @@ struct IVAS_DEC bool hasDecodedFirstGoodFrame; /* False on init. Gets set to true after first good frame has been decoded -> all bitstream information is known from that point on */ bool isInitialized; - int16_t bitstreamformat; /* Bitstream format flag (G.192/MIME/VOIP_G192_RTP/VOIP_RTPDUMP) */ - bool Opt_VOIP; /* flag indicating VOIP mode with JBM */ + int16_t bitstreamformat; /* Bitstream format flag (G.192/MIME/VOIP_G192_RTP/VOIP_RTPDUMP) */ + bool Opt_VOIP; /* flag indicating VOIP mode with JBM */ +#ifdef API_5MS + bool Opt_TSM; /* flag indicating TSM mode*/ + int16_t tsm_scale; /* scale for TSM operation */ + int16_t tsm_max_scaling; + float *apaExecBuffer; /* Buffer for APA scaling */ + PCMDSP_APA_HANDLE hTimeScaler; + bool needNewFrame; + bool hasBeenFedFrame; + uint16_t nSamplesAvailableNext; + int16_t nSamplesRendered; + int16_t nTransportChannelsOld; +#endif int16_t amrwb_rfc4867_flag; /* MIME from rfc4867 is used */ int16_t sdp_hf_only; /* RTP payload format parameter: only Header-Full format without zero padding for size collision avoidance */ int16_t prev_ft_speech; /* RXDTX handler: previous frametype flag for G.192 format AMRWB SID_FIRST detection */ @@ -105,8 +123,10 @@ static ivas_error evs_dec_main( Decoder_Struct *st_ivas, const int16_t nOutSampl static ivas_error input_format_API_to_internal( IVAS_DEC_INPUT_FORMAT input_format, int16_t *bitstream_format_internal, int16_t *sdp_hf_only, const bool is_voip_enabled ); static void init_decoder_config( DECODER_CONFIG_HANDLE hDecoderConfig ); static int16_t IVAS_DEC_VoIP_GetRenderGranularity( Decoder_Struct *st_ivas ); +#ifndef API_5MS static JBM_RENDERER_TYPE IVAS_DEC_VoIP_GetRendererConfig( IVAS_DEC_HANDLE hIvasDec ); -static ivas_error IVAS_DEC_VoIP_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ); +#endif +static ivas_error IVAS_DEC_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ); static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels, uint8_t *nOutChannels, uint16_t *nSamplesRendered, int16_t *data ); static ivas_error IVAS_DEC_GetTcSamples( IVAS_DEC_HANDLE hIvasDec, float *pcmBuf, int16_t *nOutSamples ); static ivas_error IVAS_DEC_RendererFeedTcSamples( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesForRendering, int16_t *nSamplesResidual, float *pcmBuf ); @@ -143,6 +163,18 @@ ivas_error IVAS_DEC_Open( } hIvasDec = *phIvasDec; hIvasDec->hVoIP = NULL; +#ifdef API_5MS + hIvasDec->apaExecBuffer = NULL; + hIvasDec->hTimeScaler = NULL; + hIvasDec->Opt_TSM = false; + hIvasDec->tsm_scale = 100; + hIvasDec->needNewFrame = false; + hIvasDec->nTransportChannelsOld = 0; + hIvasDec->nSamplesAvailableNext = 0; + hIvasDec->nSamplesRendered = 0; + hIvasDec->nSamplesFrame = 0; + hIvasDec->hasBeenFedFrame = false; +#endif hIvasDec->hasBeenFedFirstGoodFrame = false; hIvasDec->hasDecodedFirstGoodFrame = false; hIvasDec->isInitialized = false; @@ -238,8 +270,11 @@ static void init_decoder_config( hDecoderConfig->orientation_tracking = HEAD_ORIENT_TRK_NONE; hDecoderConfig->Opt_non_diegetic_pan = 0; hDecoderConfig->non_diegetic_pan_gain = 0; - +#ifdef API_5MS + hDecoderConfig->tsm_active = 0; +#else hDecoderConfig->voip_active = 0; +#endif hDecoderConfig->Opt_delay_comp = 0; @@ -277,6 +312,14 @@ void IVAS_DEC_Close( ( *phIvasDec )->st_ivas = NULL; } +#ifdef API_5MS + apa_exit( &( *phIvasDec )->hTimeScaler ); + + if ( ( *phIvasDec )->apaExecBuffer != NULL ) + { + free( ( *phIvasDec )->apaExecBuffer ); + } +#endif free( *phIvasDec ); *phIvasDec = NULL; phIvasDec = NULL; @@ -404,9 +447,12 @@ static IVAS_DEC_BS_FORMAT mapIvasFormat( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_Configure( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const uint32_t sampleRate, /* i : output sampling frequency */ - const IVAS_DEC_AUDIO_CONFIG outputFormat, /* i : output format */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const uint32_t sampleRate, /* i : output sampling frequency */ + const IVAS_DEC_AUDIO_CONFIG outputFormat, /* i : output format */ +#ifdef API_5MS + const int16_t tsmEnabled, /* i : enable TSM */ +#endif const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ @@ -483,6 +529,16 @@ ivas_error IVAS_DEC_Configure( hIvasDec->st_ivas->ivas_format = MONO_FORMAT; } +#ifdef API_5MS + hDecoderConfig->tsm_active = tsmEnabled; + hIvasDec->Opt_TSM = tsmEnabled; + hIvasDec->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + hIvasDec->nSamplesAvailableNext = 0; + hIvasDec->nSamplesRendered = 0; + hIvasDec->tsm_scale = 100; + hIvasDec->tsm_max_scaling = 100; +#endif + return error; } @@ -497,9 +553,11 @@ ivas_error IVAS_DEC_Configure( ivas_error IVAS_DEC_EnableVoIP( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING const IVAS_DEC_VOIP_MODE voipMode, /* i : VoIP or variable speed */ const uint16_t speedFac, /* i : speed factor for variable speed */ +#endif #endif const int16_t jbmSafetyMargin, /* i : allowed delay reserve for JBM, in milliseconds */ const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ @@ -519,7 +577,12 @@ ivas_error IVAS_DEC_EnableVoIP( hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; hIvasDec->Opt_VOIP = 1; +#ifdef API_5MS + hIvasDec->Opt_TSM = 1; + hDecoderConfig->tsm_active = 1; +#else hDecoderConfig->voip_active = 1; +#endif if ( hDecoderConfig->output_config != AUDIO_CONFIG_EXTERNAL ) { @@ -545,12 +608,15 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->hVoIP->lastDecodedWasActive = 0; hIvasDec->hVoIP->hCurrentDataUnit = NULL; +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING hIvasDec->hVoIP->voipMode = voipMode; hIvasDec->hVoIP->speedFac = speedFac; hIvasDec->hVoIP->needNewFrame = false; +#endif #endif hIvasDec->hVoIP->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); +#ifndef API_5MS hIvasDec->hVoIP->nSamplesAvailableNext = 0; hIvasDec->hVoIP->rendererType = JBM_RENDERER_NONE; hIvasDec->hVoIP->hFifoOut = NULL; @@ -558,6 +624,7 @@ ivas_error IVAS_DEC_EnableVoIP( /* postpone init of the buffers until we know the real number of TCs*/ hIvasDec->hVoIP->apaExecBuffer = NULL; hIvasDec->hVoIP->nTransportChannelsOld = 0; +#endif #define WMC_TOOL_SKIP /* Bitstream conversion is not counted towards complexity and memory usage */ @@ -570,10 +637,12 @@ ivas_error IVAS_DEC_EnableVoIP( } /* initialize JBM */ +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING hIvasDec->hVoIP->hJBM = NULL; if ( hIvasDec->hVoIP->voipMode == IVAS_DEC_VOIP_MODE_VOIP ) { +#endif #endif if ( ( error = JB4_Create( &hIvasDec->hVoIP->hJBM ) != IVAS_ERR_OK ) != IVAS_ERR_OK ) { @@ -583,10 +652,13 @@ ivas_error IVAS_DEC_EnableVoIP( { return IVAS_ERR_FAILED_ALLOC; } +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING } #endif +#endif +#ifndef API_5MS /* postpone init of time scaler and output FIFO until we know the real number of TCs */ hIvasDec->hVoIP->hTimeScaler = NULL; #ifdef VARIABLE_SPEED_DECODING @@ -595,7 +667,7 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->hVoIP->needNewFrame = true; } #endif - +#endif return error; } @@ -639,9 +711,13 @@ ivas_error IVAS_DEC_FeedFrame_Serial( { hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = ACELP_8k00; } +#ifdef API_5MS + hIvasDec->isInitialized = true; +#endif } - +#ifndef API_5MS hIvasDec->isInitialized = true; +#endif } if ( !bfi ) /* TODO(mcjbm): Is this ok for bfi == 2 (partial frame)? Is there enough info to fully configure decoder? */ @@ -683,11 +759,18 @@ ivas_error IVAS_DEC_FeedFrame_Serial( st->use_partial_copy = 1; } +#ifdef API_5MS + hIvasDec->needNewFrame = false; + hIvasDec->hasBeenFedFrame = true; + hIvasDec->nSamplesRendered = 0; + hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; +#else #ifdef VARIABLE_SPEED_DECODING if ( hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->voipMode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) { hIvasDec->hVoIP->needNewFrame = false; } +#endif #endif return error; @@ -699,7 +782,7 @@ ivas_error IVAS_DEC_FeedFrame_Serial( * * Main function to decode to PCM data *---------------------------------------------------------------------*/ - +#ifndef API_5MS ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ @@ -745,6 +828,136 @@ ivas_error IVAS_DEC_GetSamples( return error; } +#else +ivas_error IVAS_DEC_GetSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i: number of samples wanted by the caller */ + int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* indication that the decoder needs a new frame */ +) +{ + Decoder_Struct *st_ivas; + ivas_error error; + int16_t nOutSamplesElse, result, nSamplesToRender; + uint16_t nSamplesRendered, nSamplesRendered_loop, l_ts, nTimeScalerOutSamples; + uint8_t nTransportChannels, nOutChannels; + error = IVAS_ERR_OK; + nSamplesRendered = 0; + nOutChannels = 0; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; + + if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) + { + /* no frame was fed, do nothing but ask for a frame */ + *needNewFrame = true; + *nOutSamples = 0; + hIvasDec->needNewFrame = true; + return error; + } + + /* check if we are still at the beginning with bad frames, put out zeroes, keep track of subframes */ + if ( !hIvasDec->isInitialized && hIvasDec->st_ivas->bfi ) + { + hIvasDec->hasBeenFedFrame = false; + set_s( pcmBuf, 0, hIvasDec->st_ivas->hDecoderConfig->nchan_out * nSamplesAsked ); + hIvasDec->nSamplesRendered += nSamplesAsked; + *nOutSamples = nSamplesAsked; + hIvasDec->nSamplesAvailableNext -= nSamplesAsked; + if ( hIvasDec->nSamplesAvailableNext == 0 ) + { + hIvasDec->needNewFrame = true; + *needNewFrame = true; + } + } + else + { + /* check if we need to run the setup function, tc decoding and feeding the renderer */ + if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) + { + int16_t nResidualSamples, nSamplesTcsScaled; + /* setup */ + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &nSamplesRendered_loop, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + nSamplesRendered += nSamplesRendered_loop; + if ( nTransportChannels != hIvasDec->nTransportChannelsOld ) + { + IVAS_DEC_reconfigure( hIvasDec, nTransportChannels, l_ts ); + } + /* decode TCs only */ + if ( ( error = IVAS_DEC_GetTcSamples( hIvasDec, hIvasDec->apaExecBuffer, &nOutSamplesElse ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasDec->Opt_TSM ) + { + if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + result = apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ); + if ( result != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + assert( nTimeScalerOutSamples <= APA_BUF ); + } + else + { + nTimeScalerOutSamples = hIvasDec->nSamplesFrame * nTransportChannels; + } + nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; + + /* render IVAS frames */ + + + if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasDec->Opt_TSM ) + { + /* feed residual samples to TSM for the next call */ + if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + hIvasDec->hasBeenFedFrame = false; + } + /* render IVAS frames directly to the output buffer */ + nSamplesToRender = nSamplesAsked - nSamplesRendered; + if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + nSamplesRendered += nSamplesRendered_loop; + nSamplesToRender -= nSamplesRendered_loop; + if ( hIvasDec->nSamplesAvailableNext == 0 ) + { + *needNewFrame = true; + hIvasDec->needNewFrame = true; + } + else + { + *needNewFrame = false; + } + } + + *nOutSamples = nSamplesRendered; + + return error; +} +#endif /*---------------------------------------------------------------------* @@ -1144,15 +1357,26 @@ ivas_error IVAS_DEC_GetMasaMetadata( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_FeedHeadTrackData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef API_5MS + IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ + IVAS_VECTOR3 Pos /* i : listener position */ +#else IVAS_QUATERNION *orientation, /* i : head-tracking data, listener orientation */ IVAS_VECTOR3 *Pos /* i : listener position */ +#endif ) { HEAD_TRACK_DATA_HANDLE hHeadTrackData; +#ifndef API_5MS int16_t i; +#endif +#ifdef API_5MS + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) +#else if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || orientation == NULL ) +#endif { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1165,6 +1389,18 @@ ivas_error IVAS_DEC_FeedHeadTrackData( } /* Move head-tracking data to the decoder handle */ +#ifdef API_5MS + /* check for Euler angle signaling */ + if ( orientation.w == -3.0f ) + { + Euler2Quat( deg2rad( orientation.x ), deg2rad( orientation.y ), deg2rad( orientation.z ), &orientation ); + } + + ivas_orient_trk_Process( hHeadTrackData->OrientationTracker, orientation, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &hHeadTrackData->Quaternion ); + hHeadTrackData->Pos.x = Pos.x; + hHeadTrackData->Pos.y = Pos.y; + hHeadTrackData->Pos.z = Pos.z; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { /* check for Euler angle signaling */ @@ -1180,6 +1416,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( } hIvasDec->st_ivas->hHeadTrackData->num_quaternions = 0; +#endif return IVAS_ERR_OK; } @@ -1244,18 +1481,32 @@ ivas_error IVAS_DEC_FeedRefVectorData( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_FeedExternalOrientationData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef API_5MS + IVAS_QUATERNION orientation, /* i : external orientation data */ + int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#else IVAS_QUATERNION *orientation, /* i : external orientation data */ int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#endif ) { EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; +#ifndef API_5MS int16_t i; +#endif +#ifdef API_5MS + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) +#else if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || orientation == NULL ) +#endif { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1268,6 +1519,14 @@ ivas_error IVAS_DEC_FeedExternalOrientationData( } /* Move external orientation data to the decoder handle (invert orientations) */ +#ifdef API_5MS + QuaternionInverse( orientation, &hExternalOrientationData->Quaternion ); + + hExternalOrientationData->enableHeadRotation = enableHeadRotation; + hExternalOrientationData->enableExternalOrientation = enableExternalOrientation; + hExternalOrientationData->enableRotationInterpolation = enableRotationInterpolation; + hExternalOrientationData->numFramesToTargetOrientation = numFramesToTargetOrientation; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { QuaternionInverse( orientation[i], &hExternalOrientationData->Quaternions[i] ); @@ -1277,6 +1536,7 @@ ivas_error IVAS_DEC_FeedExternalOrientationData( hExternalOrientationData->enableRotationInterpolation[i] = enableRotationInterpolation[i]; hExternalOrientationData->numFramesToTargetOrientation[i] = numFramesToTargetOrientation[i]; } +#endif return IVAS_ERR_OK; } @@ -1740,8 +2000,7 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( return IVAS_ERR_OK; } -#ifdef VARIABLE_SPEED_DECODING -#ifdef DEBUGGING +#if defined( VARIABLE_SPEED_DECODING ) || defined( API_5MS ) /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_SetScale( ) * @@ -1750,20 +2009,218 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( ivas_error IVAS_DEC_VoIP_SetScale( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t scale /* i : TSM scale to set */ +#ifdef API_5MS + const int16_t maxScaling, +#endif + const int16_t scale /* i : TSM scale to set */ ) { ivas_error error; error = IVAS_ERR_OK; +#ifdef API_5MS + if ( hIvasDec->Opt_TSM == false ) + { + return IVAS_ERR_TSM_NOT_ENABLED; + } + else + { + hIvasDec->tsm_scale = scale; + hIvasDec->tsm_max_scaling = maxScaling; + } +#else hIvasDec->hVoIP->speedFac = scale; +#endif return error; } #endif + + +#ifdef API_5MS +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_GetSamples( ) + * + * Main function to decode one frame in VoIP + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_VoIP_GetSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ +#ifdef SUPPORT_JBM_TRACEFILE + , + JbmTraceFileWriterFn jbmWriterFn, + void *jbmWriter +#endif + +) +{ + Decoder_Struct *st_ivas; + DECODER_CONFIG_HANDLE hDecoderConfig; + IVAS_DEC_VOIP *hVoIP; + uint32_t extBufferedTime_ms, scale, maxScaling; +#ifndef API_5MS + uint16_t nTimeScalerOutSamples; +#endif + JB4_DATAUNIT_HANDLE dataUnit; +#ifndef API_5MS + int16_t nOutSamplesElse; +#endif + uint16_t extBufferedSamples; + int16_t timeScalingDone; + int16_t result; + ivas_error error; + int16_t nSamplesRendered; + uint16_t nSamplesTcsScaled; + uint8_t nTransportChannels; + uint8_t nOutChannels; + + error = IVAS_ERR_OK; + + st_ivas = hIvasDec->st_ivas; + hDecoderConfig = st_ivas->hDecoderConfig; + hVoIP = hIvasDec->hVoIP; + timeScalingDone = 0; + + nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + nTransportChannels = 0; + nSamplesTcsScaled = hVoIP->nSamplesFrame; + nSamplesRendered = 0; + + if ( nSamplesPerChannel == 0 ) + { + return IVAS_ERR_WRONG_PARAMS; + } + + /* make sure that the FIFO after decoder/scaler contains at least one sound card frame (i.e. 20ms) */ + while ( nSamplesRendered < nSamplesPerChannel ) + { + if ( hIvasDec->nSamplesAvailableNext == 0 ) + { + int16_t nSamplesBuffered; + nSamplesBuffered = 0; + if ( hIvasDec->hasBeenFedFirstGoodFrame ) + { + IVAS_DEC_GetBufferedNumberOfSamples( hIvasDec, &nSamplesBuffered ); + } + extBufferedSamples = nSamplesRendered + nSamplesBuffered; + + 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 ) + { + return IVAS_ERR_UNKNOWN; + } + + + maxScaling = maxScaling * hDecoderConfig->output_Fs / 1000; + /* avoid time scaling multiple times in one sound card slot */ + if ( scale != 100U ) + { + if ( timeScalingDone ) + { + scale = 100; + } + else + { + timeScalingDone = 1; + } + } + + /* limit scale to range supported by time scaler */ + if ( scale < APA_MIN_SCALE ) + { + scale = APA_MIN_SCALE; + } + else if ( scale > APA_MAX_SCALE ) + { + scale = APA_MAX_SCALE; + } + + IVAS_DEC_VoIP_SetScale( hIvasDec, (int16_t) maxScaling, (int16_t) scale ); + + /* copy bitstream into decoder state */ + if ( dataUnit ) + { + hIvasDec->hVoIP->hCurrentDataUnit = dataUnit; + + bsCompactToSerial( dataUnit->data, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize ); + IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 ); + } + else if ( hIvasDec->hasDecodedFirstGoodFrame ) + { + /* Decoder has been initialized with first good frame - do PLC */ + IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 ); + } + +#ifdef SUPPORT_JBM_TRACEFILE + /* jbmWriterFn and jbmWriter may be NULL if tracefile writing was not requested on CLI */ + if ( jbmWriterFn != NULL && jbmWriter != NULL ) + { + /* write JBM trace data entry */ + store_JbmData( hVoIP, dataUnit, systemTimestamp_ms, extBufferedSamples, hDecoderConfig->output_Fs ); + if ( ( jbmWriterFn( &hVoIP->JbmTraceData, jbmWriter ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing JBM Trace data to file\n" ); + return IVAS_ERR_UNKNOWN; + } + } #endif + if ( dataUnit ) + { + if ( dataUnit->partial_frame != 0 ) + { + hVoIP->lastDecodedWasActive = 1; + } + else + { + hVoIP->lastDecodedWasActive = !dataUnit->silenceIndicator; + } + /* data unit memory is no longer used */ + JB4_FreeDataUnit( hVoIP->hJBM, dataUnit ); + } + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; + hIvasDec->nSamplesRendered = 0; + } + } + /* decode */ + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + /* codec mode to use not known yet - simply output silence */ + /* directly set output zero */ + int16_t nSamplesToZero = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); + set_s( pcmBuf + nSamplesRendered * nOutChannels, 0, nSamplesToZero * nOutChannels ); + nSamplesRendered += nSamplesToZero; + hIvasDec->nSamplesRendered += nSamplesToZero; + hIvasDec->nSamplesAvailableNext -= nSamplesToZero; + } + else + { + int16_t nSamplesToRender, nSamplesRendered_loop; + bool tmp; + nSamplesToRender = nSamplesPerChannel - nSamplesRendered; + /* render IVAS frames directly to the output buffer */ + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nSamplesRendered * nOutChannels, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) + { + return error; + } + nSamplesRendered += nSamplesRendered_loop; + } + } + return error; +} +#else /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_GetSamples( ) * @@ -1969,7 +2426,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( nSamplesRendered += nSamplesRendered_loop; if ( nTransportChannels != hVoIP->nTransportChannelsOld ) { - IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ); + IVAS_DEC_reconfigure( hIvasDec, nTransportChannels, l_ts ); } /* decode TCs only */ @@ -2149,6 +2606,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( return error; } +#endif /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_Flush( ) @@ -2156,25 +2614,34 @@ ivas_error IVAS_DEC_VoIP_GetSamples( * Function to flush remaining audio in VoIP *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_VoIP_Flush( +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 */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ - uint16_t *nSamplesAvailableNext, /* o : number of samples still available */ - int16_t *nSamplesFlushed /* o : number of samples flushed */ +#ifndef API_5MS + uint16_t *nSamplesAvailableNext, /* o : number of samples still available */ +#endif + int16_t *nSamplesFlushed /* o : number of samples flushed */ ) { ivas_error error; IVAS_DEC_VOIP *hVoIP; +#ifndef API_5MS int16_t rendererPcmBuf[( MAX_OUTPUT_CHANNELS * L_FRAME_MAX * APA_MAX_SCALE ) / 100]; +#endif uint16_t nSamplesToRender; uint16_t nSamplesFlushedLocal; error = IVAS_ERR_OK; hVoIP = hIvasDec->hVoIP; +#ifdef API_5MS + *nSamplesFlushed = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); +#else *nSamplesFlushed = min( nSamplesPerChannel, hVoIP->nSamplesAvailableNext ); +#endif +#ifndef API_5MS if ( hVoIP->rendererType == JBM_RENDERER_NONE ) { /* fetch a user-specified number of samples from FIFO */ @@ -2187,6 +2654,7 @@ ivas_error IVAS_DEC_VoIP_Flush( } else { + nSamplesToRender = (uint16_t) *nSamplesFlushed; /* render IVAS frames */ if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hVoIP->nSamplesAvailableNext, rendererPcmBuf ) ) != IVAS_ERR_OK ) @@ -2207,7 +2675,15 @@ ivas_error IVAS_DEC_VoIP_Flush( *nSamplesAvailableNext = hVoIP->nSamplesAvailableNext; *nSamplesFlushed = (int16_t) nSamplesFlushedLocal; } +#else + nSamplesToRender = (uint16_t) *nSamplesFlushed; + /* render IVAS frames */ + if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmBuf ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif return error; } @@ -2222,7 +2698,11 @@ bool IVAS_DEC_VoIP_IsEmpty( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesAsked ) { +#ifdef API_5MS + return ( ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->nSamplesAvailableNext < nSamplesAsked ) ); +#else return ( ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->hVoIP->nSamplesAvailableNext < nSamplesAsked ) ); +#endif } @@ -2261,6 +2741,7 @@ static void IVAS_DEC_Close_VoIP( { JB4_Destroy( &hVoIP->hJBM ); +#ifndef API_5MS apa_exit( &hVoIP->hTimeScaler ); pcmdsp_fifo_destroy( &hVoIP->hFifoOut ); @@ -2269,7 +2750,7 @@ static void IVAS_DEC_Close_VoIP( { free( hVoIP->apaExecBuffer ); } - +#endif if ( hVoIP->bs_conversion_buf != NULL ) { #define WMC_TOOL_SKIP @@ -2598,15 +3079,23 @@ static ivas_error printConfigInfo_dec( } } +#ifdef API_5MS + /*-----------------------------------------------------------------* + * Print VoIP mode info + *-----------------------------------------------------------------*/ + if ( st_ivas->hDecoderConfig->tsm_active ) + { + fprintf( stdout, "TSM mode: ON\n" ); + } +#else /*-----------------------------------------------------------------* * Print VoIP mode info *-----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->voip_active ) { fprintf( stdout, "VoIP mode: ON\n" ); } - +#endif return IVAS_ERR_OK; } @@ -3006,6 +3495,7 @@ static int16_t IVAS_DEC_VoIP_GetRenderGranularity( } +#ifndef API_5MS /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_GetRendererConfig() * @@ -3029,7 +3519,7 @@ static JBM_RENDERER_TYPE IVAS_DEC_VoIP_GetRendererConfig( return rendererType; } - +#endif /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_reconfigure() @@ -3037,64 +3527,103 @@ static JBM_RENDERER_TYPE IVAS_DEC_VoIP_GetRendererConfig( * *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_VoIP_reconfigure( +ivas_error IVAS_DEC_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ) { IVAS_DEC_VOIP *hVoIP; +#ifdef API_5MS + int16_t apa_buffer_size; +#endif + ivas_error error; + hVoIP = hIvasDec->hVoIP; +#ifdef API_5MS + apa_buffer_size = hIvasDec->nSamplesFrame; +#endif +#ifdef API_5MS + if ( hIvasDec->apaExecBuffer == NULL ) +#else if ( hIvasDec->hVoIP->hTimeScaler == NULL ) +#endif { - +#ifndef API_5MS uint16_t wss, css; float startQuality; +#endif DECODER_CONFIG_HANDLE hDecoderConfig; +#ifdef API_5MS + if ( hIvasDec->Opt_TSM ) + { + uint16_t wss, css; + float startQuality; + + startQuality = 1.0f; + apa_buffer_size = APA_BUF_PER_CHANNEL; +#else #ifdef VARIABLE_SPEED_DECODING startQuality = hVoIP->voipMode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ? -2.0f : 1.0f; #else startQuality = 1.0f; +#endif #endif - /* get current renderer type*/ - hVoIP->rendererType = IVAS_DEC_VoIP_GetRendererConfig( hIvasDec ); - hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; - if ( hDecoderConfig->output_Fs == 8000 ) - { - wss = 1; - css = 1; - } - else if ( hDecoderConfig->output_Fs == 16000 ) - { - wss = 2; - css = 1; - } - else if ( hDecoderConfig->output_Fs == 32000 ) - { - wss = 4; - css = 2; - } - else if ( hDecoderConfig->output_Fs == 48000 ) - { - wss = 6; - css = 3; - } - else - { - return IVAS_ERR_INIT_ERROR; - } + /* get current renderer type*/ +#ifndef API_5MS + hVoIP->rendererType = IVAS_DEC_VoIP_GetRendererConfig( hIvasDec ); +#endif + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; - if ( ( hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); - } - set_zero( hIvasDec->hVoIP->apaExecBuffer, APA_BUF_PER_CHANNEL * nTransportChannels ); + if ( hDecoderConfig->output_Fs == 8000 ) + { + wss = 1; + css = 1; + } + else if ( hDecoderConfig->output_Fs == 16000 ) + { + wss = 2; + css = 1; + } + else if ( hDecoderConfig->output_Fs == 32000 ) + { + wss = 4; + css = 2; + } + else if ( hDecoderConfig->output_Fs == 48000 ) + { + wss = 6; + css = 3; + } + else + { + return IVAS_ERR_INIT_ERROR; + } +#ifndef API_5MS + if ( ( hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ) ) == NULL ) + + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } + set_zero( hIvasDec->hVoIP->apaExecBuffer, APA_BUF_PER_CHANNEL * nTransportChannels ); +#endif +#ifdef API_5MS + if ( apa_init( &hIvasDec->hTimeScaler, + nTransportChannels ) != IVAS_ERR_OK || + apa_set_rate( hIvasDec->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || + apa_set_complexity_options( hIvasDec->hTimeScaler, wss, css ) != 0 || + apa_set_quality( hIvasDec->hTimeScaler, startQuality, 4, 4 ) != 0 || + apa_set_renderer_granularity( hIvasDec->hTimeScaler, l_ts ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } +#else if ( apa_init( &hIvasDec->hVoIP->hTimeScaler, nTransportChannels ) != IVAS_ERR_OK || apa_set_rate( hIvasDec->hVoIP->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || @@ -3104,51 +3633,101 @@ ivas_error IVAS_DEC_VoIP_reconfigure( { return IVAS_ERR_INIT_ERROR; } +#endif - if ( hVoIP->hFifoOut == NULL && hVoIP->rendererType == JBM_RENDERER_NONE ) - { - /* we still need the FIFO out buffer */ - if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || - pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) +#ifndef API_5MS + if ( hVoIP->hFifoOut == NULL && hVoIP->rendererType == JBM_RENDERER_NONE ) { - return IVAS_ERR_INIT_ERROR; + /* we still need the FIFO out buffer */ + if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || + pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } } - } #ifdef VARIABLE_SPEED_DECODING - else if ( hIvasDec->hVoIP->voipMode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) - { - if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || - pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) + else if ( hIvasDec->hVoIP->voipMode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) { - return IVAS_ERR_INIT_ERROR; + if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || + pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } } - } +#endif #endif - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - if ( apa_set_evs_compat_mode( hIvasDec->hVoIP->hTimeScaler, true ) != 0 ) + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { - return IVAS_ERR_INIT_ERROR; +#ifdef API_5MS + if ( apa_set_evs_compat_mode( hIvasDec->hTimeScaler, true ) != 0 ) +#else + if ( apa_set_evs_compat_mode( hIvasDec->hVoIP->hTimeScaler, true ) != 0 ) +#endif + { + return IVAS_ERR_INIT_ERROR; + } } +#ifdef API_5MS + } +#endif +#ifdef API_5MS + if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) + + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } + + set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); +#else + if ( ( hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ) ) == NULL ) + + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); } + + set_zero( hVoIP->apaExecBuffer, APA_BUF_PER_CHANNEL * nTransportChannels ); +#endif } else { - if ( apa_reconfigure( hVoIP->hTimeScaler, nTransportChannels, l_ts ) != 0 ) +#ifdef API_5MS + if ( hIvasDec->Opt_TSM ) { - return IVAS_ERR_INIT_ERROR; + if ( apa_reconfigure( hIvasDec->hTimeScaler, nTransportChannels, l_ts ) != 0 ) +#else + if ( apa_reconfigure( hVoIP->hTimeScaler, nTransportChannels, l_ts ) != 0 ) +#endif + { + return IVAS_ERR_INIT_ERROR; + } +#ifdef API_5MS + apa_buffer_size = APA_BUF_PER_CHANNEL; } - +#endif /* realloc apa_exe_buffer */ +#ifdef API_5MS + free( hIvasDec->apaExecBuffer ); + if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } + set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); +#else free( hIvasDec->hVoIP->apaExecBuffer ); if ( ( hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); } set_zero( hIvasDec->hVoIP->apaExecBuffer, APA_BUF_PER_CHANNEL * nTransportChannels ); +#endif } + +#ifdef API_5MS + hIvasDec->nTransportChannelsOld = nTransportChannels; +#else hIvasDec->hVoIP->nTransportChannelsOld = (uint8_t) nTransportChannels; +#endif error = IVAS_ERR_OK; diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index ebcdd099c8..7d2afa166e 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -84,7 +84,7 @@ typedef enum _IVAS_DEC_COMPLEXITY_LEVEL IVAS_DEC_COMPLEXITY_LEVEL_THREE = 3 } IVAS_DEC_COMPLEXITY_LEVEL; - +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING typedef enum { @@ -92,6 +92,7 @@ typedef enum IVAS_DEC_VOIP_MODE_VARIABLE_SPEED = 1 } IVAS_DEC_VOIP_MODE; #endif +#endif #ifdef DEBUGGING typedef enum _IVAS_DEC_FORCED_REND_MODE @@ -141,11 +142,14 @@ ivas_error IVAS_DEC_Configure( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const uint32_t sampleRate, /* i : output sampling frequency */ const IVAS_DEC_AUDIO_CONFIG outputFormat, /* i : output format */ +#ifdef API_5MS + const int16_t tsmEnabled, /* i : enable TSM */ +#endif const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ const int16_t enableExternalOrientation, /* i : enable external orientations */ - const HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ + const HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ const int16_t renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ const int16_t Opt_non_diegetic_pan, /* i : diegetic or not */ const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ @@ -169,9 +173,17 @@ ivas_error IVAS_DEC_FeedFrame_Serial( /*! r: decoder error code */ ivas_error IVAS_DEC_GetSamples( +#ifdef API_5MS + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i: number of samples wanted by the caller */ + int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* indication that the decoder needs a new frame */ +#else IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ +#endif ); /*! r: error code */ @@ -197,8 +209,13 @@ ivas_error IVAS_DEC_GetMasaMetadata( /*! r: error code */ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION *orientation, /* i : head-tracking data */ - IVAS_VECTOR3 *Pos /* i : listener position */ +#ifdef API_5MS + IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ + IVAS_VECTOR3 Pos /* i : listener position */ +#else + IVAS_QUATERNION *orientation, /* i : head-tracking data, listener orientation */ + IVAS_VECTOR3 *Pos /* i : listener position */ +#endif ); /*! r: error code */ @@ -216,11 +233,19 @@ ivas_error IVAS_DEC_FeedRefVectorData( /*! r: error code */ ivas_error IVAS_DEC_FeedExternalOrientationData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION *orientation, /* i : external orientation data */ - int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ - int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ - int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ - int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#ifdef API_5MS + IVAS_QUATERNION orientation, /* i : external orientation data */ + int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#else + IVAS_QUATERNION *orientation, /* i : external orientation data */ + int8_t *enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t *enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t *enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t *numFramesToTargetOrientation /* i : number of frames until target orientation is reached */ +#endif ); /*! r: error code */ @@ -234,6 +259,13 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( const bool qBit /* i : Q bit for AMR-WB IO */ ); +#ifdef API_5MS +ivas_error IVAS_DEC_VoIP_SetScale( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t maxScaling, /* i : maximum allowed TSM scale */ + const int16_t scale /* i : TSM scale to set */ +); +#else #ifdef VARIABLE_SPEED_DECODING #ifdef DEBUGGING /*! r: error code */ @@ -243,25 +275,31 @@ ivas_error IVAS_DEC_VoIP_SetScale( ); #endif #endif +#endif /*! r: error code */ ivas_error IVAS_DEC_VoIP_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ - const uint32_t systemTimestamp_ms, /* i : current system timestamp */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ +#ifndef API_5MS + , uint16_t *sampleAvailableNext /* o : samples available for the next call */ +#endif #ifdef SUPPORT_JBM_TRACEFILE , JbmTraceFileWriterFn jbmWriterFn, void* jbmWriter #endif ); -ivas_error IVAS_DEC_VoIP_Flush( +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 */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ - uint16_t *nSamplesAvailableNext, /* o : number of samples still available */ +#ifndef API_5MS + uint16_t *nSamplesAvailableNext, /* o : number of samples still available */ +#endif int16_t *nSamplesFlushed /* o : number of samples flushed */ ); @@ -270,9 +308,11 @@ ivas_error IVAS_DEC_VoIP_Flush( /*! r: error code */ ivas_error IVAS_DEC_EnableVoIP( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifndef API_5MS #ifdef VARIABLE_SPEED_DECODING const IVAS_DEC_VOIP_MODE voipMode, /* i : VoIP or variable speed */ const uint16_t speedFac, /* i : speed factor for variable speed */ +#endif #endif const int16_t jbmSafetyMargin, /* i : allowed delay reserve for JBM, in milliseconds */ const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index b2b4887499..e5bdd05ed1 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1348,6 +1348,12 @@ ivas_error ivas_rend_crendProcess( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + if ( hCombinedOrientationData->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( hCombinedOrientationData->enableCombinedOrientation[subframe_idx] != 0 ) @@ -1356,6 +1362,7 @@ ivas_error ivas_rend_crendProcess( break; } } +#endif } push_wmops( "ivas_rend_crendProcess" ); @@ -1470,6 +1477,12 @@ ivas_error ivas_rend_crendProcessSubframe( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + if ( hCombinedOrientationData->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( hCombinedOrientationData->enableCombinedOrientation[subframe_idx] != 0 ) @@ -1478,6 +1491,7 @@ ivas_error ivas_rend_crendProcessSubframe( break; } } +#endif } push_wmops( "ivas_rend_crendProcessSubframe" ); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 4616993f79..c9aaf13a49 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -235,7 +235,11 @@ ivas_error ivas_dirac_dec_init_binaural_data( st_ivas->hDiracDecBin = hBinaural; /* allocate transport channels*/ +#ifdef API_5MS + if ( st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) +#endif { int16_t nchan_to_allocate; @@ -672,7 +676,11 @@ static void ivas_dirac_dec_binaural_internal( { for ( j = 0; j < 3; j++ ) { +#ifdef API_5MS + Rmat[i][j] = hCombinedOrientationData->Rmat[i][j]; +#else Rmat[i][j] = hCombinedOrientationData->Rmat[subframe][i][j]; +#endif } } @@ -685,7 +693,11 @@ static void ivas_dirac_dec_binaural_internal( } ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, +#ifdef API_5MS + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation > 0 ); +#else hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0 ); +#endif if ( st_ivas->ivas_format == ISM_FORMAT ) { @@ -701,7 +713,11 @@ static void ivas_dirac_dec_binaural_internal( } ivas_dirac_dec_binaural_determine_processing_matrices( st_ivas, max_band_decorr, Rmat, +#ifdef API_5MS + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation > 0 ); +#else hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0 ); +#endif ivas_dirac_dec_binaural_process_output( st_ivas, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, subframe ); st_ivas->hDirAC->hDiffuseDist = NULL; diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 2ba225b2f1..ddd75c28d1 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -301,8 +301,11 @@ ivas_error ivas_td_binaural_renderer_unwrap( TDREND_Update_object_positions( hBinRendererTd, num_src, ivas_format, hIsmMetaData ); } /* Update the listener's location/orientation */ +#ifdef API_5MS + TDREND_Update_listener_orientation( hBinRendererTd, ( enableCombinedOrientation != NULL ) ? *enableCombinedOrientation : 0, ( Quaternions != NULL ) ? Quaternions : NULL, ( Pos != NULL ) ? Pos : NULL ); +#else TDREND_Update_listener_orientation( hBinRendererTd, ( enableCombinedOrientation != NULL ) ? enableCombinedOrientation[subframe_idx] : 0, ( Quaternions != NULL ) ? &Quaternions[subframe_idx] : NULL, ( Pos != NULL ) ? &Pos[subframe_idx] : NULL ); - +#endif if ( hReverb != NULL ) { if ( ( error = ivas_reverb_process( hReverb, transport_config, 0, output, p_reverb_signal, subframe_idx ) ) != IVAS_ERR_OK ) @@ -393,9 +396,17 @@ ivas_error TDREND_GetMix( { pan_left = ( SrcSpatial_p->Pos_p[1] + 1.f ) * 0.5f; pan_right = 1.f - pan_left; +#ifdef FIX_XXX_TDOBJRENDERER_INPUT + v_multc_acc( Src_p->InputFrame_p, pan_left, output_buf[0], subframe_length ); + v_multc_acc( Src_p->InputFrame_p, pan_right, output_buf[1], subframe_length ); +#else v_multc_acc( &Src_p->InputFrame_p[subframe_idx * subframe_length], pan_left, output_buf[0], subframe_length ); v_multc_acc( &Src_p->InputFrame_p[subframe_idx * subframe_length], pan_right, output_buf[1], subframe_length ); +#endif } +#ifdef FIX_XXX_TDOBJRENDERER_INPUT + Src_p->InputFrame_p += subframe_length; +#endif } /* Populate output variable */ @@ -675,9 +686,15 @@ ivas_error ivas_td_binaural_renderer_ext( } if ( ( error = ivas_td_binaural_renderer_unwrap( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, +#ifdef API_5MS + ( hCombinedOrientationData != NULL ) ? &( *hCombinedOrientationData )->enableCombinedOrientation : NULL, + ( hCombinedOrientationData != NULL ) ? &( *hCombinedOrientationData )->Quaternion : NULL, + ( hCombinedOrientationData != NULL ) ? &( *hCombinedOrientationData )->listenerPos : NULL, +#else ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->enableCombinedOrientation : NULL, ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->Quaternions : NULL, ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->listenerPos : NULL, +#endif ism_md_subframe_update_ext, p_output, output_frame ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index 6463261ec4..084da6550c 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -79,8 +79,9 @@ ivas_error TDREND_REND_RenderSourceHRFilt( v_add( LeftOutputFrame, output_buf[0], output_buf[0], subframe_length ); v_add( RightOutputFrame, output_buf[1], output_buf[1], subframe_length ); +#ifndef FIX_XXX_TDOBJRENDERER_INPUT Src_p->InputFrame_p += subframe_length; /* Increment input pointer */ - +#endif return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 2cd2744b5a..0c4114ce2a 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -48,10 +48,15 @@ * Local funtion declarations *-----------------------------------------------------------------------*/ +#ifdef API_5MS +static ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, IVAS_VECTOR3 *listenerPos, EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); + +static void external_target_interpolation( EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); +#else static ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, IVAS_VECTOR3 *listenerPos, int16_t numHeadRotQuaternions, EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); static void external_target_interpolation( EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, const int16_t i ); - +#endif static bool are_orientations_same( const IVAS_QUATERNION *orientation1, const IVAS_QUATERNION *orientation2 ); @@ -75,7 +80,9 @@ ivas_error ivas_headTrack_open( } /* Initialization */ +#ifndef API_5MS ( *hHeadTrackData )->num_quaternions = 0; +#endif ( *hHeadTrackData )->lrSwitchInterpVal = 0.0f; ( *hHeadTrackData )->lrSwitchedCurrent = 0; ( *hHeadTrackData )->lrSwitchedNext = 0; @@ -295,7 +302,11 @@ void rotateFrame_shd( /* calculate ambisonics rotation matrices for the previous and current frames */ SHrotmatgen( SHrotmat_prev, hCombinedOrientationData->Rmat_prev, shd_rot_max_order ); +#ifdef API_5MS + SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat, shd_rot_max_order ); +#else SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat[subframe_idx], shd_rot_max_order ); +#endif for ( i = 0; i < subframe_len; i++ ) { @@ -347,7 +358,11 @@ void rotateFrame_shd( /* move Rmat to Rmat_prev */ for ( i = 0; i < 3; i++ ) { +#ifdef API_5MS + mvr2r( hCombinedOrientationData->Rmat[i], hCombinedOrientationData->Rmat_prev[i], 3 ); +#else mvr2r( hCombinedOrientationData->Rmat[subframe_idx][i], hCombinedOrientationData->Rmat_prev[i], 3 ); +#endif } return; @@ -435,7 +450,11 @@ void rotateFrame_sd( /* gains for current subframe rotation */ +#ifdef API_5MS + rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat, hTransSetup.is_planar_setup ); +#else rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat[subframe_idx], hTransSetup.is_planar_setup ); +#endif if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { efap_determine_gains( hEFAPdata, tmp_gains, azimuth, elevation, EFAP_MODE_EFAP ); @@ -472,7 +491,11 @@ void rotateFrame_sd( /* move Rmat to Rmat_prev */ for ( i = 0; i < 3; i++ ) { +#ifdef API_5MS + mvr2r( hCombinedOrientationData->Rmat[i], hCombinedOrientationData->Rmat_prev[i], 3 ); +#else mvr2r( hCombinedOrientationData->Rmat[subframe_idx][i], hCombinedOrientationData->Rmat_prev[i], 3 ); +#endif } /* copy to output */ @@ -701,7 +724,9 @@ ivas_error ivas_external_orientation_open( EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData /* o : external orientation handle */ ) { +#ifndef API_5MS int16_t i; +#endif IVAS_QUATERNION identity; identity.w = 1.0f; @@ -714,6 +739,13 @@ ivas_error ivas_external_orientation_open( } /* Enable head rotation and disable external orientation as default */ +#ifdef API_5MS + ( *hExtOrientationData )->enableHeadRotation = 1; + ( *hExtOrientationData )->enableExternalOrientation = 0; + ( *hExtOrientationData )->enableRotationInterpolation = 0; + ( *hExtOrientationData )->numFramesToTargetOrientation = 0; + ( *hExtOrientationData )->Quaternion = identity; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { ( *hExtOrientationData )->enableHeadRotation[i] = 1; @@ -722,7 +754,7 @@ ivas_error ivas_external_orientation_open( ( *hExtOrientationData )->numFramesToTargetOrientation[i] = 0; ( *hExtOrientationData )->Quaternions[i] = identity; } - +#endif return IVAS_ERR_OK; } @@ -759,7 +791,10 @@ ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData /* o : combined orientation handle */ ) { - int16_t i, j; +#ifndef API_5MS + int16_t i; +#endif + int16_t j; IVAS_QUATERNION identity; IVAS_VECTOR3 origo; @@ -776,7 +811,11 @@ ivas_error ivas_combined_orientation_open( /* Initialization */ ( *hCombinedOrientationData )->interpolationCoefficient = 1.0f; ( *hCombinedOrientationData )->interpolationIncrement = 1.0f; +#ifdef API_5MS + ( *hCombinedOrientationData )->maximumFramesToTargetOrientation = 2000; +#else ( *hCombinedOrientationData )->maximumFramesToTargetOrientation = 500; +#endif ( *hCombinedOrientationData )->lrSwitchedNext = 0; ( *hCombinedOrientationData )->lrSwitchedCurrent = 0; ( *hCombinedOrientationData )->lrSwitchInterpVal = 0.0f; @@ -784,6 +823,19 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->Quaternions_ext_interpolation_start = identity; ( *hCombinedOrientationData )->Quaternions_ext_interpolation_target = identity; +#ifdef API_5MS + ( *hCombinedOrientationData )->enableCombinedOrientation = 0; + ( *hCombinedOrientationData )->Quaternion = identity; + ( *hCombinedOrientationData )->Quaternion_prev_headRot = identity; + ( *hCombinedOrientationData )->Quaternion_prev_extOrientation = identity; + ( *hCombinedOrientationData )->listenerPos = origo; + + for ( j = 0; j < 3; j++ ) + { + set_zero( ( *hCombinedOrientationData )->Rmat[j], 3 ); + ( *hCombinedOrientationData )->Rmat[j][j] = 1.0f; + } +#else /* Initialise orientations to identity */ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { @@ -799,7 +851,7 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->Rmat[i][j][j] = 1.0f; } } - +#endif for ( j = 0; j < 3; j++ ) { set_zero( ( *hCombinedOrientationData )->Rmat_prev[j], 3 ); @@ -851,19 +903,29 @@ ivas_error combine_external_and_head_orientations_dec( { IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; +#ifndef API_5MS int16_t numHeadRotQuaternions = 0; +#endif if ( hHeadTrackData != NULL ) { +#ifdef API_5MS + headRotQuaternions = &hHeadTrackData->Quaternion; + listenerPos = &hHeadTrackData->Pos; +#else numHeadRotQuaternions = hHeadTrackData->num_quaternions; if ( hHeadTrackData->num_quaternions >= 0 ) { headRotQuaternions = hHeadTrackData->Quaternions; listenerPos = hHeadTrackData->Pos; } +#endif } - +#ifdef API_5MS + return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); +#else return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); +#endif } @@ -881,8 +943,10 @@ ivas_error combine_external_and_head_orientations_rend( { IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; +#ifndef API_5MS int16_t numHeadRotQuaternions = 0; int16_t i; +#endif if ( hHeadTrackData != NULL ) { @@ -895,6 +959,13 @@ ivas_error combine_external_and_head_orientations_rend( else if ( hExtOrientationData != NULL ) { /* Head rotation data not available, use the freezed value or disable */ +#ifdef API_5MS + if ( hExtOrientationData->enableHeadRotation != 2 ) + { + hExtOrientationData->enableHeadRotation = 0; + } + +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData->enableHeadRotation[i] != 2 ) @@ -902,9 +973,13 @@ ivas_error combine_external_and_head_orientations_rend( hExtOrientationData->enableHeadRotation[i] = 0; } } +#endif } - +#ifdef API_5MS + return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); +#else return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); +#endif } @@ -915,15 +990,20 @@ ivas_error combine_external_and_head_orientations_rend( * NOTE that the external orientations are inversed. *------------------------------------------------------------------------*/ -static ivas_error combine_external_and_head_orientations( - IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ - IVAS_VECTOR3 *listenerPos, /* i : listener position */ - int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ - EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ +ivas_error combine_external_and_head_orientations( + IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ + IVAS_VECTOR3 *listenerPos, /* i : listener position */ +#ifndef API_5MS + int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ +#endif + EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { - int16_t i, j; +#ifndef API_5MS + int16_t i; +#endif + int16_t j; IVAS_QUATERNION identity; IVAS_VECTOR3 origo; @@ -951,6 +1031,18 @@ static ivas_error combine_external_and_head_orientations( hCombinedOrientationData->interpolationIncrement = 1.0f; hCombinedOrientationData->Quaternions_ext_interpolation_start = identity; hCombinedOrientationData->Quaternions_ext_interpolation_target = identity; +#ifdef API_5MS + + hCombinedOrientationData->enableCombinedOrientation = 0; + hCombinedOrientationData->Quaternion = identity; + hCombinedOrientationData->listenerPos = origo; + + for ( j = 0; j < 3; j++ ) + { + set_zero( hCombinedOrientationData->Rmat[j], 3 ); + hCombinedOrientationData->Rmat[j][j] = 1.0f; + } +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { hCombinedOrientationData->enableCombinedOrientation[i] = 0; @@ -963,10 +1055,15 @@ static ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Rmat[i][j][j] = 1.0f; } } +#endif } else if ( hExtOrientationData == NULL && headRotQuaternions != NULL ) { /* Head rotation only */ +#ifdef API_5MS + hCombinedOrientationData->Quaternion = *headRotQuaternions; + +#else if ( numHeadRotQuaternions >= 0 ) { for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) @@ -974,11 +1071,47 @@ static ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; } } +#endif } if ( hExtOrientationData != NULL ) { /* External orientations */ +#ifdef API_5MS + + if ( hExtOrientationData->enableRotationInterpolation == 1 && hExtOrientationData->enableExternalOrientation > 0 ) + { + if ( hCombinedOrientationData->isInterpolationOngoing == TRUE && hCombinedOrientationData->interpolationCoefficient <= 1.0f && are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternion ) == true ) + { + /* Continue interpolation */ + QuaternionSlerp( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternion ); + hCombinedOrientationData->interpolationCoefficient += hCombinedOrientationData->interpolationIncrement; + } + else + { + /* Stop interpolation or check for new interpolation */ + hCombinedOrientationData->isInterpolationOngoing = FALSE; + hCombinedOrientationData->interpolationCoefficient = 1.0f; + hCombinedOrientationData->interpolationIncrement = 1.0f; + external_target_interpolation( hExtOrientationData, hCombinedOrientationData ); + } + } + else + { + /* Interpolation disabled, use the current orientation values */ + + /* Use the most recent external orientation */ + if ( hExtOrientationData->enableExternalOrientation == 1 ) + { + hCombinedOrientationData->Quaternion = hExtOrientationData->Quaternion; + } + /* Use the freezed external orientation */ + else if ( hExtOrientationData->enableExternalOrientation == 2 ) + { + hCombinedOrientationData->Quaternion = hCombinedOrientationData->Quaternion_prev_extOrientation; + } + } +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData->enableRotationInterpolation[i] == 1 && hExtOrientationData->enableExternalOrientation[i] > 0 ) @@ -1014,11 +1147,46 @@ static ivas_error combine_external_and_head_orientations( } } } +#endif } if ( hExtOrientationData != NULL && headRotQuaternions != NULL ) { /* Combine head and external orientations */ +#ifdef API_5MS + + /* Use the most recent head rotation */ + if ( hExtOrientationData->enableHeadRotation == 1 ) + { + if ( hExtOrientationData->enableExternalOrientation > 0 ) + { + QuaternionProduct( hCombinedOrientationData->Quaternion, *headRotQuaternions, &hCombinedOrientationData->Quaternion ); + } + else + { + hCombinedOrientationData->Quaternion = *headRotQuaternions; + } + } + /* Use the freezed head rotation */ + else if ( hExtOrientationData->enableHeadRotation == 2 ) + { + if ( hExtOrientationData->enableExternalOrientation > 0 ) + { + QuaternionProduct( hCombinedOrientationData->Quaternion, hCombinedOrientationData->Quaternion_prev_headRot, &hCombinedOrientationData->Quaternion ); + } + else + { + hCombinedOrientationData->Quaternion = hCombinedOrientationData->Quaternion_prev_headRot; + } + } + + /* Reset the combined orientations to identity */ + if ( hExtOrientationData->enableHeadRotation == 0 && hExtOrientationData->enableExternalOrientation == 0 ) + { + hCombinedOrientationData->Quaternion = identity; + } + +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { /* Use the most recent head rotation */ @@ -1052,20 +1220,36 @@ static ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternions[i] = identity; } } +#endif } if ( headRotQuaternions != NULL || hExtOrientationData != NULL ) { /* Calculate the combined rotation matrix */ +#ifdef API_5MS + QuatToRotMat( hCombinedOrientationData->Quaternion, hCombinedOrientationData->Rmat ); +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { QuatToRotMat( hCombinedOrientationData->Quaternions[i], hCombinedOrientationData->Rmat[i] ); } +#endif } /* Save the current orientations */ if ( hExtOrientationData != NULL ) { +#ifdef API_5MS + if ( hExtOrientationData->enableExternalOrientation > 0 ) + { + hCombinedOrientationData->Quaternion_prev_extOrientation = hCombinedOrientationData->Quaternion; + } + else + { + hCombinedOrientationData->Quaternion_prev_extOrientation = identity; + } + +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData->enableExternalOrientation[i] > 0 ) @@ -1077,9 +1261,29 @@ static ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternions_prev_extOrientation[i] = identity; } } +#endif } if ( headRotQuaternions != NULL ) { +#ifdef API_5MS + if ( hExtOrientationData != NULL ) + { + if ( hExtOrientationData->enableHeadRotation > 0 ) + { + hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternions; + } + else + { + hCombinedOrientationData->Quaternion_prev_headRot = identity; + } + } + else + { + hCombinedOrientationData->Quaternion_prev_headRot = *headRotQuaternions; + } + hCombinedOrientationData->listenerPos = *listenerPos; + +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData != NULL ) @@ -1106,11 +1310,16 @@ static ivas_error combine_external_and_head_orientations( } hCombinedOrientationData->listenerPos[i] = listenerPos[i]; } +#endif } /* Check if combined orientation is enabled */ if ( headRotQuaternions != NULL && hExtOrientationData == NULL ) { +#ifdef API_5MS + hCombinedOrientationData->enableCombinedOrientation = 1; + +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( numHeadRotQuaternions >= 0 ) @@ -1122,9 +1331,20 @@ static ivas_error combine_external_and_head_orientations( hCombinedOrientationData->enableCombinedOrientation[i] = 0; } } +#endif } else if ( headRotQuaternions == NULL && hExtOrientationData != NULL ) { +#ifdef API_5MS + if ( hExtOrientationData->enableExternalOrientation > 0 ) + { + hCombinedOrientationData->enableCombinedOrientation = 1; + } + else + { + hCombinedOrientationData->enableCombinedOrientation = 0; + } +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData->enableExternalOrientation[i] > 0 ) @@ -1136,9 +1356,20 @@ static ivas_error combine_external_and_head_orientations( hCombinedOrientationData->enableCombinedOrientation[i] = 0; } } +#endif } else if ( headRotQuaternions != NULL && hExtOrientationData != NULL ) { +#ifdef API_5MS + if ( hExtOrientationData->enableExternalOrientation > 0 || hExtOrientationData->enableHeadRotation > 0 ) + { + hCombinedOrientationData->enableCombinedOrientation = 1; + } + else + { + hCombinedOrientationData->enableCombinedOrientation = 0; + } +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { if ( hExtOrientationData->enableExternalOrientation[i] > 0 || ( hExtOrientationData->enableHeadRotation[i] > 0 && numHeadRotQuaternions >= 0 ) ) @@ -1150,13 +1381,18 @@ static ivas_error combine_external_and_head_orientations( hCombinedOrientationData->enableCombinedOrientation[i] = 0; } } +#endif } else { +#ifdef API_5MS + hCombinedOrientationData->enableCombinedOrientation = 0; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { hCombinedOrientationData->enableCombinedOrientation[i] = 0; } +#endif } return IVAS_ERR_OK; @@ -1169,36 +1405,69 @@ static ivas_error combine_external_and_head_orientations( * *------------------------------------------------------------------------*/ -static void external_target_interpolation( - EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ - const int16_t i ) +void external_target_interpolation( + EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ +#ifndef API_5MS + , + const int16_t i +#endif +) { /* Sanity check for number of frames */ +#ifdef API_5MS + hExtOrientationData->numFramesToTargetOrientation = min( hExtOrientationData->numFramesToTargetOrientation, hCombinedOrientationData->maximumFramesToTargetOrientation ); + hExtOrientationData->numFramesToTargetOrientation = max( hExtOrientationData->numFramesToTargetOrientation, 0 ); +#else hExtOrientationData->numFramesToTargetOrientation[i] = min( hExtOrientationData->numFramesToTargetOrientation[i], hCombinedOrientationData->maximumFramesToTargetOrientation ); hExtOrientationData->numFramesToTargetOrientation[i] = max( hExtOrientationData->numFramesToTargetOrientation[i], 0 ); +#endif /* Interpolate from the current orientation to the target orientation */ +#ifdef API_5MS + if ( hExtOrientationData->numFramesToTargetOrientation > 0 ) +#else if ( hExtOrientationData->numFramesToTargetOrientation[i] > 0 ) +#endif { +#ifdef API_5MS + if ( are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternion ) == false ) +#else if ( are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternions[i] ) == false ) +#endif { /* Target orientation is different from the previous target, update the values */ /* Set the received orientation as the target */ +#ifdef API_5MS + hCombinedOrientationData->Quaternions_ext_interpolation_target = hExtOrientationData->Quaternion; +#else hCombinedOrientationData->Quaternions_ext_interpolation_target = hExtOrientationData->Quaternions[i]; +#endif /* Use the most recent external orientation as the starting orientation */ +#ifdef API_5MS + hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternion_prev_extOrientation; +#else hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternions_prev_extOrientation[i]; +#endif /* Calculate the interpolation increment and coefficient */ +#ifdef API_5MS + hCombinedOrientationData->interpolationIncrement = 1.0f / ( (float) hExtOrientationData->numFramesToTargetOrientation ); +#else hCombinedOrientationData->interpolationIncrement = 1.0f / ( (float) hExtOrientationData->numFramesToTargetOrientation[i] * (float) MAX_PARAM_SPATIAL_SUBFRAMES ); +#endif hCombinedOrientationData->interpolationCoefficient = hCombinedOrientationData->interpolationIncrement; } /* Interpolate */ hCombinedOrientationData->isInterpolationOngoing = TRUE; +#ifdef API_5MS + QuaternionSlerp( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternion ); +#else QuaternionSlerp( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i] ); +#endif hCombinedOrientationData->interpolationCoefficient += hCombinedOrientationData->interpolationIncrement; } else @@ -1207,7 +1476,11 @@ static void external_target_interpolation( hCombinedOrientationData->isInterpolationOngoing = FALSE; hCombinedOrientationData->interpolationCoefficient = 1.0f; hCombinedOrientationData->interpolationIncrement = 1.0f; +#ifdef API_5MS + hCombinedOrientationData->Quaternion = hExtOrientationData->Quaternion; +#else hCombinedOrientationData->Quaternions[i] = hExtOrientationData->Quaternions[i]; +#endif } return; diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index c763630325..14de5e7d55 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -257,9 +257,14 @@ typedef struct typedef struct ivas_binaural_head_track_struct { +#ifdef API_5MS + IVAS_QUATERNION Quaternion; + IVAS_VECTOR3 Pos; +#else int16_t num_quaternions; IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_VECTOR3 Pos[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif float Rmat[3][3]; float Rmat_prev[3][3]; @@ -281,12 +286,19 @@ typedef struct ivas_binaural_head_track_struct typedef struct ivas_external_orientation_struct { +#ifdef API_5MS + int8_t enableHeadRotation; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ + int8_t enableExternalOrientation; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ + int8_t enableRotationInterpolation; /* 0 - disable, 1 - enable */ + int16_t numFramesToTargetOrientation; /* Number of frames until target orientation is reached */ + IVAS_QUATERNION Quaternion; /* External orientation in quaternions */ +#else int8_t enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ int8_t enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ int8_t enableRotationInterpolation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable */ int16_t numFramesToTargetOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Number of frames until target orientation is reached */ IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */ - +#endif } EXTERNAL_ORIENTATION_DATA, *EXTERNAL_ORIENTATION_HANDLE; /*----------------------------------------------------------------------------------* @@ -295,7 +307,11 @@ typedef struct ivas_external_orientation_struct typedef struct ivas_combined_orientation_struct { +#ifdef API_5MS + int16_t enableCombinedOrientation; +#else int16_t enableCombinedOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif float interpolationCoefficient; float interpolationIncrement; int16_t maximumFramesToTargetOrientation; @@ -303,17 +319,31 @@ typedef struct ivas_combined_orientation_struct uint8_t lrSwitchedCurrent; float lrSwitchInterpVal; bool isInterpolationOngoing; +#ifdef API_5MS + IVAS_QUATERNION Quaternion; + IVAS_QUATERNION Quaternion_prev_headRot; + IVAS_QUATERNION Quaternion_prev_extOrientation; +#else IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_QUATERNION Quaternions_prev_headRot[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_QUATERNION Quaternions_prev_extOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif IVAS_QUATERNION Quaternions_ext_interpolation_start; IVAS_QUATERNION Quaternions_ext_interpolation_target; +#ifdef API_5MS + float Rmat[3][3]; +#else float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; +#endif float Rmat_prev[3][3]; float chEneIIR[2][MASA_FREQUENCY_BANDS]; /* independent of the format. MASA bands are suitable for the task and readily available in ROM. */ float procChEneIIR[2][MASA_FREQUENCY_BANDS]; int16_t shd_rot_max_order; +#ifdef API_5MS + IVAS_VECTOR3 listenerPos; +#else IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 4e75d5fea8..89b51e7745 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2583,8 +2583,11 @@ static DecoderDummy *initDecoderDummy( decDummy->hDecoderConfig->output_Fs = sampleRate; decDummy->hDecoderConfig->nchan_out = numOutChannels; decDummy->hDecoderConfig->Opt_Headrotation = 0; +#ifdef API_5MS + decDummy->hDecoderConfig->tsm_active = 0; +#else decDummy->hDecoderConfig->voip_active = 0; - +#endif decDummy->hBinRenderer = NULL; decDummy->hEFAPdata = NULL; decDummy->hCrendWrapper = NULL; @@ -2616,6 +2619,12 @@ static DecoderDummy *initDecoderDummy( set_zero( decDummy->hHeadTrackData->chEneIIR[1], MASA_FREQUENCY_BANDS ); set_zero( decDummy->hHeadTrackData->procChEneIIR[0], MASA_FREQUENCY_BANDS ); set_zero( decDummy->hHeadTrackData->procChEneIIR[1], MASA_FREQUENCY_BANDS ); +#ifdef API_5MS + decDummy->hHeadTrackData->Quaternion.w = 1.0f; + decDummy->hHeadTrackData->Quaternion.x = 0.0f; + decDummy->hHeadTrackData->Quaternion.y = 0.0f; + decDummy->hHeadTrackData->Quaternion.z = 0.0f; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { decDummy->hHeadTrackData->Quaternions[i].w = 1.0f; @@ -2623,7 +2632,7 @@ static DecoderDummy *initDecoderDummy( decDummy->hHeadTrackData->Quaternions[i].y = 0.0f; decDummy->hHeadTrackData->Quaternions[i].z = 0.0f; } - decDummy->hHeadTrackData->num_quaternions = 0; +#endif decDummy->hHeadTrackData->lrSwitchInterpVal = 0.0f; decDummy->hHeadTrackData->lrSwitchedCurrent = 0; decDummy->hHeadTrackData->lrSwitchedNext = 0; @@ -4246,21 +4255,35 @@ ivas_error IVAS_REND_SetExternalOrientation( if ( orientation == NULL ) { +#ifdef API_5MS + hIvasRend->hExternalOrientationData->enableExternalOrientation = 0; +#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { hIvasRend->hExternalOrientationData->enableExternalOrientation[i] = 0; } +#endif } else { for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { +#ifdef API_5MS + /* just fix compilation issues, ToDo: change ext renderer also to 5ms */ + QuaternionInverse( orientation[i], &hIvasRend->hExternalOrientationData->Quaternion ); + + hIvasRend->hExternalOrientationData->enableHeadRotation = enableHeadRotation[i]; + hIvasRend->hExternalOrientationData->enableExternalOrientation = enableExternalOrientation[i]; + hIvasRend->hExternalOrientationData->enableRotationInterpolation = enableRotationInterpolation[i]; + hIvasRend->hExternalOrientationData->numFramesToTargetOrientation = numFramesToTargetOrientation[i]; +#else QuaternionInverse( orientation[i], &hIvasRend->hExternalOrientationData->Quaternions[i] ); hIvasRend->hExternalOrientationData->enableHeadRotation[i] = enableHeadRotation[i]; hIvasRend->hExternalOrientationData->enableExternalOrientation[i] = enableExternalOrientation[i]; hIvasRend->hExternalOrientationData->enableRotationInterpolation[i] = enableRotationInterpolation[i]; hIvasRend->hExternalOrientationData->numFramesToTargetOrientation[i] = numFramesToTargetOrientation[i]; +#endif } } @@ -4309,7 +4332,12 @@ ivas_error IVAS_REND_GetCombinedOrientation( { for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { +#ifdef API_5MS + /* fix compilation only,ToDo adapt ext renderer to 5ms , this functions looks stale anyway */ + pOrientation[i] = hIvasRend->hCombinedOrientationData->Quaternion; +#else pOrientation[i] = hIvasRend->hCombinedOrientationData->Quaternions[i]; +#endif } } @@ -4468,7 +4496,12 @@ static ivas_error rotateFrameMc( { for ( j = 0; j < 3; j++ ) { +#ifdef API_5MS + /* fix compiling only, ToDo adapt ext renderer to 5ms */ + Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[i][j]; +#else Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][j]; +#endif } } else @@ -4585,7 +4618,12 @@ static ivas_error rotateFrameSba( { for ( l = 0; l < 3; l++ ) { +#ifdef API_5MS + /* fix compilation only, ToDo adapt ext renderer to 5ms */ + Rmat[i][l] = ( *hCombinedOrientationData )->Rmat[i][l]; +#else Rmat[i][l] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][l]; +#endif } } else @@ -4723,14 +4761,23 @@ static ivas_error renderIsmToBinauralRoom( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compilation only, ToDo adapt ext renderer to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { + if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) { combinedOrientationEnabled = 1; break; } } +#endif } @@ -4742,6 +4789,16 @@ static ivas_error renderIsmToBinauralRoom( { for ( i = 0; i < 3; i++ ) { +#ifdef API_5MS + /* at least this looks like it is adapted to 5ms already since it "loops" only over the first subframe, ToDo needs to be checked */ + if ( hCombinedOrientationData != NULL && ( *hCombinedOrientationData )->enableCombinedOrientation ) + { + for ( j = 0; j < 3; j++ ) + { + Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[i][j]; + } + } +#else if ( hCombinedOrientationData != NULL && ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] ) { for ( j = 0; j < 3; j++ ) @@ -4749,6 +4806,7 @@ static ivas_error renderIsmToBinauralRoom( Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][j]; } } +#endif else { /* Set to identity */ @@ -5148,7 +5206,9 @@ static ivas_error renderMcToBinaural( IVAS_REND_AudioBuffer tmpRotBuffer; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; +#ifndef API_5MS int16_t subframe_idx; +#endif float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; int16_t i; @@ -5165,6 +5225,14 @@ static ivas_error renderMcToBinaural( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compiling only, ToDo ext renderer needs to adapted to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } + +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) @@ -5173,6 +5241,7 @@ static ivas_error renderMcToBinaural( break; } } +#endif } if ( ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) || ( combinedOrientationEnabled @@ -5246,7 +5315,9 @@ static ivas_error renderMcToBinauralRoom( int16_t i; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; +#ifndef API_5MS int16_t subframe_idx; +#endif for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { @@ -5261,6 +5332,13 @@ static ivas_error renderMcToBinauralRoom( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compiling only, ToDo ext renderer needs to adapted to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) @@ -5269,6 +5347,7 @@ static ivas_error renderMcToBinauralRoom( break; } } +#endif } if ( ( mcInput->hReverb != NULL && outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && ( ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) || ( combinedOrientationEnabled && ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1 || inConfig == IVAS_REND_AUDIO_CONFIG_7_1 ) ) ) ) @@ -5341,7 +5420,9 @@ static ivas_error renderMcCustomLsToBinauralRoom( float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; +#ifndef API_5MS int16_t subframe_idx; +#endif push_wmops( "renderMcCustomLsToBinauralRoom" ); @@ -5356,6 +5437,13 @@ static ivas_error renderMcCustomLsToBinauralRoom( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compilin only, ToDo adapt renderer to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) @@ -5364,6 +5452,7 @@ static ivas_error renderMcCustomLsToBinauralRoom( break; } } +#endif } /* apply rotation */ @@ -5627,7 +5716,9 @@ static ivas_error renderSbaToBinaural( int16_t i; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; +#ifndef API_5MS int16_t subframe_idx; +#endif push_wmops( "renderSbaToBinaural" ); @@ -5640,6 +5731,13 @@ static ivas_error renderSbaToBinaural( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compiling only, ToDo ext renderer needs to adapted to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) @@ -5648,6 +5746,7 @@ static ivas_error renderSbaToBinaural( break; } } +#endif } /* apply rotation */ @@ -5703,7 +5802,9 @@ static ivas_error renderSbaToBinauralRoom( float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; +#ifndef API_5MS int16_t subframe_idx; +#endif tmpRotBuffer = outAudio; /* avoid compilation warning */ @@ -5718,6 +5819,13 @@ static ivas_error renderSbaToBinauralRoom( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { +#ifdef API_5MS + /* fix compiling only, ToDo ext renderer needs to adapted to 5ms */ + if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) + { + combinedOrientationEnabled = 1; + } +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) @@ -5726,6 +5834,7 @@ static ivas_error renderSbaToBinauralRoom( break; } } +#endif } /* apply rotation */ @@ -6193,8 +6302,14 @@ static ivas_error renderActiveInputsMasa( { for ( sf_idx = 0; sf_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; ++sf_idx ) { +#ifdef API_5MS + /* fix compilation only, ToDo adapt ext renderer to 5ms */ + pCurrentInput->decDummy->hHeadTrackData->Quaternion = hIvasRend->headRotData.headPositions[sf_idx]; + pCurrentInput->decDummy->hHeadTrackData->Pos = hIvasRend->headRotData.Pos[sf_idx]; +#else pCurrentInput->decDummy->hHeadTrackData->Quaternions[sf_idx] = hIvasRend->headRotData.headPositions[sf_idx]; pCurrentInput->decDummy->hHeadTrackData->Pos[sf_idx] = hIvasRend->headRotData.Pos[sf_idx]; +#endif } } diff --git a/scripts/self_test.py b/scripts/self_test.py index d7118832db..321f83419b 100755 --- a/scripts/self_test.py +++ b/scripts/self_test.py @@ -186,6 +186,13 @@ class SelfTest(IvasScriptsCommon.IvasScript): "--dectest", help="Test decoder binary (default:{})".format(default_dec_test), ) + self.parser.add_argument( + "--list_conditions", + "-l", + help="List all comditions in the parameter file", + action="store_true", + default=False, + ) if shutil.which("valgrind"): self.valgrind = [ "valgrind", @@ -858,6 +865,7 @@ class SelfTest(IvasScriptsCommon.IvasScript): # add the detailed results for this condition self.fail_results["detailedResults"].append(result_str) + self.fail_results["failed_modes"].append(mode) self.logger.progress( "Comparing conditions: {}/{} ({} running), {} failed ".format( self.stat["num_tests_done"], @@ -1140,6 +1148,11 @@ class SelfTest(IvasScriptsCommon.IvasScript): self.parse_args() + if self.args["list_conditions"] is True: + run_dict = self.parse_self_test_prm(self.args["test_prm"]) + for mode in run_dict.keys(): + self.logger.console(f"- {run_dict[mode]['cmd']['table_name']}") + return # create/update test vectors (export from SVN server if not existing) svn_action = None if not os.path.exists(TESTV_DIR): @@ -1540,6 +1553,7 @@ class SelfTest(IvasScriptsCommon.IvasScript): "corrupt_test_conditions": {"cnt": 0, "conditions": []}, "diff_nsamples_conditions": {"cnt": 0, "conditions": []}, "detailedResults": [], + "failed_modes":[], } self.run_pesq = self.args["pesq"] failed_ref_conditions = {} @@ -1948,6 +1962,15 @@ class SelfTest(IvasScriptsCommon.IvasScript): for l in r: self.logger.info(l) + self.logger.info("\n\n") + self.logger.info("Summary of all tests") + self.logger.info("---------------------\n") + for mode in run_dict.keys(): + if mode in self.fail_results["failed_modes"]: + self.logger.info(f"[FAIL] {run_dict[mode]['cmd']['table_name']}") + else: + self.logger.info(f"[OK] {run_dict[mode]['cmd']['table_name']}") + if __name__ == "__main__": if sys.version_info[0] < 3 or sys.version_info[1] < 7: -- GitLab From 43982584c91aefd85c71a829190c91d57238146a Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Tue, 20 Jun 2023 09:57:09 +0200 Subject: [PATCH 23/66] fix Linux comppile and instrumentation problems, clang-format --- lib_com/ivas_error.h | 10 +++++----- lib_com/options.h | 1 - lib_dec/ivas_binRenderer_internal.c | 6 +++--- lib_dec/ivas_dec.c | 2 +- lib_dec/ivas_ism_param_dec.c | 10 +++++----- lib_dec/ivas_sba_dec.c | 10 +++++----- lib_dec/jbm_pcmdsp_fifo.c | 2 +- lib_dec/lib_dec.c | 25 +++++++++---------------- lib_rend/ivas_stat_rend.h | 2 +- 9 files changed, 30 insertions(+), 38 deletions(-) diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 251be0d38a..63914dda53 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -86,6 +86,11 @@ typedef enum IVAS_ERR_ISM_INVALID_METADATA_VALUE, IVAS_ERR_INVALID_MASA_FORMAT_METADATA_FILE, IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED, +#ifdef API_5MS + IVAS_ERR_TSM_NOT_ENABLED, + IVAS_ERR_FETCH_SIZE_NO_MULTIPLE_OF_5MS, + IVAS_ERR_NEED_NEW_FRAME, +#endif #ifdef DEBUGGING IVAS_ERR_INVALID_FORCE_MODE, #ifdef DEBUG_AGC_ENCODER_CMD_OPTION @@ -94,11 +99,6 @@ typedef enum #ifdef VARIABLE_SPEED_DECODING IVAS_ERR_VS_FRAME_NEEDED, #endif -#ifdef API_5MS - IVAS_ERR_TSM_NOT_ENABLED, - IVAS_ERR_FETCH_SIZE_NO_MULTIPLE_OF_5MS, - IVAS_ERR_NEED_NEW_FRAME, -#endif #endif /*----------------------------------------* diff --git a/lib_com/options.h b/lib_com/options.h index c6d3a9c108..34ad115fe2 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -166,7 +166,6 @@ #define FIX_558_PLC_DISCONT /* FhG: issue 558: fix discontinuities in DFT Stereo when switching from TCX concealment to ACELP */ #define FIX_564 /* Nokia: Issue 564: Fix gains in JBM path for SBA with parametric binaural renderer */ #define FIX_566_2DIR_MASA_384K /* Nokia: Issued 566: Bugfix in 384k MASA metadata encoding of second direction */ -#define FIX_XXX_JITTER_SBA_BINAURAL_GAIN #define FIX_XXX_HEADTRACKER_INIT #define FIX_XXX_TDOBJRENDERER_INPUT #define FIX_XXX_ISM_SBA_ASAN diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index efc3b11215..02ef041bc1 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1127,10 +1127,10 @@ void ivas_binaural_cldfb_sf( *-------------------------------------------------------------------------*/ void ivas_binRenderer( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ #ifndef API_5MS - int16_t subframe_idx, /* i : subframe index */ + int16_t subframe_idx, /* i : subframe index */ #endif const int16_t numTimeSlots, /* i : number of time slots to render */ float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 1f588ac2cc..f9277264ea 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -761,4 +761,4 @@ ivas_error ivas_dec( pop_wmops(); return error; } -#endif \ No newline at end of file +#endif diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index f73b40b666..7a243dc266 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1392,11 +1392,11 @@ static void ivas_ism_param_dec_render_sf( *-------------------------------------------------------------------------*/ void ivas_param_ism_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ ) { int16_t ch, slots_to_render, first_sf, last_sf, subframe_idx; diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 50bb1b3ddf..23c4d90387 100755 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -471,11 +471,11 @@ ivas_error ivas_sba_dec_digest_tc( *-------------------------------------------------------------------*/ void ivas_sba_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ ) { int16_t slots_to_render, first_sf, last_sf, subframe_idx; diff --git a/lib_dec/jbm_pcmdsp_fifo.c b/lib_dec/jbm_pcmdsp_fifo.c index d3c93679fe..ad0a860944 100644 --- a/lib_dec/jbm_pcmdsp_fifo.c +++ b/lib_dec/jbm_pcmdsp_fifo.c @@ -268,4 +268,4 @@ uint16_t pcmdsp_fifo_nReadableSamplesPerChannel( { return h->size; } -#endif \ No newline at end of file +#endif diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 1e4dd48a60..5fbbee3df3 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -837,7 +837,6 @@ ivas_error IVAS_DEC_GetSamples( bool *needNewFrame /* indication that the decoder needs a new frame */ ) { - Decoder_Struct *st_ivas; ivas_error error; int16_t nOutSamplesElse, result, nSamplesToRender; uint16_t nSamplesRendered, nSamplesRendered_loop, l_ts, nTimeScalerOutSamples; @@ -850,7 +849,6 @@ ivas_error IVAS_DEC_GetSamples( { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - st_ivas = hIvasDec->st_ivas; if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) { @@ -1362,8 +1360,8 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ IVAS_VECTOR3 Pos /* i : listener position */ #else - IVAS_QUATERNION *orientation, /* i : head-tracking data, listener orientation */ - IVAS_VECTOR3 *Pos /* i : listener position */ + IVAS_QUATERNION *orientation, /* i : head-tracking data, listener orientation */ + IVAS_VECTOR3 *Pos /* i : listener position */ #endif ) { @@ -2062,20 +2060,12 @@ ivas_error IVAS_DEC_VoIP_GetSamples( DECODER_CONFIG_HANDLE hDecoderConfig; IVAS_DEC_VOIP *hVoIP; uint32_t extBufferedTime_ms, scale, maxScaling; -#ifndef API_5MS - uint16_t nTimeScalerOutSamples; -#endif JB4_DATAUNIT_HANDLE dataUnit; -#ifndef API_5MS - int16_t nOutSamplesElse; -#endif uint16_t extBufferedSamples; int16_t timeScalingDone; int16_t result; ivas_error error; int16_t nSamplesRendered; - uint16_t nSamplesTcsScaled; - uint8_t nTransportChannels; uint8_t nOutChannels; error = IVAS_ERR_OK; @@ -2086,8 +2076,6 @@ ivas_error IVAS_DEC_VoIP_GetSamples( timeScalingDone = 0; nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; - nTransportChannels = 0; - nSamplesTcsScaled = hVoIP->nSamplesFrame; nSamplesRendered = 0; if ( nSamplesPerChannel == 0 ) @@ -2625,8 +2613,8 @@ ivas_error IVAS_DEC_Flush( ) { ivas_error error; - IVAS_DEC_VOIP *hVoIP; #ifndef API_5MS + IVAS_DEC_VOIP *hVoIP; int16_t rendererPcmBuf[( MAX_OUTPUT_CHANNELS * L_FRAME_MAX * APA_MAX_SCALE ) / 100]; #endif uint16_t nSamplesToRender; @@ -2634,7 +2622,9 @@ ivas_error IVAS_DEC_Flush( error = IVAS_ERR_OK; +#ifndef API_5MS hVoIP = hIvasDec->hVoIP; +#endif #ifdef API_5MS *nSamplesFlushed = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); #else @@ -3533,15 +3523,18 @@ ivas_error IVAS_DEC_reconfigure( const uint16_t l_ts ) { +#ifndef API_5MS IVAS_DEC_VOIP *hVoIP; +#endif #ifdef API_5MS int16_t apa_buffer_size; #endif ivas_error error; - +#ifndef API_5MS hVoIP = hIvasDec->hVoIP; +#endif #ifdef API_5MS apa_buffer_size = hIvasDec->nSamplesFrame; #endif diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 14de5e7d55..bd0aa1151c 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -291,7 +291,7 @@ typedef struct ivas_external_orientation_struct int8_t enableExternalOrientation; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ int8_t enableRotationInterpolation; /* 0 - disable, 1 - enable */ int16_t numFramesToTargetOrientation; /* Number of frames until target orientation is reached */ - IVAS_QUATERNION Quaternion; /* External orientation in quaternions */ + IVAS_QUATERNION Quaternion; /* External orientation in quaternions */ #else int8_t enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ int8_t enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ -- GitLab From ccd8dbb85b39d0a1f1b30c18442d730b0bb6378e Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Tue, 20 Jun 2023 12:02:47 +0200 Subject: [PATCH 24/66] Fix msan issue in crend --- lib_com/options.h | 1 + lib_debug/debug.h | 19 ++++++++++++++++ lib_rend/ivas_crend.c | 23 +++++++++++++++++++- lib_rend/ivas_prot_rend.h | 3 +++ lib_rend/lib_rend.c | 46 ++++++++++++++++++++++++++++++++++----- 5 files changed, 85 insertions(+), 7 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 544100fb35..fe524ca6a1 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -160,6 +160,7 @@ #define FIX_XXX_ISM_SBA_ASAN #define API_5MS #define LIB_REND_API_5MS /* FhG: Adds 5ms framing capability to lib_rend */ +#define SGI_DBG /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_debug/debug.h b/lib_debug/debug.h index 3d59cb00a0..3cfe128d98 100644 --- a/lib_debug/debug.h +++ b/lib_debug/debug.h @@ -36,6 +36,9 @@ #include "options.h" #include #include +#ifdef SGI_DBG +#include +#endif #ifdef DEBUG_SBA #include "sba_debug.h" #endif @@ -97,6 +100,22 @@ int16_t dbgwrite( const char *const filename #endif ); +#ifdef SGI_DBG +inline static void sgi_dbgwrite( + const float *const buffer, + const int16_t count, + const char *const filename ) +{ + float tmp[960]; + + for ( int i = 0; i < count; ++i ) + { + tmp[i] = buffer[i] / INT16_MAX; + } + + dbgwrite( tmp, sizeof( float ), count, 1, filename ); +} +#endif void dbgwrite_mat_repeat( float *buffer, /* i : write buffer */ diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index e5bdd05ed1..2aa19296dd 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1332,9 +1332,18 @@ ivas_error ivas_rend_crendProcess( IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, float *output[], /* i/o: input/output audio channels */ - const int32_t output_Fs ) + const int32_t output_Fs +#ifdef LIB_REND_API_5MS + , + const int16_t num_subframes /* i : number of subframes to render */ +#endif +) { +#ifdef LIB_REND_API_5MS + int16_t i, subframe_idx, subframe_len; +#else int16_t i, subframe_idx, output_frame, subframe_len; +#endif int16_t nchan_out; float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; float *p_pcm_tmp[BINAURAL_CHANNELS]; @@ -1379,15 +1388,23 @@ ivas_error ivas_rend_crendProcess( return error; } +#ifdef LIB_REND_API_5MS + subframe_len = (int16_t) output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES; +#else output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); subframe_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; +#endif for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { p_pcm_tmp[i] = pcm_tmp[i]; } +#ifdef LIB_REND_API_5MS + for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) +#endif { if ( hDecoderConfig && combinedOrientationEnabled ) { @@ -1432,7 +1449,11 @@ ivas_error ivas_rend_crendProcess( /* move to output */ for ( i = 0; i < nchan_out; i++ ) { +#ifdef LIB_REND_API_5MS + mvr2r( pcm_tmp[i], output[i], num_subframes * subframe_len ); +#else mvr2r( pcm_tmp[i], output[i], output_frame ); +#endif } pop_wmops(); diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index d96f5228f2..812c6575ad 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -509,6 +509,9 @@ ivas_error ivas_rend_crendProcess( EFAP_HANDLE hEFAPdata, float *output[], /* i/o: input/output audio channels */ const int32_t output_Fs +#ifdef LIB_REND_API_5MS + ,const int16_t num_subframes /* i : number of subframes to render */ +#endif ); ivas_error ivas_rend_crendProcessSubframe( diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 158110012f..e8f4843ade 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -5078,7 +5078,12 @@ static ivas_error renderIsmToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpRendBuffer ); if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM_IR, - NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate +#ifdef LIB_REND_API_5MS + , + *ismInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -5493,10 +5498,19 @@ static ivas_error renderMcToBinaural( /* call CREND */ if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), - NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate +#ifdef LIB_REND_API_5MS + , + *mcInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel +#endif + ) ) != IVAS_ERR_OK ) { return error; } + +#ifdef SGI_DBG + sgi_dbgwrite( p_tmpRendBuffer[0], outAudio.config.numSamplesPerChannel, "res/p_tmpRendBuffer.pcm" ); +#endif } accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); @@ -5602,7 +5616,12 @@ static ivas_error renderMcToBinauralRoom( /* call CREND */ if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), - NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate +#ifdef LIB_REND_API_5MS + , + *mcInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -5712,7 +5731,12 @@ static ivas_error renderMcCustomLsToBinauralRoom( /* call CREND */ if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, - p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate +#ifdef LIB_REND_API_5MS + , + *mcInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -5996,7 +6020,12 @@ static ivas_error renderSbaToBinaural( /* call CREND */ if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( sbaInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), - NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate +#ifdef LIB_REND_API_5MS + , + *sbaInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -6097,7 +6126,12 @@ static ivas_error renderSbaToBinauralRoom( /* call CREND */ if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), - NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate +#ifdef LIB_REND_API_5MS + , + *sbaInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel +#endif + ) ) != IVAS_ERR_OK ) { return error; } -- GitLab From ed8d75678abbae0293c36c80be0c54ab0d50652c Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Tue, 20 Jun 2023 13:29:49 +0200 Subject: [PATCH 25/66] Fix msan issues --- lib_com/ivas_prot.h | 3 + lib_dec/ivas_dirac_dec.c | 8 +++ lib_rend/ivas_dirac_dec_binaural_functions.c | 7 +++ lib_rend/ivas_prot_rend.h | 3 + lib_rend/lib_rend.c | 62 +++++++++++++++----- 5 files changed, 67 insertions(+), 16 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 0a56c5081e..4c61d6bf7c 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3605,6 +3605,9 @@ void ivas_dirac_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t nchan_transport /* i : number of transport channels */ +#ifdef LIB_REND_API_5MS + ,const int16_t num_subframes /* i : number of subframes to render */ +#endif ); void ivas_dirac_dec_render( diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 19f99cad4e..6394a90566 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2205,6 +2205,10 @@ void ivas_dirac_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t nchan_transport /* i : number of transport channels */ +#ifdef LIB_REND_API_5MS + , + const int16_t num_subframes /* i : number of subframes to render */ +#endif ) { int16_t subframe_idx; @@ -2234,7 +2238,11 @@ void ivas_dirac_dec( ivas_dirac_dec_set_md_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); +#ifdef LIB_REND_API_5MS + for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) +#else for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) +#endif { ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL ); for ( n = 0; n < nchan_out; n++ ) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index c698ad1d3f..7456b9d7aa 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -423,6 +423,9 @@ void ivas_dirac_dec_binaural( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t nchan_transport /* i : number of transport channels */ +#ifdef LIB_REND_API_5MS + ,const int16_t num_subframes /* i : number of subframes to render */ +#endif ) { int16_t subframe; @@ -475,7 +478,11 @@ void ivas_dirac_dec_binaural( generate_masking_noise_lb_dirac( st->hFdCngDec->hFdCngCom, st_ivas->hTcBuffer->tc[nchan_transport], DEFAULT_JBM_CLDFB_TIMESLOTS, st->cna_dirac_flag && st->flag_cna ); } +#ifdef LIB_REND_API_5MS + for ( subframe = 0; subframe < num_subframes; subframe++ ) +#else for ( subframe = 0; subframe < MAX_PARAM_SPATIAL_SUBFRAMES; subframe++ ) +#endif { int16_t n_samples_sf = slot_size * st_ivas->hDirAC->subframe_nbslots[subframe]; diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 812c6575ad..2308848a40 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -154,6 +154,9 @@ void ivas_dirac_dec_binaural( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t nchan_transport /* i : number of transport channels */ +#ifdef LIB_REND_API_5MS + ,const int16_t num_subframes /* i : number of subframes to render */ +#endif ); void ivas_dirac_dec_binaural_render( diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index e8f4843ade..6a5656d0a4 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4925,6 +4925,16 @@ static ivas_error renderIsmToBinaural( return IVAS_ERR_OK; } +#ifdef LIB_REND_API_5MS +static int16_t num_subframes_in_buffer( const IVAS_REND_AudioBuffer *buffer, int32_t sampleRate ) +{ +#ifdef DEBUGGING + assert( buffer->config.numSamplesPerChannel % (sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES) == 0 ); +#endif + return buffer->config.numSamplesPerChannel / (sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES); +} +#endif + static ivas_error renderIsmToBinauralRoom( input_ism *ismInput, IVAS_REND_AudioBuffer outAudio ) @@ -5081,9 +5091,9 @@ static ivas_error renderIsmToBinauralRoom( NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate #ifdef LIB_REND_API_5MS , - *ismInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel + num_subframes_in_buffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) + ) ) != IVAS_ERR_OK ) { return error; } @@ -5501,9 +5511,9 @@ static ivas_error renderMcToBinaural( NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate #ifdef LIB_REND_API_5MS , - *mcInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel + num_subframes_in_buffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) + ) ) != IVAS_ERR_OK ) { return error; } @@ -5619,9 +5629,9 @@ static ivas_error renderMcToBinauralRoom( NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate #ifdef LIB_REND_API_5MS , - *mcInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel + num_subframes_in_buffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) + ) ) != IVAS_ERR_OK ) { return error; } @@ -5734,9 +5744,9 @@ static ivas_error renderMcCustomLsToBinauralRoom( p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate #ifdef LIB_REND_API_5MS , - *mcInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel + num_subframes_in_buffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) + ) ) != IVAS_ERR_OK ) { return error; } @@ -6023,9 +6033,9 @@ static ivas_error renderSbaToBinaural( NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate #ifdef LIB_REND_API_5MS , - *sbaInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel + num_subframes_in_buffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) + ) ) != IVAS_ERR_OK ) { return error; } @@ -6129,9 +6139,9 @@ static ivas_error renderSbaToBinauralRoom( NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate #ifdef LIB_REND_API_5MS , - *sbaInput->base.ctx.pOutSampleRate / FRAMES_PER_SEC / outAudio.config.numSamplesPerChannel + num_subframes_in_buffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) + ) ) != IVAS_ERR_OK ) { return error; } @@ -6300,11 +6310,21 @@ static void renderMasaToMc( if ( masaInput->decDummy->renderer_type == RENDERER_STEREO_PARAMETRIC ) { - ivas_dirac_dec_binaural( masaInput->decDummy, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, masaInput->base.inputBuffer.config.numChannels ); + ivas_dirac_dec_binaural( masaInput->decDummy, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, masaInput->base.inputBuffer.config.numChannels +#ifdef LIB_REND_API_5MS + , + num_subframes_in_buffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) +#endif + ); } else { - ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels ); + ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels +#ifdef LIB_REND_API_5MS + , + num_subframes_in_buffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) +#endif + ); } accumulate2dArrayToBuffer( tmpBuffer, &outAudio ); @@ -6321,7 +6341,12 @@ static void renderMasaToSba( copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer ); copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hDirAC ); - ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels ); + ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels +#ifdef LIB_REND_API_5MS + , + num_subframes_in_buffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) +#endif + ); accumulate2dArrayToBuffer( tmpBuffer, &outAudio ); @@ -6337,7 +6362,12 @@ static void renderMasaToBinaural( copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer ); copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hDirAC ); - ivas_dirac_dec_binaural( masaInput->decDummy, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, masaInput->base.inputBuffer.config.numChannels ); + ivas_dirac_dec_binaural( masaInput->decDummy, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, masaInput->base.inputBuffer.config.numChannels +#ifdef LIB_REND_API_5MS + , + num_subframes_in_buffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) +#endif + ); accumulate2dArrayToBuffer( tmpBuffer, &outAudio ); -- GitLab From e28b3e16c201fb0ce772b6a91e68f692ed9be873 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Tue, 20 Jun 2023 13:58:01 +0200 Subject: [PATCH 26/66] Fix memleak --- lib_com/options.h | 1 + lib_rend/lib_rend.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index fe524ca6a1..7eb54cd66d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -160,6 +160,7 @@ #define FIX_XXX_ISM_SBA_ASAN #define API_5MS #define LIB_REND_API_5MS /* FhG: Adds 5ms framing capability to lib_rend */ +#define LIB_REND_FIX_HRTFPARAMBIN_MEMLEAK #define SGI_DBG /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 6a5656d0a4..942b8c546f 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2803,6 +2803,12 @@ static void freeDecoderDummy( { free( pDecDummy->hCombinedOrientationData ); } +#ifdef LIB_REND_FIX_HRTFPARAMBIN_MEMLEAK + if ( pDecDummy->hHrtfParambin != NULL ) + { + free( pDecDummy->hHrtfParambin ); + } +#endif ivas_render_config_close( &pDecDummy->hRenderConfig ); -- GitLab From 0e6288ee6932bebed18fa425ff8e3f9a2fa24919 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 14:54:02 +0200 Subject: [PATCH 27/66] Make gitignoring ref executables more generic --- .gitignore | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 1829cde3a7..a0132de63b 100644 --- a/.gitignore +++ b/.gitignore @@ -48,9 +48,9 @@ tests/dut tests/ref scripts/testv/*_cut*.pcm # default reference binary name -IVAS_cod_ref -IVAS_dec_ref -IVAS_rend_ref +IVAS_cod_ref* +IVAS_dec_ref* +IVAS_rend_ref* # Python files that pop up when running scripts __pycache__/ -- GitLab From 100970f829e71212866d28f3c440dfcdcf3e2efc Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 15:00:45 +0200 Subject: [PATCH 28/66] Add ivas-razel-runner as submodule --- .gitmodules | 4 ++++ scripts/razel/ivas_razel_runner | 1 + 2 files changed, 5 insertions(+) create mode 100644 .gitmodules create mode 160000 scripts/razel/ivas_razel_runner diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..3ca7eb7d97 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "scripts/razel/ivas_razel_runner"] + path = scripts/razel/ivas_razel_runner + url = git@git01.iis.fhg.de:sgi/ivas-razel-runner.git + branch = rend diff --git a/scripts/razel/ivas_razel_runner b/scripts/razel/ivas_razel_runner new file mode 160000 index 0000000000..3096b12e17 --- /dev/null +++ b/scripts/razel/ivas_razel_runner @@ -0,0 +1 @@ +Subproject commit 3096b12e173137dfbafa9fe6658bdf461c6529f3 -- GitLab From 155596955316f0ab26d5435f337b3907b4c3ecc6 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 15:12:31 +0200 Subject: [PATCH 29/66] Update ivas-razel-runner --- scripts/razel/ivas_razel_runner | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/razel/ivas_razel_runner b/scripts/razel/ivas_razel_runner index 3096b12e17..9bc7a9da1c 160000 --- a/scripts/razel/ivas_razel_runner +++ b/scripts/razel/ivas_razel_runner @@ -1 +1 @@ -Subproject commit 3096b12e173137dfbafa9fe6658bdf461c6529f3 +Subproject commit 9bc7a9da1c25a9b2845f0a816f8427c6c611d83a -- GitLab From c1eb02d624c0d2e2c8e408420520b913605c7f14 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 15:15:28 +0200 Subject: [PATCH 30/66] Add test scripts for Razel --- scripts/razel/ivas_files_map_for_razel.py | 82 ++++++++++ scripts/razel/test_renderer_razel.py | 177 ++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 scripts/razel/ivas_files_map_for_razel.py create mode 100755 scripts/razel/test_renderer_razel.py diff --git a/scripts/razel/ivas_files_map_for_razel.py b/scripts/razel/ivas_files_map_for_razel.py new file mode 100644 index 0000000000..0939b0b53b --- /dev/null +++ b/scripts/razel/ivas_files_map_for_razel.py @@ -0,0 +1,82 @@ +from typing import Optional + +from ivas_razel_runner.include.core import ( + AudioConfig, + AudioFormat, + AudioSampleType, + CustomSpeakerLayoutFile, + File, + Files, + SceneDescriptionFile, + WavFile, +) +from ivas_razel_runner.include.ivas_rend import IvasRendInputFile + + +def in_file_for_audio_config(config: AudioConfig | SceneDescriptionFile) -> IvasRendInputFile: + if config == AudioFormat.MONO: + return WavFile("scripts/testv/stv48c.wav", True, 48000, 1, AudioSampleType.INT16) + if config == AudioFormat.STEREO: + return WavFile("scripts/testv/stvST48c.wav", True, 48000, 2, AudioSampleType.INT16) + if config == AudioFormat.ISM1: + return WavFile("scripts/testv/stv1ISM48s.wav", True, 48000, 1, AudioSampleType.INT16) + if config == AudioFormat.ISM2: + return WavFile("scripts/testv/stv2ISM48s.wav", True, 48000, 2, AudioSampleType.INT16) + if config == AudioFormat.ISM3: + return WavFile("scripts/testv/stv3ISM48s.wav", True, 48000, 3, AudioSampleType.INT16) + if config == AudioFormat.ISM4: + return WavFile("scripts/testv/stv4ISM48s.wav", True, 48000, 4, AudioSampleType.INT16) + if config == AudioFormat.MC_5_1: + return WavFile("scripts/testv/stv51MC48c.wav", True, 48000, 6, AudioSampleType.INT16) + if config == AudioFormat.MC_7_1: + return WavFile("scripts/testv/stv71MC48c.wav", True, 48000, 8, AudioSampleType.INT16) + if config == AudioFormat.MC_5_1_2: + return WavFile("scripts/testv/stv512MC48c.wav", True, 48000, 8, AudioSampleType.INT16) + if config == AudioFormat.MC_5_1_4: + return WavFile("scripts/testv/stv514MC48c.wav", True, 48000, 10, AudioSampleType.INT16) + if config == AudioFormat.MC_7_1_4: + return WavFile("scripts/testv/stv714MC48c.wav", True, 48000, 12, AudioSampleType.INT16) + if config == AudioFormat.FOA: + return WavFile("scripts/testv/stvFOA48c.wav", True, 48000, 4, AudioSampleType.INT16) + if config == AudioFormat.HOA2: + return WavFile("scripts/testv/stv2OA48c.wav", True, 48000, 9, AudioSampleType.INT16) + if config == AudioFormat.HOA3: + return WavFile("scripts/testv/stv3OA48c.wav", True, 48000, 16, AudioSampleType.INT16) + if config == AudioFormat.MASA1: + return WavFile("scripts/testv/stv2MASA1TC48c.wav", True, 48000, 1, AudioSampleType.INT16) + if config == AudioFormat.MASA2: + return WavFile("scripts/testv/stv2MASA2TC48c.wav", True, 48000, 2, AudioSampleType.INT16) + if isinstance(config, SceneDescriptionFile): + return config + if isinstance(config, CustomSpeakerLayoutFile): + # Assume test file is 5_1 for now + assert config.num_channels == AudioFormat.MC_5_1.num_channels + return WavFile("scripts/testv/stv51MC48c.wav", True, 48000, 6, AudioSampleType.INT16) + + raise RuntimeError(f"No input file for audio config {config}") + + +def md_files_for_audio_config(config: AudioConfig | SceneDescriptionFile) -> Optional[Files]: + if config == AudioFormat.ISM1: + return [File("scripts/testv/stvISM1.csv", True)] + if config == AudioFormat.ISM2: + return [File("scripts/testv/stvISM1.csv", True), File("scripts/testv/stvISM2.csv", True)] + if config == AudioFormat.ISM3: + return [ + File("scripts/testv/stvISM1.csv", True), + File("scripts/testv/stvISM2.csv", True), + File("scripts/testv/stvISM3.csv", True), + ] + if config == AudioFormat.ISM4: + return [ + File("scripts/testv/stvISM1.csv", True), + File("scripts/testv/stvISM2.csv", True), + File("scripts/testv/stvISM3.csv", True), + File("scripts/testv/stvISM4.csv", True), + ] + if config == AudioFormat.MASA1: + return [File("scripts/testv/stv2MASA1TC48c.met", True)] + if config == AudioFormat.MASA2: + return [File("scripts/testv/stv2MASA2TC48c.met", True)] + + return None diff --git a/scripts/razel/test_renderer_razel.py b/scripts/razel/test_renderer_razel.py new file mode 100755 index 0000000000..4a61dcfa57 --- /dev/null +++ b/scripts/razel/test_renderer_razel.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python3 + +import itertools +import logging +from pathlib import Path + +from ivas_files_map_for_razel import in_file_for_audio_config, md_files_for_audio_config +from ivas_razel_runner.include.core import ( + AudioFile, + AudioFormat, + CustomSpeakerLayoutFile, + File, + FileFormat, + SceneDescriptionFile, + WavDiffArgs, + WavFile, +) +from ivas_razel_runner.include.ivas_rend import IvasRend, IvasRendConfig, UnsupportedConfigWarning +from ivas_razel_runner.include.sox import Sox +from razel import Razel + +####################################################### + +BINAURAL_FORMATS = [ + AudioFormat.BINAURAL, + AudioFormat.BINAURAL_ROOM_IR, + AudioFormat.BINAURAL_ROOM_REVERB, +] +DEFAULT_CUSTOM_SPEAKER_LAYOUT = CustomSpeakerLayoutFile("scripts/ls_layouts/cicp6.txt", 6) +DEFAULT_SCENE_DESCRIPTION_FILE = SceneDescriptionFile("_dev/in/scene_ism2.txt", in_file_for_audio_config(AudioFormat.ISM2)) # type: ignore + +####################################################### + +INPUT_FORMATS = IvasRend.get_valid_in_audio_configs(DEFAULT_CUSTOM_SPEAKER_LAYOUT, DEFAULT_SCENE_DESCRIPTION_FILE) +OUTPUT_FORMATS = IvasRend.get_valid_out_audio_configs(DEFAULT_CUSTOM_SPEAKER_LAYOUT) +HEAD_ROTATION_FILES = [File("scripts/testv/headrot_case00_3000_q.csv", True), None] +SAMPLING_RATES = [48000] # TODO(sgi): use others + +####################################################### + +KNOWN_BROKEN_BASELINE_CONFIGS = [ + lambda config: config.in_audio_config == AudioFormat.MASA1, + lambda config: isinstance(config.in_audio_config, SceneDescriptionFile), + lambda config: config.in_audio_config == AudioFormat.MASA2 + and isinstance(config.out_audio_config, CustomSpeakerLayoutFile), + lambda config: config.in_audio_config == AudioFormat.MASA2 + and config.out_audio_config in [AudioFormat.BINAURAL_ROOM_IR, AudioFormat.BINAURAL_ROOM_REVERB], +] +KNOWN_CLIPPING_CONFIGS = [ + lambda config: config.in_audio_config + in [AudioFormat.MC_5_1_2, AudioFormat.MC_5_1_4, AudioFormat.MC_5_1, AudioFormat.MC_7_1_4, AudioFormat.MC_7_1] + and config.out_audio_config in [AudioFormat.MONO, AudioFormat.FOA, AudioFormat.HOA2, AudioFormat.HOA3], + lambda config: isinstance(config.in_audio_config, CustomSpeakerLayoutFile) + and config.out_audio_config + in [AudioFormat.MONO, AudioFormat.STEREO, AudioFormat.FOA, AudioFormat.HOA2, AudioFormat.HOA3], + lambda config: config.in_audio_config + in [ + AudioFormat.MC_5_1, + AudioFormat.MC_5_1_2, + AudioFormat.MC_5_1_4, + AudioFormat.MC_7_1, + AudioFormat.MC_7_1_4, + AudioFormat.FOA, + AudioFormat.HOA2, + AudioFormat.HOA3, + ] + and config.out_audio_config in BINAURAL_FORMATS, +] +NON_BE_TO_REF_WITH_5MS_FRAMING = [ + lambda config: config.in_audio_config + in [ + AudioFormat.ISM1, + AudioFormat.ISM2, + AudioFormat.ISM3, + AudioFormat.ISM4, + ] + and config.out_audio_config != AudioFormat.MONO, + lambda config: config.in_audio_config + in [ + AudioFormat.MASA1, + AudioFormat.MASA2, + ], +] +NON_BE_TO_REF_WITH_20MS_FRAMING = [ + lambda config: config.out_audio_config in BINAURAL_FORMATS and config.head_rotation is not None, +] + +####################################################### + + +def main(): + root_workspace = Path(__file__).parent / ".." / ".." + Razel.init(str(root_workspace)) + logging.basicConfig(level=logging.INFO) + + rend_cut = IvasRend(str(root_workspace / "IVAS_rend")) + rend_ref = IvasRend(str(root_workspace / "IVAS_rend_ref_5ms")) + sox = Sox("sox") + AudioFile.set_audio_conversion_tool(sox) + + # Define exceptional configs - order matters here! + rend_ref.add_support_check_for_nonstandard_configs(match_broken_config) + rend_cut.add_support_check_for_nonstandard_configs(match_broken_config) + rend_ref.add_support_check_for_nonstandard_configs( + # Reference can do binaural rendering with 20 ms frames + lambda config: config.out_audio_config in BINAURAL_FORMATS + and config.in_audio_config not in [AudioFormat.MONO, AudioFormat.STEREO] + and not config.framing_5ms + ) + + for in_format, out_format, head_rotation_file in itertools.product( + INPUT_FORMATS, OUTPUT_FORMATS, HEAD_ROTATION_FILES + ): + in_file = in_file_for_audio_config(in_format) + md_files = md_files_for_audio_config(in_format) + config = IvasRendConfig(in_format, out_format, md_files, head_rotation=head_rotation_file, framing_5ms=False) + + if any(match(config) for match in KNOWN_CLIPPING_CONFIGS): + config.input_gain = 0.2 + + # These files' length is not a multiple of 5ms, which causes different output lengths with 5ms framing on/off + if in_file.basename in ["stvFOA48c.wav", "stv2OA48c.wav", "stv3OA48c.wav"]: + assert isinstance(in_file, WavFile) + in_file = in_file.trim(0, 20) + + # Run REF 20ms + try: + out_20ms_ref = rend_ref.render(in_file, config, FileFormat.WAV) + except UnsupportedConfigWarning as e: + logging.info("%s Skipping %s", e.reason, config) + out_20ms_ref = None + + # Run CUT 20ms + try: + out_20ms_cut = rend_cut.render(in_file, config, FileFormat.WAV) + except UnsupportedConfigWarning as e: + logging.info("%s Skipping %s", e.reason, config) + out_20ms_cut = None + + if out_20ms_ref and out_20ms_cut: + if any(match(config) for match in NON_BE_TO_REF_WITH_20MS_FRAMING): + assert isinstance(out_20ms_cut, WavFile) + out_20ms_cut.should_not_equal(out_20ms_ref) + out_20ms_cut.should_be_similar_to(out_20ms_ref, WavDiffArgs(mld_max=0.01)) + else: + out_20ms_cut.should_equal(out_20ms_ref) + + # Run CUT 5ms + config.framing_5ms = True + try: + out_5ms_cut = rend_cut.render(in_file, config, FileFormat.WAV) + except UnsupportedConfigWarning as e: + logging.info("%s Skipping %s", e.reason, config) + out_5ms_cut = None + + if out_5ms_cut and out_20ms_ref: + if any(match(config) for match in NON_BE_TO_REF_WITH_5MS_FRAMING): + assert isinstance(out_5ms_cut, WavFile) + out_5ms_cut.should_not_equal(out_20ms_ref) + out_5ms_cut.should_be_similar_to( + out_20ms_ref, WavDiffArgs(mld_max=16) + ) # TODO(sgi): also test ISM with no metadata (should be BE) + else: + out_5ms_cut.should_equal(out_20ms_ref) + + Razel.instance().run(["exec", "-k"]) + + +def match_broken_config(config): + if any(match(config) for match in KNOWN_BROKEN_BASELINE_CONFIGS): + raise UnsupportedConfigWarning("Known broken config.") + + return False + + +if __name__ == "__main__": + main() -- GitLab From 0adf96d7ec9542a2cf470b33e0ad16085d8babb4 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 15:22:30 +0200 Subject: [PATCH 31/66] Add CI job for 5ms framing --- .gitlab-ci-custom.yml | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index f3453eedff..2ce99be7c9 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -368,6 +368,48 @@ renderer-msan: - report-junit.xml +renderer-5ms-framing-asan: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-cmake"] + stage: test + script: + # Build reference executable - 5ms framing disabled + - cp lib_com/options.h lib_com/options.h.bak + - sed -i '/API_5MS/d' lib_com/options.h + - mkdir cmake-build && cmake -B cmake-build . && cmake --build cmake-build -- -j + - cp cmake-build/IVAS_rend IVAS_rend_ref + + # Build test executable + - mv -f lib_com/options.h.bak lib_com/options.h + - cmake -B cmake-build -DCLANG=asan . && cmake --build cmake-build -- -j + - cp cmake-build/IVAS_rend . + + # Run Razel test + - scripts/razel/test_renderer_razel.py + +renderer-5ms-framing-msan: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-cmake"] + stage: test + script: + # Build reference executable - 5ms framing disabled + - cp lib_com/options.h lib_com/options.h.bak + - sed -i '/API_5MS/d' lib_com/options.h + - mkdir cmake-build && cmake -B cmake-build . && cmake --build cmake-build -- -j + - cp cmake-build/IVAS_rend IVAS_rend_ref + + # Build test executable + - mv -f lib_com/options.h.bak lib_com/options.h + - cmake -B cmake-build -DCLANG=msan . && cmake --build cmake-build -- -j + - cp cmake-build/IVAS_rend . + + # Run Razel test + - scripts/razel/test_renderer_razel.py + .merge-request-comparison-setup-codec: &merge-request-comparison-setup-codec ### build test binaries, initial clean for paranoia reasons - make clean -- GitLab From 963bc877016791fe92960e3589f9338aec2afdd3 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 15:27:32 +0200 Subject: [PATCH 32/66] [tmp] debug submodule --- .gitlab-ci-custom.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index 2ce99be7c9..9413dc8573 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -396,6 +396,7 @@ renderer-5ms-framing-msan: needs: ["build-codec-linux-cmake"] stage: test script: + - git submodule status # tmp DBG # Build reference executable - 5ms framing disabled - cp lib_com/options.h lib_com/options.h.bak - sed -i '/API_5MS/d' lib_com/options.h -- GitLab From 77f916883e1039e2157230dd098efa1b8599057b Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 15:30:27 +0200 Subject: [PATCH 33/66] [tmp] debug submodule --- .gitlab-ci-custom.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index 9413dc8573..f49a8fab71 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -396,7 +396,11 @@ renderer-5ms-framing-msan: needs: ["build-codec-linux-cmake"] stage: test script: - - git submodule status # tmp DBG + # tmp DBG + - git submodule status + - ls -la scripts/razel + - ls -la scripts/razel/ivas_razel_runner + # Build reference executable - 5ms framing disabled - cp lib_com/options.h lib_com/options.h.bak - sed -i '/API_5MS/d' lib_com/options.h -- GitLab From dba2648e8d82ec2ceabdc0aa608c22ce33abba75 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 15:34:00 +0200 Subject: [PATCH 34/66] Fix submodule checkout --- .gitlab-ci-custom.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index f49a8fab71..dc11fb76ac 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -21,6 +21,7 @@ variables: UPSTREAM_URL: "https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/" INTERNAL_TESTV_DIR: "/testv" INTERNAL_CI_REPO_CLONE_DIR: "ivas-internal-ci" + GIT_SUBMODULE_STRATEGY: recursive # This sets when pipelines are created. Jobs have more specific rules to restrict them. -- GitLab From 65413e7ff8a307605fa95732212322ed01f10898 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 15:35:48 +0200 Subject: [PATCH 35/66] Remove debugging code --- .gitlab-ci-custom.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index dc11fb76ac..2771d66f37 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -397,11 +397,6 @@ renderer-5ms-framing-msan: needs: ["build-codec-linux-cmake"] stage: test script: - # tmp DBG - - git submodule status - - ls -la scripts/razel - - ls -la scripts/razel/ivas_razel_runner - # Build reference executable - 5ms framing disabled - cp lib_com/options.h lib_com/options.h.bak - sed -i '/API_5MS/d' lib_com/options.h -- GitLab From 6000eb10b67d3573789a03aa4bdca937e69c11b9 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 16:23:29 +0200 Subject: [PATCH 36/66] Use relative submodule URL --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 3ca7eb7d97..192aece8ec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "scripts/razel/ivas_razel_runner"] path = scripts/razel/ivas_razel_runner - url = git@git01.iis.fhg.de:sgi/ivas-razel-runner.git + url = ../../sgi/ivas-razel-runner.git branch = rend -- GitLab From 3935354834f02888e9ac5d05db41703c45cf85bf Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 16:31:49 +0200 Subject: [PATCH 37/66] Try to fix search for clang --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8098dc1c68..ddd1816562 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,7 @@ if(UNIX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror-implicit-function-declaration -Wno-unused-parameter -Wno-unused-function") # CLANG if(CLANG) - find_program(clangBin NAMES /home/amm-archiv/soft/Linux/clang/current/bin/clang clang REQUIRED) + find_program(clangBin NAMES clang-13 /home/amm-archiv/soft/Linux/clang/current/bin/clang clang REQUIRED) set(CMAKE_C_COMPILER "${clangBin}" CACHE STRING "") if("${CLANG}" MATCHES "1" OR "${CLANG}" MATCHES "msan") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory") -- GitLab From 65c81e0533bc6603619e1d77fab4365bc9eba8c2 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 16:41:34 +0200 Subject: [PATCH 38/66] Revert "Try to fix search for clang" This reverts commit 3935354834f02888e9ac5d05db41703c45cf85bf. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ddd1816562..8098dc1c68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,7 @@ if(UNIX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror-implicit-function-declaration -Wno-unused-parameter -Wno-unused-function") # CLANG if(CLANG) - find_program(clangBin NAMES clang-13 /home/amm-archiv/soft/Linux/clang/current/bin/clang clang REQUIRED) + find_program(clangBin NAMES /home/amm-archiv/soft/Linux/clang/current/bin/clang clang REQUIRED) set(CMAKE_C_COMPILER "${clangBin}" CACHE STRING "") if("${CLANG}" MATCHES "1" OR "${CLANG}" MATCHES "msan") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory") -- GitLab From 6045854454599f4c7fe189b01496b26d36f66a8a Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 16:44:46 +0200 Subject: [PATCH 39/66] Fix building reference without sanitizer --- .gitlab-ci-custom.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index 2771d66f37..4eab63e877 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -379,12 +379,14 @@ renderer-5ms-framing-asan: # Build reference executable - 5ms framing disabled - cp lib_com/options.h lib_com/options.h.bak - sed -i '/API_5MS/d' lib_com/options.h - - mkdir cmake-build && cmake -B cmake-build . && cmake --build cmake-build -- -j - - cp cmake-build/IVAS_rend IVAS_rend_ref + - cmake -B cmake-build-ref . + - cmake --build cmake-build-ref -- -j + - cp cmake-build-ref/IVAS_rend IVAS_rend_ref # Build test executable - mv -f lib_com/options.h.bak lib_com/options.h - - cmake -B cmake-build -DCLANG=asan . && cmake --build cmake-build -- -j + - cmake -B cmake-build -DCLANG=asan . + - cmake --build cmake-build -- -j - cp cmake-build/IVAS_rend . # Run Razel test @@ -400,12 +402,14 @@ renderer-5ms-framing-msan: # Build reference executable - 5ms framing disabled - cp lib_com/options.h lib_com/options.h.bak - sed -i '/API_5MS/d' lib_com/options.h - - mkdir cmake-build && cmake -B cmake-build . && cmake --build cmake-build -- -j - - cp cmake-build/IVAS_rend IVAS_rend_ref + - cmake -B cmake-build-ref . + - cmake --build cmake-build-ref -- -j + - cp cmake-build-ref/IVAS_rend IVAS_rend_ref # Build test executable - mv -f lib_com/options.h.bak lib_com/options.h - - cmake -B cmake-build -DCLANG=msan . && cmake --build cmake-build -- -j + - cmake -B cmake-build -DCLANG=msan . + - cmake --build cmake-build -- -j - cp cmake-build/IVAS_rend . # Run Razel test -- GitLab From 9fba8fd275d248d1b173ca700d5ebc97055808b7 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 16:46:28 +0200 Subject: [PATCH 40/66] Fix reference binary name --- .gitlab-ci-custom.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index 4eab63e877..89cc0a6a4b 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -381,7 +381,7 @@ renderer-5ms-framing-asan: - sed -i '/API_5MS/d' lib_com/options.h - cmake -B cmake-build-ref . - cmake --build cmake-build-ref -- -j - - cp cmake-build-ref/IVAS_rend IVAS_rend_ref + - cp cmake-build-ref/IVAS_rend IVAS_rend_ref_5ms # Build test executable - mv -f lib_com/options.h.bak lib_com/options.h @@ -404,7 +404,7 @@ renderer-5ms-framing-msan: - sed -i '/API_5MS/d' lib_com/options.h - cmake -B cmake-build-ref . - cmake --build cmake-build-ref -- -j - - cp cmake-build-ref/IVAS_rend IVAS_rend_ref + - cp cmake-build-ref/IVAS_rend IVAS_rend_ref_5ms # Build test executable - mv -f lib_com/options.h.bak lib_com/options.h -- GitLab From 1866d6d87d90c2473651fda8adceb709d30db475 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 30 Jun 2023 17:02:08 +0200 Subject: [PATCH 41/66] Update ivas-razel-runner --- scripts/razel/ivas_razel_runner | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/razel/ivas_razel_runner b/scripts/razel/ivas_razel_runner index 9bc7a9da1c..9676b98c61 160000 --- a/scripts/razel/ivas_razel_runner +++ b/scripts/razel/ivas_razel_runner @@ -1 +1 @@ -Subproject commit 9bc7a9da1c25a9b2845f0a816f8427c6c611d83a +Subproject commit 9676b98c617410b94bbb61feb4fb2dc778887255 -- GitLab From b4c76218f33146a7da416f5a28e3ede9134b78dd Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 5 Jul 2023 11:11:42 +0200 Subject: [PATCH 42/66] fix synchronization of subframe information, fix compile problem when API_5MS is deactivated, memory optimization --- apps/decoder.c | 4 + lib_dec/ivas_dirac_dec.c | 4 + lib_dec/ivas_ism_param_dec.c | 19 +- lib_dec/ivas_jbm_dec.c | 712 +++++++++++++++++++++++++---------- lib_dec/ivas_mc_param_dec.c | 28 +- lib_dec/ivas_spar_decoder.c | 4 + lib_dec/lib_dec.c | 32 +- 7 files changed, 566 insertions(+), 237 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 71a296ed00..d7600702a8 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -421,8 +421,12 @@ int main( { #ifdef API_5MS if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) +#else +#ifndef VARIABLE_SPEED_DECODING + if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, IVAS_DEC_VOIP_MODE_VOIP, 100, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) +#endif #endif { fprintf( stderr, "\nCould not enable VOIP: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index f692ef1931..35cfeecfe3 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2141,6 +2141,10 @@ void ivas_dirac_dec_set_md_map( hDirAC->subframes_rendered = 0; ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hDirAC->subframe_nbslots, &hDirAC->nb_subframes ); +#ifdef API_5MS + st_ivas->hTcBuffer->nb_subframes = hDirAC->nb_subframes; + mvs2s( hDirAC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hDirAC->nb_subframes ); +#endif /* set mapping according to dirac_read_idx */ diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 7a243dc266..22c5822f30 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1263,14 +1263,23 @@ void ivas_param_ism_dec_digest_tc( *-----------------------------------------------------------------*/ for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { - float RealBuffer[CLDFB_NO_CHANNELS_MAX]; - float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) + { +#endif - cldfbAnalysis_ts( &( transport_channels_f[ch][hDirAC->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hDirAC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); - mvr2r( RealBuffer, &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], hDirAC->num_freq_bands ); - mvr2r( ImagBuffer, &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], hDirAC->num_freq_bands ); + float RealBuffer[CLDFB_NO_CHANNELS_MAX]; + float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; + cldfbAnalysis_ts( &( transport_channels_f[ch][hDirAC->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hDirAC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + mvr2r( RealBuffer, &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], hDirAC->num_freq_bands ); + mvr2r( ImagBuffer, &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], hDirAC->num_freq_bands ); +#ifdef API_5MS + } + ivas_param_ism_collect_slot( hDirAC, &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], ch, ref_power, cx_diag ); +#else ivas_param_ism_collect_slot( hDirAC, RealBuffer, ImagBuffer, ch, ref_power, cx_diag ); +#endif } } diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 42c834c70f..e36905725b 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -60,6 +60,9 @@ static void ivas_jbm_dec_copy_masa_meta_to_buffer( Decoder_Struct *st_ivas ); static void ivas_jbm_masa_sf_to_slot_map( Decoder_Struct *st_ivas, const int16_t nCldfbTs ); #endif +#ifdef API_5MS +static void ivas_jbm_dec_copy_tc_no_tsm( Decoder_Struct *st_ivas, float *tc[], const int16_t output_frame ); +#endif /*--------------------------------------------------------------------------* * ivas_jbm_dec_tc() @@ -497,9 +500,19 @@ ivas_error ivas_jbm_dec_tc( /*----------------------------------------------------------------* * Write IVAS transport channels *----------------------------------------------------------------*/ - - ivas_syn_output_f( p_output, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data ); - +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active == 1 ) + { +#endif + ivas_syn_output_f( p_output, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data ); +#ifdef API_5MS + } + else + { + /* directly copy to tc buffers */ + ivas_jbm_dec_copy_tc_no_tsm( st_ivas, p_output, output_frame ); + } +#endif /*----------------------------------------------------------------* * Common updates @@ -563,7 +576,18 @@ ivas_error ivas_jbm_dec_feed_tc_to_renderer( { p_data_f[n] = &data_f[n][0]; } - ivas_jbm_dec_copy_tc( st_ivas, nSamplesForRendering, nSamplesResidual, data, p_data_f ); +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) + { +#endif + ivas_jbm_dec_copy_tc( st_ivas, nSamplesForRendering, nSamplesResidual, data, p_data_f ); +#ifdef API_5MS + } + else + { + *nSamplesResidual = 0; + } +#endif n_render_timeslots = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) @@ -642,7 +666,12 @@ ivas_error ivas_jbm_dec_render( { int16_t n, nchan_out; int16_t nchan_transport; +#ifdef API_5MS + uint16_t nSamplesRenderedLocal; + float output[MAX_OUTPUT_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; /* 'float' buffer for output synthesis, MAX_OUTPUT_CHANNELS channels */ +#else float output[MAX_OUTPUT_CHANNELS][L_FRAME48k]; /* 'float' buffer for output synthesis, MAX_OUTPUT_CHANNELS channels */ +#endif int16_t nchan_remapped; int32_t output_Fs; AUDIO_CONFIG output_config; @@ -664,294 +693,478 @@ ivas_error ivas_jbm_dec_render( nchan_out = st_ivas->hDecoderConfig->nchan_out; nchan_transport = st_ivas->hTcBuffer->nchan_transport_jbm; output_config = st_ivas->hDecoderConfig->output_config; +#ifndef API_5MS nSamplesAskedLocal = nSamplesAsked + st_ivas->hTcBuffer->n_samples_discard; +#endif - for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) +#ifdef API_5MS + nSamplesRenderedLocal = 0; + *nSamplesRendered = 0; + while ( *nSamplesRendered < nSamplesAsked && st_ivas->hTcBuffer->n_samples_available > 0 ) { - p_output[n] = &output[n][0]; - } + nSamplesAskedLocal = st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered] * st_ivas->hTcBuffer->n_samples_granularity; +#endif - for ( n = 0; n < st_ivas->hTcBuffer->nchan_transport_internal; n++ ) - { - p_tc[n] = &st_ivas->hTcBuffer->tc[n][st_ivas->hTcBuffer->n_samples_rendered]; - } + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + { + p_output[n] = &output[n][0]; + } - /*----------------------------------------------------------------* - * Combine orientations - *----------------------------------------------------------------*/ + for ( n = 0; n < st_ivas->hTcBuffer->nchan_transport_internal; n++ ) + { + p_tc[n] = &st_ivas->hTcBuffer->tc[n][st_ivas->hTcBuffer->n_samples_rendered]; + } - if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, - st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) - { - return error; - } + /*----------------------------------------------------------------* + * Combine orientations + *----------------------------------------------------------------*/ - /*----------------------------------------------------------------* - * Rendering - *----------------------------------------------------------------*/ + if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, + st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( st_ivas->ivas_format == UNDEFINED_FORMAT ) - { - assert( 0 ); - } - else if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) - { + /*----------------------------------------------------------------* + * Rendering + *----------------------------------------------------------------*/ + + if ( st_ivas->ivas_format == UNDEFINED_FORMAT ) + { + assert( 0 ); + } + else if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) + { +#ifdef API_5MS + ivas_jbm_dec_tc_buffer_playout( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, p_output ); +#else ivas_jbm_dec_tc_buffer_playout( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output ); - } - else if ( st_ivas->ivas_format == STEREO_FORMAT ) - { - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_MC ) +#endif + } + else if ( st_ivas->ivas_format == STEREO_FORMAT ) { + /* Rendering */ + if ( st_ivas->renderer_type == RENDERER_MC ) + { +#ifdef API_5MS + nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); + ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, nSamplesRenderedLocal, p_tc, p_output ); +#else *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc, p_output ); +#endif + } } - } - else if ( st_ivas->ivas_format == ISM_FORMAT ) - { - /* Rendering */ - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + else if ( st_ivas->ivas_format == ISM_FORMAT ) { - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + /* Rendering */ + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { +#ifdef API_5MS + ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, st_ivas->nchan_transport, p_output ); +#else ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, st_ivas->nchan_transport, p_output ); - } - else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) - { +#endif + } + else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) + { +#ifdef API_5MS + nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); +#else *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); - pan_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; - pan_right = 1.f - pan_left; +#endif + pan_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; + pan_right = 1.f - pan_left; +#ifdef API_5MS + v_multc( st_ivas->hTcBuffer->tc[0], pan_right, output[1], nSamplesRenderedLocal ); + v_multc( st_ivas->hTcBuffer->tc[0], pan_left, output[0], nSamplesRenderedLocal ); +#else v_multc( st_ivas->hTcBuffer->tc[0], pan_right, output[1], *nSamplesRendered ); v_multc( st_ivas->hTcBuffer->tc[0], pan_left, output[0], *nSamplesRendered ); - } - else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - ivas_param_ism_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); - - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) +#endif + } + else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { - /* Convert CICP19 -> Ambisonics */ +#ifdef API_5MS + ivas_param_ism_dec_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, p_output ); +#else + ivas_param_ism_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); +#endif + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + /* Convert CICP19 -> Ambisonics */ +#ifdef API_5MS + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, nSamplesRenderedLocal, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#else ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#endif + } } } - } - else /* ISM_MODE_DISC */ - { + else /* ISM_MODE_DISC */ + { +#ifdef API_5MS + nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); +#else *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); +#endif - /* Loudspeaker or Ambisonics rendering */ - if ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) - { - /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */ + /* Loudspeaker or Ambisonics rendering */ + if ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */ +#ifdef API_5MS + ivas_ism_render_sf( st_ivas, p_output, nSamplesRenderedLocal ); +#else ivas_ism_render_sf( st_ivas, p_output, *nSamplesRendered ); - } - else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) - { - pan_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; - pan_right = 1.f - pan_left; +#endif + } + else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) + { + pan_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; + pan_right = 1.f - pan_left; +#ifdef API_5MS + v_multc( st_ivas->hTcBuffer->tc[0], pan_right, output[1], nSamplesRenderedLocal ); + v_multc( st_ivas->hTcBuffer->tc[0], pan_left, output[0], nSamplesRenderedLocal ); +#else v_multc( st_ivas->hTcBuffer->tc[0], pan_right, output[1], *nSamplesRendered ); v_multc( st_ivas->hTcBuffer->tc[0], pan_left, output[0], *nSamplesRendered ); - } - else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) - { - /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ +#endif + } + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ +#ifdef API_5MS + ivas_ism2sba_sf( st_ivas->hTcBuffer->tc, p_output, st_ivas->hIsmRendererData, st_ivas->nchan_transport, nSamplesRenderedLocal, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order ); +#else ivas_ism2sba_sf( st_ivas->hTcBuffer->tc, p_output, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order ); - } +#endif + } - /* Binaural rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) - { - if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + /* Binaural rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { - return error; +#ifdef API_5MS + if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, nSamplesRenderedLocal ) ) != IVAS_ERR_OK ) +#else + if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } } - } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) - { + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { +#ifdef API_5MS + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, + NULL, st_ivas->hTcBuffer, p_output, p_output, nSamplesRenderedLocal, output_Fs ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) - { - return error; - } +#endif + { + return error; + } +#ifdef API_5MS + ivas_binaural_add_LFE( st_ivas, nSamplesRenderedLocal, p_output, p_output ); +#else ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); - } +#endif + } #ifdef DEBUGGING - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) - { - ivas_binaural_cldfb_sf( st_ivas, *nSamplesRendered, p_output ); - } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { +#ifdef API_5MS + ivas_binaural_cldfb_sf( st_ivas, nSamplesRenderedLocal, p_output ); +#else + ivas_binaural_cldfb_sf( st_ivas, *nSamplesRendered, p_output ); #endif + } +#endif + } } - } - else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) - { - nchan_remapped = nchan_transport; - - /* Loudspeakers, Ambisonics or Binaural rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) { + nchan_remapped = nchan_transport; + + /* Loudspeakers, Ambisonics or Binaural rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { +#ifdef API_5MS + ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, nchan_remapped, p_output ); +#else ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ); - } - else if ( st_ivas->ivas_format == MASA_FORMAT ) - { - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) +#endif + } + else if ( st_ivas->ivas_format == MASA_FORMAT ) { - *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); - for ( n = 0; n < nchan_remapped; n++ ) + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) { +#ifdef API_5MS + nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); +#else + *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); +#endif + for ( n = 0; n < nchan_remapped; n++ ) + { +#ifdef API_5MS + mvr2r( st_ivas->hTcBuffer->tc[n] + st_ivas->hTcBuffer->n_samples_rendered, p_output[n], nSamplesRenderedLocal ); +#else mvr2r( st_ivas->hTcBuffer->tc[n] + st_ivas->hTcBuffer->n_samples_rendered, p_output[n], *nSamplesRendered ); - } +#endif + } +#ifdef API_5MS + if ( ( error = ivas_sba_linear_renderer( p_output, nSamplesRenderedLocal, nchan_remapped, output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_sba_linear_renderer( p_output, *nSamplesRendered, nchan_remapped, output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } + else if ( st_ivas->renderer_type == RENDERER_DIRAC ) { - return error; +#ifdef API_5MS + ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, p_output ); +#else + ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); +#endif } } - else if ( st_ivas->renderer_type == RENDERER_DIRAC ) + else /* SBA_MODE_SPAR */ { - ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); - } - } - else /* SBA_MODE_SPAR */ - { +#ifdef API_5MS + ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, p_output ); +#else ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); +#endif + } } - } - else if ( st_ivas->ivas_format == MC_FORMAT ) - { - if ( st_ivas->mc_mode == MC_MODE_MCT ) + else if ( st_ivas->ivas_format == MC_FORMAT ) { - *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); - if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == AUDIO_CONFIG_FOA || st_ivas->intern_config == AUDIO_CONFIG_HOA2 || st_ivas->intern_config == AUDIO_CONFIG_HOA3 ) ) + if ( st_ivas->mc_mode == MC_MODE_MCT ) { +#ifdef API_5MS + nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); +#else + *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); +#endif + if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == AUDIO_CONFIG_FOA || st_ivas->intern_config == AUDIO_CONFIG_HOA2 || st_ivas->intern_config == AUDIO_CONFIG_HOA3 ) ) + { +#ifdef API_5MS + ivas_mc2sba( st_ivas->hTransSetup, p_tc, p_output, nSamplesRenderedLocal, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); +#else ivas_mc2sba( st_ivas->hTransSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); - } +#endif + } - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) - { + /* Rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { +#ifdef API_5MS + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, + st_ivas->hCombinedOrientationData, + &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, p_tc, p_output, nSamplesRenderedLocal, output_Fs ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) - { - return error; - } - +#endif + { + return error; + } +#ifdef API_5MS + ivas_binaural_add_LFE( st_ivas, nSamplesRenderedLocal, st_ivas->hTcBuffer->tc, p_output ); +#else ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->tc, p_output ); - } - else if ( st_ivas->renderer_type == RENDERER_MC ) - { +#endif + } + else if ( st_ivas->renderer_type == RENDERER_MC ) + { +#ifdef API_5MS + nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); + ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, nSamplesRenderedLocal, p_tc, p_output ); +#else *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc, p_output ); - } - else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - ivas_mc2sba( st_ivas->hIntSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); - } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) - { - if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#endif + } + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { - return error; +#ifdef API_5MS + ivas_mc2sba( st_ivas->hIntSetup, p_tc, p_output, nSamplesRenderedLocal, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#else + ivas_mc2sba( st_ivas->hIntSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#endif } - + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { +#ifdef API_5MS + if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, nSamplesRenderedLocal ) ) != IVAS_ERR_OK ) +#else + if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } +#ifdef API_5MS + ivas_binaural_add_LFE( st_ivas, nSamplesRenderedLocal, st_ivas->hTcBuffer->tc, p_output ); +#else ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->tc, p_output ); +#endif + } } - } - else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) - { + else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) + { +#ifdef API_5MS + ivas_param_mc_dec_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, p_output ); +#else ivas_param_mc_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); - } +#endif + } #ifdef API_5MS - else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) - { - /* zero output for now, not yet implemented... */ - int16_t ch; - *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); - for ( ch = 0; ch < nchan_out; ch++ ) + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) { - set_zero( p_output[ch], *nSamplesRendered ); - } - } -#endif - else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) - { - int16_t offset = st_ivas->hDirAC->slots_rendered * st_ivas->hDirAC->slot_size; - nchan_remapped = st_ivas->nchan_transport; + /* zero output for now, not yet implemented... */ + int16_t ch; + nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ); + for ( ch = 0; ch < nchan_out; ch++ ) + { + set_zero( p_output[ch], nSamplesRenderedLocal ); + } } - else if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) /* rendering to CICPxx and Ambisonics */ +#endif + else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { - ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); + int16_t offset = st_ivas->hDirAC->slots_rendered * st_ivas->hDirAC->slot_size; + nchan_remapped = st_ivas->nchan_transport; - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { +#ifdef API_5MS + ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, nchan_remapped, p_output ); +#else + ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ); +#endif + } + else if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) /* rendering to CICPxx and Ambisonics */ { - /* we still need to copy the separate channel if available */ - if ( st_ivas->hOutSetup.separateChannelEnabled ) +#ifdef API_5MS + ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, p_output ); +#else + ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); +#endif + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { + /* we still need to copy the separate channel if available */ + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { +#ifdef API_5MS + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], nSamplesRenderedLocal ); +#else mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); - } - +#endif + } +#ifdef API_5MS + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, nSamplesRenderedLocal, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#else ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); - } - else if ( st_ivas->intern_config == AUDIO_CONFIG_5_1 && ( output_config == AUDIO_CONFIG_5_1_2 || output_config == AUDIO_CONFIG_5_1_4 || output_config == AUDIO_CONFIG_7_1 ) ) - { - for ( n = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; n < st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; n++ ) +#endif + } + else if ( st_ivas->intern_config == AUDIO_CONFIG_5_1 && ( output_config == AUDIO_CONFIG_5_1_2 || output_config == AUDIO_CONFIG_5_1_4 || output_config == AUDIO_CONFIG_7_1 ) ) { + for ( n = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; n < st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; n++ ) + { +#ifdef API_5MS + set_zero( output[n], nSamplesRenderedLocal ); +#else set_zero( output[n], *nSamplesRendered ); +#endif + } } } - } - /* copy discrete C and TD LFE from internal TC to output */ - if ( st_ivas->hOutSetup.separateChannelEnabled ) - { - if ( output_config == AUDIO_CONFIG_5_1 || output_config == AUDIO_CONFIG_7_1 || - output_config == AUDIO_CONFIG_5_1_4 || output_config == AUDIO_CONFIG_7_1_4 || - output_config == AUDIO_CONFIG_5_1_2 || ( output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) + /* copy discrete C and TD LFE from internal TC to output */ + if ( st_ivas->hOutSetup.separateChannelEnabled ) { + if ( output_config == AUDIO_CONFIG_5_1 || output_config == AUDIO_CONFIG_7_1 || + output_config == AUDIO_CONFIG_5_1_4 || output_config == AUDIO_CONFIG_7_1_4 || + output_config == AUDIO_CONFIG_5_1_2 || ( output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) + { +#ifdef API_5MS + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL] + offset, output[LFE_CHANNEL], nSamplesRenderedLocal ); + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], nSamplesRenderedLocal ); +#else mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL] + offset, output[LFE_CHANNEL], *nSamplesRendered ); mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); - } - else if ( output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 ) - { - /* Delay the separated channel to sync with the DirAC rendering */ +#endif + } + else if ( output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 ) + { + /* Delay the separated channel to sync with the DirAC rendering */ +#ifdef API_5MS + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], nSamplesRenderedLocal ); +#else mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#endif + } } } } - } - /*----------------------------------------------------------------* - * Write IVAS output channels - * - compensation for saturation - * - float to integer conversion - *----------------------------------------------------------------*/ + /*----------------------------------------------------------------* + * Write IVAS output channels + * - compensation for saturation + * - float to integer conversion + *----------------------------------------------------------------*/ +#ifdef API_5MS + st_ivas->hTcBuffer->n_samples_available -= nSamplesRenderedLocal; + st_ivas->hTcBuffer->n_samples_rendered += nSamplesRenderedLocal; +#else st_ivas->hTcBuffer->n_samples_available -= *nSamplesRendered; st_ivas->hTcBuffer->n_samples_rendered += *nSamplesRendered; +#endif - if ( st_ivas->hTcBuffer->n_samples_discard > 0 ) - { - for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + if ( st_ivas->hTcBuffer->n_samples_discard > 0 ) { - p_output[n] += st_ivas->hTcBuffer->n_samples_discard; - } + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + { + p_output[n] += st_ivas->hTcBuffer->n_samples_discard; + } +#ifdef API_5MS + nSamplesRenderedLocal -= st_ivas->hTcBuffer->n_samples_discard; +#else *nSamplesRendered -= st_ivas->hTcBuffer->n_samples_discard; - st_ivas->hTcBuffer->n_samples_discard = 0; - } +#endif + st_ivas->hTcBuffer->n_samples_discard = 0; + } +#ifdef API_5MS + ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, nSamplesRenderedLocal, st_ivas->BER_detect ); +#else ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, *nSamplesRendered, st_ivas->BER_detect ); +#endif + +#ifdef API_5MS +#ifdef DEBUGGING + st_ivas->noClipping += +#endif + ivas_syn_output( p_output, nSamplesRenderedLocal, nchan_out, data + *nSamplesRendered * nchan_out ); + *nSamplesRendered += nSamplesRenderedLocal; + } +#else #ifdef DEBUGGING st_ivas->noClipping += #endif ivas_syn_output( p_output, *nSamplesRendered, nchan_out, data ); - +#endif *nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available; pop_wmops(); @@ -1508,6 +1721,9 @@ static void ivas_jbm_dec_copy_tc( } hTcBuffer->n_samples_rendered = 0; +#ifdef API_5MS + hTcBuffer->subframes_rendered = 0; +#endif return; } @@ -1627,27 +1843,42 @@ ivas_error ivas_jbm_dec_tc_buffer_open( nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; nsamp_to_allocate += nchan_residual * n_samp_residual; - if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); - } - set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate ); - - offset = 0; - for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; - offset += n_samp_full; - } - for ( ; ch_idx < hTcBuffer->nchan_transport_internal; ch_idx++ ) +#ifdef API_5MS + if ( nsamp_to_allocate == 0 ) { - hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; - offset += n_samp_residual; + hTcBuffer->tc_buffer = NULL; + for ( ch_idx = 0; ch_idx < MAX_TRANSPORT_CHANNELS; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = NULL; + } } - for ( ; ch_idx < MAX_TRANSPORT_CHANNELS; ch_idx++ ) + else { - hTcBuffer->tc[ch_idx] = NULL; +#endif + if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); + } + set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate ); + + offset = 0; + for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; + offset += n_samp_full; + } + for ( ; ch_idx < hTcBuffer->nchan_transport_internal; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; + offset += n_samp_residual; + } + for ( ; ch_idx < MAX_TRANSPORT_CHANNELS; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = NULL; + } +#ifdef API_5MS } +#endif } st_ivas->hTcBuffer = hTcBuffer; @@ -1985,6 +2216,75 @@ TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( return buffer_mode; } +#ifdef API_5MS +void ivas_jbm_dec_copy_tc_no_tsm( + Decoder_Struct *st_ivas, + float *tc[], + const int16_t output_frame ) +{ + int16_t n_ch_full_copy; + int16_t n_ch_cldfb; + int16_t ch_idx; + DECODER_TC_BUFFER_HANDLE hTcBuffer; + + hTcBuffer = st_ivas->hTcBuffer; + hTcBuffer->n_samples_buffered = output_frame; + hTcBuffer->n_samples_available = hTcBuffer->n_samples_buffered; + n_ch_full_copy = min( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); + n_ch_cldfb = hTcBuffer->nchan_transport_jbm - hTcBuffer->nchan_buffer_full; + /* copy full tcs*/ + for ( ch_idx = 0; ch_idx < n_ch_full_copy; ch_idx++ ) + { + mvr2r( tc[ch_idx], st_ivas->hTcBuffer->tc[ch_idx], hTcBuffer->n_samples_buffered ); + } + + /* CLDFB ana for ParamMC/ParamISM */ + if ( n_ch_cldfb > 0 ) + { + float *cldfb_real_buffer; + float *cldfb_imag_buffer; + int16_t cldfb_ch, slot_idx, num_freq_bands; + + cldfb_real_buffer = NULL; + cldfb_imag_buffer = NULL; + num_freq_bands = 0; + + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + cldfb_real_buffer = st_ivas->hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc; + cldfb_imag_buffer = st_ivas->hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc; + num_freq_bands = st_ivas->hDirAC->num_freq_bands; + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + cldfb_real_buffer = st_ivas->hParamMC->Cldfb_RealBuffer_tc; + cldfb_imag_buffer = st_ivas->hParamMC->Cldfb_ImagBuffer_tc; + num_freq_bands = st_ivas->hParamMC->num_freq_bands; + } +#ifdef DEBUGGING + else + { + assert( 0 && "Residual (direct CLDFB transport channels) only possible for ParamMC/ParamISM!" ); + } +#endif + /* CLDFB Analysis*/ + + for ( cldfb_ch = 0; cldfb_ch < n_ch_cldfb; cldfb_ch++, ch_idx++ ) + { + for ( slot_idx = 0; slot_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; slot_idx++ ) + { + cldfbAnalysis_ts( &( tc[ch_idx][num_freq_bands * slot_idx] ), + &cldfb_real_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], + &cldfb_imag_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], + num_freq_bands, st_ivas->cldfbAnaDec[cldfb_ch] ); + } + } + } + hTcBuffer->n_samples_rendered = 0; + hTcBuffer->subframes_rendered = 0; +} +#endif + #ifdef FIX_470_MASA_JBM_EXT /*--------------------------------------------------------------------------* diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 16159ad005..6fe970d227 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1456,6 +1456,10 @@ void ivas_param_mc_dec_digest_tc( hParamMC->slots_rendered = 0; hParamMC->subframes_rendered = 0; ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); +#ifdef API_5MS + st_ivas->hTcBuffer->nb_subframes = hParamMC->nb_subframes; + mvs2s( hParamMC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hParamMC->nb_subframes ); +#endif ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); @@ -1468,18 +1472,24 @@ void ivas_param_mc_dec_digest_tc( /* slot loop for gathering the input data */ for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { - float RealBuffer[CLDFB_NO_CHANNELS_MAX]; - float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; - - /* CLDFB Analysis*/ - for ( ch = 0; ch < nchan_transport; ch++ ) +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) { - cldfbAnalysis_ts( &( transport_channels_f[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); +#endif + float RealBuffer[CLDFB_NO_CHANNELS_MAX]; + float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; - mvr2r( RealBuffer, &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); - mvr2r( ImagBuffer, &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); - } + /* CLDFB Analysis*/ + for ( ch = 0; ch < nchan_transport; ch++ ) + { + cldfbAnalysis_ts( &( transport_channels_f[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + mvr2r( RealBuffer, &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); + mvr2r( ImagBuffer, &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); + } +#ifdef API_5MS + } +#endif if ( slot_idx >= 2 * hParamMC->hMetadataPMC->attackIndex ) { ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], cx, cx_imag, hParamMC, nchan_transport ); diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index df60891a58..ce339e80cc 100755 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -1166,6 +1166,10 @@ void ivas_spar_dec_set_render_map( hSpar->subframes_rendered = 0; set_s( hSpar->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hSpar->subframe_nbslots, &hSpar->nb_subframes ); +#ifdef API_5MS + st_ivas->hTcBuffer->nb_subframes = hSpar->nb_subframes; + mvs2s( hSpar->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hSpar->nb_subframes ); +#endif ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, 1, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hSpar->render_to_md_map ); return; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 5fbbee3df3..d33c55deff 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3662,17 +3662,16 @@ ivas_error IVAS_DEC_reconfigure( } } #ifdef API_5MS - } -#endif -#ifdef API_5MS - if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) + if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); - } + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } - set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); -#else + set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); + } +#endif +#ifndef API_5MS if ( ( hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ) ) == NULL ) { @@ -3696,17 +3695,16 @@ ivas_error IVAS_DEC_reconfigure( } #ifdef API_5MS apa_buffer_size = APA_BUF_PER_CHANNEL; + free( hIvasDec->apaExecBuffer ); + if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } + set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); } #endif /* realloc apa_exe_buffer */ -#ifdef API_5MS - free( hIvasDec->apaExecBuffer ); - if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); - } - set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); -#else +#ifndef API_5MS free( hIvasDec->hVoIP->apaExecBuffer ); if ( ( hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ) ) == NULL ) { -- GitLab From ba524608b434a48d60d63f018acef51c2a62d1b6 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 5 Jul 2023 16:33:07 +0200 Subject: [PATCH 43/66] fix JBM problems --- lib_dec/ivas_jbm_dec.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index e36905725b..e5c6955bcf 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -702,6 +702,7 @@ ivas_error ivas_jbm_dec_render( *nSamplesRendered = 0; while ( *nSamplesRendered < nSamplesAsked && st_ivas->hTcBuffer->n_samples_available > 0 ) { + uint16_t subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; nSamplesAskedLocal = st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered] * st_ivas->hTcBuffer->n_samples_granularity; #endif @@ -749,6 +750,7 @@ ivas_error ivas_jbm_dec_render( #ifdef API_5MS nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, nSamplesRenderedLocal, p_tc, p_output ); + st_ivas->hTcBuffer->subframes_rendered++; #else *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc, p_output ); @@ -802,6 +804,9 @@ ivas_error ivas_jbm_dec_render( #endif } } +#ifdef API_5MS + st_ivas->hTcBuffer->subframes_rendered++; +#endif } else /* ISM_MODE_DISC */ { @@ -883,6 +888,11 @@ ivas_error ivas_jbm_dec_render( ivas_binaural_cldfb_sf( st_ivas, *nSamplesRendered, p_output ); #endif } +#endif +#ifdef API_5MS + { + st_ivas->hTcBuffer->subframes_rendered++; + } #endif } } @@ -943,6 +953,9 @@ ivas_error ivas_jbm_dec_render( ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); #endif } +#ifdef API_5MS + st_ivas->hTcBuffer->subframes_rendered++; +#endif } else if ( st_ivas->ivas_format == MC_FORMAT ) { @@ -1158,6 +1171,8 @@ ivas_error ivas_jbm_dec_render( #endif ivas_syn_output( p_output, nSamplesRenderedLocal, nchan_out, data + *nSamplesRendered * nchan_out ); *nSamplesRendered += nSamplesRenderedLocal; + + st_ivas->hTcBuffer->subframes_rendered = subframes_rendered+1; } #else #ifdef DEBUGGING -- GitLab From 01319e9f01c6ca6e3e2735bff97465439cda62c3 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 6 Jul 2023 10:36:54 +0200 Subject: [PATCH 44/66] fix EVS decoding --- lib_com/ivas_prot.h | 7 +++++++ lib_dec/ivas_jbm_dec.c | 4 ---- lib_dec/lib_dec.c | 8 ++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 9d7e6b5806..994c6ac747 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -827,6 +827,13 @@ int16_t ivas_jbm_dec_get_num_tc_channels( Decoder_Struct *st_ivas /* i : IVAS decoder handle */ ); +#ifdef API_5MS +void ivas_jbm_dec_copy_tc_no_tsm( + Decoder_Struct *st_ivas, + float *tc[], + const int16_t output_frame ); +#endif + #ifdef FIX_470_MASA_JBM_EXT void ivas_jbm_dec_get_md_map_even_spacing( const int16_t default_len, /* i : default frame length in metadata slots */ diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index e5c6955bcf..d40cc7c1df 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -60,10 +60,6 @@ static void ivas_jbm_dec_copy_masa_meta_to_buffer( Decoder_Struct *st_ivas ); static void ivas_jbm_masa_sf_to_slot_map( Decoder_Struct *st_ivas, const int16_t nCldfbTs ); #endif -#ifdef API_5MS -static void ivas_jbm_dec_copy_tc_no_tsm( Decoder_Struct *st_ivas, float *tc[], const int16_t output_frame ); -#endif - /*--------------------------------------------------------------------------* * ivas_jbm_dec_tc() * diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index d33c55deff..8581b4cb46 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3259,6 +3259,14 @@ static ivas_error evs_dec_main( v_multc( output[0], mixer_left, output[0], nOutSamples ); } + +#ifdef API_5MS + if ( !st_ivas->hDecoderConfig->tsm_active ) + { + ivas_jbm_dec_copy_tc_no_tsm( st_ivas, p_output, nOutSamples ); + } + else +#endif if ( floatBuf != NULL ) { /* BE workaround */ -- GitLab From 4eabe5a3268b4f0620529424934a0cbc235ef18b Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 7 Jul 2023 08:10:22 +0200 Subject: [PATCH 45/66] fix ParamISM tx energy adjustment, fix tc offsets --- lib_com/ivas_prot.h | 9 ++++ lib_dec/ivas_ism_param_dec.c | 90 ++++++++++++++++++++++++++++++++++-- lib_dec/ivas_jbm_dec.c | 18 +++----- 3 files changed, 103 insertions(+), 14 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 994c6ac747..95b5a28cad 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1074,6 +1074,15 @@ void ivas_param_ism_dec_digest_tc( float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ ); +#ifdef API_5MS +void ivas_ism_param_dec_tc_gain_ajust( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamples, /* i : number of samples to be compensate */ + const uint16_t nFadeLength, /* i : length of the crossfade in samples */ + float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ +); +#endif + void ivas_param_ism_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 22c5822f30..1172ef536f 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -748,8 +748,12 @@ void ivas_param_ism_dec( int32_t ivas_total_brate; #ifdef FIX_549_DMX_GAIN int16_t output_frame; +#ifndef API_5MS float gain, ene_tc, ene_sum, grad; float last_gain; +#else + float *p_tc[PARAM_ISM_MAX_DMX]; +#endif #endif float ref_power[CLDFB_NO_CHANNELS_MAX]; float cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; @@ -775,9 +779,16 @@ void ivas_param_ism_dec( hDirAC = st_ivas->hDirAC; assert( hDirAC ); #ifdef FIX_549_DMX_GAIN +#ifdef API_5MS + for ( i = 0; i < PARAM_ISM_MAX_DMX; i++ ) + { + p_tc[i] = output_f[i]; + } +#else ene_tc = 0.0f; ene_sum = 0.0f; last_gain = st_ivas->hDirAC->hParamIsm->last_dmx_gain; +#endif output_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); #endif @@ -862,7 +873,9 @@ void ivas_param_ism_dec( } } } - +#ifdef API_5MS + ivas_ism_param_dec_tc_gain_ajust( st_ivas, output_frame, output_frame / 2, p_tc ); +#else #ifdef FIX_549_DMX_GAIN /* Energy Compensation */ for ( i = 0; i < output_frame; i++ ) @@ -898,7 +911,7 @@ void ivas_param_ism_dec( } st_ivas->hDirAC->hParamIsm->last_dmx_gain = gain; #endif - +#endif for ( ch = 0; ch < nchan_transport; ch++ ) { /*-----------------------------------------------------------------* @@ -1114,10 +1127,12 @@ void ivas_param_ism_dec_digest_tc( int16_t ch, nchan_transport, nchan_out, nchan_out_woLFE, i; int16_t slot_idx, bin_idx; int32_t ivas_total_brate; +#ifndef API_5MS #ifdef FIX_549_DMX_GAIN int16_t output_frame; float gain, ene_tc, ene_sum, grad; float last_gain; +#endif #endif float ref_power[CLDFB_NO_CHANNELS_MAX]; float cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; @@ -1128,11 +1143,13 @@ void ivas_param_ism_dec_digest_tc( /* Initialization */ hDirAC = st_ivas->hDirAC; assert( hDirAC ); +#ifndef API_5MS #ifdef FIX_549_DMX_GAIN ene_tc = 0.0f; ene_sum = 0.0f; last_gain = st_ivas->hDirAC->hParamIsm->last_dmx_gain; output_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); +#endif #endif nchan_transport = st_ivas->nchan_transport; @@ -1219,7 +1236,12 @@ void ivas_param_ism_dec_digest_tc( } } } - +#ifdef API_5MS + if ( st_ivas->hDecoderConfig->tsm_active ) + { + ivas_ism_param_dec_tc_gain_ajust( st_ivas, nCldfbSlots * st_ivas->hDirAC->num_freq_bands, (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( 2 * FRAMES_PER_SEC ) ), transport_channels_f ); + } +#else #ifdef FIX_549_DMX_GAIN /* Energy Compensation */ for ( i = 0; i < output_frame; i++ ) @@ -1254,6 +1276,7 @@ void ivas_param_ism_dec_digest_tc( } } st_ivas->hDirAC->hParamIsm->last_dmx_gain = gain; +#endif #endif for ( ch = 0; ch < nchan_transport; ch++ ) @@ -1298,6 +1321,67 @@ void ivas_param_ism_dec_digest_tc( } +#ifdef API_5MS +/*-------------------------------------------------------------------------* + * ivas_ism_param_dec_tc_gain_ajust() + * + * + *-------------------------------------------------------------------------*/ + +void ivas_ism_param_dec_tc_gain_ajust( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamples, /* i : number of samples to be compensate */ + const uint16_t nFadeLength, /* i : length of the crossfade in samples */ + float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ +) + +{ + int16_t i; + float gain, ene_tc, ene_sum, grad; + float last_gain; + + ene_tc = 0.0f; + ene_sum = 0.0f; + last_gain = st_ivas->hDirAC->hParamIsm->last_dmx_gain; + + + for ( i = 0; i < nSamples; i++ ) + { + ene_tc += transport_channels_f[0][i] * transport_channels_f[0][i] + transport_channels_f[1][i] * transport_channels_f[1][i]; // L*L + R*R + ene_sum += ( transport_channels_f[0][i] + transport_channels_f[1][i] ) * ( transport_channels_f[0][i] + transport_channels_f[1][i] ); // (L+R)*(L+R) + } + gain = sqrtf( ene_tc / ( ene_sum + EPSILON ) ); + if ( st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame > 1 ) + { + /* Smoothing */ + gain = 0.75f * gain + 0.25f * last_gain; + /* 10ms ramp */ + grad = ( gain - last_gain ) / (float) nFadeLength; /* slope between two consecutive gains, 480 samples length */ + for ( i = 0; i < ( nFadeLength ); i++ ) + { + transport_channels_f[0][i] *= ( last_gain + i * grad ); + transport_channels_f[1][i] *= ( last_gain + i * grad ); + } + for ( ; i < nSamples; i++ ) + { + transport_channels_f[0][i] *= gain; + transport_channels_f[1][i] *= gain; + } + } + else + { + for ( i = 0; i < nSamples; i++ ) + { + transport_channels_f[0][i] *= gain; + transport_channels_f[1][i] *= gain; + } + } + st_ivas->hDirAC->hParamIsm->last_dmx_gain = gain; + + return; +} +#endif + /*-------------------------------------------------------------------------* * ivas_ism_param_dec_render_sf() * diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index d40cc7c1df..ee98db24ee 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -776,8 +776,8 @@ ivas_error ivas_jbm_dec_render( pan_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; pan_right = 1.f - pan_left; #ifdef API_5MS - v_multc( st_ivas->hTcBuffer->tc[0], pan_right, output[1], nSamplesRenderedLocal ); - v_multc( st_ivas->hTcBuffer->tc[0], pan_left, output[0], nSamplesRenderedLocal ); + v_multc( p_tc[0], pan_right, output[1], nSamplesRenderedLocal ); + v_multc( p_tc[0], pan_left, output[0], nSamplesRenderedLocal ); #else v_multc( st_ivas->hTcBuffer->tc[0], pan_right, output[1], *nSamplesRendered ); v_multc( st_ivas->hTcBuffer->tc[0], pan_left, output[0], *nSamplesRendered ); @@ -827,8 +827,8 @@ ivas_error ivas_jbm_dec_render( pan_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; pan_right = 1.f - pan_left; #ifdef API_5MS - v_multc( st_ivas->hTcBuffer->tc[0], pan_right, output[1], nSamplesRenderedLocal ); - v_multc( st_ivas->hTcBuffer->tc[0], pan_left, output[0], nSamplesRenderedLocal ); + v_multc( p_tc[0], pan_right, output[1], nSamplesRenderedLocal ); + v_multc( p_tc[0], pan_left, output[0], nSamplesRenderedLocal ); #else v_multc( st_ivas->hTcBuffer->tc[0], pan_right, output[1], *nSamplesRendered ); v_multc( st_ivas->hTcBuffer->tc[0], pan_left, output[0], *nSamplesRendered ); @@ -884,11 +884,6 @@ ivas_error ivas_jbm_dec_render( ivas_binaural_cldfb_sf( st_ivas, *nSamplesRendered, p_output ); #endif } -#endif -#ifdef API_5MS - { - st_ivas->hTcBuffer->subframes_rendered++; - } #endif } } @@ -987,7 +982,7 @@ ivas_error ivas_jbm_dec_render( return error; } #ifdef API_5MS - ivas_binaural_add_LFE( st_ivas, nSamplesRenderedLocal, st_ivas->hTcBuffer->tc, p_output ); + ivas_binaural_add_LFE( st_ivas, nSamplesRenderedLocal, p_tc, p_output ); #else ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->tc, p_output ); #endif @@ -1021,7 +1016,7 @@ ivas_error ivas_jbm_dec_render( return error; } #ifdef API_5MS - ivas_binaural_add_LFE( st_ivas, nSamplesRenderedLocal, st_ivas->hTcBuffer->tc, p_output ); + ivas_binaural_add_LFE( st_ivas, nSamplesRenderedLocal, p_tc, p_output ); #else ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->tc, p_output ); #endif @@ -2265,6 +2260,7 @@ void ivas_jbm_dec_copy_tc_no_tsm( cldfb_real_buffer = st_ivas->hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc; cldfb_imag_buffer = st_ivas->hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc; num_freq_bands = st_ivas->hDirAC->num_freq_bands; + ivas_ism_param_dec_tc_gain_ajust( st_ivas, output_frame, output_frame / 2, tc ); } else if ( st_ivas->ivas_format == MC_FORMAT ) { -- GitLab From 1dd207fb4b84d7428b2eac9cd5369c63ed6855a8 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 7 Jul 2023 11:14:12 +0200 Subject: [PATCH 46/66] Move second step mem optim (renderer output channels buffer size) since it is expected to be non-BE to selection test (cause: different limiting). Add NONBE_FIX_589_JBM_TC_OFFSETS purely for BE check. Add DISABLE_LIMITER switch to be able to better check BE. --- lib_com/options.h | 6 +- lib_dec/ivas_dec.c | 3 +- lib_dec/ivas_jbm_dec.c | 127 +++++++++++++++++++++++++---------------- 3 files changed, 84 insertions(+), 52 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 34ad115fe2..e176ad5d3e 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -129,7 +129,7 @@ #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*/ #endif /* #################### End DEBUGGING switches ############################ */ @@ -169,7 +169,11 @@ #define FIX_XXX_HEADTRACKER_INIT #define FIX_XXX_TDOBJRENDERER_INPUT #define FIX_XXX_ISM_SBA_ASAN +#define NONBE_FIX_589_JBM_TC_OFFSETS #define API_5MS +#ifdef API_5MS +/*#define JITTER_MEM_OPTIM_RENDERING*/ +#endif /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index f9277264ea..59a800fa5b 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -721,8 +721,9 @@ ivas_error ivas_dec( * - compensation for saturation * - float to integer conversion *----------------------------------------------------------------*/ - +#ifndef DISABLE_LIMITER ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, output_frame, st_ivas->BER_detect ); +#endif #ifdef DEBUGGING st_ivas->noClipping += diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index ee98db24ee..cfa2c3fe1c 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -662,7 +662,7 @@ ivas_error ivas_jbm_dec_render( { int16_t n, nchan_out; int16_t nchan_transport; -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING uint16_t nSamplesRenderedLocal; float output[MAX_OUTPUT_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; /* 'float' buffer for output synthesis, MAX_OUTPUT_CHANNELS channels */ #else @@ -689,11 +689,11 @@ ivas_error ivas_jbm_dec_render( nchan_out = st_ivas->hDecoderConfig->nchan_out; nchan_transport = st_ivas->hTcBuffer->nchan_transport_jbm; output_config = st_ivas->hDecoderConfig->output_config; -#ifndef API_5MS +#ifndef JITTER_MEM_OPTIM_RENDERING nSamplesAskedLocal = nSamplesAsked + st_ivas->hTcBuffer->n_samples_discard; #endif -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING nSamplesRenderedLocal = 0; *nSamplesRendered = 0; while ( *nSamplesRendered < nSamplesAsked && st_ivas->hTcBuffer->n_samples_available > 0 ) @@ -732,7 +732,7 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_jbm_dec_tc_buffer_playout( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, p_output ); #else ivas_jbm_dec_tc_buffer_playout( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output ); @@ -743,7 +743,7 @@ ivas_error ivas_jbm_dec_render( /* Rendering */ if ( st_ivas->renderer_type == RENDERER_MC ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, nSamplesRenderedLocal, p_tc, p_output ); st_ivas->hTcBuffer->subframes_rendered++; @@ -760,7 +760,7 @@ ivas_error ivas_jbm_dec_render( { if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, st_ivas->nchan_transport, p_output ); #else ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, st_ivas->nchan_transport, p_output ); @@ -768,24 +768,29 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); #else *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); #endif pan_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; pan_right = 1.f - pan_left; -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING v_multc( p_tc[0], pan_right, output[1], nSamplesRenderedLocal ); v_multc( p_tc[0], pan_left, output[0], nSamplesRenderedLocal ); +#else +#ifdef NONBE_FIX_589_JBM_TC_OFFSETS + v_multc( p_tc[0], pan_right, output[1], *nSamplesRendered ); + v_multc( p_tc[0], pan_left, output[0], *nSamplesRendered ); #else v_multc( st_ivas->hTcBuffer->tc[0], pan_right, output[1], *nSamplesRendered ); v_multc( st_ivas->hTcBuffer->tc[0], pan_left, output[0], *nSamplesRendered ); +#endif #endif } else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_param_ism_dec_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, p_output ); #else ivas_param_ism_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); @@ -793,20 +798,20 @@ ivas_error ivas_jbm_dec_render( if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { /* Convert CICP19 -> Ambisonics */ -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, nSamplesRenderedLocal, st_ivas->hOutSetup.ambisonics_order, 0.f ); #else ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); #endif } } -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING st_ivas->hTcBuffer->subframes_rendered++; #endif } else /* ISM_MODE_DISC */ { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); #else *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); @@ -816,7 +821,7 @@ ivas_error ivas_jbm_dec_render( if ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */ -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_ism_render_sf( st_ivas, p_output, nSamplesRenderedLocal ); #else ivas_ism_render_sf( st_ivas, p_output, *nSamplesRendered ); @@ -826,18 +831,24 @@ ivas_error ivas_jbm_dec_render( { pan_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; pan_right = 1.f - pan_left; -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING v_multc( p_tc[0], pan_right, output[1], nSamplesRenderedLocal ); v_multc( p_tc[0], pan_left, output[0], nSamplesRenderedLocal ); #else +#ifdef NONBE_FIX_589_JBM_TC_OFFSETS + v_multc( p_tc[0], pan_right, output[1], *nSamplesRendered ); + v_multc( p_tc[0], pan_left, output[0], *nSamplesRendered ); +#else + v_multc( st_ivas->hTcBuffer->tc[0], pan_right, output[1], *nSamplesRendered ); v_multc( st_ivas->hTcBuffer->tc[0], pan_left, output[0], *nSamplesRendered ); +#endif #endif } else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) { /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_ism2sba_sf( st_ivas->hTcBuffer->tc, p_output, st_ivas->hIsmRendererData, st_ivas->nchan_transport, nSamplesRenderedLocal, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order ); #else ivas_ism2sba_sf( st_ivas->hTcBuffer->tc, p_output, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order ); @@ -847,7 +858,7 @@ ivas_error ivas_jbm_dec_render( /* Binaural rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, nSamplesRenderedLocal ) ) != IVAS_ERR_OK ) #else if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) @@ -858,7 +869,7 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, nSamplesRenderedLocal, output_Fs ) ) != IVAS_ERR_OK ) #else @@ -869,7 +880,7 @@ ivas_error ivas_jbm_dec_render( return error; } -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_binaural_add_LFE( st_ivas, nSamplesRenderedLocal, p_output, p_output ); #else ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); @@ -878,7 +889,7 @@ ivas_error ivas_jbm_dec_render( #ifdef DEBUGGING else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_binaural_cldfb_sf( st_ivas, nSamplesRenderedLocal, p_output ); #else ivas_binaural_cldfb_sf( st_ivas, *nSamplesRendered, p_output ); @@ -894,7 +905,7 @@ ivas_error ivas_jbm_dec_render( /* Loudspeakers, Ambisonics or Binaural rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, nchan_remapped, p_output ); #else ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ); @@ -904,21 +915,21 @@ ivas_error ivas_jbm_dec_render( { if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); #else *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); #endif for ( n = 0; n < nchan_remapped; n++ ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING mvr2r( st_ivas->hTcBuffer->tc[n] + st_ivas->hTcBuffer->n_samples_rendered, p_output[n], nSamplesRenderedLocal ); #else mvr2r( st_ivas->hTcBuffer->tc[n] + st_ivas->hTcBuffer->n_samples_rendered, p_output[n], *nSamplesRendered ); #endif } -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING if ( ( error = ivas_sba_linear_renderer( p_output, nSamplesRenderedLocal, nchan_remapped, output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_sba_linear_renderer( p_output, *nSamplesRendered, nchan_remapped, output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ) ) != IVAS_ERR_OK ) @@ -929,7 +940,7 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_DIRAC ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, p_output ); #else ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); @@ -938,13 +949,13 @@ ivas_error ivas_jbm_dec_render( } else /* SBA_MODE_SPAR */ { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, p_output ); #else ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); #endif } -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING st_ivas->hTcBuffer->subframes_rendered++; #endif } @@ -952,14 +963,14 @@ ivas_error ivas_jbm_dec_render( { if ( st_ivas->mc_mode == MC_MODE_MCT ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); #else *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); #endif if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == AUDIO_CONFIG_FOA || st_ivas->intern_config == AUDIO_CONFIG_HOA2 || st_ivas->intern_config == AUDIO_CONFIG_HOA3 ) ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_mc2sba( st_ivas->hTransSetup, p_tc, p_output, nSamplesRenderedLocal, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); #else ivas_mc2sba( st_ivas->hTransSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); @@ -969,7 +980,7 @@ ivas_error ivas_jbm_dec_render( /* Rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, p_tc, p_output, nSamplesRenderedLocal, output_Fs ) ) != IVAS_ERR_OK ) @@ -981,15 +992,19 @@ ivas_error ivas_jbm_dec_render( { return error; } -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_binaural_add_LFE( st_ivas, nSamplesRenderedLocal, p_tc, p_output ); +#else +#ifdef NONBE_FIX_589_JBM_TC_OFFSETS + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); #else ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->tc, p_output ); +#endif #endif } else if ( st_ivas->renderer_type == RENDERER_MC ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, nSamplesRenderedLocal, p_tc, p_output ); #else @@ -999,7 +1014,7 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_mc2sba( st_ivas->hIntSetup, p_tc, p_output, nSamplesRenderedLocal, st_ivas->hOutSetup.ambisonics_order, 0.f ); #else ivas_mc2sba( st_ivas->hIntSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); @@ -1007,7 +1022,7 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, nSamplesRenderedLocal ) ) != IVAS_ERR_OK ) #else if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) @@ -1015,16 +1030,20 @@ ivas_error ivas_jbm_dec_render( { return error; } -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_binaural_add_LFE( st_ivas, nSamplesRenderedLocal, p_tc, p_output ); +#else +#ifdef NONBE_FIX_589_JBM_TC_OFFSETS + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); #else ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->tc, p_output ); +#endif #endif } } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_param_mc_dec_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, p_output ); #else ivas_param_mc_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); @@ -1035,11 +1054,18 @@ ivas_error ivas_jbm_dec_render( { /* zero output for now, not yet implemented... */ int16_t ch; +#ifdef JITTER_MEM_OPTIM_RENDERING nSamplesRenderedLocal = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); - +#else + *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAsked ); +#endif for ( ch = 0; ch < nchan_out; ch++ ) { +#ifdef JITTER_MEM_OPTIM_RENDERING set_zero( p_output[ch], nSamplesRenderedLocal ); +#else + set_zero( p_output[ch], *nSamplesRendered ); +#endif } } #endif @@ -1050,7 +1076,7 @@ ivas_error ivas_jbm_dec_render( if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, nchan_remapped, p_output ); #else ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ); @@ -1058,7 +1084,7 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) /* rendering to CICPxx and Ambisonics */ { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, &nSamplesRenderedLocal, nSamplesAvailableNext, p_output ); #else ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); @@ -1068,13 +1094,13 @@ ivas_error ivas_jbm_dec_render( /* we still need to copy the separate channel if available */ if ( st_ivas->hOutSetup.separateChannelEnabled ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], nSamplesRenderedLocal ); #else mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); #endif } -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, nSamplesRenderedLocal, st_ivas->hOutSetup.ambisonics_order, 0.f ); #else ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); @@ -1084,7 +1110,7 @@ ivas_error ivas_jbm_dec_render( { for ( n = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; n < st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; n++ ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING set_zero( output[n], nSamplesRenderedLocal ); #else set_zero( output[n], *nSamplesRendered ); @@ -1100,7 +1126,7 @@ ivas_error ivas_jbm_dec_render( output_config == AUDIO_CONFIG_5_1_4 || output_config == AUDIO_CONFIG_7_1_4 || output_config == AUDIO_CONFIG_5_1_2 || ( output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) { -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL] + offset, output[LFE_CHANNEL], nSamplesRenderedLocal ); mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], nSamplesRenderedLocal ); #else @@ -1111,7 +1137,7 @@ ivas_error ivas_jbm_dec_render( else if ( output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 ) { /* Delay the separated channel to sync with the DirAC rendering */ -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], nSamplesRenderedLocal ); #else mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); @@ -1127,7 +1153,7 @@ ivas_error ivas_jbm_dec_render( * - float to integer conversion *----------------------------------------------------------------*/ -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING st_ivas->hTcBuffer->n_samples_available -= nSamplesRenderedLocal; st_ivas->hTcBuffer->n_samples_rendered += nSamplesRenderedLocal; #else @@ -1141,7 +1167,7 @@ ivas_error ivas_jbm_dec_render( { p_output[n] += st_ivas->hTcBuffer->n_samples_discard; } -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING nSamplesRenderedLocal -= st_ivas->hTcBuffer->n_samples_discard; #else *nSamplesRendered -= st_ivas->hTcBuffer->n_samples_discard; @@ -1149,21 +1175,22 @@ ivas_error ivas_jbm_dec_render( st_ivas->hTcBuffer->n_samples_discard = 0; } -#ifdef API_5MS +#ifndef DISABLE_LIMITER +#ifdef JITTER_MEM_OPTIM_RENDERING ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, nSamplesRenderedLocal, st_ivas->BER_detect ); #else - ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, *nSamplesRendered, st_ivas->BER_detect ); + ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, *nSamplesRendered, st_ivas->BER_detect ); +#endif #endif - -#ifdef API_5MS +#ifdef JITTER_MEM_OPTIM_RENDERING #ifdef DEBUGGING st_ivas->noClipping += #endif ivas_syn_output( p_output, nSamplesRenderedLocal, nchan_out, data + *nSamplesRendered * nchan_out ); *nSamplesRendered += nSamplesRenderedLocal; - st_ivas->hTcBuffer->subframes_rendered = subframes_rendered+1; + st_ivas->hTcBuffer->subframes_rendered = subframes_rendered + 1; } #else #ifdef DEBUGGING -- GitLab From 1a9fd9fa8b097bd9c7fd4b2679d705f5854ec3be Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Tue, 11 Jul 2023 09:28:49 +0200 Subject: [PATCH 47/66] correct size of ParamMC cldfb buffers for non-TSM mode --- lib_com/options.h | 2 +- lib_dec/ivas_jbm_dec.c | 9 +++------ lib_dec/ivas_mc_param_dec.c | 22 +++++++++++++++++++++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index e176ad5d3e..d195e3aa11 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -172,7 +172,7 @@ #define NONBE_FIX_589_JBM_TC_OFFSETS #define API_5MS #ifdef API_5MS -/*#define JITTER_MEM_OPTIM_RENDERING*/ +#define JITTER_MEM_OPTIM_RENDERING #endif /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index cfa2c3fe1c..f9a83d0b6f 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -65,14 +65,13 @@ static void ivas_jbm_masa_sf_to_slot_map( Decoder_Struct *st_ivas, const int16_t * * Principal IVAS JBM decoder routine, decoding of metadata and transport channels *--------------------------------------------------------------------------*/ - ivas_error ivas_jbm_dec_tc( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *data /* o : transport channel signals */ + float *data /* o : transport channel signals */ ) { int16_t n, output_frame, nchan_out; - Decoder_State *st; /* used for bitstream handling */ + Decoder_State *st; /* used for bitstream handling */ float output[MAX_TRANSPORT_CHANNELS][L_FRAME48k]; /* 'float' buffer for transport channels, MAX_TRANSPORT_CHANNELS channels */ int16_t nchan_remapped, hodirac_flag; float output_lfe_ch[L_FRAME48k]; @@ -81,7 +80,6 @@ ivas_error ivas_jbm_dec_tc( AUDIO_CONFIG output_config; ivas_error error; float *p_output[MAX_TRANSPORT_CHANNELS]; - error = IVAS_ERR_OK; push_wmops( "ivas_jbm_dec_tc" ); @@ -112,7 +110,7 @@ ivas_error ivas_jbm_dec_tc( /* zero output when first frame(s) is lost */ for ( n = 0; n < nchan_out; n++ ) { - set_f( output[n], 0.0f, output_frame ); + set_f( p_output[n], 0.0f, output_frame ); } #ifdef DEBUG_MODE_INFO @@ -125,7 +123,6 @@ ivas_error ivas_jbm_dec_tc( else if ( st_ivas->ivas_format == STEREO_FORMAT ) { st_ivas->hCPE[0]->element_brate = ivas_total_brate; - if ( ( error = ivas_cpe_dec( st_ivas, 0, output, output_frame, 0 ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 6fe970d227..f69dd372bc 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -465,6 +465,26 @@ ivas_error ivas_param_mc_dec_open( if ( st_ivas->hDecoderConfig->voip_active && hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) #endif { +#ifdef API_5MS + int16_t n_cldfb_slots; + + n_cldfb_slots = DEFAULT_JBM_CLDFB_TIMESLOTS; + if ( st_ivas->hDecoderConfig->tsm_active ) + { + n_cldfb_slots = MAX_JBM_CLDFB_TIMESLOTS; + } + if ( ( hParamMC->Cldfb_RealBuffer_tc = (float *) malloc( n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); + } + set_zero( hParamMC->Cldfb_RealBuffer_tc, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); + + if ( ( hParamMC->Cldfb_ImagBuffer_tc = (float *) malloc( n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); + } + set_zero( hParamMC->Cldfb_ImagBuffer_tc, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); +#else if ( ( hParamMC->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); @@ -476,7 +496,7 @@ ivas_error ivas_param_mc_dec_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); } set_zero( hParamMC->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hParamMC->num_freq_bands ); - +#endif if ( st_ivas->hTcBuffer == NULL ) { if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, 0, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) -- GitLab From 6f1a7a0e0a2fb4777a8e5e3b8433498c937f8555 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 12 Jul 2023 17:33:56 +0200 Subject: [PATCH 48/66] Remove unused variable --- lib_rend/lib_rend.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 942b8c546f..3f2609dbf7 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -6579,7 +6579,9 @@ static ivas_error renderActiveInputsMasa( int16_t i; input_masa *pCurrentInput; ivas_error error; +#ifndef LIB_REND_API_5MS int16_t sf_idx; +#endif for ( i = 0, pCurrentInput = hIvasRend->inputsMasa; i < RENDERER_MAX_MASA_INPUTS; ++i, ++pCurrentInput ) { -- GitLab From ca1d6d376aeb1b6591143238a0b4872c901d7c35 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 12 Jul 2023 17:35:36 +0200 Subject: [PATCH 49/66] Fix MSVC warnings --- apps/renderer.c | 4 ++-- lib_rend/lib_rend.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 73125900c1..e7413a3c58 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1132,7 +1132,7 @@ int main( if ( !args.framing_5ms ) { /* Skip over 3 following head positions - they are given on 5ms grid */ - for ( int16_t i = 0; i < 3; ++i ) + for ( i = 0; i < 3; ++i ) { if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) { @@ -1202,7 +1202,7 @@ int main( if ( !args.framing_5ms ) { /* Skip over 3 following entries in file - they are given on 5ms grid */ - for ( int16_t i = 0; i < 3; ++i ) + for ( i = 0; i < 3; ++i ) { if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &quat, &enableHeadRotation, &enableExternalOrientation, &enableRotationInterpolation, &numFramesToTargetOrientation ) ) != IVAS_ERR_OK ) { diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 3f2609dbf7..7a555c070f 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4937,7 +4937,7 @@ static int16_t num_subframes_in_buffer( const IVAS_REND_AudioBuffer *buffer, int #ifdef DEBUGGING assert( buffer->config.numSamplesPerChannel % (sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES) == 0 ); #endif - return buffer->config.numSamplesPerChannel / (sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES); + return (int16_t) ( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); } #endif -- GitLab From e93e4389c19e8aad317ce5a71f19f156a5cfdf66 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 12 Jul 2023 17:50:58 +0200 Subject: [PATCH 50/66] Remove dbg code --- lib_com/options.h | 1 - lib_debug/debug.h | 19 ------------------- lib_rend/lib_rend.c | 4 ---- 3 files changed, 24 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 1937352fe3..f11d264f7b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -176,7 +176,6 @@ #define LIB_REND_API_5MS /* FhG: Adds 5ms framing capability to lib_rend */ #endif #define LIB_REND_FIX_HRTFPARAMBIN_MEMLEAK -#define SGI_DBG /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_debug/debug.h b/lib_debug/debug.h index 3cfe128d98..3d59cb00a0 100644 --- a/lib_debug/debug.h +++ b/lib_debug/debug.h @@ -36,9 +36,6 @@ #include "options.h" #include #include -#ifdef SGI_DBG -#include -#endif #ifdef DEBUG_SBA #include "sba_debug.h" #endif @@ -100,22 +97,6 @@ int16_t dbgwrite( const char *const filename #endif ); -#ifdef SGI_DBG -inline static void sgi_dbgwrite( - const float *const buffer, - const int16_t count, - const char *const filename ) -{ - float tmp[960]; - - for ( int i = 0; i < count; ++i ) - { - tmp[i] = buffer[i] / INT16_MAX; - } - - dbgwrite( tmp, sizeof( float ), count, 1, filename ); -} -#endif void dbgwrite_mat_repeat( float *buffer, /* i : write buffer */ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 7a555c070f..c90c53ad4f 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -5523,10 +5523,6 @@ static ivas_error renderMcToBinaural( { return error; } - -#ifdef SGI_DBG - sgi_dbgwrite( p_tmpRendBuffer[0], outAudio.config.numSamplesPerChannel, "res/p_tmpRendBuffer.pcm" ); -#endif } accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); -- GitLab From 6c57c8fd230732e7b5281c9b75d11f7cd61b80d9 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 13 Jul 2023 10:37:09 +0200 Subject: [PATCH 51/66] clang-format --- apps/renderer.c | 8 +-- lib_dec/ivas_jbm_dec.c | 4 +- lib_dec/lib_dec.c | 2 +- lib_rend/ivas_dirac_dec_binaural_functions.c | 3 +- lib_rend/ivas_rotation.c | 4 +- lib_rend/lib_rend.c | 68 ++++++++++---------- 6 files changed, 45 insertions(+), 44 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index e7413a3c58..909bc4a62a 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1142,12 +1142,12 @@ int main( } } #else - IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; + IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + if ( ( error = HeadRotationFileReading( headRotReader, &quatBuffer[i], &Pos[i] ) ) != IVAS_ERR_OK ) { - if ( ( error = HeadRotationFileReading( headRotReader, &quatBuffer[i], &Pos[i] ) ) != IVAS_ERR_OK ) - { fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index f9a83d0b6f..71faa7880a 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -67,11 +67,11 @@ static void ivas_jbm_masa_sf_to_slot_map( Decoder_Struct *st_ivas, const int16_t *--------------------------------------------------------------------------*/ ivas_error ivas_jbm_dec_tc( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *data /* o : transport channel signals */ + float *data /* o : transport channel signals */ ) { int16_t n, output_frame, nchan_out; - Decoder_State *st; /* used for bitstream handling */ + Decoder_State *st; /* used for bitstream handling */ float output[MAX_TRANSPORT_CHANNELS][L_FRAME48k]; /* 'float' buffer for transport channels, MAX_TRANSPORT_CHANNELS channels */ int16_t nchan_remapped, hodirac_flag; float output_lfe_ch[L_FRAME48k]; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 8581b4cb46..929365b277 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3267,7 +3267,7 @@ static ivas_error evs_dec_main( } else #endif - if ( floatBuf != NULL ) + if ( floatBuf != NULL ) { /* BE workaround */ int16_t pcm_buf_local[L_FRAME48k * MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN]; diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index c2761edf79..b93564b7b1 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -444,7 +444,8 @@ void ivas_dirac_dec_binaural( float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t nchan_transport /* i : number of transport channels */ #ifdef LIB_REND_API_5MS - ,const int16_t num_subframes /* i : number of subframes to render */ + , + const int16_t num_subframes /* i : number of subframes to render */ #endif ) { diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index ea524b9dae..63061144de 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -997,11 +997,11 @@ ivas_error combine_external_and_head_orientations_rend( ivas_error combine_external_and_head_orientations( #ifdef LIB_REND_API_5MS - IVAS_QUATERNION *headRotQuaternion, /* i : quaternion for head rotation */ + IVAS_QUATERNION *headRotQuaternion, /* i : quaternion for head rotation */ #else IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ #endif - IVAS_VECTOR3 *listenerPos, /* i : listener position */ + IVAS_VECTOR3 *listenerPos, /* i : listener position */ #ifndef API_5MS int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ #endif diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index c90c53ad4f..6f301fdc35 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4114,7 +4114,7 @@ int16_t IVAS_REND_FeedRenderConfig( *-------------------------------------------------------------------*/ ivas_error IVAS_REND_SetHeadRotation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ #ifdef LIB_REND_API_5MS const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos /* i : listener positions for next rendering call */ @@ -4326,8 +4326,8 @@ ivas_error IVAS_REND_SetReferenceVector( *---------------------------------------------------------------------*/ ivas_error IVAS_REND_SetExternalOrientation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_QUATERNION *orientation, /* i : external orientation data */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_QUATERNION *orientation, /* i : external orientation data */ #ifdef LIB_REND_API_5MS int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ @@ -4548,8 +4548,8 @@ static void renderBufferChannel( } static ivas_error rotateFrameMc( - IVAS_REND_AudioBuffer inAudio, /* i : Input Audio buffer */ - IVAS_REND_AudioConfig inConfig, /* i : Input Audio config */ + IVAS_REND_AudioBuffer inAudio, /* i : Input Audio buffer */ + IVAS_REND_AudioConfig inConfig, /* i : Input Audio config */ #ifdef LIB_REND_API_5MS const LSSETUP_CUSTOM_STRUCT *pInCustomLs, /* i : Input Custom LS setup */ #else @@ -4649,7 +4649,7 @@ static ivas_error rotateFrameMc( /* fix compiling only, ToDo adapt ext renderer to 5ms */ Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[i][j]; #else - Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][j]; + Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][j]; #endif } } @@ -4712,16 +4712,16 @@ static ivas_error rotateFrameMc( readPtr++; } #else - writePtr = getSmplPtr( outAudio, ch_out, subframe_idx * subframe_len ); - readPtr = getSmplPtr( inAudio, ch_in, subframe_idx * subframe_len ); - /* crossfade with previous rotation gains */ - for ( i = 0; i < subframe_len; i++ ) - { - *writePtr++ += - ( *readPtr ) * ( ( 1 - headRotData->crossfade[i] ) * gains_prev[ch_in][ch_out] ) + - ( *readPtr ) * ( headRotData->crossfade[i] * gains[ch_in][ch_out] ); - readPtr++; - } + writePtr = getSmplPtr( outAudio, ch_out, subframe_idx * subframe_len ); + readPtr = getSmplPtr( inAudio, ch_in, subframe_idx * subframe_len ); + /* crossfade with previous rotation gains */ + for ( i = 0; i < subframe_len; i++ ) + { + *writePtr++ += + ( *readPtr ) * ( ( 1 - headRotData->crossfade[i] ) * gains_prev[ch_in][ch_out] ) + + ( *readPtr ) * ( headRotData->crossfade[i] * gains[ch_in][ch_out] ); + readPtr++; + } #endif } } @@ -4808,7 +4808,7 @@ static ivas_error rotateFrameSba( /* fix compilation only, ToDo adapt ext renderer to 5ms */ Rmat[i][l] = ( *hCombinedOrientationData )->Rmat[i][l]; #else - Rmat[i][l] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][l]; + Rmat[i][l] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][l]; #endif } } @@ -4826,7 +4826,7 @@ static ivas_error rotateFrameSba( #ifdef LIB_REND_API_5MS for ( i = 0; i < inAudio.config.numSamplesPerChannel; i++ ) #else - for ( i = 0; i < subframe_len; i++ ) + for ( i = 0; i < subframe_len; i++ ) #endif { /* As the rotation matrix becomes block diagonal in a SH basis, we can*/ @@ -4850,10 +4850,10 @@ static ivas_error rotateFrameSba( tmpRot[n - m1] += crossfade[i] * gains[n][m] * ( *readPtr ) + ( 1 - crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); #else - readPtr = getSmplPtr( inAudio, m, subframe_idx * subframe_len + i ); - /* crossfade with previous rotation gains */ - tmpRot[n - m1] += headRotData->crossfade[i] * gains[n][m] * ( *readPtr ) + - ( 1 - headRotData->crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); + readPtr = getSmplPtr( inAudio, m, subframe_idx * subframe_len + i ); + /* crossfade with previous rotation gains */ + tmpRot[n - m1] += headRotData->crossfade[i] * gains[n][m] * ( *readPtr ) + + ( 1 - headRotData->crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); #endif } } @@ -4863,7 +4863,7 @@ static ivas_error rotateFrameSba( #ifdef LIB_REND_API_5MS writePtr = getSmplPtr( outAudio, n, i ); #else - writePtr = getSmplPtr( outAudio, n, subframe_idx * subframe_len + i ); + writePtr = getSmplPtr( outAudio, n, subframe_idx * subframe_len + i ); #endif ( *writePtr ) = tmpRot[n - m1]; } @@ -4935,7 +4935,7 @@ static ivas_error renderIsmToBinaural( static int16_t num_subframes_in_buffer( const IVAS_REND_AudioBuffer *buffer, int32_t sampleRate ) { #ifdef DEBUGGING - assert( buffer->config.numSamplesPerChannel % (sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES) == 0 ); + assert( buffer->config.numSamplesPerChannel % ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) == 0 ); #endif return (int16_t) ( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); } @@ -5016,13 +5016,13 @@ static ivas_error renderIsmToBinauralRoom( } } #else - if ( hCombinedOrientationData != NULL && ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] ) + if ( hCombinedOrientationData != NULL && ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] ) + { + for ( j = 0; j < 3; j++ ) { - for ( j = 0; j < 3; j++ ) - { - Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][j]; - } + Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][j]; } + } #endif else { @@ -6321,10 +6321,10 @@ static void renderMasaToMc( } else { - ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels + ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels #ifdef LIB_REND_API_5MS - , - num_subframes_in_buffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) + , + num_subframes_in_buffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) #endif ); } @@ -6345,8 +6345,8 @@ static void renderMasaToSba( ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels #ifdef LIB_REND_API_5MS - , - num_subframes_in_buffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) + , + num_subframes_in_buffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) #endif ); -- GitLab From 080e731b95fc910c3c61ac69f6b00f08f99eab76 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 13 Jul 2023 17:19:42 +0200 Subject: [PATCH 52/66] Use 5 ms framing in tests with binaural output --- lib_rend/lib_rend.c | 20 ++++++----------- tests/renderer/test_renderer.py | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 6f301fdc35..ef5829806a 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -3820,7 +3820,7 @@ ivas_error IVAS_REND_FeedInputAudio( if ( inputAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel ) { - return IVAS_ERR_INVALID_BUFFER_SIZE; + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Buffer size outside of supported range" ); } if ( inputAudio.config.numChannels <= 0 || MAX_INPUT_CHANNELS < inputAudio.config.numChannels ) @@ -3831,8 +3831,7 @@ ivas_error IVAS_REND_FeedInputAudio( if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && inputAudio.config.numSamplesPerChannel * 1000 != BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->sampleRateOut ) { - /* Binaural rendering requires specific frame size */ - return IVAS_ERR_INVALID_BUFFER_SIZE; + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) @@ -5298,8 +5297,7 @@ static ivas_error renderInputIsm( if ( ismInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) { - /* Mismatch between the number of input samples vs number of requested output samples - currently not allowed */ - return IVAS_ERR_INVALID_BUFFER_SIZE; + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } ismInput->base.numNewSamplesPerChannel = 0; @@ -5844,8 +5842,7 @@ static ivas_error renderInputMc( if ( mcInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) { - /* Mismatch between the number of input samples vs number of requested output samples - currently not allowed */ - return IVAS_ERR_INVALID_BUFFER_SIZE; + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } mcInput->base.numNewSamplesPerChannel = 0; @@ -6192,8 +6189,7 @@ static ivas_error renderInputSba( if ( sbaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) { - /* Mismatch between the number of input samples vs number of requested output samples - currently not allowed */ - return IVAS_ERR_INVALID_BUFFER_SIZE; + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } sbaInput->base.numNewSamplesPerChannel = 0; @@ -6520,8 +6516,7 @@ static ivas_error renderInputMasa( if ( masaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) { - /* Mismatch between the number of input samples vs number of requested output samples - currently not allowed */ - return IVAS_ERR_INVALID_BUFFER_SIZE; + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } masaInput->base.numNewSamplesPerChannel = 0; @@ -6794,8 +6789,7 @@ ivas_error IVAS_REND_GetSamples( if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && outAudio.config.numSamplesPerChannel * 1000 != BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->sampleRateOut ) { - /* Binaural rendering requires specific frame size */ - return IVAS_ERR_INVALID_BUFFER_SIZE; + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } /* Check that there is allowed configuration for MASA format output */ diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index beed8e897b..ab759d6d2f 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -44,6 +44,9 @@ def test_ambisonics(test_info, in_fmt, out_fmt, framing_5ms): @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) @pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt, framing_5ms): + if not framing_5ms: + pytest.xfail("Binaural output currently only supported with 5ms framing") + run_renderer(in_fmt, out_fmt, framing_5ms=framing_5ms) @@ -52,6 +55,9 @@ def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt, framing_5ms): @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) @pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file, framing_5ms): + if not framing_5ms: + pytest.xfail("Binaural output currently only supported with 5ms framing") + run_renderer( in_fmt, out_fmt, @@ -75,10 +81,12 @@ def test_ambisonics_binaural_headrotation_refrotzero( ref_kwargs={ "name_extension": "refrotzero", "trj_file": HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + "framing_5ms": True, }, cut_kwargs={ "trj_file": HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), "refrot_file": HR_TRAJECTORY_DIR.joinpath("const000.csv"), + "framing_5ms": True, }, ) @@ -95,6 +103,7 @@ def test_ambisonics_binaural_headrotation_refrotequal(test_info, in_fmt, out_fmt out_fmt, ref_kwargs={ "name_extension": "refrotequal", + "framing_5ms": True, }, cut_kwargs={ "trj_file": HR_TRAJECTORY_DIR.joinpath( @@ -103,6 +112,7 @@ def test_ambisonics_binaural_headrotation_refrotequal(test_info, in_fmt, out_fmt "refrot_file": HR_TRAJECTORY_DIR.joinpath( "azi_plus_2-ele_plus_2-every-25-rows.csv" ), + "framing_5ms": True, }, ) @@ -124,10 +134,12 @@ def test_ambisonics_binaural_headrotation_refveczero( ref_kwargs={ "name_extension": "refveczero", "trj_file": HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + "framing_5ms": True, }, cut_kwargs={ "trj_file": HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), "refvec_file": HR_TRAJECTORY_DIR.joinpath("const000-Vector3.csv"), + "framing_5ms": True, }, ) @@ -149,6 +161,7 @@ def test_ambisonics_binaural_headrotation_refvecequal(test_info, in_fmt, out_fmt out_fmt, ref_kwargs={ "name_extension": "refvecequal", + "framing_5ms": True, }, cut_kwargs={ "trj_file": HR_TRAJECTORY_DIR.joinpath( @@ -157,6 +170,7 @@ def test_ambisonics_binaural_headrotation_refvecequal(test_info, in_fmt, out_fmt "refvec_file": HR_TRAJECTORY_DIR.joinpath( "full-circle-with-up-and-down-4s-Vector3.csv" ), + "framing_5ms": True, }, ) @@ -181,12 +195,14 @@ def test_ambisonics_binaural_headrotation_refvec_rotating(test_info, in_fmt, out "trj_file": HR_TRAJECTORY_DIR.joinpath( "full-circle-with-up-and-down-4s.csv" ), + "framing_5ms": True, }, cut_kwargs={ "trj_file": HR_TRAJECTORY_DIR.joinpath("const000.csv"), "refvec_file": HR_TRAJECTORY_DIR.joinpath( "full-circle-with-up-and-down-4s-ccw-Vector3.csv" ), + "framing_5ms": True, }, ) @@ -211,12 +227,14 @@ def test_ambisonics_binaural_headrotation_refvec_rotating_fixed_pos_offset( "trj_file": HR_TRAJECTORY_DIR.joinpath( "full-circle-with-up-and-down-4s-ccw.csv" ), + "framing_5ms": True, }, cut_kwargs={ "trj_file": HR_TRAJECTORY_DIR.joinpath("const000.csv"), "refvec_file": HR_TRAJECTORY_DIR.joinpath( "full-circle-with-up-and-down-4s-fixed-pos-offset-Vector3.csv" ), + "framing_5ms": True, }, ) @@ -241,10 +259,12 @@ def test_ambisonics_binaural_headrotation_refveclev_vs_refvec( "refveclev_file": HR_TRAJECTORY_DIR.joinpath( "full-circle-with-up-and-down-4s-Vector3.csv" ), + "framing_5ms": True, }, cut_kwargs={ "trj_file": HR_TRAJECTORY_DIR.joinpath("const000.csv"), "refvec_file": HR_TRAJECTORY_DIR.joinpath("full-circle-4s-Vector3.csv"), + "framing_5ms": True, }, ) @@ -265,6 +285,8 @@ def test_multichannel(test_info, in_fmt, out_fmt, framing_5ms): def test_multichannel_binaural_static(test_info, in_fmt, out_fmt, framing_5ms): if in_fmt in ["MONO", "STEREO"]: pytest.skip("MONO or STEREO to Binaural rendering unsupported") + if not framing_5ms: + pytest.xfail("Binaural output currently only supported with 5ms framing") run_renderer(in_fmt, out_fmt, framing_5ms=framing_5ms) @@ -276,6 +298,8 @@ def test_multichannel_binaural_static(test_info, in_fmt, out_fmt, framing_5ms): def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file, framing_5ms): if in_fmt in ["MONO", "STEREO"]: pytest.skip("MONO or STEREO to Binaural rendering unsupported") + if not framing_5ms: + pytest.xfail("Binaural output currently only supported with 5ms framing") if (in_fmt == "5_1" or in_fmt == "7_1") and out_fmt == "BINAURAL": run_renderer( @@ -312,12 +336,14 @@ def test_multichannel_binaural_headrotation_refvec_rotating(test_info, in_fmt, o "trj_file": HR_TRAJECTORY_DIR.joinpath( "full-circle-with-up-and-down-4s.csv" ), + "framing_5ms": True, }, cut_kwargs={ "trj_file": HR_TRAJECTORY_DIR.joinpath("const000.csv"), "refvec_file": HR_TRAJECTORY_DIR.joinpath( "full-circle-with-up-and-down-4s-ccw-Vector3.csv" ), + "framing_5ms": True, }, ) @@ -336,6 +362,9 @@ def test_ism(test_info, in_fmt, out_fmt, framing_5ms): @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) @pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) def test_ism_binaural_static(test_info, in_fmt, out_fmt, framing_5ms): + if not framing_5ms: + pytest.xfail("Binaural output currently only supported with 5ms framing") + try: in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] except: @@ -352,6 +381,9 @@ def test_ism_binaural_static(test_info, in_fmt, out_fmt, framing_5ms): @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) @pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file, framing_5ms): + if not framing_5ms: + pytest.xfail("Binaural output currently only supported with 5ms framing") + try: in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] except: @@ -397,6 +429,7 @@ def test_ism_binaural_headrotation_refvec_rotating(test_info, in_fmt, out_fmt): "full-circle-with-up-and-down-4s.csv" ), "in_meta_files": in_meta_files, + "framing_5ms": True, }, cut_kwargs={ "trj_file": HR_TRAJECTORY_DIR.joinpath("const000.csv"), @@ -404,6 +437,7 @@ def test_ism_binaural_headrotation_refvec_rotating(test_info, in_fmt, out_fmt): "full-circle-with-up-and-down-4s-ccw-Vector3.csv" ), "in_meta_files": in_meta_files, + "framing_5ms": True, }, ) @@ -450,6 +484,9 @@ def test_custom_ls_input_output(test_info, in_fmt, out_fmt): @pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) @pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) def test_custom_ls_input_binaural(test_info, in_layout, out_fmt, framing_5ms): + if not framing_5ms: + pytest.xfail("Binaural output currently only supported with 5ms framing") + run_renderer( CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt, @@ -462,6 +499,9 @@ def test_custom_ls_input_binaural(test_info, in_layout, out_fmt, framing_5ms): @pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) @pytest.mark.parametrize("framing_5ms", FRAMING_5MS_TO_TEST) def test_custom_ls_input_binaural_headrotation(test_info, in_layout, out_fmt, trj_file, framing_5ms): + if not framing_5ms: + pytest.xfail("Binaural output currently only supported with 5ms framing") + run_renderer( CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt, -- GitLab From 3e7fec37297bae10ae7e6906151d5c53a46e8ca8 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Mon, 31 Jul 2023 13:02:32 +0200 Subject: [PATCH 53/66] Finish resolving merge conflicts --- lib_rend/ivas_rotation.c | 121 +++++++++++++++----------------------- lib_rend/ivas_stat_rend.h | 10 +--- lib_rend/lib_rend.c | 74 +++++------------------ 3 files changed, 64 insertions(+), 141 deletions(-) diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 9b5fa135ea..c38deff1ef 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -433,16 +433,18 @@ void rotateFrame_shd( /* move Rmat to Rmat_prev */ for ( i = 0; i < 3; i++ ) { -<<<<<<< HEAD + mvr2r( #ifdef API_5MS - mvr2r( hCombinedOrientationData->Rmat[i], hCombinedOrientationData->Rmat_prev[i], 3 ); -======= + hCombinedOrientationData->Rmat[i], +#else + hCombinedOrientationData->Rmat[subframe_idx][i], +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT - mvr2r( hCombinedOrientationData->Rmat[subframe_idx][i], hCombinedOrientationData->Rmat_prev[0][i], 3 ); ->>>>>>> main + hCombinedOrientationData->Rmat_prev[0][i] #else - mvr2r( hCombinedOrientationData->Rmat[subframe_idx][i], hCombinedOrientationData->Rmat_prev[i], 3 ); + hCombinedOrientationData->Rmat_prev[i], #endif + 3 ); } return; @@ -576,16 +578,18 @@ void rotateFrame_sd( /* move Rmat to Rmat_prev */ for ( i = 0; i < 3; i++ ) { -<<<<<<< HEAD + mvr2r( #ifdef API_5MS - mvr2r( hCombinedOrientationData->Rmat[i], hCombinedOrientationData->Rmat_prev[i], 3 ); -======= + hCombinedOrientationData->Rmat[i], +#else + hCombinedOrientationData->Rmat[subframe_idx][i], +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT - mvr2r( hCombinedOrientationData->Rmat[subframe_idx][i], hCombinedOrientationData->Rmat_prev[0][i], 3 ); ->>>>>>> main + hCombinedOrientationData->Rmat_prev[0][i], #else - mvr2r( hCombinedOrientationData->Rmat[subframe_idx][i], hCombinedOrientationData->Rmat_prev[i], 3 ); + hCombinedOrientationData->Rmat_prev[i] #endif + 3 ); } /* copy to output */ @@ -928,7 +932,7 @@ ivas_error ivas_combined_orientation_open( set_zero( ( *hCombinedOrientationData )->Rmat[j], 3 ); ( *hCombinedOrientationData )->Rmat[j][j] = 1.0f; } -#else +#else /* API_5MS */ /* Initialise orientations to identity */ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { @@ -937,7 +941,7 @@ ivas_error ivas_combined_orientation_open( #ifndef FIX_570_SF_EXT_ORIENTATION ( *hCombinedOrientationData )->Quaternions_prev_headRot[i] = identity; ( *hCombinedOrientationData )->Quaternions_prev_extOrientation[i] = identity; -#endif +#endif /* FIX_570_SF_EXT_ORIENTATION */ ( *hCombinedOrientationData )->listenerPos[i] = origo; for ( j = 0; j < 3; j++ ) @@ -946,9 +950,7 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->Rmat[i][j][j] = 1.0f; } } -<<<<<<< HEAD -#endif -======= +#endif /* API_5MS */ #ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) { @@ -959,7 +961,6 @@ ivas_error ivas_combined_orientation_open( } } #else ->>>>>>> main for ( j = 0; j < 3; j++ ) { set_zero( ( *hCombinedOrientationData )->Rmat_prev[j], 3 ); @@ -1022,14 +1023,10 @@ ivas_error combine_external_and_head_orientations_dec( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { -<<<<<<< HEAD - IVAS_QUATERNION *headRotQuaternions = NULL; /* TODO(sgi): Rename to "headRotQuaternion" - it's a single value now */ -======= #ifdef SPLIT_REND_WITH_HEAD_ROT IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; #endif - IVAS_QUATERNION *headRotQuaternions = NULL; ->>>>>>> main + IVAS_QUATERNION *headRotQuaternions = NULL; /* TODO(sgi): Rename to "headRotQuaternion" - it's a single value now */ IVAS_VECTOR3 *listenerPos = NULL; #ifndef API_5MS int16_t numHeadRotQuaternions = 0; @@ -1047,15 +1044,7 @@ ivas_error combine_external_and_head_orientations_dec( headRotQuaternions = hHeadTrackData->Quaternions; listenerPos = hHeadTrackData->Pos; } -<<<<<<< HEAD #endif - } -#ifdef API_5MS - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); -#else - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); -#endif -======= #ifdef SPLIT_REND_WITH_HEAD_ROT sr_pose_pred_axis = hHeadTrackData->sr_pose_pred_axis; #endif @@ -1067,12 +1056,18 @@ ivas_error combine_external_and_head_orientations_dec( } #endif - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, + return combine_external_and_head_orientations( + headRotQuaternions, + listenerPos, #ifdef SPLIT_REND_WITH_HEAD_ROT - sr_pose_pred_axis, + sr_pose_pred_axis, #endif - numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); ->>>>>>> main +#ifndef API_5MS + numHeadRotQuaternions, +#endif + hExtOrientationData, + hCombinedOrientationData, + ); } @@ -1136,20 +1131,18 @@ ivas_error combine_external_and_head_orientations_rend( } #endif } -<<<<<<< HEAD -#ifdef API_5MS - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, hExtOrientationData, hCombinedOrientationData ); -#else - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); -#endif -======= - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, + return combine_external_and_head_orientations( + headRotQuaternions, + listenerPos, #ifdef SPLIT_REND_WITH_HEAD_ROT - sr_pose_pred_axis, + sr_pose_pred_axis, #endif - numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); ->>>>>>> main +#ifndef API_5MS + numHeadRotQuaternions, +#endif + hExtOrientationData, + hCombinedOrientationData ); } @@ -1160,7 +1153,6 @@ ivas_error combine_external_and_head_orientations_rend( * NOTE that the external orientations are inversed. *------------------------------------------------------------------------*/ -<<<<<<< HEAD ivas_error combine_external_and_head_orientations( #ifdef LIB_REND_API_5MS IVAS_QUATERNION *headRotQuaternion, /* i : quaternion for head rotation */ @@ -1168,22 +1160,14 @@ ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ #endif IVAS_VECTOR3 *listenerPos, /* i : listener position */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ +#endif #ifndef API_5MS int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ #endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ -======= -static ivas_error combine_external_and_head_orientations( - IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ - IVAS_VECTOR3 *listenerPos, /* i : listener position */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ -#endif - int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ - EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ->>>>>>> main ) { #ifndef API_5MS @@ -1502,26 +1486,24 @@ static ivas_error combine_external_and_head_orientations( /* Save the current orientations */ if ( hExtOrientationData != NULL ) { -<<<<<<< HEAD #ifdef API_5MS if ( hExtOrientationData->enableExternalOrientation > 0 ) { hCombinedOrientationData->Quaternion_prev_extOrientation = hCombinedOrientationData->Quaternion; -======= -#ifdef FIX_570_SF_EXT_ORIENTATION + } + else + { + hCombinedOrientationData->Quaternion_prev_extOrientation = identity; + } +#elif defined FIX_570_SF_EXT_ORIENTATION /* ToDo: ensure FIX_570_SF_EXT_ORIENTATION is correctly included in API_5MS */ if ( hExtOrientationData->enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES - 1] > 0 ) { hCombinedOrientationData->Quaternion_prev_extOrientation = hExtOrientationData->Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES - 1]; ->>>>>>> main } else { hCombinedOrientationData->Quaternion_prev_extOrientation = identity; } -<<<<<<< HEAD - -======= ->>>>>>> main #else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { @@ -1748,11 +1730,7 @@ void external_target_interpolation( #endif /* Use the most recent external orientation as the starting orientation */ -<<<<<<< HEAD -#ifdef API_5MS - hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternion_prev_extOrientation; -======= -#ifdef FIX_570_SF_EXT_ORIENTATION +#if defined FIX_570_SF_EXT_ORIENTATION || defined API_5MS if ( hExtOrientationData->enableExternalOrientation[i] == 1 ) { if ( i > 0 ) @@ -1768,7 +1746,6 @@ void external_target_interpolation( { hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternion_frozen_ext; } ->>>>>>> main #else hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternions_prev_extOrientation[i]; #endif diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 6db0a6445b..d24521e1a5 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -796,11 +796,9 @@ typedef struct IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME]; IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME]; float crossfade[L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME]; -<<<<<<< HEAD -======= +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; ->>>>>>> main #endif ivas_orient_trk_state_t *hOrientationTracker; @@ -891,13 +889,10 @@ typedef struct ivas_combined_orientation_struct float Rmat[3][3]; #else float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; -<<<<<<< HEAD #endif -======= #ifdef SPLIT_REND_WITH_HEAD_ROT float Rmat_prev[MAX_HEAD_ROT_POSES][3][3]; #else ->>>>>>> main float Rmat_prev[3][3]; #endif float chEneIIR[2][MASA_FREQUENCY_BANDS]; /* independent of the format. MASA bands are suitable for the task and readily available in ROM. */ @@ -907,9 +902,7 @@ typedef struct ivas_combined_orientation_struct IVAS_VECTOR3 listenerPos; #else IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; -<<<<<<< HEAD #endif -======= #ifdef SPLIT_REND_WITH_HEAD_ROT IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; #endif @@ -917,7 +910,6 @@ typedef struct ivas_combined_orientation_struct IVAS_QUATERNION Quaternion_frozen_head; int8_t isExtOrientationFrozen; int8_t isHeadRotationFrozen; ->>>>>>> main } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 528f09f58f..7236c5d468 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -6108,19 +6108,15 @@ static ivas_error renderIsmToBinauralRoom( if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate -<<<<<<< HEAD #ifdef LIB_REND_API_5MS , num_subframes_in_buffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) -======= #ifdef SPLIT_REND_WITH_HEAD_ROT , 0 #endif - ) ) != IVAS_ERR_OK ) ->>>>>>> main + ) ) != IVAS_ERR_OK ) { return error; } @@ -6779,20 +6775,15 @@ static ivas_error renderMcToBinaural( /* call CREND */ if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate -<<<<<<< HEAD #ifdef LIB_REND_API_5MS , num_subframes_in_buffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) -======= #ifdef SPLIT_REND_WITH_HEAD_ROT , 0 #endif - ) ) != IVAS_ERR_OK ) - ->>>>>>> main + ) ) != IVAS_ERR_OK ) { return error; } @@ -6911,19 +6902,15 @@ static ivas_error renderMcToBinauralRoom( /* call CREND */ if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate -<<<<<<< HEAD #ifdef LIB_REND_API_5MS , num_subframes_in_buffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) -======= #ifdef SPLIT_REND_WITH_HEAD_ROT , 0 #endif - ) ) != IVAS_ERR_OK ) ->>>>>>> main + ) ) != IVAS_ERR_OK ) { return error; } @@ -7038,19 +7025,15 @@ static ivas_error renderMcCustomLsToBinauralRoom( /* call CREND */ if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate -<<<<<<< HEAD #ifdef LIB_REND_API_5MS , num_subframes_in_buffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) -======= #ifdef SPLIT_REND_WITH_HEAD_ROT , 0 #endif - ) ) != IVAS_ERR_OK ) ->>>>>>> main + ) ) != IVAS_ERR_OK ) { return error; } @@ -7857,7 +7840,11 @@ static ivas_error renderSbaToBinaural( else #endif { -<<<<<<< HEAD + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpCrendBuffer[i] = tmpCrendBuffer[i]; + } + #ifdef API_5MS /* fix compiling only, ToDo ext renderer needs to adapted to 5ms */ if ( ( *hCombinedOrientationData )->enableCombinedOrientation != 0 ) @@ -7865,14 +7852,6 @@ static ivas_error renderSbaToBinaural( combinedOrientationEnabled = 1; } #else - for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) -======= - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) ->>>>>>> main - { - p_tmpCrendBuffer[i] = tmpCrendBuffer[i]; - } - hCombinedOrientationData = sbaInput->base.ctx.pCombinedOrientationData; combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) @@ -7886,11 +7865,7 @@ static ivas_error renderSbaToBinaural( } } } -<<<<<<< HEAD #endif - } -======= ->>>>>>> main /* apply rotation */ if ( combinedOrientationEnabled ) @@ -7927,6 +7902,10 @@ static ivas_error renderSbaToBinaural( /* call CREND */ if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( sbaInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate +#ifdef LIB_REND_API_5MS + , + num_subframes_in_buffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT , 0 @@ -7938,27 +7917,6 @@ static ivas_error renderSbaToBinaural( accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); } -<<<<<<< HEAD - else - { - copyBufferTo2dArray( sbaInput->base.inputBuffer, tmpCrendBuffer ); - } - - /* call CREND */ - if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( sbaInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), - NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate -#ifdef LIB_REND_API_5MS - , - num_subframes_in_buffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) -#endif - ) ) != IVAS_ERR_OK ) - { - return error; - } - - accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); -======= ->>>>>>> main pop_wmops(); @@ -8060,19 +8018,15 @@ static ivas_error renderSbaToBinauralRoom( /* call CREND */ if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate -<<<<<<< HEAD #ifdef LIB_REND_API_5MS , num_subframes_in_buffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) #endif - ) ) != IVAS_ERR_OK ) -======= #ifdef SPLIT_REND_WITH_HEAD_ROT , 0 #endif - ) ) != IVAS_ERR_OK ) ->>>>>>> main + ) ) != IVAS_ERR_OK ) { return error; } -- GitLab From b376fb1ca6c0f73a7e456e1f916e643e21c3e8df Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Mon, 31 Jul 2023 15:01:19 +0200 Subject: [PATCH 54/66] Fixing build errors WIP --- lib_dec/ivas_binRenderer_internal.c | 17 +++++++- lib_dec/ivas_ism_param_dec.c | 5 +-- lib_dec/ivas_jbm_dec.c | 2 +- lib_dec/ivas_mc_paramupmix_dec.c | 8 +++- lib_dec/ivas_output_config.c | 14 ++++++- lib_dec/lib_dec.c | 3 +- lib_rend/ivas_crend.c | 31 +++++++++++++++ lib_rend/ivas_objectRenderer.c | 33 ++++++++++++++++ lib_rend/ivas_prot_rend.h | 5 +++ lib_rend/ivas_rotation.c | 15 +++++-- lib_rend/ivas_splitRenderer_utils.c | 9 +++++ lib_rend/ivas_stat_rend.h | 1 + lib_rend/lib_rend.c | 61 +++++++++++++++++++---------- 13 files changed, 171 insertions(+), 33 deletions(-) diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 259d0b7a91..3f6494b0ff 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1608,7 +1608,11 @@ void ivas_binRenderer( if ( hCombinedOrientationData && hBinRenderer->rotInCldfb ) { +#ifdef API_5MS + Quaternions_ref = &hCombinedOrientationData->Quaternion; +#else Quaternions_ref = &hCombinedOrientationData->Quaternions[0]; +#endif Quaternions_rel.w = -3.0f; /*euler*/ Quaternions_abs.w = -3.0f; /*euler*/ Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ @@ -1722,9 +1726,10 @@ void ivas_rend_CldfbMultiBinRendProcess( float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; #endif - +#ifndef API_5MS for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) { +#endif for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx; @@ -1739,12 +1744,18 @@ void ivas_rend_CldfbMultiBinRendProcess( { if ( ( low_res_pre_rend_rot ) && ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) { +#ifdef API_5MS + ( *pCombinedOrientationData )->Quaternion = ( *pCombinedOrientationData )->Quaternion; +#else ( *pCombinedOrientationData )->Quaternions[sf_idx] = ( *pCombinedOrientationData )->Quaternions[0]; +#endif for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 3; j++ ) { - ( *pCombinedOrientationData )->Rmat[sf_idx][i][j] = ( *pCombinedOrientationData )->Rmat[0][i][j]; +#ifdef API_5MS + ( *pCombinedOrientationData )->Rmat[i][j] = ( *pCombinedOrientationData )->Rmat[i][j]; +#endif } } } @@ -1776,7 +1787,9 @@ void ivas_rend_CldfbMultiBinRendProcess( } } } +#ifndef API_5MS } +#endif return; } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 96558ebc00..97fc604794 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -804,7 +804,6 @@ void ivas_param_ism_dec( // assert( hSpatParamRendCom ); // >>>>>>> main // merged to: -#ifdef FIX_549_DMX_GAIN #ifdef API_5MS for ( i = 0; i < PARAM_ISM_MAX_DMX; i++ ) { @@ -1270,7 +1269,7 @@ void ivas_param_ism_dec_digest_tc( #ifdef API_5MS if ( st_ivas->hDecoderConfig->tsm_active ) { - ivas_ism_param_dec_tc_gain_ajust( st_ivas, nCldfbSlots * st_ivas->hDirAC->num_freq_bands, (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( 2 * FRAMES_PER_SEC ) ), transport_channels_f ); + ivas_ism_param_dec_tc_gain_ajust( st_ivas, nCldfbSlots * hSpatParamRendCom->num_freq_bands, (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( 2 * FRAMES_PER_SEC ) ), transport_channels_f ); } #else #ifdef FIX_549_DMX_GAIN @@ -1330,7 +1329,7 @@ void ivas_param_ism_dec_digest_tc( mvr2r( ImagBuffer, &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands ); #ifdef API_5MS } - ivas_param_ism_collect_slot( hDirAC, &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], ch, ref_power, cx_diag ); + ivas_param_ism_collect_slot( hDirAC, &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], ch, ref_power, cx_diag ); #else ivas_param_ism_collect_slot( hDirAC, RealBuffer, ImagBuffer, ch, ref_power, cx_diag ); #endif diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index dae2deda18..9cc79be379 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -2425,7 +2425,7 @@ void ivas_jbm_dec_copy_tc_no_tsm( { cldfb_real_buffer = st_ivas->hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc; cldfb_imag_buffer = st_ivas->hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc; - num_freq_bands = st_ivas->hDirAC->num_freq_bands; + num_freq_bands = st_ivas->hSpatParamRendCom->num_freq_bands; ivas_ism_param_dec_tc_gain_ajust( st_ivas, output_frame, output_frame / 2, tc ); } else if ( st_ivas->ivas_format == MC_FORMAT ) diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index 9ae580ae3a..02f663f668 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -491,7 +491,13 @@ ivas_error ivas_mc_paramupmix_dec_open( /* allocate transport channels*/ hMCParamUpmix->free_param_interpolator = 0; hMCParamUpmix->param_interpolator = NULL; - if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) + if ( +#ifdef API_5MS + st_ivas->hDecoderConfig->tsm_active == 1 +#else + st_ivas->hDecoderConfig->voip_active == 1 +#endif + && st_ivas->hTcBuffer == NULL ) { int16_t nchan_to_allocate; int16_t nchan_tc; diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index abc9a9012d..01dfa0f44a 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -518,7 +518,18 @@ void ivas_set_split_rend_setup( IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, IVAS if ( ( hCombinedOrientationData != NULL ) && ( hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) { - int16_t sf, i, j; + int16_t i, j; +#ifdef API_5MS + hCombinedOrientationData->Quaternion = hCombinedOrientationData->Quaternion; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + hCombinedOrientationData->Rmat[i][j] = hCombinedOrientationData->Rmat[i][j]; + } + } +#else + int16_t sf; for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) { hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0]; @@ -530,6 +541,7 @@ void ivas_set_split_rend_setup( IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, IVAS } } } +#endif } return; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index c1ae75b331..09801c0a62 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1428,8 +1428,6 @@ ivas_error IVAS_DEC_FeedHeadTrackData( for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { /* check for Euler angle signaling */ -#ifdef SPLIT_REND_WITH_HEAD_ROT -#endif { if ( orientation[i].w == -3.0f ) { @@ -1441,6 +1439,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( hHeadTrackData->Pos[i].y = Pos[i].y; hHeadTrackData->Pos[i].z = Pos[i].z; } +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT hHeadTrackData->num_quaternions = 0; diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index e3396bafe4..6db2a8ccce 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1829,6 +1829,16 @@ ivas_error ivas_rend_crendProcessSplitBin( combinedOrientationDataLocal = *pCombinedOrientationDataLocal; if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { +#ifdef API_5MS + combinedOrientationDataLocal.Quaternion = combinedOrientationDataLocal.Quaternion; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat[i][j] = combinedOrientationDataLocal.Rmat[i][j]; + } + } +#else for ( sf = 1; sf < RENDERER_HEAD_POSITIONS_PER_FRAME; ++sf ) { combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; @@ -1840,6 +1850,7 @@ ivas_error ivas_rend_crendProcessSplitBin( } } } +#endif } /* copy LFE to tmpLfeBuffer and apply gain only once */ @@ -1859,6 +1870,18 @@ ivas_error ivas_rend_crendProcessSplitBin( for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; ++pos_idx ) { /* Update head positions */ +#ifdef API_5MS + IVAS_QUATERNION Quaternion_orig, Quaternion_abs; + Quaternion_orig = combinedOrientationDataLocal.Quaternion; + Quaternion_abs.w = -3.0f; + Quat2EulerDegree( combinedOrientationDataLocal.Quaternion, &Quaternion_abs.z, &Quaternion_abs.y, &Quaternion_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternion_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternion_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternion_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + combinedOrientationDataLocal.Quaternion = Quaternion_abs; + QuatToRotMat( combinedOrientationDataLocal.Quaternion, combinedOrientationDataLocal.Rmat ); +#else IVAS_QUATERNION Quaternions_orig[RENDERER_HEAD_POSITIONS_PER_FRAME], Quaternions_abs; for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { @@ -1872,6 +1895,7 @@ ivas_error ivas_rend_crendProcessSplitBin( combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); } +#endif /* render inplace to first two channels of tmpInputBuffer */ pCombinedOrientationDataLocal = &combinedOrientationDataLocal; @@ -1889,6 +1913,9 @@ ivas_error ivas_rend_crendProcessSplitBin( hEFAPdata, p_tmpInputBuffer, output_Fs, +#ifdef API_5MS + 4, +#endif pos_idx ) ) != IVAS_ERR_OK ) { return error; @@ -1914,10 +1941,14 @@ ivas_error ivas_rend_crendProcessSplitBin( } /* restore original headrotation data */ +#ifdef API_5MS + combinedOrientationDataLocal.Quaternion = Quaternion_orig; +#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; } +#endif } diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 0cb1ae05ac..4cdca32cb0 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -809,7 +809,11 @@ void ObjRenderIvasFrame_splitBinaural( float *p_tmpProcessing[MAX_OUTPUT_CHANNELS]; int16_t pos_idx; +#ifdef API_5MS + IVAS_QUATERNION originalHeadRot; +#else IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; BINAURAL_TD_OBJECT_RENDERER_HANDLE tmpTdRendHandle; @@ -837,10 +841,14 @@ void ObjRenderIvasFrame_splitBinaural( } /* Save current head positions */ +#ifdef API_5MS + originalHeadRot = st_ivas->hCombinedOrientationData->Quaternion; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) { originalHeadRot[i] = st_ivas->hCombinedOrientationData->Quaternions[i]; } +#endif /* Copy input audio to a processing buffer. Cannot render in-place because binaurally rendered * audio would overwrite original material, which is still needed for rendering next head pose. */ @@ -854,6 +862,26 @@ void ObjRenderIvasFrame_splitBinaural( /* Update head positions */ if ( pos_idx != 0 ) { +#ifdef API_5MS + if ( originalHeadRot.w == -3.0f ) + { + st_ivas->hCombinedOrientationData->Quaternion.w = -3.0f; + st_ivas->hCombinedOrientationData->Quaternion.x = originalHeadRot.x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; + st_ivas->hCombinedOrientationData->Quaternion.y = originalHeadRot.y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; + st_ivas->hCombinedOrientationData->Quaternion.z = originalHeadRot.z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + else + { + st_ivas->hCombinedOrientationData->Quaternion.w = -3.0f; + Quat2EulerDegree( originalHeadRot, /* TODO tmu : fix bug with ordering*/ + &st_ivas->hCombinedOrientationData->Quaternion.z, + &st_ivas->hCombinedOrientationData->Quaternion.y, + &st_ivas->hCombinedOrientationData->Quaternion.x ); + st_ivas->hCombinedOrientationData->Quaternion.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + st_ivas->hCombinedOrientationData->Quaternion.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + st_ivas->hCombinedOrientationData->Quaternion.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) { if ( originalHeadRot[i].w == -3.0f ) @@ -875,6 +903,7 @@ void ObjRenderIvasFrame_splitBinaural( st_ivas->hCombinedOrientationData->Quaternions[i].z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; } } +#endif } /* Handle the 1 ISM case where there is only one channel in the input buffer */ for ( i = 0; i < max( st_ivas->nchan_transport, BINAURAL_CHANNELS ); ++i ) @@ -916,10 +945,14 @@ void ObjRenderIvasFrame_splitBinaural( } /* Restore original head rotation */ +#ifdef API_5MS + st_ivas->hCombinedOrientationData->Quaternion = originalHeadRot; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) { st_ivas->hCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; } +#endif pop_wmops(); } diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 4c7c142f19..adac6aff17 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -909,7 +909,12 @@ void ivas_SplitRenderer_getdiagdiff( void ivas_split_rend_bitstream_write_int32( ivas_split_rend_bits_t *pBits, int32_t val, int32_t bits ); int32_t ivas_split_rend_bitstream_read_int32( ivas_split_rend_bits_t *pBits, int32_t bits ); IVAS_QUATERNION ivas_split_rend_get_sf_rot_data( +#ifdef API_5MS + /* TODO(splirend): clean up */ + const IVAS_QUATERNION headPositions[1], +#else const IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME], +#endif int16_t subframe_idx ); void ivas_rend_closeCldfbRend( CLDFB_REND_WRAPPER *pCldfbRend ); diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index c38deff1ef..e726d9b9ca 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -440,7 +440,7 @@ void rotateFrame_shd( hCombinedOrientationData->Rmat[subframe_idx][i], #endif #ifdef SPLIT_REND_WITH_HEAD_ROT - hCombinedOrientationData->Rmat_prev[0][i] + hCombinedOrientationData->Rmat_prev[0][i], #else hCombinedOrientationData->Rmat_prev[i], #endif @@ -1066,7 +1066,7 @@ ivas_error combine_external_and_head_orientations_dec( numHeadRotQuaternions, #endif hExtOrientationData, - hCombinedOrientationData, + hCombinedOrientationData ); } @@ -1730,7 +1730,16 @@ void external_target_interpolation( #endif /* Use the most recent external orientation as the starting orientation */ -#if defined FIX_570_SF_EXT_ORIENTATION || defined API_5MS +#ifdef API_5MS + if ( hExtOrientationData->enableExternalOrientation == 1 ) + { + hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternion_prev_extOrientation; + } + else if ( hExtOrientationData->enableExternalOrientation == 2 ) + { + hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternion_frozen_ext; + } +#elif defined FIX_570_SF_EXT_ORIENTATION if ( hExtOrientationData->enableExternalOrientation[i] == 1 ) { if ( i > 0 ) diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_rend/ivas_splitRenderer_utils.c index b1068054f8..faf62ba946 100644 --- a/lib_rend/ivas_splitRenderer_utils.c +++ b/lib_rend/ivas_splitRenderer_utils.c @@ -315,12 +315,21 @@ void ivas_split_rend_bitstream_write_int32( ivas_split_rend_bits_t *pBits, int32 } IVAS_QUATERNION ivas_split_rend_get_sf_rot_data( +#ifdef API_5MS + const IVAS_QUATERNION headPositions[1], +#else const IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME], +#endif int16_t subframe_idx ) { int16_t idx; +#ifdef API_5MS + /* TODO(splitrend): we no longer use subframes. Needs refactoring */ + idx = 0 * subframe_idx; /* tmp change */ +#else idx = ( subframe_idx * RENDERER_HEAD_POSITIONS_PER_FRAME ) / MAX_PARAM_SPATIAL_SUBFRAMES; +#endif return headPositions[idx]; } diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index d24521e1a5..a983c701fc 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -882,6 +882,7 @@ typedef struct ivas_combined_orientation_struct #else IVAS_QUATERNION Quaternions_prev_headRot[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_QUATERNION Quaternions_prev_extOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif #endif IVAS_QUATERNION Quaternions_ext_interpolation_start; IVAS_QUATERNION Quaternions_ext_interpolation_target; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 7236c5d468..f63b2a6392 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -5527,6 +5527,26 @@ static void renderBufferChannel( return; } +#ifdef API_5MS +static ivas_error chooseCrossfade( const IVAS_REND_HeadRotData *headRotData, int16_t numSamplesPerChannel, const float **pCrossfade ) +{ + if ( numSamplesPerChannel == L_FRAME48k ) + { + *pCrossfade = headRotData->crossfade_20ms; + } + else if ( numSamplesPerChannel == L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) + { + *pCrossfade = headRotData->crossfade_5ms; + } + else + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Only 5 and 20 ms framing is supported" ); + } + + return IVAS_ERR_OK; +} +#endif + static ivas_error rotateFrameMc( IVAS_REND_AudioBuffer inAudio, /* i : Input Audio buffer */ IVAS_REND_AudioConfig inConfig, /* i : Input Audio config */ @@ -5564,17 +5584,9 @@ static ivas_error rotateFrameMc( push_wmops( "rotateFrameMc" ); #ifdef LIB_REND_API_5MS - if ( inAudio.config.numSamplesPerChannel == L_FRAME48k ) - { - crossfade = headRotData->crossfade_20ms; - } - else if ( inAudio.config.numSamplesPerChannel == L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) + if ( ( error = chooseCrossfade( headRotData, inAudio.config.numSamplesPerChannel, &crossfade ) ) != IVAS_ERR_OK ) { - crossfade = headRotData->crossfade_5ms; - } - else - { - return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Only 5 and 20 ms framing is supported" ); + return error; } #endif @@ -5748,17 +5760,9 @@ static ivas_error rotateFrameSba( push_wmops( "rotateFrameSba" ); #ifdef LIB_REND_API_5MS - if ( inAudio.config.numSamplesPerChannel == L_FRAME48k ) - { - crossfade = headRotData->crossfade_20ms; - } - else if ( inAudio.config.numSamplesPerChannel == L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) - { - crossfade = headRotData->crossfade_5ms; - } - else + if ( ( error = chooseCrossfade( headRotData, inAudio.config.numSamplesPerChannel, &crossfade ) ) != IVAS_ERR_OK ) { - return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Only 5 and 20 ms framing is supported" ); + return error; } #endif @@ -5811,8 +5815,13 @@ static ivas_error rotateFrameSba( for ( i = 0; i < subframe_len; i++ ) #endif { +#ifdef API_5MS + idx = i; + cf = crossfade[i]; +#else idx = subframe_idx * subframe_len + i; cf = headRotData->crossfade[i]; +#endif oneminuscf = 1 - cf; /* As the rotation matrix becomes block diagonal in a SH basis, we can*/ /* apply each angular-momentum block individually to save complexity. */ @@ -6296,7 +6305,11 @@ static ivas_error renderIsmToSplitBinaural( int16_t pos_idx; const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; const SPLIT_REND_WRAPPER *pSplitRendWrapper; +#ifdef API_5MS + IVAS_QUATERNION originalHeadRot; +#else IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif float tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; int16_t output_frame = ismInput->base.inputBuffer.config.numSamplesPerChannel; COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; @@ -6338,17 +6351,25 @@ static ivas_error renderIsmToSplitBinaural( if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { +#ifdef API_5MS + pCombinedOrientationData->Quaternion = pCombinedOrientationData->Quaternion; +#else for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) { pCombinedOrientationData->Quaternions[i] = pCombinedOrientationData->Quaternions[0]; } +#endif } /* Save current head positions */ +#ifdef API_5MS + originalHeadRot = pCombinedOrientationData->Quaternion; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) { originalHeadRot[i] = pCombinedOrientationData->Quaternions[i]; } +#endif /* Copy input audio to a processing buffer. */ copyBufferTo2dArray( ismInput->base.inputBuffer, tmpProcessing ); -- GitLab From 68b6fc68ec50c6c073ed78ad5950afd7ac3dcabe Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Mon, 31 Jul 2023 16:31:53 +0200 Subject: [PATCH 55/66] Fixing build errors WIP (pt. 2) --- apps/decoder.c | 29 +++++++++-- apps/renderer.c | 7 ++- lib_com/options.h | 2 +- lib_dec/ivas_binRenderer_internal.c | 6 ++- lib_dec/lib_dec.c | 13 ++++- lib_rend/ivas_prot_rend.h | 6 ++- lib_rend/lib_rend.c | 77 +++++++++++++++++++++++++++++ 7 files changed, 131 insertions(+), 9 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index cb78f9dafd..c7f60e33c5 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1800,6 +1800,9 @@ static ivas_error decodeG192( RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, +#ifdef SPLIT_REND_WITH_HEAD_ROT + uint8_t *splitRendBitsBuf, +#endif IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ) @@ -1955,7 +1958,12 @@ static ivas_error decodeG192( } - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos +#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; @@ -2040,7 +2048,12 @@ static ivas_error decodeG192( goto cleanup; } } - error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nOutChannels * nSamplesRendered, &nSamplesRendered_loop, &needNewFrame ); + error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nOutChannels * nSamplesRendered, &nSamplesRendered_loop, &needNewFrame +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + NULL /* TODO(sgi): pass IVAS_SPLIT_REND_BITS_HANDLE or change API so that split rendering has its dedicated GetSamples function */ +#endif + ); nSamplesRendered += nSamplesRendered_loop; nSamplesToRender -= nSamplesRendered_loop; if ( error != IVAS_ERR_OK ) @@ -2082,7 +2095,11 @@ static ivas_error decodeG192( &masaWriter, ismWriters, &nOutChannels, - &numObj ); + &numObj +#ifdef SPLIT_REND_WITH_HEAD_ROT + ,NULL /* TODO(sgi): see #else branch for reference */ +#endif + ); if ( error != IVAS_ERR_OK ) { goto cleanup; @@ -2237,7 +2254,11 @@ static ivas_error decodeG192( } - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos +#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; diff --git a/apps/renderer.c b/apps/renderer.c index b620a714da..8b4dbe8201 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1574,7 +1574,12 @@ int main( fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + DEFAULT_AXIS +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); diff --git a/lib_com/options.h b/lib_com/options.h index cd0431444d..cb7750d46f 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -166,7 +166,7 @@ #define API_5MS #ifdef API_5MS #define JITTER_MEM_OPTIM_RENDERING -#define LIB_REND_API_5MS /* FhG: Adds 5ms framing capability to lib_rend */ +#define LIB_REND_API_5MS /* FhG: Adds 5ms framing capability to lib_rend */ /* TODO(sgi): needs to be joined with API_5MS */ #endif #define LIB_REND_FIX_HRTFPARAMBIN_MEMLEAK // 5 ms branch switches end diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 3f6494b0ff..a7fceba53d 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1769,7 +1769,11 @@ void ivas_rend_CldfbMultiBinRendProcess( ivas_binRenderer( hCldfbRend, pMultiBinPoseData, - *pCombinedOrientationData, sf_idx, MAX_PARAM_SPATIAL_SUBFRAMES, + *pCombinedOrientationData, +#ifndef API_5MS + sf_idx, +#endif + MAX_PARAM_SPATIAL_SUBFRAMES, #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG &head_track_post, #endif diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 09801c0a62..05a1230dd7 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -857,6 +857,10 @@ ivas_error IVAS_DEC_GetSamples( int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ bool *needNewFrame /* indication that the decoder needs a new frame */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits /* o : bitstream output for split rendering mode*/ +#endif ) { ivas_error error; @@ -1442,7 +1446,9 @@ ivas_error IVAS_DEC_FeedHeadTrackData( #endif #ifdef SPLIT_REND_WITH_HEAD_ROT +#ifndef API_5MS hHeadTrackData->num_quaternions = 0; +#endif #else hIvasDec->st_ivas->hHeadTrackData->num_quaternions = 0; #endif @@ -2265,7 +2271,12 @@ ivas_error IVAS_DEC_VoIP_GetSamples( nSamplesToRender = nSamplesPerChannel - nSamplesRendered; /* render IVAS frames directly to the output buffer */ - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nSamplesRendered * nOutChannels, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nSamplesRendered * nOutChannels, &nSamplesRendered_loop, &tmp +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + NULL /* TODO(sgi): pass hSplitRendBits here or create separate get samples function for split rendering */ +#endif + ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index adac6aff17..747cf7e17c 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -910,7 +910,7 @@ void ivas_split_rend_bitstream_write_int32( ivas_split_rend_bits_t *pBits, int32 int32_t ivas_split_rend_bitstream_read_int32( ivas_split_rend_bits_t *pBits, int32_t bits ); IVAS_QUATERNION ivas_split_rend_get_sf_rot_data( #ifdef API_5MS - /* TODO(splirend): clean up */ + /* TODO(splitrend): clean up */ const IVAS_QUATERNION headPositions[1], #else const IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME], @@ -1494,7 +1494,11 @@ void ivas_renderSplitUpdateNoCorrectionPoseData( ivas_error ivas_renderMultiBinToSplitBinaural( SPLIT_REND_WRAPPER *hSplitBin, +#ifdef API_5MS + const IVAS_QUATERNION headPosition[MAX_PARAM_SPATIAL_SUBFRAMES], +#else const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], +#endif const int32_t SplitRendBitRate, IVAS_SPLIT_REND_CODEC splitCodec, ivas_split_rend_bits_t *pBits, diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index f63b2a6392..f0a05b9f93 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -6379,6 +6379,26 @@ static ivas_error renderIsmToSplitBinaural( /* Update head positions */ if ( pos_idx != 0 ) { +#ifdef API_5MS + if ( originalHeadRot.w == -3.0f ) + { + pCombinedOrientationData->Quaternion.w = -3.0f; + pCombinedOrientationData->Quaternion.x = originalHeadRot.x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; + pCombinedOrientationData->Quaternion.y = originalHeadRot.y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; + pCombinedOrientationData->Quaternion.z = originalHeadRot.z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + else + { + pCombinedOrientationData->Quaternion.w = -3.0f; + Quat2EulerDegree( originalHeadRot, + &pCombinedOrientationData->Quaternion.z, + &pCombinedOrientationData->Quaternion.y, + &pCombinedOrientationData->Quaternion.x ); + pCombinedOrientationData->Quaternion.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + pCombinedOrientationData->Quaternion.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + pCombinedOrientationData->Quaternion.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) { if ( originalHeadRot[i].w == -3.0f ) @@ -6400,6 +6420,7 @@ static ivas_error renderIsmToSplitBinaural( pCombinedOrientationData->Quaternions[i].z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; } } +#endif } /* Render */ @@ -6449,10 +6470,14 @@ static ivas_error renderIsmToSplitBinaural( copyBufferTo2dArray( ismInput->base.inputBuffer, tmpProcessing ); } /* Restore original head rotation */ +#ifdef API_5MS + pCombinedOrientationData->Quaternion = originalHeadRot; +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) { pCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; } +#endif accumulate2dArrayToBuffer( tmpBinaural, &outAudio ); pop_wmops(); @@ -7177,6 +7202,16 @@ static ivas_error renderMcToSplitBinaural( combinedOrientationDataLocal = *pCombinedOrientationDataLocal; if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { +#ifdef API_5MS + combinedOrientationDataLocal.Quaternion = combinedOrientationDataLocal.Quaternion; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat[i][j] = combinedOrientationDataLocal.Rmat[i][j]; + } + } +#else for ( sf = 1; sf < RENDERER_HEAD_POSITIONS_PER_FRAME; ++sf ) { combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; @@ -7188,12 +7223,25 @@ static ivas_error renderMcToSplitBinaural( } } } +#endif } for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) { /* Update head positions */ +#ifdef API_5MS + IVAS_QUATERNION Quaternion_orig, Quaternion_abs; + Quaternion_orig = combinedOrientationDataLocal.Quaternion; + Quaternion_abs.w = -3.0f; + Quat2EulerDegree( combinedOrientationDataLocal.Quaternion, &Quaternion_abs.z, &Quaternion_abs.y, &Quaternion_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternion_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternion_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternion_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + combinedOrientationDataLocal.Quaternion = Quaternion_abs; + QuatToRotMat( combinedOrientationDataLocal.Quaternion, combinedOrientationDataLocal.Rmat ); +#else IVAS_QUATERNION Quaternions_orig[RENDERER_HEAD_POSITIONS_PER_FRAME], Quaternions_abs; for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { @@ -7207,6 +7255,7 @@ static ivas_error renderMcToSplitBinaural( combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); } +#endif if ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM || inConfig == IVAS_REND_AUDIO_CONFIG_5_1 || inConfig == IVAS_REND_AUDIO_CONFIG_7_1 ) { @@ -7298,10 +7347,14 @@ static ivas_error renderMcToSplitBinaural( } /* restore original headrotation data */ +#ifdef API_5MS + combinedOrientationDataLocal.Quaternion = Quaternion_orig; +#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; } +#endif } /* TODO tmu : needs delay compensation */ @@ -7690,6 +7743,16 @@ static ivas_error renderSbaToMultiBinaural( combinedOrientationDataLocal = *pCombinedOrientationDataLocal; if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { +#ifdef API_5MS + combinedOrientationDataLocal.Quaternion = combinedOrientationDataLocal.Quaternion; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat[i][j] = combinedOrientationDataLocal.Rmat[i][j]; + } + } +#else for ( sf = 1; sf < RENDERER_HEAD_POSITIONS_PER_FRAME; sf++ ) { combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; @@ -7701,6 +7764,7 @@ static ivas_error renderSbaToMultiBinaural( } } } +#endif } tmpRotBuffer = sbaInput->base.inputBuffer; @@ -7708,6 +7772,18 @@ static ivas_error renderSbaToMultiBinaural( for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) { +#ifdef API_5MS + IVAS_QUATERNION Quaternion_orig, Quaternion_abs; + Quaternion_orig = combinedOrientationDataLocal.Quaternion; + Quaternion_abs.w = -3.0f; + Quat2EulerDegree( combinedOrientationDataLocal.Quaternion, &Quaternion_abs.z, &Quaternion_abs.y, &Quaternion_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternion_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternion_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternion_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + combinedOrientationDataLocal.Quaternion = Quaternion_abs; + QuatToRotMat( combinedOrientationDataLocal.Quaternion, combinedOrientationDataLocal.Rmat ); +#else IVAS_QUATERNION Quaternions_orig[RENDERER_HEAD_POSITIONS_PER_FRAME], Quaternions_abs; for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { @@ -7721,6 +7797,7 @@ static ivas_error renderSbaToMultiBinaural( combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); } +#endif /* copy input for in-place rotation */ -- GitLab From 2b11e9ab474310cb00f0e3a941341bcaa94e93f7 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Tue, 1 Aug 2023 14:24:07 +0200 Subject: [PATCH 56/66] fix small merge error in ParamISM decoding function --- lib_dec/ivas_ism_param_dec.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 97fc604794..ac816b4e8e 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -790,29 +790,15 @@ void ivas_param_ism_dec( /* Initialization */ hDirAC = st_ivas->hDirAC; assert( hDirAC ); -// sgi2bay: please review merge -// <<<<<<< HEAD -// #ifdef FIX_549_DMX_GAIN -// #ifdef API_5MS -// for ( i = 0; i < PARAM_ISM_MAX_DMX; i++ ) -// { -// p_tc[i] = output_f[i]; -// } -// #else -// ======= -// hSpatParamRendCom = st_ivas->hSpatParamRendCom; -// assert( hSpatParamRendCom ); -// >>>>>>> main -// merged to: + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + assert( hSpatParamRendCom ); #ifdef API_5MS for ( i = 0; i < PARAM_ISM_MAX_DMX; i++ ) { p_tc[i] = output_f[i]; } #else - hSpatParamRendCom = st_ivas->hSpatParamRendCom; - assert( hSpatParamRendCom ); -// merge end + ene_tc = 0.0f; ene_sum = 0.0f; last_gain = st_ivas->hDirAC->hParamIsm->last_dmx_gain; -- GitLab From 00fe90ba356b6edc72658f384c871a2fa817b98f Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Tue, 1 Aug 2023 14:26:36 +0200 Subject: [PATCH 57/66] small merge error fix --- lib_dec/ivas_ism_param_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index ac816b4e8e..06208595a7 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1157,10 +1157,10 @@ void ivas_param_ism_dec_digest_tc( /* Initialization */ hDirAC = st_ivas->hDirAC; assert( hDirAC ); -#ifndef API_5MS -#ifdef FIX_549_DMX_GAIN hSpatParamRendCom = st_ivas->hSpatParamRendCom; assert( hSpatParamRendCom ); +#ifndef API_5MS +#ifdef FIX_549_DMX_GAIN ene_tc = 0.0f; ene_sum = 0.0f; last_gain = st_ivas->hDirAC->hParamIsm->last_dmx_gain; -- GitLab From 9dc8cab2c330d9bd8fc9a127fdf0812b92b8d398 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Tue, 1 Aug 2023 14:32:19 +0200 Subject: [PATCH 58/66] reviewed merge conflict solution --- lib_dec/ivas_dirac_dec.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 6ecb4affbd..a8f81b21a3 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1502,23 +1502,11 @@ void ivas_dirac_dec_set_md_map( num_slots_in_subfr = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; hSpatParamRendCom->subframes_rendered = 0; -// sgi2bay: please review -// <<<<<<< HEAD -// ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hDirAC->subframe_nbslots, &hDirAC->nb_subframes ); -// #ifdef API_5MS -// st_ivas->hTcBuffer->nb_subframes = hDirAC->nb_subframes; -// mvs2s( hDirAC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hDirAC->nb_subframes ); -// #endif -// ======= -// ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hSpatParamRendCom->subframe_nbslots, &hSpatParamRendCom->nb_subframes ); -// >>>>>>> main -// merged to: ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hSpatParamRendCom->subframe_nbslots, &hSpatParamRendCom->nb_subframes ); #ifdef API_5MS st_ivas->hTcBuffer->nb_subframes = hSpatParamRendCom->nb_subframes; mvs2s( hSpatParamRendCom->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hSpatParamRendCom->nb_subframes ); #endif -// end merge /* set mapping according to dirac_read_idx */ -- GitLab From c4a3807589fecf564c4a5fae9c82b6d9afa26e58 Mon Sep 17 00:00:00 2001 From: Treffehn Date: Tue, 1 Aug 2023 09:58:34 +0200 Subject: [PATCH 59/66] removed redundant variable --- lib_dec/lib_dec.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 05a1230dd7..e062188480 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -96,7 +96,6 @@ struct IVAS_DEC int16_t bitstreamformat; /* Bitstream format flag (G.192/MIME/VOIP_G192_RTP/VOIP_RTPDUMP) */ bool Opt_VOIP; /* flag indicating VOIP mode with JBM */ #ifdef API_5MS - bool Opt_TSM; /* flag indicating TSM mode*/ int16_t tsm_scale; /* scale for TSM operation */ int16_t tsm_max_scaling; float *apaExecBuffer; /* Buffer for APA scaling */ @@ -169,7 +168,6 @@ ivas_error IVAS_DEC_Open( #ifdef API_5MS hIvasDec->apaExecBuffer = NULL; hIvasDec->hTimeScaler = NULL; - hIvasDec->Opt_TSM = false; hIvasDec->tsm_scale = 100; hIvasDec->needNewFrame = false; hIvasDec->nTransportChannelsOld = 0; @@ -544,7 +542,6 @@ ivas_error IVAS_DEC_Configure( #ifdef API_5MS hDecoderConfig->tsm_active = tsmEnabled; - hIvasDec->Opt_TSM = tsmEnabled; hIvasDec->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); hIvasDec->nSamplesAvailableNext = 0; hIvasDec->nSamplesRendered = 0; @@ -591,7 +588,6 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->Opt_VOIP = 1; #ifdef API_5MS - hIvasDec->Opt_TSM = 1; hDecoderConfig->tsm_active = 1; #else hDecoderConfig->voip_active = 1; @@ -921,7 +917,7 @@ ivas_error IVAS_DEC_GetSamples( return error; } - if ( hIvasDec->Opt_TSM ) + if ( hIvasDec->st_ivas->hDecoderConfig->tsm_active ) { if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) { @@ -948,7 +944,7 @@ ivas_error IVAS_DEC_GetSamples( return error; } - if ( hIvasDec->Opt_TSM ) + if ( hIvasDec->st_ivas->hDecoderConfig->tsm_active ) { /* feed residual samples to TSM for the next call */ if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) @@ -2090,7 +2086,7 @@ ivas_error IVAS_DEC_VoIP_SetScale( error = IVAS_ERR_OK; #ifdef API_5MS - if ( hIvasDec->Opt_TSM == false ) + if ( hIvasDec->st_ivas->hDecoderConfig->tsm_active == false ) { return IVAS_ERR_TSM_NOT_ENABLED; } @@ -3647,7 +3643,7 @@ ivas_error IVAS_DEC_reconfigure( DECODER_CONFIG_HANDLE hDecoderConfig; #ifdef API_5MS - if ( hIvasDec->Opt_TSM ) + if ( hIvasDec->st_ivas->hDecoderConfig->tsm_active ) { uint16_t wss, css; float startQuality; @@ -3779,7 +3775,7 @@ ivas_error IVAS_DEC_reconfigure( else { #ifdef API_5MS - if ( hIvasDec->Opt_TSM ) + if ( hIvasDec->st_ivas->hDecoderConfig->tsm_active ) { if ( apa_reconfigure( hIvasDec->hTimeScaler, nTransportChannels, l_ts ) != 0 ) #else -- GitLab From 9574ba1f27ac0647a12bee188fe7965d3bc01435 Mon Sep 17 00:00:00 2001 From: Treffehn Date: Tue, 1 Aug 2023 16:43:59 +0200 Subject: [PATCH 60/66] fix compilation with API_5MS switch disabled --- lib_dec/ivas_jbm_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 9cc79be379..e1ebe3fa1f 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -949,7 +949,7 @@ ivas_error ivas_jbm_dec_render( #ifdef JITTER_MEM_OPTIM_RENDERING nSamplesRenderedLocal, #else - *nSamplesRendered + *nSamplesRendered, #endif #ifdef JBM_PARAMUPMIX st_ivas->hTcBuffer->nb_subframes, -- GitLab From 5d0c233ee7943c488bd2c0a631d97dd71bcfe013 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 2 Aug 2023 08:27:19 +0200 Subject: [PATCH 61/66] Add first draft of IVAS_DEC_GetSplitBinaural (untested) --- lib_dec/lib_dec.c | 90 +++++++++++++++++++++++++++++++- lib_dec/lib_dec.h | 10 +++- lib_rend/ivas_prot_rend.h | 2 +- lib_rend/ivas_splitRendererPre.c | 8 +++ 4 files changed, 106 insertions(+), 4 deletions(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 05a1230dd7..bd6dd5b0a1 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -857,9 +857,9 @@ ivas_error IVAS_DEC_GetSamples( int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ bool *needNewFrame /* indication that the decoder needs a new frame */ -#ifdef SPLIT_REND_WITH_HEAD_ROT +#if defined SPLIT_REND_WITH_HEAD_ROT && !defined API_5MS , - IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits /* o : bitstream output for split rendering mode*/ + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits /* o : bitstream output for split rendering mode*/ #endif ) { @@ -983,6 +983,92 @@ ivas_error IVAS_DEC_GetSamples( } #endif +#if defined API_5MS && defined SPLIT_REND_WITH_HEAD_ROT +ivas_error IVAS_DEC_GetSplitBinaural( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + bool *needNewFrame, /* indication that the decoder needs a new frame */ + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits /* o : bitstream output for split rendering mode*/ +) +{ + Decoder_Struct *st_ivas; + AUDIO_CONFIG output_config; + int32_t output_Fs; + float output[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; + int16_t output_int[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k]; /* TODO(sgi): Need conversion */ + int16_t numSamplesPerChannel, nOutSamples; + int16_t i, j; + ivas_error error; + + error = IVAS_ERR_OK; + st_ivas = hIvasDec->st_ivas; + output_config = st_ivas->hDecoderConfig->output_config; + output_Fs = st_ivas->hDecoderConfig->output_Fs; + numSamplesPerChannel = output_Fs / FRAMES_PER_SEC; /* TODO(sgi): Accommodate 5ms framing */ + + if ( output_config != AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + return IVAS_ERR_WRONG_PARAMS; + } + + while ( error == IVAS_ERR_OK ) + { + /* Decode and render */ + if ( ( error = IVAS_DEC_GetSamples( + hIvasDec, + numSamplesPerChannel, + output_int, + &nOutSamples, + needNewFrame ) ) != IVAS_ERR_OK ) + { + return error; + } + + /*split rendering process calls*/ + IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend; + int16_t max_band; + int16_t pcm_out; + int16_t numPoses; + + hSplitBinRend = &st_ivas->splitBinRend; + + ivas_set_split_rend_setup(hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, hSplitRendBits ); + + numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; + + /* [tmp] convert int back to float and change buffer layout */ + for (i = 0; i < numSamplesPerChannel; ++i) + { + for (j = 0; j < BINAURAL_CHANNELS * numPoses; ++j) + { + output[j][i] = (float) output_int[i * BINAURAL_CHANNELS * numPoses + j]; + } + } + + max_band = (int16_t) ( ( BINAURAL_MAXBANDS * output_Fs ) / 48000 ); + pcm_out = ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + + error = ivas_renderMultiBinToSplitBinaural( &hSplitBinRend->splitrend, + st_ivas->hHeadTrackData->Quaternion, + st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, + st_ivas->hRenderConfig->split_rend_config.codec, + hSplitBinRend->hSplitRendBits, + hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural, + hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural, + max_band, output, 1, + st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV, + pcm_out ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + + free( st_ivas->splitBinRend.hMultiBinCldfbData ); + } + + return error; +} +#endif + /*---------------------------------------------------------------------* * IVAS_DEC_Setup( ) diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 04b60f7e95..7ad7a6d87d 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -188,12 +188,20 @@ ivas_error IVAS_DEC_GetSamples( int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ #endif -#ifdef SPLIT_REND_WITH_HEAD_ROT +#if defined SPLIT_REND_WITH_HEAD_ROT && !defined API_5MS , IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits /* o : bitstream output for split rendering mode*/ #endif ); +#if defined API_5MS && defined SPLIT_REND_WITH_HEAD_ROT +ivas_error IVAS_DEC_GetSplitBinaural( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + bool *needNewFrame, /* indication that the decoder needs a new frame */ + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits /* o : bitstream output for split rendering mode*/ +); +#endif + /*! r: error code */ ivas_error IVAS_DEC_GetObjectMetadata( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 747cf7e17c..5535ced049 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1495,7 +1495,7 @@ void ivas_renderSplitUpdateNoCorrectionPoseData( ivas_error ivas_renderMultiBinToSplitBinaural( SPLIT_REND_WRAPPER *hSplitBin, #ifdef API_5MS - const IVAS_QUATERNION headPosition[MAX_PARAM_SPATIAL_SUBFRAMES], + const IVAS_QUATERNION headPosition, #else const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], #endif diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c index 1b8a157f5b..64acb14760 100644 --- a/lib_rend/ivas_splitRendererPre.c +++ b/lib_rend/ivas_splitRendererPre.c @@ -1897,7 +1897,11 @@ static ivas_error splitRendLc3plusEncodeAndWrite( static ivas_error ivas_renderMultiTDBinToSplitBinaural( SPLIT_REND_WRAPPER *hSplitBin, +#ifdef API_5MS + const IVAS_QUATERNION headPosition, +#else const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], +#endif const int32_t SplitRendBitRate, ivas_split_rend_bits_t *pBits, const int16_t max_bands, @@ -2095,7 +2099,11 @@ static void lc3plusTimeAlignCldfbPoseCorr( ivas_error ivas_renderMultiBinToSplitBinaural( SPLIT_REND_WRAPPER *hSplitBin, +#ifdef API_5MS + const IVAS_QUATERNION headPosition, +#else const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], +#endif const int32_t SplitRendBitRate, IVAS_SPLIT_REND_CODEC splitCodec, ivas_split_rend_bits_t *pBits, -- GitLab From cd639983e689650001509d1931065e91605d08ca Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 2 Aug 2023 09:26:19 +0200 Subject: [PATCH 62/66] Fix build errors --- apps/decoder.c | 7 +----- lib_dec/lib_dec.c | 7 +----- lib_rend/ivas_prot_rend.h | 4 ++++ lib_rend/ivas_splitRendererPre.c | 33 ++++++++++++++++++++++++++++- lib_rend/ivas_splitRenderer_utils.c | 11 ++-------- lib_rend/lib_rend.c | 22 +++++++++++++++++-- 6 files changed, 60 insertions(+), 24 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index c7f60e33c5..6202d48394 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -2048,12 +2048,7 @@ static ivas_error decodeG192( goto cleanup; } } - error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nOutChannels * nSamplesRendered, &nSamplesRendered_loop, &needNewFrame -#ifdef SPLIT_REND_WITH_HEAD_ROT - , - NULL /* TODO(sgi): pass IVAS_SPLIT_REND_BITS_HANDLE or change API so that split rendering has its dedicated GetSamples function */ -#endif - ); + error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nOutChannels * nSamplesRendered, &nSamplesRendered_loop, &needNewFrame ); nSamplesRendered += nSamplesRendered_loop; nSamplesToRender -= nSamplesRendered_loop; if ( error != IVAS_ERR_OK ) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 69f63607b2..8b49a653ff 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -2353,12 +2353,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( nSamplesToRender = nSamplesPerChannel - nSamplesRendered; /* render IVAS frames directly to the output buffer */ - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nSamplesRendered * nOutChannels, &nSamplesRendered_loop, &tmp -#ifdef SPLIT_REND_WITH_HEAD_ROT - , - NULL /* TODO(sgi): pass hSplitRendBits here or create separate get samples function for split rendering */ -#endif - ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nSamplesRendered * nOutChannels, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 5535ced049..941eeff6c2 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1513,7 +1513,11 @@ ivas_error ivas_renderMultiBinToSplitBinaural( void ivas_rend_CldfbSplitPreRendProcess( const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, +#ifdef API_5MS + const IVAS_QUATERNION headPosition, +#else const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], +#endif MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c index 64acb14760..f98e09d2ea 100644 --- a/lib_rend/ivas_splitRendererPre.c +++ b/lib_rend/ivas_splitRendererPre.c @@ -1037,7 +1037,11 @@ static void ivas_SplitRenderer_code_md_huff( static void ivas_SplitRenderer_quant_code( const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, +#ifdef API_5MS + const IVAS_QUATERNION headPosition, +#else const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], +#endif MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, ivas_split_rend_bits_t *pBits, const int16_t low_res_pre_rend_rot, @@ -1072,7 +1076,12 @@ static void ivas_SplitRenderer_quant_code( { int16_t angle; IVAS_QUATERNION head_pos_euler; +#ifdef API_5MS + /* FhG@Dolby: please review, this can be likely optimised */ + Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x ); +#else Quat2EulerDegree( headPositions[sf_idx], &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x ); +#endif angle = (int16_t) roundf( head_pos_euler.x ); angle += 180; ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); @@ -1395,7 +1404,11 @@ void ivas_SplitRenderer_GetRotMd( void ivas_rend_CldfbSplitPreRendProcess( const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, +#ifdef API_5MS + const IVAS_QUATERNION headPosition, +#else const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], +#endif MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], @@ -1414,7 +1427,11 @@ void ivas_rend_CldfbSplitPreRendProcess( ivas_SplitRenderer_quant_code( hBinHrSplitPreRend, +#ifdef API_5MS + headPosition, +#else headPositions, +#endif pMultiBinPoseData, pBits, low_res_pre_rend_rot, @@ -1992,7 +2009,11 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( actual_md_bits = pBits->bits_written; ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, +#ifdef API_5MS + headPosition, +#else headPositions, +#endif &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, @@ -2134,7 +2155,13 @@ ivas_error ivas_renderMultiBinToSplitBinaural( { /*TD input*/ /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ - error = ivas_renderMultiTDBinToSplitBinaural( hSplitBin, headPositions, SplitRendBitRate, pBits, max_bands, out, + error = ivas_renderMultiTDBinToSplitBinaural( hSplitBin, +#ifdef API_5MS + headPosition, +#else + headPositions, +#endif + SplitRendBitRate, pBits, max_bands, out, low_res_pre_rend_rot, pcm_out ); pop_wmops(); return error; @@ -2153,7 +2180,11 @@ ivas_error ivas_renderMultiBinToSplitBinaural( actual_md_bits = pBits->bits_written; ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, +#ifdef API_5MS + headPosition, +#else headPositions, +#endif &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_rend/ivas_splitRenderer_utils.c index faf62ba946..df0863e773 100644 --- a/lib_rend/ivas_splitRenderer_utils.c +++ b/lib_rend/ivas_splitRenderer_utils.c @@ -314,24 +314,17 @@ void ivas_split_rend_bitstream_write_int32( ivas_split_rend_bits_t *pBits, int32 return; } +#ifndef API_5MS IVAS_QUATERNION ivas_split_rend_get_sf_rot_data( -#ifdef API_5MS - const IVAS_QUATERNION headPositions[1], -#else const IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME], -#endif int16_t subframe_idx ) { int16_t idx; -#ifdef API_5MS - /* TODO(splitrend): we no longer use subframes. Needs refactoring */ - idx = 0 * subframe_idx; /* tmp change */ -#else idx = ( subframe_idx * RENDERER_HEAD_POSITIONS_PER_FRAME ) / MAX_PARAM_SPATIAL_SUBFRAMES; -#endif return headPositions[idx]; } +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index f0a05b9f93..f3878b0e23 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -7311,7 +7311,11 @@ static ivas_error renderMcToSplitBinaural( pCombinedOrientationDataLocal = &combinedOrientationDataLocal; if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, +#ifdef API_5MS + &mcInput->customLsInput, +#else mcInput->customLsInput, +#endif mcInput->base.ctx.pHeadRotData, &pCombinedOrientationDataLocal, mcInput->rot_gains_prev, @@ -7333,6 +7337,9 @@ static ivas_error renderMcToSplitBinaural( NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, +#ifdef API_5MS + 4, +#endif pos_idx ) ) != IVAS_ERR_OK ) { return error; @@ -7557,7 +7564,7 @@ static ivas_error renderSplitBinauralWithPostRot( float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; ivas_error error; - IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; /* TODO(splitrend): remove subframes */ int16_t sf_idx; ivas_split_rend_bits_t bits; float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; @@ -7600,7 +7607,11 @@ static ivas_error renderSplitBinauralWithPostRot( for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) { +#ifdef API_5MS + QuaternionsPost[sf_idx] = pCombinedOrientationData->Quaternion; +#else QuaternionsPost[sf_idx] = ivas_split_rend_get_sf_rot_data( pCombinedOrientationData->Quaternions, sf_idx ); +#endif } if ( !SplitRendBFI ) @@ -7820,15 +7831,22 @@ static ivas_error renderSbaToMultiBinaural( NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, +#ifdef API_5MS + 4, +#endif pos_idx ) ) != IVAS_ERR_OK ) { return error; } +#ifdef API_5MS + combinedOrientationDataLocal.Quaternion = Quaternion_orig; +#else for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; } +#endif /* move to output */ for ( i = 0; i < BINAURAL_CHANNELS; i++ ) @@ -9040,7 +9058,7 @@ ivas_error IVAS_REND_GetSamples( /* Encode split rendering bitstream */ convertBitsBufferToInternalBitsBuff( *hBits, &bits ); error = ivas_renderMultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, - hIvasRend->headRotData.headPositions, + hIvasRend->headRotData.headPosition, hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, hIvasRend->hRendererConfig->split_rend_config.codec, &bits, -- GitLab From 4f1720b0410cc35d5a207458044f4a63e566e5e3 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 2 Aug 2023 10:00:55 +0200 Subject: [PATCH 63/66] Port split rendering changes to new version of decodeG192 --- apps/decoder.c | 89 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 6202d48394..55b33d2bc6 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1839,6 +1839,10 @@ static ivas_error decodeG192( IVAS_VECTOR3 Pos; int16_t vec_pos_update, vec_pos_len; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_BITS splitRendBits; + SplitFileReadWrite *hSplitRendFileReadWrite; +#endif for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { @@ -1901,6 +1905,15 @@ static ivas_error decodeG192( nOutSamples = (int16_t) ( arg.output_Fs / 1000 * DEFAULT_FETCH_FRAMESIZE_MS ); vec_pos_len = 1; } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + splitRendBits.bits_buf = splitRendBitsBuf; + splitRendBits.bits_read = 0; + splitRendBits.bits_written = 0; + splitRendBits.buf_len = MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; + hSplitRendFileReadWrite = NULL; +#endif + /*------------------------------------------------------------------------------------------* * Loop for every packet (frame) of bitstream data * - Read the bitstream packet @@ -1951,11 +1964,25 @@ static ivas_error decodeG192( { IVAS_QUATERNION Quaternion; - if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( headRotReader == NULL ) { - fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); - goto cleanup; + Quaternion.w = -3.0f; + Quaternion.x = 0.0f; + Quaternion.y = 0.0f; + Quaternion.z = 0.0f; + } + else + { +#endif + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternion, &Pos ) ) != 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 if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos @@ -2048,6 +2075,8 @@ static ivas_error decodeG192( goto cleanup; } } + + /* TODO(sgi): Get split bitstream here */ error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nOutChannels * nSamplesRendered, &nSamplesRendered_loop, &needNewFrame ); nSamplesRendered += nSamplesRendered_loop; nSamplesToRender -= nSamplesRendered_loop; @@ -2092,7 +2121,8 @@ static ivas_error decodeG192( &nOutChannels, &numObj #ifdef SPLIT_REND_WITH_HEAD_ROT - ,NULL /* TODO(sgi): see #else branch for reference */ + , + &hSplitRendFileReadWrite #endif ); if ( error != IVAS_ERR_OK ) @@ -2109,19 +2139,44 @@ static ivas_error decodeG192( /* Write current frame */ if ( decodedGoodFrame ) { - if ( delayNumSamples < nOutSamples ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( hSplitRendFileReadWrite != NULL ) && ( arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CODED ) ) { - if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, splitRendBits.bits_buf, &splitRendBits.bits_read, &splitRendBits.bits_written, + splitRendBits.codec, splitRendBits.pose_correction ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nOutput audio file writer error\n" ); + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); goto cleanup; } - delayNumSamples = 0; } else { - delayNumSamples -= nOutSamples; + if ( ( hSplitRendFileReadWrite != NULL ) && ( arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM ) ) + { + if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, splitRendBits.bits_buf, &splitRendBits.bits_read, &splitRendBits.bits_written, + splitRendBits.codec, splitRendBits.pose_correction ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); + goto cleanup; + } + } +#endif + if ( delayNumSamples < nOutSamples ) + { + if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + goto cleanup; + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= nOutSamples; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif } /* Write ISm metadata to external file(s) */ @@ -2370,11 +2425,18 @@ static ivas_error decodeG192( /* add zeros at the end to have equal length of synthesized signals */ memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( afWriter != NULL ) { - fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); - goto cleanup; +#endif + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif /*------------------------------------------------------------------------------------------* * Close files and deallocate resources @@ -2384,6 +2446,9 @@ static ivas_error decodeG192( cleanup: +#ifdef SPLIT_REND_WITH_HEAD_ROT + split_rend_reader_writer_close( &hSplitRendFileReadWrite ); +#endif AudioFileWriter_close( &afWriter ); MasaFileWriter_close( &masaWriter ); #ifdef DEBUGGING -- GitLab From 8c837c38bf8ac1e073db1161201b4c98015aa5ce Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 2 Aug 2023 11:14:29 +0200 Subject: [PATCH 64/66] Use first draft of IVAS_DEC_GetSplitBinaural --- apps/decoder.c | 31 ++++++++++++++++++++++------- lib_dec/ivas_binRenderer_internal.c | 6 +++++- lib_dec/lib_dec.c | 17 +++++++++++----- lib_dec/lib_dec.h | 5 +++-- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 55b33d2bc6..63bc7f5d5b 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -2076,15 +2076,32 @@ static ivas_error decodeG192( } } - /* TODO(sgi): Get split bitstream here */ - error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nOutChannels * nSamplesRendered, &nSamplesRendered_loop, &needNewFrame ); - nSamplesRendered += nSamplesRendered_loop; - nSamplesToRender -= nSamplesRendered_loop; - if ( error != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CODED || arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM ) { - fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; + error = IVAS_DEC_GetSplitBinaural(hIvasDec, &splitRendBits, &nSamplesRendered_loop, &needNewFrame ); + nSamplesRendered += nSamplesRendered_loop; + nSamplesToRender -= nSamplesRendered_loop; + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetSplitBinaural: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + else + { +#endif + error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nOutChannels * nSamplesRendered, &nSamplesRendered_loop, &needNewFrame ); + nSamplesRendered += nSamplesRendered_loop; + nSamplesToRender -= nSamplesRendered_loop; + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif } while ( nSamplesRendered < nOutSamples && error == IVAS_ERR_OK ); diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index a7fceba53d..c01769aaaa 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1730,9 +1730,13 @@ void ivas_rend_CldfbMultiBinRendProcess( for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) { #endif - for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) /* FhG@Dolby: this looks suspicious */ { +#ifdef API_5MS + idx = slot_idx; +#else idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx; +#endif for ( ch_idx = 0; ch_idx < hCldfbRend->nInChannels; ch_idx++ ) { mvr2r( &Cldfb_In_Real[ch_idx][idx][0], &Cldfb_RealBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band ); diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 8b49a653ff..f6d2fd67d0 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -981,9 +981,10 @@ ivas_error IVAS_DEC_GetSamples( #if defined API_5MS && defined SPLIT_REND_WITH_HEAD_ROT ivas_error IVAS_DEC_GetSplitBinaural( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - bool *needNewFrame, /* indication that the decoder needs a new frame */ - IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits /* o : bitstream output for split rendering mode*/ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits, /* o : bitstream output for split rendering mode*/ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* indication that the decoder needs a new frame */ ) { Decoder_Struct *st_ivas; @@ -991,7 +992,7 @@ ivas_error IVAS_DEC_GetSplitBinaural( int32_t output_Fs; float output[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; int16_t output_int[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k]; /* TODO(sgi): Need conversion */ - int16_t numSamplesPerChannel, nOutSamples; + int16_t numSamplesPerChannel; int16_t i, j; ivas_error error; @@ -1006,19 +1007,25 @@ ivas_error IVAS_DEC_GetSplitBinaural( return IVAS_ERR_WRONG_PARAMS; } + *nOutSamples = 0; + while ( error == IVAS_ERR_OK ) { + int16_t nOutSamplesLocal; + /* Decode and render */ if ( ( error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannel, output_int, - &nOutSamples, + &nOutSamplesLocal, needNewFrame ) ) != IVAS_ERR_OK ) { return error; } + *nOutSamples += nOutSamplesLocal; + /*split rendering process calls*/ IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend; int16_t max_band; diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 7ad7a6d87d..a897c1e0c6 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -197,8 +197,9 @@ ivas_error IVAS_DEC_GetSamples( #if defined API_5MS && defined SPLIT_REND_WITH_HEAD_ROT ivas_error IVAS_DEC_GetSplitBinaural( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - bool *needNewFrame, /* indication that the decoder needs a new frame */ - IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits /* o : bitstream output for split rendering mode*/ + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits, /* o : bitstream output for split rendering mode*/ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* indication that the decoder needs a new frame */ ); #endif -- GitLab From b90b8976daee9c74534d22aa97f7bcab556dc59f Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 2 Aug 2023 12:17:55 +0200 Subject: [PATCH 65/66] Remove leftover enum member --- lib_com/ivas_error.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 7837ff0ac3..9732638af6 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -89,7 +89,6 @@ typedef enum #ifdef API_5MS IVAS_ERR_TSM_NOT_ENABLED, IVAS_ERR_FETCH_SIZE_NO_MULTIPLE_OF_5MS, - IVAS_ERR_NEED_NEW_FRAME, #endif #ifdef DEBUGGING IVAS_ERR_INVALID_FORCE_MODE, -- GitLab From 9cebadc99f69e5d60d51bae52b73bdb73ed6ccd3 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 2 Aug 2023 16:03:31 +0200 Subject: [PATCH 66/66] Fix infinite loop in the decoder --- lib_dec/lib_dec.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index f6d2fd67d0..75dc13f597 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1008,18 +1008,20 @@ ivas_error IVAS_DEC_GetSplitBinaural( } *nOutSamples = 0; + *needNewFrame = FALSE; - while ( error == IVAS_ERR_OK ) + while ( error == IVAS_ERR_OK && !*needNewFrame ) { int16_t nOutSamplesLocal; /* Decode and render */ - if ( ( error = IVAS_DEC_GetSamples( + error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannel, output_int, &nOutSamplesLocal, - needNewFrame ) ) != IVAS_ERR_OK ) + needNewFrame ); + if ( error != IVAS_ERR_OK || *needNewFrame ) { return error; } @@ -1039,7 +1041,7 @@ ivas_error IVAS_DEC_GetSplitBinaural( numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; /* [tmp] convert int back to float and change buffer layout */ - for (i = 0; i < numSamplesPerChannel; ++i) + for (i = 0; i < nOutSamplesLocal; ++i) { for (j = 0; j < BINAURAL_CHANNELS * numPoses; ++j) { -- GitLab