From 0f6ce2d51e3a8184ac431411be727f50fd50971e Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 20 Oct 2025 17:15:12 +0200 Subject: [PATCH 01/18] Linking compact room acoustics data provided with RTP to the rendering reconfiguration --- apps/decoder.c | 8 ++ lib_com/common_api_types.h | 3 + lib_com/ivas_cnst.h | 3 + lib_com/options.h | 1 + lib_dec/lib_dec.c | 126 ++++++++++++++++++++++++++++++++ lib_rend/ivas_render_config.c | 3 + lib_rend/lib_rend.c | 6 ++ lib_util/ivas_rtp_pi_data.c | 41 +++++++++++ lib_util/ivas_rtp_pi_data.h | 9 +++ lib_util/render_config_reader.c | 8 +- 10 files changed, 207 insertions(+), 1 deletion(-) diff --git a/apps/decoder.c b/apps/decoder.c index 33e0aeeff9..a378e2fbb3 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -41,6 +41,10 @@ #ifdef IVAS_RTPDUMP #include "ivas_rtp_file.h" #endif +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +#include "ivas_cnst.h" +#endif + #include "jbm_file_writer.h" #include "hrtf_file_reader.h" #include "ls_custom_file_reader.h" @@ -446,7 +450,11 @@ int main( *------------------------------------------------------------------------------------------*/ asked_frame_size = arg.renderFramesize; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + uint16_t aeID = arg.aeSequence.count > 0 ? arg.aeSequence.pID[0] : IVAS_DEFAULT_AEID; +#else uint16_t aeID = arg.aeSequence.count > 0 ? arg.aeSequence.pID[0] : 65535; +#endif if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.non_diegetic_pan_enabled, diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 80c90d6b31..15a87a1461 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -312,6 +312,9 @@ typedef enum #endif typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + int16_t aeID; /* Acoustic environment ID*/ +#endif int16_t nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ float pFc_input[IVAS_CLDFB_NO_CHANNELS_MAX]; /* Center frequencies for which following values are provided: */ float pAcoustic_rt60[IVAS_CLDFB_NO_CHANNELS_MAX]; /* - The room's T60 per center frequency */ diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 6f679f0fd8..ad41df88a1 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1580,6 +1580,9 @@ typedef enum #define RV_LENGTH_NR_FC ( RV_FILTER_MAX_FFT_SIZE / 2 ) + 1 #define RV_LENGTH_NR_FC_16KHZ ( RV_FILTER_MAX_FFT_SIZE / 4 ) + 1 #define IVAS_REVERB_DEFAULT_N_BANDS 31 +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +#define IVAS_DEFAULT_AEID ( 65535 ) +#endif #define LR_IAC_LENGTH_NR_FC ( RV_LENGTH_NR_FC ) #define LR_IAC_LENGTH_NR_FC_16KHZ ( RV_LENGTH_NR_FC_16KHZ ) diff --git a/lib_com/options.h b/lib_com/options.h index 6d394089cd..48cb9fe29c 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -161,6 +161,7 @@ #define RTP_S4_251135_CR26253_0016_REV1 /* RTP Pack/Unpack API corresponding to CR 26253 */ #define IVAS_RTPDUMP /* RTPDUMP writing and reading for IVAS payloads */ +#define IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT /* RTPDUMP acoustic environment */ /* ################### Start BE switches ################################# */ /* only BE switches wrt selection floating point code */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 7ab22259ad..83578d5268 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3210,6 +3210,9 @@ static ivas_error copyRendererConfigStruct( hRCout->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; break; } +#endif +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + hRCout->roomAcoustics.aeID = hRCin->roomAcoustics.aeID; #endif hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; @@ -3307,6 +3310,9 @@ ivas_error IVAS_DEC_FeedRenderConfig( { hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_CREND; } +#endif +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + hRenderConfig->roomAcoustics.aeID = renderConfig.roomAcoustics.aeID; #endif hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.roomAcoustics.acousticPreDelay; @@ -3393,6 +3399,112 @@ ivas_error IVAS_DEC_FeedRenderConfig( return IVAS_ERR_OK; } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +/*---------------------------------------------------------------------* + * IVAS_DEC_FeedAcousticEnvPI( ) + * + * Set acoustic environment from the PI data + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_FeedAcousticEnvPI( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_PIDATA_ACOUSTIC_ENV hAcoustEnvPI /* i : Render configuration struct */ +) +{ + RENDER_CONFIG_HANDLE hRenderConfig; + Decoder_Struct *st_ivas; + ivas_error error; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hRenderConfig = hIvasDec->st_ivas->hRenderConfig; + st_ivas = hIvasDec->st_ivas; + +#ifdef DEBUGGING + hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; + if ( renderConfig.renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) + { + hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_FASTCONV; + } + if ( renderConfig.renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_CREND ) + { + hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_CREND; + } +#endif + hRenderConfig->roomAcoustics.aeID = hAcoustEnvPI.aeid; + hRenderConfig->roomAcoustics.nBands = IVAS_PI_AE_NUM_BANDS; + hRenderConfig->roomAcoustics.pFc_input[IVAS_PI_AE_LOW] = IVAS_PI_AE_LOW_FREQ; + hRenderConfig->roomAcoustics.pFc_input[IVAS_PI_AE_MID] = IVAS_PI_AE_MID_FREQ; + hRenderConfig->roomAcoustics.pFc_input[IVAS_PI_AE_HIGH] = IVAS_PI_AE_HIGH_FREQ; + hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_LOW] = hAcoustEnvPI.rt60[IVAS_PI_AE_LOW]; + hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_MID] = hAcoustEnvPI.rt60[IVAS_PI_AE_MID]; + hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_HIGH] = hAcoustEnvPI.rt60[IVAS_PI_AE_HIGH]; + hRenderConfig->roomAcoustics.inputPreDelay = (float)(0.1 * hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_MID]); + hRenderConfig->roomAcoustics.pAcoustic_dsr[IVAS_PI_AE_LOW] = hAcoustEnvPI.dsr[IVAS_PI_AE_LOW]; + hRenderConfig->roomAcoustics.pAcoustic_dsr[IVAS_PI_AE_MID] = hAcoustEnvPI.dsr[IVAS_PI_AE_MID]; + hRenderConfig->roomAcoustics.pAcoustic_dsr[IVAS_PI_AE_HIGH] = hAcoustEnvPI.dsr[IVAS_PI_AE_HIGH]; + + hRenderConfig->roomAcoustics.use_er = hAcoustEnvPI.availEarlyReflections; + + if ( hAcoustEnvPI.availEarlyReflections ) + { + hRenderConfig->roomAcoustics.dimensions.x = hAcoustEnvPI.roomDimensions.x; + hRenderConfig->roomAcoustics.dimensions.y = hAcoustEnvPI.roomDimensions.y; + hRenderConfig->roomAcoustics.dimensions.z = hAcoustEnvPI.roomDimensions.z; + mvr2r( hAcoustEnvPI.absorbCoeffs, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); + } + + /* Re-initialize reverb instance if already available */ + + /* TD renderer Jot reverberator */ + if ( st_ivas->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* CREND Jot reverberator */ + if ( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* Parametric renderer reverberator */ + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( st_ivas->hDiracDecBin[0]->hReverb ) ); + + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hDiracDecBin[0]->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* FastConv renderer reverberator */ + if ( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( st_ivas->hBinRenderer->hReverb ) ); + + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hBinRenderer->conv_band, st_ivas->hBinRenderer->timeSlots, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} + +#endif /*---------------------------------------------------------------------* * IVAS_DEC_GetDelay( ) @@ -5647,6 +5759,20 @@ ivas_error IVAS_RTP_ApplyPiData( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *piData, ui } break; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + case IVAS_PI_ACOUSTIC_ENVIRONMENT: + { + uint16_t aeid = piData->data.acousticEnv.aeid; + DEBUG_PRINT( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); + + if ( piData->data.acousticEnv.availLateReverb && aeid != hIvasDec->st_ivas->hRenderConfig->roomAcoustics.aeID ) + { + error = IVAS_DEC_FeedAcousticEnvPI( hIvasDec, piData->data.acousticEnv ); + } + } + break; +#endif + #ifdef RTP_S4_251135_CR26253_0016_REV1 case IVAS_PI_DIEGETIC_TYPE: { diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index c3a39b426e..1ba683033a 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -112,6 +112,9 @@ ivas_error ivas_render_config_init_from_rom( #ifdef DEBUGGING ( *hRenderConfig )->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; +#endif +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + ( *hRenderConfig )->roomAcoustics.aeID = IVAS_DEFAULT_AEID; #endif ( *hRenderConfig )->roomAcoustics.nBands = IVAS_REVERB_DEFAULT_N_BANDS; ( *hRenderConfig )->roomAcoustics.acousticPreDelay = IVAS_REVERB_DEFAULT_PRE_DELAY; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index bba3fbb187..fbdc2ab505 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4530,6 +4530,9 @@ ivas_error IVAS_REND_GetRenderConfig( hRCout->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; break; } +#endif +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + hRCout->roomAcoustics.aeID = hRCin->roomAcoustics.aeID; #endif hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; @@ -4586,6 +4589,9 @@ ivas_error IVAS_REND_FeedRenderConfig( hRenderConfig = hIvasRend->hRendererConfig; #ifdef DEBUGGING hRenderConfig->renderer_type_override = renderConfig.renderer_type_override; +#endif +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + hRenderConfig->roomAcoustics.aeID = renderConfig.roomAcoustics.aeID; #endif hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.roomAcoustics.acousticPreDelay; diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index 7150cfe4a8..0100c833cc 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -296,6 +296,46 @@ static ivas_error unpackAcousticEnvironment( const uint8_t *buffer, uint32_t num } dWord <<= ( 8 - numDataBytes ) * 8; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + uint32_t offset = numDataBytes * 8; + aeEnv->aeid = (uint8_t) ( ( dWord >> ( offset - 7 ) ) & MASK_AEID ); + offset -= 7; + aeEnv->rt60[IVAS_PI_AE_LOW] = mapRT60[( dWord >> ( offset - 5 ) ) & MASK_RT60]; + offset -= 5; + aeEnv->dsr[IVAS_PI_AE_LOW] = mapDSR[( dWord >> ( offset - 6 ) ) & MASK_DSR]; + offset -= 6; + aeEnv->rt60[IVAS_PI_AE_MID] = mapRT60[( dWord >> ( offset - 5 ) ) & MASK_RT60]; + offset -= 5; + aeEnv->dsr[IVAS_PI_AE_MID] = mapDSR[( dWord >> ( offset - 6 ) ) & MASK_DSR]; + offset -= 6; + aeEnv->rt60[IVAS_PI_AE_HIGH] = mapRT60[( dWord >> ( offset - 5 ) ) & MASK_RT60]; + offset -= 5; + aeEnv->dsr[IVAS_PI_AE_HIGH] = mapDSR[( dWord >> ( offset - 6 ) ) & MASK_DSR]; + offset -= 6; + + if (aeEnv->availEarlyReflections) + { + aeEnv->roomDimensions.x = mapRoomDims[( dWord >> ( offset - 4 ) ) & MASK_DIM]; + offset -= 4; + aeEnv->roomDimensions.y = mapRoomDims[( dWord >> ( offset - 4 ) ) & MASK_DIM]; + offset -= 4; + aeEnv->roomDimensions.z = mapRoomDims[( dWord >> ( offset - 4 ) ) & MASK_DIM]; + offset -= 4; + + aeEnv->absorbCoeffs[IVAS_PI_AE_FRONT] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + offset -= 2; + aeEnv->absorbCoeffs[IVAS_PI_AE_BACK] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + offset -= 2; + aeEnv->absorbCoeffs[IVAS_PI_AE_LEFT] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + offset -= 2; + aeEnv->absorbCoeffs[IVAS_PI_AE_RIGHT] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + offset -= 2; + aeEnv->absorbCoeffs[IVAS_PI_AE_CEILING] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + offset -= 2; + aeEnv->absorbCoeffs[IVAS_PI_AE_FLOOR] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + offset -= 2; + } +#else aeEnv->aeid = (uint8_t) ( ( dWord >> 57 ) & MASK_AEID ); aeEnv->rt60[IVAS_PI_AE_LOW] = mapRT60[( dWord >> 52 ) & MASK_RT60]; aeEnv->dsr[IVAS_PI_AE_LOW] = mapDSR[( dWord >> 46 ) & MASK_DSR]; @@ -314,6 +354,7 @@ static ivas_error unpackAcousticEnvironment( const uint8_t *buffer, uint32_t num aeEnv->absorbCoeffs[IVAS_PI_AE_RIGHT] = mapAbsorbtion[( dWord >> 4 ) & MASK_ABS]; aeEnv->absorbCoeffs[IVAS_PI_AE_CEILING] = mapAbsorbtion[( dWord >> 2 ) & MASK_ABS]; aeEnv->absorbCoeffs[IVAS_PI_AE_FLOOR] = mapAbsorbtion[( dWord >> 0 ) & MASK_ABS]; +#endif } return IVAS_ERR_OK; diff --git a/lib_util/ivas_rtp_pi_data.h b/lib_util/ivas_rtp_pi_data.h index 3fc95f8d8d..3a7931125c 100644 --- a/lib_util/ivas_rtp_pi_data.h +++ b/lib_util/ivas_rtp_pi_data.h @@ -124,6 +124,15 @@ typedef enum IVAS_PI_AE_NUM_BANDS /* number of ae bands */ } IVAS_PI_AE_BANDS; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +typedef enum +{ + IVAS_PI_AE_LOW_FREQ = 25, + IVAS_PI_AE_MID_FREQ = 250, + IVAS_PI_AE_HIGH_FREQ = 2500 +} IVAS_PI_AE_BANDS_FREQ; +#endif + typedef enum { IVAS_PI_AE_FRONT, diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 7729efbc7c..3514a986b9 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -36,7 +36,9 @@ #include #include #include "cmdl_tools.h" - +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +#include "ivas_cnst.h" +#endif /*------------------------------------------------------------------------------------------* * PreProc Local Macros @@ -2978,7 +2980,11 @@ ivas_error RenderConfigReader_getAcousticEnvironment( } /* case when -aeid is not specified, select first ID from config file */ +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + if ( id == IVAS_DEFAULT_AEID && pRenderConfigReader->nAE > 0 ) +#else if ( id == 65535 && pRenderConfigReader->nAE > 0 ) +#endif { id = (uint16_t) pRenderConfigReader->pAE[0].id; } -- GitLab From 94592af34761036b2fe9710e6c4620b3bcf1fd42 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 21 Oct 2025 08:30:03 +0200 Subject: [PATCH 02/18] Minor refactoring --- lib_util/ivas_rtp_pi_data.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index 0100c833cc..409e713026 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -298,42 +298,42 @@ static ivas_error unpackAcousticEnvironment( const uint8_t *buffer, uint32_t num #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT uint32_t offset = numDataBytes * 8; - aeEnv->aeid = (uint8_t) ( ( dWord >> ( offset - 7 ) ) & MASK_AEID ); offset -= 7; - aeEnv->rt60[IVAS_PI_AE_LOW] = mapRT60[( dWord >> ( offset - 5 ) ) & MASK_RT60]; + aeEnv->aeid = (uint8_t) ( ( dWord >> offset ) & MASK_AEID ); offset -= 5; - aeEnv->dsr[IVAS_PI_AE_LOW] = mapDSR[( dWord >> ( offset - 6 ) ) & MASK_DSR]; + aeEnv->rt60[IVAS_PI_AE_LOW] = mapRT60[( dWord >> offset ) & MASK_RT60]; offset -= 6; - aeEnv->rt60[IVAS_PI_AE_MID] = mapRT60[( dWord >> ( offset - 5 ) ) & MASK_RT60]; + aeEnv->dsr[IVAS_PI_AE_LOW] = mapDSR[( dWord >> offset ) & MASK_DSR]; offset -= 5; - aeEnv->dsr[IVAS_PI_AE_MID] = mapDSR[( dWord >> ( offset - 6 ) ) & MASK_DSR]; + aeEnv->rt60[IVAS_PI_AE_MID] = mapRT60[( dWord >> offset ) & MASK_RT60]; offset -= 6; - aeEnv->rt60[IVAS_PI_AE_HIGH] = mapRT60[( dWord >> ( offset - 5 ) ) & MASK_RT60]; + aeEnv->dsr[IVAS_PI_AE_MID] = mapDSR[( dWord >> offset ) & MASK_DSR]; offset -= 5; - aeEnv->dsr[IVAS_PI_AE_HIGH] = mapDSR[( dWord >> ( offset - 6 ) ) & MASK_DSR]; + aeEnv->rt60[IVAS_PI_AE_HIGH] = mapRT60[( dWord >> offset ) & MASK_RT60]; offset -= 6; + aeEnv->dsr[IVAS_PI_AE_HIGH] = mapDSR[( dWord >> offset ) & MASK_DSR]; if (aeEnv->availEarlyReflections) { - aeEnv->roomDimensions.x = mapRoomDims[( dWord >> ( offset - 4 ) ) & MASK_DIM]; offset -= 4; - aeEnv->roomDimensions.y = mapRoomDims[( dWord >> ( offset - 4 ) ) & MASK_DIM]; + aeEnv->roomDimensions.x = mapRoomDims[( dWord >> offset ) & MASK_DIM]; offset -= 4; - aeEnv->roomDimensions.z = mapRoomDims[( dWord >> ( offset - 4 ) ) & MASK_DIM]; + aeEnv->roomDimensions.y = mapRoomDims[( dWord >> offset ) & MASK_DIM]; offset -= 4; + aeEnv->roomDimensions.z = mapRoomDims[( dWord >> offset ) & MASK_DIM]; - aeEnv->absorbCoeffs[IVAS_PI_AE_FRONT] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; offset -= 2; - aeEnv->absorbCoeffs[IVAS_PI_AE_BACK] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + aeEnv->absorbCoeffs[IVAS_PI_AE_FRONT] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; offset -= 2; - aeEnv->absorbCoeffs[IVAS_PI_AE_LEFT] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + aeEnv->absorbCoeffs[IVAS_PI_AE_BACK] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; offset -= 2; - aeEnv->absorbCoeffs[IVAS_PI_AE_RIGHT] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + aeEnv->absorbCoeffs[IVAS_PI_AE_LEFT] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; offset -= 2; - aeEnv->absorbCoeffs[IVAS_PI_AE_CEILING] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + aeEnv->absorbCoeffs[IVAS_PI_AE_RIGHT] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; offset -= 2; - aeEnv->absorbCoeffs[IVAS_PI_AE_FLOOR] = mapAbsorbtion[( dWord >> ( offset - 2 ) ) & MASK_ABS]; + aeEnv->absorbCoeffs[IVAS_PI_AE_CEILING] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; offset -= 2; + aeEnv->absorbCoeffs[IVAS_PI_AE_FLOOR] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; } #else aeEnv->aeid = (uint8_t) ( ( dWord >> 57 ) & MASK_AEID ); -- GitLab From b045cdd792f6e6f2f0cfe69faa1203ffdf58796c Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 21 Oct 2025 08:33:33 +0200 Subject: [PATCH 03/18] Minor refactoring --- lib_util/ivas_rtp_pi_data.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index 409e713026..4c04a74ff7 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -298,41 +298,41 @@ static ivas_error unpackAcousticEnvironment( const uint8_t *buffer, uint32_t num #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT uint32_t offset = numDataBytes * 8; - offset -= 7; + offset -= NBITS_AEID; aeEnv->aeid = (uint8_t) ( ( dWord >> offset ) & MASK_AEID ); - offset -= 5; + offset -= NBITS_RT60; aeEnv->rt60[IVAS_PI_AE_LOW] = mapRT60[( dWord >> offset ) & MASK_RT60]; - offset -= 6; + offset -= NBITS_DSR; aeEnv->dsr[IVAS_PI_AE_LOW] = mapDSR[( dWord >> offset ) & MASK_DSR]; - offset -= 5; + offset -= NBITS_RT60; aeEnv->rt60[IVAS_PI_AE_MID] = mapRT60[( dWord >> offset ) & MASK_RT60]; - offset -= 6; + offset -= NBITS_DSR; aeEnv->dsr[IVAS_PI_AE_MID] = mapDSR[( dWord >> offset ) & MASK_DSR]; - offset -= 5; + offset -= NBITS_RT60; aeEnv->rt60[IVAS_PI_AE_HIGH] = mapRT60[( dWord >> offset ) & MASK_RT60]; - offset -= 6; + offset -= NBITS_DSR; aeEnv->dsr[IVAS_PI_AE_HIGH] = mapDSR[( dWord >> offset ) & MASK_DSR]; if (aeEnv->availEarlyReflections) { - offset -= 4; + offset -= NBITS_DIM; aeEnv->roomDimensions.x = mapRoomDims[( dWord >> offset ) & MASK_DIM]; - offset -= 4; + offset -= NBITS_DIM; aeEnv->roomDimensions.y = mapRoomDims[( dWord >> offset ) & MASK_DIM]; - offset -= 4; + offset -= NBITS_DIM; aeEnv->roomDimensions.z = mapRoomDims[( dWord >> offset ) & MASK_DIM]; - offset -= 2; + offset -= NBITS_ABS; aeEnv->absorbCoeffs[IVAS_PI_AE_FRONT] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - offset -= 2; + offset -= NBITS_ABS; aeEnv->absorbCoeffs[IVAS_PI_AE_BACK] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - offset -= 2; + offset -= NBITS_ABS; aeEnv->absorbCoeffs[IVAS_PI_AE_LEFT] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - offset -= 2; + offset -= NBITS_ABS; aeEnv->absorbCoeffs[IVAS_PI_AE_RIGHT] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - offset -= 2; + offset -= NBITS_ABS; aeEnv->absorbCoeffs[IVAS_PI_AE_CEILING] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - offset -= 2; + offset -= NBITS_ABS; aeEnv->absorbCoeffs[IVAS_PI_AE_FLOOR] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; } #else -- GitLab From 02346cc8ad3cec777ee7f086d2aa27c3cea5eeb4 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 21 Oct 2025 10:22:17 +0200 Subject: [PATCH 04/18] IVAS_DEC_FeedAcousticEnvPI needs to be static --- lib_dec/lib_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 83578d5268..24c4077f6d 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3406,7 +3406,7 @@ ivas_error IVAS_DEC_FeedRenderConfig( * Set acoustic environment from the PI data *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_FeedAcousticEnvPI( +static ivas_error IVAS_DEC_FeedAcousticEnvPI( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const IVAS_PIDATA_ACOUSTIC_ENV hAcoustEnvPI /* i : Render configuration struct */ ) -- GitLab From cdf736e0f557c1c3143b101a873347aeb7537612 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 21 Oct 2025 11:01:39 +0200 Subject: [PATCH 05/18] Fixes for acoustic environment ID data type handling --- lib_com/common_api_types.h | 2 +- lib_rend/ivas_render_config.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 15a87a1461..506b155ef5 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -313,7 +313,7 @@ typedef enum typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - int16_t aeID; /* Acoustic environment ID*/ + uint16_t aeID; /* Acoustic environment ID*/ #endif int16_t nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ float pFc_input[IVAS_CLDFB_NO_CHANNELS_MAX]; /* Center frequencies for which following values are provided: */ diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index 1ba683033a..63eaaf0227 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -114,7 +114,7 @@ ivas_error ivas_render_config_init_from_rom( ( *hRenderConfig )->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; #endif #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - ( *hRenderConfig )->roomAcoustics.aeID = IVAS_DEFAULT_AEID; + ( *hRenderConfig )->roomAcoustics.aeID = (uint16_t) IVAS_DEFAULT_AEID; #endif ( *hRenderConfig )->roomAcoustics.nBands = IVAS_REVERB_DEFAULT_N_BANDS; ( *hRenderConfig )->roomAcoustics.acousticPreDelay = IVAS_REVERB_DEFAULT_PRE_DELAY; -- GitLab From e1736a1949b22a3fab5d46055d8e5f1448078ac6 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Thu, 30 Oct 2025 16:46:51 +0100 Subject: [PATCH 06/18] Removed unnecessary change within unpackAcousticEnvironment --- lib_util/ivas_rtp_pi_data.c | 41 ------------------------------------- 1 file changed, 41 deletions(-) diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index 7f04e1c5d0..8db9d41f9d 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -296,46 +296,6 @@ static ivas_error unpackAcousticEnvironment( const uint8_t *buffer, uint32_t num } dWord <<= ( 8 - numDataBytes ) * 8; -#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - uint32_t offset = numDataBytes * 8; - offset -= NBITS_AEID; - aeEnv->aeid = (uint8_t) ( ( dWord >> offset ) & MASK_AEID ); - offset -= NBITS_RT60; - aeEnv->rt60[IVAS_PI_AE_LOW] = mapRT60[( dWord >> offset ) & MASK_RT60]; - offset -= NBITS_DSR; - aeEnv->dsr[IVAS_PI_AE_LOW] = mapDSR[( dWord >> offset ) & MASK_DSR]; - offset -= NBITS_RT60; - aeEnv->rt60[IVAS_PI_AE_MID] = mapRT60[( dWord >> offset ) & MASK_RT60]; - offset -= NBITS_DSR; - aeEnv->dsr[IVAS_PI_AE_MID] = mapDSR[( dWord >> offset ) & MASK_DSR]; - offset -= NBITS_RT60; - aeEnv->rt60[IVAS_PI_AE_HIGH] = mapRT60[( dWord >> offset ) & MASK_RT60]; - offset -= NBITS_DSR; - aeEnv->dsr[IVAS_PI_AE_HIGH] = mapDSR[( dWord >> offset ) & MASK_DSR]; - - if (aeEnv->availEarlyReflections) - { - offset -= NBITS_DIM; - aeEnv->roomDimensions.x = mapRoomDims[( dWord >> offset ) & MASK_DIM]; - offset -= NBITS_DIM; - aeEnv->roomDimensions.y = mapRoomDims[( dWord >> offset ) & MASK_DIM]; - offset -= NBITS_DIM; - aeEnv->roomDimensions.z = mapRoomDims[( dWord >> offset ) & MASK_DIM]; - - offset -= NBITS_ABS; - aeEnv->absorbCoeffs[IVAS_PI_AE_FRONT] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - offset -= NBITS_ABS; - aeEnv->absorbCoeffs[IVAS_PI_AE_BACK] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - offset -= NBITS_ABS; - aeEnv->absorbCoeffs[IVAS_PI_AE_LEFT] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - offset -= NBITS_ABS; - aeEnv->absorbCoeffs[IVAS_PI_AE_RIGHT] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - offset -= NBITS_ABS; - aeEnv->absorbCoeffs[IVAS_PI_AE_CEILING] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - offset -= NBITS_ABS; - aeEnv->absorbCoeffs[IVAS_PI_AE_FLOOR] = mapAbsorbtion[( dWord >> offset ) & MASK_ABS]; - } -#else aeEnv->aeid = (uint8_t) ( ( dWord >> 57 ) & MASK_AEID ); aeEnv->rt60[IVAS_PI_AE_LOW] = mapRT60[( dWord >> 52 ) & MASK_RT60]; aeEnv->dsr[IVAS_PI_AE_LOW] = mapDSR[( dWord >> 46 ) & MASK_DSR]; @@ -354,7 +314,6 @@ static ivas_error unpackAcousticEnvironment( const uint8_t *buffer, uint32_t num aeEnv->absorbCoeffs[IVAS_PI_AE_RIGHT] = mapAbsorbtion[( dWord >> 4 ) & MASK_ABS]; aeEnv->absorbCoeffs[IVAS_PI_AE_CEILING] = mapAbsorbtion[( dWord >> 2 ) & MASK_ABS]; aeEnv->absorbCoeffs[IVAS_PI_AE_FLOOR] = mapAbsorbtion[( dWord >> 0 ) & MASK_ABS]; -#endif } return IVAS_ERR_OK; -- GitLab From 1468ce62608741f5ad98f7974713f5c674e3dce5 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Thu, 30 Oct 2025 17:21:57 +0100 Subject: [PATCH 07/18] Updated RTP tests for acoustic environment (prototype) --- tests/rtp/test_rtp.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/tests/rtp/test_rtp.py b/tests/rtp/test_rtp.py index 44d08a91e1..fbf7be9fcb 100644 --- a/tests/rtp/test_rtp.py +++ b/tests/rtp/test_rtp.py @@ -228,6 +228,23 @@ def generatePiData(startTs: int, endTs: int) -> dict: someAuFocusLvl = lambda: AUDIO_FOCUS(level=AUDIO_FOCUS_LEVEL(random.randint(0, 15))) someAuFocusList = [someAuFocusDirLvl, someAuFocusDir, someAuFocusLvl] + someAcousticEnvAEID = lambda: ACOUSTIC_ENVIRONMENT( + aeid=random.randint(0, 127) + ) + someAcousticEnvLR = lambda: ACOUSTIC_ENVIRONMENT( + aeid=random.randint(0, 127), + rt60=[random.randint(0, len(rt60Value)) for _ in range(3)], + dsr=[random.randint(0, len(dsrValue)) for _ in range(3)], + ) + someAcousticEnvERLR = lambda: ACOUSTIC_ENVIRONMENT( + aeid=random.randint(0, 127), + rt60=[random.randint(0, len(rt60Value)) for _ in range(3)], + dsr=[random.randint(0, len(dsrValue)) for _ in range(3)], + dim=[random.randint(0, len(roomDimensionValue)) for _ in range(3)], + abscoeff=[random.randint(0, len(absorptionCoeffValues)) for _ in range(6)], + ) + someAcousticEnvList = [someAcousticEnvAEID, someAcousticEnvLR, someAcousticEnvERLR] + for ts in range(startTs, endTs, 320): pidata = dict() pidata["SCENE_ORIENTATION"] = someOrientation() @@ -240,9 +257,7 @@ def generatePiData(startTs: int, endTs: int) -> dict: pidata["DYNAMIC_AUDIO_SUPPRESSION_REQUEST"] = someDAS() pidata["AUDIO_DESCRIPTION"] = [someDesc() for n in range(random.randint(1, 5))] pidata["DIEGETIC_TYPE"] = someDIG() - pidata["ACOUSTIC_ENVIRONMENT"] = ACOUSTIC_ENVIRONMENT( - aeid=random.randint(0, 127) - ) + pidata["ACOUSTIC_ENVIRONMENT"] = random.choice(someAcousticEnvList)() data[str(ts)] = pidata return data @@ -312,6 +327,12 @@ def isEqualAcousticEnv(ref: ACOUSTIC_ENVIRONMENT, dut: ACOUSTIC_ENVIRONMENT): ), "Acoustic Env PI Data mismatch in len(abscoeff)" for r, d in zip(ref.rt60, dut.rt60): assert r == d, f"Acoustic Env PI Data mismatch in rt60 {r} != {d}" + for r, d in zip(ref.dsr, dut.dsr): + assert r == d, f"Acoustic Env PI Data mismatch in dsr {r} != {d}" + for r, d in zip(ref.dim, dut.dim): + assert r == d, f"Acoustic Env PI Data mismatch in dim {r} != {d}" + for r, d in zip(ref.abscoeff, dut.abscoeff): + assert r == d, f"Acoustic Env PI Data mismatch in abscoeff {r} != {d}" def isEqualAudioFocus(ref: AUDIO_FOCUS, dut: AUDIO_FOCUS): -- GitLab From 5961558073ae814a85fcec8fcc0308accaaa3ce8 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Thu, 30 Oct 2025 17:24:52 +0100 Subject: [PATCH 08/18] Updated debugging logging --- lib_dec/lib_dec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index fcf3d69d82..d34a000f7d 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -5761,7 +5761,9 @@ ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *pi case IVAS_PI_ACOUSTIC_ENVIRONMENT: { uint16_t aeid = piData->data.acousticEnv.aeid; - DEBUG_PRINT( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); +#ifdef DEBUGGING + fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); +#endif if ( piData->data.acousticEnv.availLateReverb && aeid != hIvasDec->st_ivas->hRenderConfig->roomAcoustics.aeID ) { -- GitLab From c11990d1b0824d3c7d2ace677fe6a668c2a8c607 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Fri, 31 Oct 2025 13:44:17 +0100 Subject: [PATCH 09/18] Selectable AE based on already available acoustic environments --- apps/decoder.c | 27 +++++ lib_dec/ivas_init_dec.c | 4 + lib_dec/ivas_stat_dec.h | 4 + lib_dec/lib_dec.c | 197 ++++++++++++++++++++++++++++---- lib_dec/lib_dec.h | 13 +++ lib_util/render_config_reader.c | 80 ++++++++++++- lib_util/render_config_reader.h | 14 +++ 7 files changed, 317 insertions(+), 22 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 7063a80a27..a7235e5356 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -636,6 +636,29 @@ int main( fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); goto cleanup; } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + uint32_t aeCount = RenderConfigReader_getAcousticEnvironmentCount( renderConfigReader ); + if ( aeCount > 0 ) + { + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAE = malloc( aeCount * sizeof( IVAS_ROOM_ACOUSTICS_CONFIG_DATA ) ); + uint32_t n; + + if ( ( error = RenderConfigReader_getAcousticEnvironments( renderConfigReader, &pAE ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error while getting acoustic environments\n\n" ); + goto cleanup; + } + + for ( n = 0; n < aeCount; n++ ) + { + if ( ( error = IVAS_DEC_AddAcousticEnvironment( hIvasDec, pAE[n] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to add acoustic environments\n\n" ); + goto cleanup; + } + } + } +#endif if ( ( error = RenderConfigReader_getDirectivity( renderConfigReader, arg.directivityPatternId, renderConfig.directivity ) ) != IVAS_ERR_OK ) { @@ -674,7 +697,11 @@ int main( if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, aeID, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) +#else if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, aeID, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) +#endif { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 7e09074af0..29e0fd64e5 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2631,6 +2631,10 @@ void ivas_initialize_handles_dec( st_ivas->hRenderConfig = NULL; st_ivas->hExtOrientationData = NULL; st_ivas->hCombinedOrientationData = NULL; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + st_ivas->acousticEnvironmentsCount = 0; + st_ivas->pAcousticEnvironments = NULL; +#endif st_ivas->hSplitBinRend = NULL; for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index f1efb32a10..3214dc9dd0 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1128,6 +1128,10 @@ typedef struct Decoder_Struct MASA_ISM_DATA_HANDLE hMasaIsmData; /* OMASA rendering handle */ SBA_ISM_DATA_HANDLE hSbaIsmData; /* OSBA rendering handle */ +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcousticEnvironments; /* Acoustic environment array */ + uint16_t acousticEnvironmentsCount; /* Number of acoustic environments in the array*/ +#endif int16_t flag_omasa_brate; ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; /* ISAR split binaural rendering handle */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index d34a000f7d..2174c985a1 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3181,6 +3181,138 @@ ivas_error IVAS_DEC_HRTF_binary_close( return IVAS_ERR_OK; } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +/*---------------------------------------------------------------------* + * IVAS_DEC_AddAcousticEnvironment( ) + * + * Adds acoustic environment configuration + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_AddAcousticEnvironment( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcousticsConfig /* i : Room acoustic configuration */ +) +{ + uint16_t n; + Decoder_Struct *st_ivas; + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAE = NULL; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || ( hIvasDec->st_ivas->acousticEnvironmentsCount > 0 && hIvasDec->st_ivas->pAcousticEnvironments == NULL ) ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasDec->st_ivas; + + /* Check if already there */ + for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) + { + if ( st_ivas->pAcousticEnvironments[n].aeID == roomAcousticsConfig.aeID ) + { + pAE = &st_ivas->pAcousticEnvironments[n]; + break; + } + } + + /* If not found */ + if ( pAE == NULL ) + { + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *ppAE = realloc( st_ivas->pAcousticEnvironments, ( st_ivas->acousticEnvironmentsCount + 1 ) * sizeof( IVAS_ROOM_ACOUSTICS_CONFIG_DATA ) ); + + if ( ppAE == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + st_ivas->pAcousticEnvironments = ppAE; + n = st_ivas->acousticEnvironmentsCount++; + pAE = &st_ivas->pAcousticEnvironments[n]; + } + + pAE->aeID = roomAcousticsConfig.aeID; + pAE->nBands = roomAcousticsConfig.nBands; + pAE->acousticPreDelay = roomAcousticsConfig.acousticPreDelay; + pAE->inputPreDelay = roomAcousticsConfig.inputPreDelay; + + mvr2r( roomAcousticsConfig.pFc_input, pAE->pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( roomAcousticsConfig.pAcoustic_rt60, pAE->pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( roomAcousticsConfig.pAcoustic_dsr, pAE->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + + if ( pAE->use_er == 1 ) + { + pAE->use_er = roomAcousticsConfig.use_er; + pAE->lowComplexity = roomAcousticsConfig.lowComplexity; + pAE->dimensions = roomAcousticsConfig.dimensions; + pAE->ListenerOrigin = roomAcousticsConfig.ListenerOrigin; + + mvr2r( roomAcousticsConfig.AbsCoeff, pAE->AbsCoeff, IVAS_ROOM_ABS_COEFF ); + } + + return IVAS_ERR_OK; +} + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetAcousticEnvironment( ) + * + * Gets acoustic environment configuration with a given ID + *---------------------------------------------------------------------*/ +ivas_error IVAS_DEC_GetAcousticEnvironment( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t aeID, /* i : Acoustic environment ID */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcEnv /* o : Room acoustic environment data pointer */ +) +{ + uint16_t n, m; + uint16_t found = 0; + + Decoder_Struct *st_ivas; + + if ( hIvasDec == NULL || pAcEnv == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; + + for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) + { + IVAS_ROOM_ACOUSTICS_CONFIG_DATA ae = st_ivas->pAcousticEnvironments[n]; + if ( aeID == ae.aeID ) + { + found = 1; + pAcEnv->aeID = aeID; + pAcEnv->nBands = ae.nBands; + pAcEnv->inputPreDelay = ae.inputPreDelay; + for ( m = 0; m < pAcEnv->nBands; m++ ) + { + pAcEnv->pFc_input[m] = ae.pFc_input[m]; + pAcEnv->pAcoustic_rt60[m] = ae.pAcoustic_rt60[m]; + pAcEnv->pAcoustic_dsr[m] = ae.pAcoustic_dsr[m]; + } + + /* If ER are allocated then propagate parameters */ + pAcEnv->use_er = ae.use_er; + if ( ae.use_er != 0 ) + { + pAcEnv->lowComplexity = ae.lowComplexity; + + pAcEnv->dimensions.x = ae.dimensions.x; + pAcEnv->dimensions.y = ae.dimensions.y; + pAcEnv->dimensions.z = ae.dimensions.z; + + pAcEnv->ListenerOrigin.x = ae.ListenerOrigin.x; + pAcEnv->ListenerOrigin.y = ae.ListenerOrigin.y; + pAcEnv->ListenerOrigin.z = ae.ListenerOrigin.z; + + for ( m = 0; m < IVAS_ROOM_ABS_COEFF; m++ ) + { + pAcEnv->AbsCoeff[m] = ae.AbsCoeff[m]; + } + } + } + } + + return found ? IVAS_ERR_OK : IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING; +} +#endif /*---------------------------------------------------------------------* * copyRendererConfigStruct( ) @@ -3434,27 +3566,50 @@ static ivas_error IVAS_DEC_FeedAcousticEnvPI( hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_CREND; } #endif - hRenderConfig->roomAcoustics.aeID = hAcoustEnvPI.aeid; - hRenderConfig->roomAcoustics.nBands = IVAS_PI_AE_NUM_BANDS; - hRenderConfig->roomAcoustics.pFc_input[IVAS_PI_AE_LOW] = IVAS_PI_AE_LOW_FREQ; - hRenderConfig->roomAcoustics.pFc_input[IVAS_PI_AE_MID] = IVAS_PI_AE_MID_FREQ; - hRenderConfig->roomAcoustics.pFc_input[IVAS_PI_AE_HIGH] = IVAS_PI_AE_HIGH_FREQ; - hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_LOW] = hAcoustEnvPI.rt60[IVAS_PI_AE_LOW]; - hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_MID] = hAcoustEnvPI.rt60[IVAS_PI_AE_MID]; - hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_HIGH] = hAcoustEnvPI.rt60[IVAS_PI_AE_HIGH]; - hRenderConfig->roomAcoustics.inputPreDelay = (float)(0.1 * hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_MID]); - hRenderConfig->roomAcoustics.pAcoustic_dsr[IVAS_PI_AE_LOW] = hAcoustEnvPI.dsr[IVAS_PI_AE_LOW]; - hRenderConfig->roomAcoustics.pAcoustic_dsr[IVAS_PI_AE_MID] = hAcoustEnvPI.dsr[IVAS_PI_AE_MID]; - hRenderConfig->roomAcoustics.pAcoustic_dsr[IVAS_PI_AE_HIGH] = hAcoustEnvPI.dsr[IVAS_PI_AE_HIGH]; - - hRenderConfig->roomAcoustics.use_er = hAcoustEnvPI.availEarlyReflections; - - if ( hAcoustEnvPI.availEarlyReflections ) - { - hRenderConfig->roomAcoustics.dimensions.x = hAcoustEnvPI.roomDimensions.x; - hRenderConfig->roomAcoustics.dimensions.y = hAcoustEnvPI.roomDimensions.y; - hRenderConfig->roomAcoustics.dimensions.z = hAcoustEnvPI.roomDimensions.z; - mvr2r( hAcoustEnvPI.absorbCoeffs, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); + /* Ignore if AE ID already in use */ + if ( hRenderConfig->roomAcoustics.aeID == hAcoustEnvPI.aeid ) + { + return IVAS_ERR_OK; + } + + /* Attempt to load the one already available */ + if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) == IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) + { + /* Add the new compact room environment */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA acEnv; + + acEnv.aeID = hAcoustEnvPI.aeid; + acEnv.nBands = IVAS_PI_AE_NUM_BANDS; + acEnv.pFc_input[IVAS_PI_AE_LOW] = IVAS_PI_AE_LOW_FREQ; + acEnv.pFc_input[IVAS_PI_AE_MID] = IVAS_PI_AE_MID_FREQ; + acEnv.pFc_input[IVAS_PI_AE_HIGH] = IVAS_PI_AE_HIGH_FREQ; + acEnv.pAcoustic_rt60[IVAS_PI_AE_LOW] = hAcoustEnvPI.rt60[IVAS_PI_AE_LOW]; + acEnv.pAcoustic_rt60[IVAS_PI_AE_MID] = hAcoustEnvPI.rt60[IVAS_PI_AE_MID]; + acEnv.pAcoustic_rt60[IVAS_PI_AE_HIGH] = hAcoustEnvPI.rt60[IVAS_PI_AE_HIGH]; + acEnv.inputPreDelay = (float) ( 0.1 * hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_MID] ); + acEnv.pAcoustic_dsr[IVAS_PI_AE_LOW] = hAcoustEnvPI.dsr[IVAS_PI_AE_LOW]; + acEnv.pAcoustic_dsr[IVAS_PI_AE_MID] = hAcoustEnvPI.dsr[IVAS_PI_AE_MID]; + acEnv.pAcoustic_dsr[IVAS_PI_AE_HIGH] = hAcoustEnvPI.dsr[IVAS_PI_AE_HIGH]; + + acEnv.use_er = hAcoustEnvPI.availEarlyReflections; + + if ( hAcoustEnvPI.availEarlyReflections ) + { + hRenderConfig->roomAcoustics.dimensions.x = hAcoustEnvPI.roomDimensions.x; + hRenderConfig->roomAcoustics.dimensions.y = hAcoustEnvPI.roomDimensions.y; + hRenderConfig->roomAcoustics.dimensions.z = hAcoustEnvPI.roomDimensions.z; + mvr2r( hAcoustEnvPI.absorbCoeffs, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); + } + + if ( ( error = IVAS_DEC_AddAcousticEnvironment( hIvasDec, acEnv ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) != IVAS_ERR_OK ) + { + return error; + } } /* Re-initialize reverb instance if already available */ diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index d0d2b501d8..5fefb03f66 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -475,6 +475,19 @@ ivas_error IVAS_DEC_HRTF_binary_close( const IVAS_BIN_RENDERER_TYPE binaural_renderer_old /* i : previous binaural renderer type */ ); +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +ivas_error IVAS_DEC_AddAcousticEnvironment( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcousticsConfig /* i : Room acoustic configuration */ +); + +ivas_error IVAS_DEC_GetAcousticEnvironment( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t aeID, /* i : Acoustic environment ID */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcEnv /* o : Room acoustic environment data pointer */ +); +#endif + /*! r: error code*/ ivas_error IVAS_DEC_GetRenderConfig( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 3514a986b9..86c145df13 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2959,8 +2959,86 @@ ivas_error RenderConfigReader_read( return IVAS_ERR_OK; } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getAcousticEnvironments() + * + * Gets all acoustic environments data + *------------------------------------------------------------------------------------------*/ +uint32_t RenderConfigReader_getAcousticEnvironmentCount( + RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ +) +{ + return pRenderConfigReader->nAE; +} + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getAcousticEnvironments() + * + * Gets all acoustic environments data + *------------------------------------------------------------------------------------------*/ +ivas_error RenderConfigReader_getAcousticEnvironments( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA **ppAcEnv /* o : Acoustic environment array pointer */ +) +{ + uint16_t n, m, j; + + if ( pRenderConfigReader == NULL || ppAcEnv == NULL || pRenderConfigReader->nAE == 0 || pRenderConfigReader->pAE == NULL ) + { + return 0; + } + + for (n = 0; n < pRenderConfigReader->nAE; n++) + { + AcousticEnv pIn = pRenderConfigReader->pAE[n]; + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pOut = ppAcEnv[n]; + + pOut->nBands = (uint16_t)pIn.pFG->nrBands; + pOut->inputPreDelay = pIn.preDelay; + + for ( m = 0; m < pOut->nBands; m++ ) + { + pOut->pFc_input[m] = pIn.pFG->pFc[m]; + pOut->pAcoustic_rt60[m] = pIn.pRT60[m]; + pOut->pAcoustic_dsr[m] = pIn.pDSR[m]; + } + + /* If ER are allocated then propagate parameters */ + if ( pIn.pEarlyReflections != 0 ) + { + pOut->use_er = pIn.pEarlyReflections->use_er; /* ER activation flag */ + pOut->lowComplexity = pIn.pEarlyReflections->lowComplexity; /* Low complexity flag */ + pOut->dimensions = pIn.pEarlyReflections->dimensions; + /* Use default listener origin position if non provided */ + if ( pIn.pEarlyReflections->pListenerOrigin == NULL ) + { + if ( ( pIn.pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + pIn.pEarlyReflections->pListenerOrigin->x = IVAS_ER_LIST_ORIGIN_X; + pIn.pEarlyReflections->pListenerOrigin->y = IVAS_ER_LIST_ORIGIN_Y; + pIn.pEarlyReflections->pListenerOrigin->z = IVAS_ER_LIST_HEIGHT; + } + pOut->ListenerOrigin = *pIn.pEarlyReflections->pListenerOrigin; + for ( j = 0; j < IVAS_ROOM_ABS_COEFF; j++ ) + { + pOut->AbsCoeff[j] = pIn.pEarlyReflections->pAbsCoeff[j]; + } + } + else + { + pOut->use_er = false; + } + } + + return IVAS_ERR_OK; +} +#endif + /*------------------------------------------------------------------------------------------* - * RenderConfigReader_getEnvironment() + * RenderConfigReader_getAcousticEnvironment() * * Gets Acoustic environment with a given ID *------------------------------------------------------------------------------------------*/ diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 8edaecc2f4..5fc5e09a4a 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -51,12 +51,26 @@ ivas_error RenderConfigReader_open( RenderConfigReader **ppRenderConfigReader /* o : RenderConfigReader handle */ ); +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +/* Get number of acoustic environments */ +uint32_t RenderConfigReader_getAcousticEnvironmentCount( + RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ +); + +/* Get all acoustic environments */ +ivas_error RenderConfigReader_getAcousticEnvironments( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA **ppAcEnv /* o : Acoustic environment array pointer */ +); +#endif + /* Get an acoustic environment */ ivas_error RenderConfigReader_getAcousticEnvironment( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ uint16_t id, /* i : Acoustic environment ID */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcEnv /* o : Target acoustic environment pointer */ ); + ivas_error RenderConfigReader_getDirectivity( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ uint16_t *pId, /* i : Directivity pattern ID */ -- GitLab From 6f9a19f029659bc0cb59666a76aa52521a225a3d Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 3 Nov 2025 10:22:43 +0100 Subject: [PATCH 10/18] Selectable AE based on already available acoustic environments --- apps/decoder.c | 43 ++++++++++++++++++++++++++++++--- lib_dec/lib_dec.c | 17 ++++++++++--- lib_util/render_config_reader.c | 38 ++++++++++++++++------------- 3 files changed, 74 insertions(+), 24 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index a7235e5356..b6af7c7c6e 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -227,6 +227,10 @@ int main( IVAS_RENDER_FRAMESIZE asked_frame_size; IVAS_DEC_HRTF_BINARY_WRAPPER hHrtfBinary; ObjectEditFileReader *objectEditFileReader = NULL; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + IVAS_ROOM_ACOUSTICS_CONFIG_DATA **pAE = NULL; + uint32_t aeCount = 0; +#endif #ifdef DEBUGGING int32_t noClipping; int32_t cnt_frames_limited; @@ -637,13 +641,31 @@ int main( goto cleanup; } #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - uint32_t aeCount = RenderConfigReader_getAcousticEnvironmentCount( renderConfigReader ); + aeCount = RenderConfigReader_getAcousticEnvironmentCount( renderConfigReader ); if ( aeCount > 0 ) { - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAE = malloc( aeCount * sizeof( IVAS_ROOM_ACOUSTICS_CONFIG_DATA ) ); uint32_t n; - if ( ( error = RenderConfigReader_getAcousticEnvironments( renderConfigReader, &pAE ) ) != IVAS_ERR_OK ) + pAE = malloc( aeCount * sizeof( IVAS_ROOM_ACOUSTICS_CONFIG_DATA * ) ); + + if ( pAE == NULL ) + { + fprintf( stderr, "\nError: cannot allocate memory for acoustic environment array\n\n" ); + goto cleanup; + } + + for ( n = 0; n < aeCount; n++ ) + { + pAE[n] = NULL; + + if ( NULL == ( pAE[n] = malloc( sizeof( IVAS_ROOM_ACOUSTICS_CONFIG_DATA ) ) ) ) + { + fprintf( stderr, "\nError: cannot allocate memory for acoustic environment\n\n" ); + goto cleanup; + } + } + + if ( ( error = RenderConfigReader_getAcousticEnvironments( renderConfigReader, pAE ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error while getting acoustic environments\n\n" ); goto cleanup; @@ -651,7 +673,7 @@ int main( for ( n = 0; n < aeCount; n++ ) { - if ( ( error = IVAS_DEC_AddAcousticEnvironment( hIvasDec, pAE[n] ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_AddAcousticEnvironment( hIvasDec, *pAE[n] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to add acoustic environments\n\n" ); goto cleanup; @@ -836,6 +858,19 @@ cleanup: free( pcmBuf ); +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + if ( pAE != NULL ) + { + uint16_t n; + + for ( n = 0; n < aeCount; n++ ) + { + free( pAE[n] ); + } + + free( pAE ); + } +#endif if ( arg.aeSequence.count > 0 ) { free( arg.aeSequence.pID ); diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 2174c985a1..4fbe51422c 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3237,12 +3237,17 @@ ivas_error IVAS_DEC_AddAcousticEnvironment( mvr2r( roomAcousticsConfig.pAcoustic_rt60, pAE->pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( roomAcousticsConfig.pAcoustic_dsr, pAE->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + pAE->use_er = roomAcousticsConfig.use_er; + if ( pAE->use_er == 1 ) { - pAE->use_er = roomAcousticsConfig.use_er; pAE->lowComplexity = roomAcousticsConfig.lowComplexity; - pAE->dimensions = roomAcousticsConfig.dimensions; - pAE->ListenerOrigin = roomAcousticsConfig.ListenerOrigin; + pAE->dimensions.x = roomAcousticsConfig.dimensions.x; + pAE->dimensions.y = roomAcousticsConfig.dimensions.y; + pAE->dimensions.z = roomAcousticsConfig.dimensions.z; + pAE->ListenerOrigin.x = roomAcousticsConfig.ListenerOrigin.x; + pAE->ListenerOrigin.y = roomAcousticsConfig.ListenerOrigin.y; + pAE->ListenerOrigin.z = roomAcousticsConfig.ListenerOrigin.z; mvr2r( roomAcousticsConfig.AbsCoeff, pAE->AbsCoeff, IVAS_ROOM_ABS_COEFF ); } @@ -3272,6 +3277,12 @@ ivas_error IVAS_DEC_GetAcousticEnvironment( } st_ivas = hIvasDec->st_ivas; + /* In case of default AE ID, select the first one available */ + if ( aeID == IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) + { + aeID = (uint16_t) st_ivas->pAcousticEnvironments[0].aeID; + } + for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) { IVAS_ROOM_ACOUSTICS_CONFIG_DATA ae = st_ivas->pAcousticEnvironments[n]; diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 86c145df13..3f710ad428 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2963,10 +2963,10 @@ ivas_error RenderConfigReader_read( /*------------------------------------------------------------------------------------------* * RenderConfigReader_getAcousticEnvironments() * - * Gets all acoustic environments data + * Gets number of acoustic environments available *------------------------------------------------------------------------------------------*/ uint32_t RenderConfigReader_getAcousticEnvironmentCount( - RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ + RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ ) { return pRenderConfigReader->nAE; @@ -2975,11 +2975,11 @@ uint32_t RenderConfigReader_getAcousticEnvironmentCount( /*------------------------------------------------------------------------------------------* * RenderConfigReader_getAcousticEnvironments() * - * Gets all acoustic environments data + * Gets all acoustic environments *------------------------------------------------------------------------------------------*/ ivas_error RenderConfigReader_getAcousticEnvironments( - RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ - IVAS_ROOM_ACOUSTICS_CONFIG_DATA **ppAcEnv /* o : Acoustic environment array pointer */ + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA **ppAcEnv /* o : Acoustic environment array pointer */ ) { uint16_t n, m, j; @@ -2989,12 +2989,13 @@ ivas_error RenderConfigReader_getAcousticEnvironments( return 0; } - for (n = 0; n < pRenderConfigReader->nAE; n++) + for ( n = 0; n < pRenderConfigReader->nAE; n++ ) { AcousticEnv pIn = pRenderConfigReader->pAE[n]; IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pOut = ppAcEnv[n]; - pOut->nBands = (uint16_t)pIn.pFG->nrBands; + pOut->aeID = (uint16_t) pIn.id; + pOut->nBands = (uint16_t) pIn.pFG->nrBands; pOut->inputPreDelay = pIn.preDelay; for ( m = 0; m < pOut->nBands; m++ ) @@ -3007,21 +3008,24 @@ ivas_error RenderConfigReader_getAcousticEnvironments( /* If ER are allocated then propagate parameters */ if ( pIn.pEarlyReflections != 0 ) { - pOut->use_er = pIn.pEarlyReflections->use_er; /* ER activation flag */ + pOut->use_er = pIn.pEarlyReflections->use_er; /* ER activation flag */ pOut->lowComplexity = pIn.pEarlyReflections->lowComplexity; /* Low complexity flag */ pOut->dimensions = pIn.pEarlyReflections->dimensions; + /* Use default listener origin position if non provided */ - if ( pIn.pEarlyReflections->pListenerOrigin == NULL ) + if ( pIn.pEarlyReflections->pListenerOrigin != NULL ) { - if ( ( pIn.pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - pIn.pEarlyReflections->pListenerOrigin->x = IVAS_ER_LIST_ORIGIN_X; - pIn.pEarlyReflections->pListenerOrigin->y = IVAS_ER_LIST_ORIGIN_Y; - pIn.pEarlyReflections->pListenerOrigin->z = IVAS_ER_LIST_HEIGHT; + pOut->ListenerOrigin.x = pIn.pEarlyReflections->pListenerOrigin->x; + pOut->ListenerOrigin.y = pIn.pEarlyReflections->pListenerOrigin->y; + pOut->ListenerOrigin.z = pIn.pEarlyReflections->pListenerOrigin->z; } - pOut->ListenerOrigin = *pIn.pEarlyReflections->pListenerOrigin; + else + { + pOut->ListenerOrigin.x = IVAS_ER_LIST_ORIGIN_X; + pOut->ListenerOrigin.y = IVAS_ER_LIST_ORIGIN_Y; + pOut->ListenerOrigin.z = IVAS_ER_LIST_HEIGHT; + } + for ( j = 0; j < IVAS_ROOM_ABS_COEFF; j++ ) { pOut->AbsCoeff[j] = pIn.pEarlyReflections->pAbsCoeff[j]; -- GitLab From 0483770829210e51c813618007fd431187ecc3b1 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 3 Nov 2025 10:36:22 +0100 Subject: [PATCH 11/18] Resolving clang complaints --- lib_util/render_config_reader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 5fc5e09a4a..d69249734f 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -54,7 +54,7 @@ ivas_error RenderConfigReader_open( #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT /* Get number of acoustic environments */ uint32_t RenderConfigReader_getAcousticEnvironmentCount( - RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ + RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ ); /* Get all acoustic environments */ -- GitLab From 83e8b50b081f67efa0ed29babc7804f482c157fe Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 3 Nov 2025 17:17:32 +0100 Subject: [PATCH 12/18] PI data updates related to acoustic environments --- tests/rtp/test_rtp.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/rtp/test_rtp.py b/tests/rtp/test_rtp.py index fbf7be9fcb..c693a42c96 100644 --- a/tests/rtp/test_rtp.py +++ b/tests/rtp/test_rtp.py @@ -61,6 +61,7 @@ from tempfile import TemporaryDirectory from pathlib import Path from ivasrtp import * import numpy as np +import json from pyaudio3dtools.audiofile import readfile ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) @@ -233,15 +234,30 @@ def generatePiData(startTs: int, endTs: int) -> dict: ) someAcousticEnvLR = lambda: ACOUSTIC_ENVIRONMENT( aeid=random.randint(0, 127), - rt60=[random.randint(0, len(rt60Value)) for _ in range(3)], - dsr=[random.randint(0, len(dsrValue)) for _ in range(3)], + rt60=(float(rt60Value[random.randint(0, len(rt60Value) - 1)]), + float(rt60Value[random.randint(0, len(rt60Value) - 1)]), + float(rt60Value[random.randint(0, len(rt60Value) - 1)])), + dsr=(float(dsrValue[random.randint(0, len(dsrValue) - 1)]), + float(dsrValue[random.randint(0, len(dsrValue) - 1)]), + float(dsrValue[random.randint(0, len(dsrValue) - 1)])), ) someAcousticEnvERLR = lambda: ACOUSTIC_ENVIRONMENT( aeid=random.randint(0, 127), - rt60=[random.randint(0, len(rt60Value)) for _ in range(3)], - dsr=[random.randint(0, len(dsrValue)) for _ in range(3)], - dim=[random.randint(0, len(roomDimensionValue)) for _ in range(3)], - abscoeff=[random.randint(0, len(absorptionCoeffValues)) for _ in range(6)], + rt60=(float(rt60Value[random.randint(0, len(rt60Value) - 1)]), + float(rt60Value[random.randint(0, len(rt60Value) - 1)]), + float(rt60Value[random.randint(0, len(rt60Value) - 1)])), + dsr=(float(dsrValue[random.randint(0, len(dsrValue) - 1)]), + float(dsrValue[random.randint(0, len(dsrValue) - 1)]), + float(dsrValue[random.randint(0, len(dsrValue) - 1)])), + dim=(float(roomDimensionValue[random.randint(0, len(roomDimensionValue) - 1)]), + float(roomDimensionValue[random.randint(0, len(roomDimensionValue) - 1)]), + float(roomDimensionValue[random.randint(0, len(roomDimensionValue) - 1)])), + abscoeff=(float(absorptionCoeffValues[random.randint(0, len(absorptionCoeffValues) - 1)]), + float(absorptionCoeffValues[random.randint(0, len(absorptionCoeffValues) - 1)]), + float(absorptionCoeffValues[random.randint(0, len(absorptionCoeffValues) - 1)]), + float(absorptionCoeffValues[random.randint(0, len(absorptionCoeffValues) - 1)]), + float(absorptionCoeffValues[random.randint(0, len(absorptionCoeffValues) - 1)]), + float(absorptionCoeffValues[random.randint(0, len(absorptionCoeffValues) - 1)])), ) someAcousticEnvList = [someAcousticEnvAEID, someAcousticEnvLR, someAcousticEnvERLR] -- GitLab From 9651a9594b1eb5c8aabbad156d1a9c246c7ff51e Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 3 Nov 2025 21:02:43 +0100 Subject: [PATCH 13/18] Added tolerance for PI room acoustics testing --- tests/rtp/test_rtp.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/rtp/test_rtp.py b/tests/rtp/test_rtp.py index c693a42c96..2a37f01103 100644 --- a/tests/rtp/test_rtp.py +++ b/tests/rtp/test_rtp.py @@ -342,13 +342,13 @@ def isEqualAcousticEnv(ref: ACOUSTIC_ENVIRONMENT, dut: ACOUSTIC_ENVIRONMENT): dut.abscoeff ), "Acoustic Env PI Data mismatch in len(abscoeff)" for r, d in zip(ref.rt60, dut.rt60): - assert r == d, f"Acoustic Env PI Data mismatch in rt60 {r} != {d}" + assert abs(r - d) < 0.0001, f"Acoustic Env PI Data mismatch in RT60 {r} != {d}" for r, d in zip(ref.dsr, dut.dsr): - assert r == d, f"Acoustic Env PI Data mismatch in dsr {r} != {d}" + assert abs(r - d) < 0.0001, f"Acoustic Env PI Data mismatch in DSR {r} != {d}" for r, d in zip(ref.dim, dut.dim): - assert r == d, f"Acoustic Env PI Data mismatch in dim {r} != {d}" + assert abs(r - d) < 0.0001, f"Acoustic Env PI Data mismatch in room dimension {r} != {d}" for r, d in zip(ref.abscoeff, dut.abscoeff): - assert r == d, f"Acoustic Env PI Data mismatch in abscoeff {r} != {d}" + assert abs(r - d) < 0.0001, f"Acoustic Env PI Data mismatch in absorption coefficient {r} != {d}" def isEqualAudioFocus(ref: AUDIO_FOCUS, dut: AUDIO_FOCUS): -- GitLab From d4b87c72225d20c57b857de8b2805aec18b9843d Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 3 Nov 2025 21:13:36 +0100 Subject: [PATCH 14/18] Acoustic environments structure cleanup --- lib_dec/ivas_init_dec.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 29e0fd64e5..c44d63bd5f 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2881,6 +2881,14 @@ void ivas_destroy_dec( st_ivas->p_output_f[i] = NULL; } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + /* Acoustic environments*/ + if ( st_ivas->pAcousticEnvironments != NULL ) + { + free( st_ivas->pAcousticEnvironments ); + } +#endif + /* main IVAS handle */ free( st_ivas ); -- GitLab From c3cda67b6b1ab22d9eacb147e55099fda94cd69a Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 4 Nov 2025 09:42:31 +0100 Subject: [PATCH 15/18] Fix for logging PI data to JSON in Windows --- lib_util/ivas_rtp_file.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib_util/ivas_rtp_file.c b/lib_util/ivas_rtp_file.c index 698ea875be..ffd490b2e4 100644 --- a/lib_util/ivas_rtp_file.c +++ b/lib_util/ivas_rtp_file.c @@ -158,7 +158,15 @@ void IVAS_RTP_LogPiData( return; } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +#ifdef _WIN32 + if ( ftell( f_piDataOut ) > 3 ) +#else if ( ftell( f_piDataOut ) > 2 ) +#endif +#else + if ( ftell( f_piDataOut ) > 2 ) +#endif { fprintf( f_piDataOut, ",\n" ); } -- GitLab From a80195d6d161817276bf5f29f81bec8d98ce0eb9 Mon Sep 17 00:00:00 2001 From: Lauros Pajunen Date: Wed, 5 Nov 2025 14:43:57 +0200 Subject: [PATCH 16/18] Add null check --- lib_dec/lib_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 4fbe51422c..dff4c2f112 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -5931,7 +5931,7 @@ ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *pi fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); #endif - if ( piData->data.acousticEnv.availLateReverb && aeid != hIvasDec->st_ivas->hRenderConfig->roomAcoustics.aeID ) + if ( piData->data.acousticEnv.availLateReverb && hIvasDec->st_ivas->hRenderConfig != NULL && aeid != hIvasDec->st_ivas->hRenderConfig->roomAcoustics.aeID ) { error = IVAS_DEC_FeedAcousticEnvPI( hIvasDec, piData->data.acousticEnv ); } -- GitLab From 711d41b91f7ee6b9c4c66f3b9543f51c201b757a Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Wed, 5 Nov 2025 17:21:42 +0100 Subject: [PATCH 17/18] Fix for converting DSR from dB to linear in case of acoustic environment PI frame --- lib_dec/lib_dec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 4fbe51422c..ccbc82e199 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3598,9 +3598,9 @@ static ivas_error IVAS_DEC_FeedAcousticEnvPI( acEnv.pAcoustic_rt60[IVAS_PI_AE_MID] = hAcoustEnvPI.rt60[IVAS_PI_AE_MID]; acEnv.pAcoustic_rt60[IVAS_PI_AE_HIGH] = hAcoustEnvPI.rt60[IVAS_PI_AE_HIGH]; acEnv.inputPreDelay = (float) ( 0.1 * hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_MID] ); - acEnv.pAcoustic_dsr[IVAS_PI_AE_LOW] = hAcoustEnvPI.dsr[IVAS_PI_AE_LOW]; - acEnv.pAcoustic_dsr[IVAS_PI_AE_MID] = hAcoustEnvPI.dsr[IVAS_PI_AE_MID]; - acEnv.pAcoustic_dsr[IVAS_PI_AE_HIGH] = hAcoustEnvPI.dsr[IVAS_PI_AE_HIGH]; + acEnv.pAcoustic_dsr[IVAS_PI_AE_LOW] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_LOW] / 10.0f ); + acEnv.pAcoustic_dsr[IVAS_PI_AE_MID] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_MID] / 10.0f ); + acEnv.pAcoustic_dsr[IVAS_PI_AE_HIGH] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_HIGH] / 10.0f ); acEnv.use_er = hAcoustEnvPI.availEarlyReflections; -- GitLab From 6a733f972009928de144355ad1e9a2aeaa96045b Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 10 Nov 2025 09:39:09 +0100 Subject: [PATCH 18/18] Comments cleanup --- lib_dec/ivas_init_dec.c | 3 ++- lib_util/render_config_reader.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index c44d63bd5f..8136895a9c 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2882,10 +2882,11 @@ void ivas_destroy_dec( } #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - /* Acoustic environments*/ + /* Acoustic environments */ if ( st_ivas->pAcousticEnvironments != NULL ) { free( st_ivas->pAcousticEnvironments ); + st_ivas->pAcousticEnvironments = NULL; } #endif diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 3f710ad428..761b203cb0 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2961,7 +2961,7 @@ ivas_error RenderConfigReader_read( #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT /*------------------------------------------------------------------------------------------* - * RenderConfigReader_getAcousticEnvironments() + * RenderConfigReader_getAcousticEnvironmentCount() * * Gets number of acoustic environments available *------------------------------------------------------------------------------------------*/ -- GitLab