From 7cb13e43e20fcde3fb7705b33b7b2c0bbed20726 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Fri, 7 Nov 2025 10:49:11 +0100 Subject: [PATCH 01/14] Porting floating-point MR 2298, prototype --- apps/decoder.c | 70 +++++- lib_com/common_api_types.h | 3 + lib_com/ivas_cnst.h | 3 + lib_com/options.h | 1 + lib_dec/ivas_init_dec_fx.c | 9 + lib_dec/ivas_stat_dec.h | 5 + lib_dec/lib_dec.h | 13 ++ lib_dec/lib_dec_fx.c | 364 +++++++++++++++++++++++++++++++ lib_rend/ivas_render_config_fx.c | 4 + lib_rend/lib_rend_fx.c | 8 + lib_util/ivas_rtp_file.c | 8 + lib_util/ivas_rtp_pi_data.c | 26 +++ lib_util/ivas_rtp_pi_data.h | 20 ++ lib_util/render_config_reader.c | 102 ++++++++- lib_util/render_config_reader.h | 13 ++ 15 files changed, 647 insertions(+), 2 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index c176e5be7..9d8f1ad35 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -55,6 +55,9 @@ #ifdef IVAS_RTPDUMP #include "ivas_rtp_file.h" #endif +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +#include "ivas_cnst.h" +#endif #ifdef FIXED_RTP_SEQUENCE_NUM #define RANDOM_INITSEED_DEC ( 0xFEEDFADE ) @@ -208,7 +211,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 WMOPS reset_wmops(); reset_mem( USE_BYTES ); @@ -419,7 +425,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 #ifdef IVAS_RTPDUMP arg.enableHeadRotation = arg.enableHeadRotation || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; @@ -525,7 +535,47 @@ int main( fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); goto cleanup; } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + aeCount = RenderConfigReader_getAcousticEnvironmentCount( renderConfigReader ); + if ( aeCount > 0 ) + { + uint32_t n; + + 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; + } + + 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_fx ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to get directivity patterns for one or more of IDs: %d %d %d %d\n\n", arg.directivityPatternId[0], arg.directivityPatternId[1], arg.directivityPatternId[2], arg.directivityPatternId[3] ); @@ -564,7 +614,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 ) { @@ -692,6 +746,20 @@ 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_com/common_api_types.h b/lib_com/common_api_types.h index 6259b5f8d..d78ea5cef 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -330,6 +330,9 @@ typedef enum typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + Word16 aeID; /* Acoustic environment ID */ +#endif Word16 nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ Word32 pFc_input_fx[IVAS_CLDFB_NO_CHANNELS_MAX]; /*Q16 Center frequencies for which following values are provided: */ Word32 pAcoustic_rt60_fx[IVAS_CLDFB_NO_CHANNELS_MAX]; /*Q26 - The room's T60 per center frequency */ diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index c445d0299..cfcad5a34 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1649,6 +1649,9 @@ typedef enum #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 1189abd99..49863d38b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -153,6 +153,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 FIXED_RTP_SEQUENCE_NUM /* Remove random sequence number initialization */ +#define IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT /* RTPDUMP acoustic environment */ /* #################### End BASOP porting switches ############################ */ diff --git a/lib_dec/ivas_init_dec_fx.c b/lib_dec/ivas_init_dec_fx.c index c005b1aa5..ffb4061a7 100644 --- a/lib_dec/ivas_init_dec_fx.c +++ b/lib_dec/ivas_init_dec_fx.c @@ -3192,6 +3192,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 ) @@ -3208,6 +3212,11 @@ void ivas_initialize_handles_dec( st_ivas->p_output_fx[i] = NULL; } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + /* Acoustic environments */ + st_ivas->pAcousticEnvironments = NULL; +#endif + return; } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 4a464705d..ac1f9aaad 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1199,6 +1199,11 @@ 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 */ + Word16 acousticEnvironmentsCount; /* Number of acoustic environments in the array*/ +#endif + Word16 flag_omasa_brate; ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; /* ISAR split binaural rendering handle */ diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 1167d60b9..4a15804fd 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -446,6 +446,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 */ + Word16 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_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 6c6700558..da4860bd5 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -2928,6 +2928,193 @@ 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 */ +) +{ + Word16 n; + Decoder_Struct *st_ivas; + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAE = NULL; + + test(); + 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++ ) + { + test(); + IF( st_ivas->pAcousticEnvironments[n].aeID == roomAcousticsConfig.aeID ) + { + move32(); + pAE = &st_ivas->pAcousticEnvironments[n]; + break; + } + } + + /* If not found */ + test(); + 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]; + move32(); + move16(); + move32(); + } + + pAE->aeID = roomAcousticsConfig.aeID; + pAE->nBands = roomAcousticsConfig.nBands; + pAE->acousticPreDelay_fx = roomAcousticsConfig.acousticPreDelay_fx; + pAE->inputPreDelay_fx = roomAcousticsConfig.inputPreDelay_fx; + + Copy32( roomAcousticsConfig.pFc_input_fx, pAE->pFc_input_fx, CLDFB_NO_CHANNELS_MAX ); // Q16 + Copy32( roomAcousticsConfig.pAcoustic_rt60_fx, pAE->pAcoustic_rt60_fx, CLDFB_NO_CHANNELS_MAX ); // Q26 + Copy32( roomAcousticsConfig.pAcoustic_dsr_fx, pAE->pAcoustic_dsr_fx, CLDFB_NO_CHANNELS_MAX ); // Q30 + + pAE->use_er = roomAcousticsConfig.use_er; + + move16(); + move16(); + move32(); + move32(); + move16(); + + test(); + IF( pAE->use_er == 1 ) + { + pAE->lowComplexity = roomAcousticsConfig.lowComplexity; + move32(); + + pAE->dimensions.x_fx = roomAcousticsConfig.dimensions.x_fx; + pAE->dimensions.y_fx = roomAcousticsConfig.dimensions.y_fx; + pAE->dimensions.z_fx = roomAcousticsConfig.dimensions.z_fx; + move32(); + move32(); + move32(); + + pAE->ListenerOrigin.x_fx = roomAcousticsConfig.ListenerOrigin.x_fx; + pAE->ListenerOrigin.y_fx = roomAcousticsConfig.ListenerOrigin.y_fx; + pAE->ListenerOrigin.z_fx = roomAcousticsConfig.ListenerOrigin.z_fx; + move32(); + move32(); + move32(); + + Copy32( roomAcousticsConfig.AbsCoeff_fx, pAE->AbsCoeff_fx, 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 */ + Word16 aeID, /* i : Acoustic environment ID */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcEnv /* o : Room acoustic environment data pointer */ +) +{ + Word16 n, m; + Word16 found = 0; + + Decoder_Struct *st_ivas; + + test(); + IF( hIvasDec == NULL || pAcEnv == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; + move32(); + + /* In case of default AE ID, select the first one available */ + test(); + IF( aeID == IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) + { + aeID = (uint16_t) st_ivas->pAcousticEnvironments[0].aeID; + move32(); + } + + FOR( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) + { + IVAS_ROOM_ACOUSTICS_CONFIG_DATA ae = st_ivas->pAcousticEnvironments[n]; + move32(); + test(); + IF( aeID == ae.aeID ) + { + found = 1; + pAcEnv->aeID = aeID; + pAcEnv->nBands = ae.nBands; + pAcEnv->inputPreDelay_fx = ae.inputPreDelay_fx; + move16(); + move16(); + move16(); + move32(); + + FOR( m = 0; m < pAcEnv->nBands; m++ ) + { + pAcEnv->pFc_input_fx[m] = ae.pFc_input_fx[m]; + pAcEnv->pAcoustic_rt60_fx[m] = ae.pAcoustic_rt60_fx[m]; + pAcEnv->pAcoustic_dsr_fx[m] = ae.pAcoustic_dsr_fx[m]; + move32(); + move32(); + move32(); + } + + /* If ER are allocated then propagate parameters */ + pAcEnv->use_er = ae.use_er; + move16(); + test(); + IF( ae.use_er != 0 ) + { + pAcEnv->lowComplexity = ae.lowComplexity; + move32(); + + pAcEnv->dimensions.x_fx = ae.dimensions.x_fx; + pAcEnv->dimensions.y_fx = ae.dimensions.y_fx; + pAcEnv->dimensions.z_fx = ae.dimensions.z_fx; + move32(); + move32(); + move32(); + + pAcEnv->ListenerOrigin.x_fx = ae.ListenerOrigin.x_fx; + pAcEnv->ListenerOrigin.y_fx = ae.ListenerOrigin.y_fx; + pAcEnv->ListenerOrigin.z_fx = ae.ListenerOrigin.z_fx; + move32(); + move32(); + move32(); + + Copy32( ae.AbsCoeff_fx, pAcEnv->AbsCoeff_fx, IVAS_ROOM_ABS_COEFF ); + } + } + } + + test(); + return found ? IVAS_ERR_OK : IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING; +} +#endif /*---------------------------------------------------------------------* * copyRendererConfigStruct( ) @@ -2945,6 +3132,10 @@ static ivas_error copyRendererConfigStruct( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + hRCout->roomAcoustics.aeID = hRCin->roomAcoustics.aeID; + move16(); +#endif hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; hRCout->roomAcoustics.acousticPreDelay_fx = hRCin->roomAcoustics.acousticPreDelay_fx; hRCout->roomAcoustics.inputPreDelay_fx = hRCin->roomAcoustics.inputPreDelay_fx; @@ -3042,6 +3233,10 @@ ivas_error IVAS_DEC_FeedRenderConfig( hRenderConfig = hIvasDec->st_ivas->hRenderConfig; st_ivas = hIvasDec->st_ivas; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + hRenderConfig->roomAcoustics.aeID = renderConfig.roomAcoustics.aeID; + move16(); +#endif hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; hRenderConfig->roomAcoustics.acousticPreDelay_fx = renderConfig.roomAcoustics.acousticPreDelay_fx; hRenderConfig->roomAcoustics.inputPreDelay_fx = renderConfig.roomAcoustics.inputPreDelay_fx; @@ -3136,6 +3331,159 @@ ivas_error IVAS_DEC_FeedRenderConfig( return IVAS_ERR_OK; } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +/*---------------------------------------------------------------------* + * IVAS_DEC_FeedAcousticEnvPI( ) + * + * Set acoustic environment from the PI data + *---------------------------------------------------------------------*/ + +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 */ +) +{ + RENDER_CONFIG_HANDLE hRenderConfig; + Decoder_Struct *st_ivas; + ivas_error error; + + test(); + test(); + 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; + move32(); + move32(); + + /* Ignore if AE ID already in use */ + test(); + IF( hRenderConfig->roomAcoustics.aeID == hAcoustEnvPI.aeid ) + { + return IVAS_ERR_OK; + } + + /* Attempt to load the one already available */ + test(); + 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; + move16(); + move16(); + + acEnv.pFc_input_fx[IVAS_PI_AE_LOW] = IVAS_PI_AE_LOW_FREQ * 0x10000; /* Q16 */ + acEnv.pFc_input_fx[IVAS_PI_AE_MID] = IVAS_PI_AE_MID_FREQ * 0x10000; + acEnv.pFc_input_fx[IVAS_PI_AE_HIGH] = IVAS_PI_AE_HIGH_FREQ * 0x10000; + move32(); + move32(); + move32(); + + acEnv.pAcoustic_rt60_fx[IVAS_PI_AE_LOW] = hAcoustEnvPI.rt60_fx[IVAS_PI_AE_LOW]; + acEnv.pAcoustic_rt60_fx[IVAS_PI_AE_MID] = hAcoustEnvPI.rt60_fx[IVAS_PI_AE_MID]; + acEnv.pAcoustic_rt60_fx[IVAS_PI_AE_HIGH] = hAcoustEnvPI.rt60_fx[IVAS_PI_AE_HIGH]; + acEnv.inputPreDelay_fx = ( ( hAcoustEnvPI.rt60_fx[IVAS_PI_AE_MID] * 0x00CCCCC ) >> 26 ); /* Q26 RT60[MID] / 10 -> Q27 */ + move32(); + move32(); + move32(); + move32(); + + acEnv.pAcoustic_dsr_fx[IVAS_PI_AE_LOW] = hAcoustEnvPI.dsr_fx[IVAS_PI_AE_LOW]; + acEnv.pAcoustic_dsr_fx[IVAS_PI_AE_MID] = hAcoustEnvPI.dsr_fx[IVAS_PI_AE_MID]; + acEnv.pAcoustic_dsr_fx[IVAS_PI_AE_HIGH] = hAcoustEnvPI.dsr_fx[IVAS_PI_AE_HIGH]; + move32(); + move32(); + move32(); + + acEnv.use_er = hAcoustEnvPI.availEarlyReflections; + move16(); + + test(); + IF( hAcoustEnvPI.availEarlyReflections ) + { + hRenderConfig->roomAcoustics.dimensions.x_fx = hAcoustEnvPI.roomDimensions.x_fx; + hRenderConfig->roomAcoustics.dimensions.y_fx = hAcoustEnvPI.roomDimensions.y_fx; + hRenderConfig->roomAcoustics.dimensions.z_fx = hAcoustEnvPI.roomDimensions.z_fx; + move32(); + move32(); + move32(); + + mvr2r( hAcoustEnvPI.absorbCoeffs, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); + } + + test(); + IF( ( error = IVAS_DEC_AddAcousticEnvironment( hIvasDec, acEnv ) ) != IVAS_ERR_OK ) + { + return error; + } + + test(); + IF( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* Re-initialize reverb instance if already available */ + + /* TD renderer Jot reverberator */ + test(); + IF( st_ivas->hReverb != NULL ) + { + test(); + IF( ( error = ivas_reverb_open_fx( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* CREND Jot reverberator */ + test(); + IF( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) + { + test(); + IF( ( error = ivas_reverb_open_fx( &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_fx( &( st_ivas->hDiracDecBin[0]->hReverb ) ); + + test(); + IF( ( error = ivas_binaural_reverb_init_fx( &( 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 */ + test(); + IF( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) + { + ivas_binaural_reverb_close_fx( &( st_ivas->hBinRenderer->hReverb ) ); + + test(); + IF( ( error = ivas_binaural_reverb_init_fx( &( 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( ) @@ -6434,6 +6782,22 @@ ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *pi } BREAK; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + case IVAS_PI_ACOUSTIC_ENVIRONMENT: + { + Word16 aeid = piData->data.acousticEnv.aeid; +#ifdef DEBUGGING + fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); +#endif + test(); + 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 ); + } + } + BREAK; +#endif + #ifdef RTP_S4_251135_CR26253_0016_REV1 case IVAS_PI_DIEGETIC_TYPE: { diff --git a/lib_rend/ivas_render_config_fx.c b/lib_rend/ivas_render_config_fx.c index 3c43b59e1..23a54d355 100644 --- a/lib_rend/ivas_render_config_fx.c +++ b/lib_rend/ivas_render_config_fx.c @@ -107,6 +107,10 @@ ivas_error ivas_render_config_init_from_rom_fx( { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "Unexpected null pointer while attempting to fill renderer configuration from ROM" ); } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + ( *hRenderConfig )->roomAcoustics.aeID = IVAS_DEFAULT_AEID; + move16(); +#endif ( *hRenderConfig )->roomAcoustics.nBands = IVAS_REVERB_DEFAULT_N_BANDS; move16(); ( *hRenderConfig )->roomAcoustics.acousticPreDelay_fx = IVAS_REVERB_DEFAULT_PRE_DELAY_FX; diff --git a/lib_rend/lib_rend_fx.c b/lib_rend/lib_rend_fx.c index b8e282d91..6552d924a 100644 --- a/lib_rend/lib_rend_fx.c +++ b/lib_rend/lib_rend_fx.c @@ -5226,6 +5226,10 @@ ivas_error IVAS_REND_GetRenderConfig( } hRCin = hIvasRend->hRendererConfig; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + hRCout->roomAcoustics.aeID = hRCin->roomAcoustics.aeID; + move16(); +#endif hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; hRCout->roomAcoustics.acousticPreDelay_fx = hRCin->roomAcoustics.acousticPreDelay_fx; hRCout->roomAcoustics.inputPreDelay_fx = hRCin->roomAcoustics.inputPreDelay_fx; @@ -5289,6 +5293,10 @@ ivas_error IVAS_REND_FeedRenderConfig( hRenderConfig = hIvasRend->hRendererConfig; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + hRenderConfig->roomAcoustics.aeID = renderConfig.roomAcoustics.aeID; + move16(); +#endif hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; move16(); hRenderConfig->roomAcoustics.acousticPreDelay_fx = renderConfig.roomAcoustics.acousticPreDelay_fx; diff --git a/lib_util/ivas_rtp_file.c b/lib_util/ivas_rtp_file.c index 82f198135..56b4509cf 100644 --- a/lib_util/ivas_rtp_file.c +++ b/lib_util/ivas_rtp_file.c @@ -159,7 +159,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" ); } diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index be2e9dd4d..506264ade 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -33,6 +33,11 @@ #include "ivas_error_utils.h" #include "ivas_rtp_internal.h" +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +#include "cnst.h" +#include +#endif + #ifdef IVAS_RTPDUMP /* Generic PI data packing/unpacking functions */ @@ -314,6 +319,27 @@ 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]; + +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + aeEnv->rt60_fx[IVAS_PI_AE_LOW] = (Word32) ( aeEnv->rt60[IVAS_PI_AE_LOW] * ONE_IN_Q26 ); /* Q26 */ + aeEnv->rt60_fx[IVAS_PI_AE_MID] = (Word32) ( aeEnv->rt60[IVAS_PI_AE_MID] * ONE_IN_Q26 ); + aeEnv->rt60_fx[IVAS_PI_AE_HIGH] = (Word32) ( aeEnv->rt60[IVAS_PI_AE_HIGH] * ONE_IN_Q26 ); + aeEnv->dsr_fx[IVAS_PI_AE_LOW] = (Word32) ( powf( 10.0f, aeEnv->dsr[IVAS_PI_AE_LOW] / 10.0f ) * ONE_IN_Q30 ); /* Q30 */ + aeEnv->dsr_fx[IVAS_PI_AE_MID] = (Word32) ( powf( 10.0f, aeEnv->dsr[IVAS_PI_AE_MID] / 10.0f ) * ONE_IN_Q30 ); + aeEnv->dsr_fx[IVAS_PI_AE_HIGH] = (Word32) ( powf( 10.0f, aeEnv->dsr[IVAS_PI_AE_HIGH] / 10.0f ) * ONE_IN_Q30 ); + + aeEnv->roomDimensions.x_fx = (Word32) ( aeEnv->roomDimensions.x * ONE_IN_Q22 ); /* Q22 */ + aeEnv->roomDimensions.y_fx = (Word32) ( aeEnv->roomDimensions.y * ONE_IN_Q22 ); + aeEnv->roomDimensions.z_fx = (Word32) ( aeEnv->roomDimensions.z * ONE_IN_Q22 ); + aeEnv->roomDimensions.q_fact = Q22; + + aeEnv->absorbCoeffs_fx[IVAS_PI_AE_FRONT] = (Word32) ( aeEnv->absorbCoeffs[IVAS_PI_AE_FRONT] * ONE_IN_Q30 ); /* Q30 */ + aeEnv->absorbCoeffs_fx[IVAS_PI_AE_BACK] = (Word32) ( aeEnv->absorbCoeffs[IVAS_PI_AE_BACK] * ONE_IN_Q30 ); + aeEnv->absorbCoeffs_fx[IVAS_PI_AE_LEFT] = (Word32) ( aeEnv->absorbCoeffs[IVAS_PI_AE_LEFT] * ONE_IN_Q30 ); + aeEnv->absorbCoeffs_fx[IVAS_PI_AE_RIGHT] = (Word32) ( aeEnv->absorbCoeffs[IVAS_PI_AE_RIGHT] * ONE_IN_Q30 ); + aeEnv->absorbCoeffs_fx[IVAS_PI_AE_CEILING] = (Word32) ( aeEnv->absorbCoeffs[IVAS_PI_AE_CEILING] * ONE_IN_Q30 ); + aeEnv->absorbCoeffs_fx[IVAS_PI_AE_FLOOR] = (Word32) ( aeEnv->absorbCoeffs[IVAS_PI_AE_FLOOR] * ONE_IN_Q30 ); +#endif } return IVAS_ERR_OK; diff --git a/lib_util/ivas_rtp_pi_data.h b/lib_util/ivas_rtp_pi_data.h index dc4c7f8ba..ae40afbff 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, @@ -146,10 +155,21 @@ typedef struct /* only valid if availLateReverb==true or availEarlyReflections==true */ float rt60[IVAS_PI_AE_NUM_BANDS]; /* time for the reflections to reduce 60 dB per band in seconds */ float dsr[IVAS_PI_AE_NUM_BANDS]; /* diffuse to source signal energy ratio per band in dB */ +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + Word32 rt60_fx[IVAS_PI_AE_NUM_BANDS]; /* Q26: time for the reflections to reduce 60 dB per band in seconds */ + Word32 dsr_fx[IVAS_PI_AE_NUM_BANDS]; /* Q30: diffuse to source signal energy ratio per band in dB */ +#endif /* only valid if availEarlyReflections==true */ +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + IVAS_VECTOR3 roomDimensions; /* room dimensions in meters length (x), width (y), height (z) */ +#else IVAS_COORDINATE roomDimensions; /* room dimensions in meters length (x), width (y), height (z) */ +#endif float absorbCoeffs[IVAS_PI_AE_NUM_SURFACE]; /* absorption coefficients for all surfaces */ +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + Word32 absorbCoeffs_fx[IVAS_PI_AE_NUM_SURFACE]; /* Q30: absorption coefficients for all surfaces */ +#endif } IVAS_PIDATA_ACOUSTIC_ENV; #ifdef RTP_S4_251135_CR26253_0016_REV1 diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 14538b5ee..49c5fe49a 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -38,7 +38,9 @@ #include #include "cmdl_tools.h" #include "prot_fx.h" - +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +#include "ivas_cnst.h" +#endif /*------------------------------------------------------------------------------------------* * PreProc Local Macros @@ -2832,6 +2834,100 @@ ivas_error RenderConfigReader_read( } return IVAS_ERR_OK; } + +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getAcousticEnvironmentCount() + * + * Gets number of acoustic environments available + *------------------------------------------------------------------------------------------*/ +uint32_t RenderConfigReader_getAcousticEnvironmentCount( + RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ +) +{ + return pRenderConfigReader->nAE; +} + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getAcousticEnvironments() + * + * Gets all acoustic environments + *------------------------------------------------------------------------------------------*/ +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->aeID = (Word16) pIn.id; + pOut->nBands = (Word16) pIn.pFG->nrBands; + pOut->inputPreDelay_fx = (Word32) ( pIn.preDelay * ONE_IN_Q27 ); + + for ( m = 0; m < pOut->nBands; m++ ) + { + pOut->pFc_input_fx[m] = (Word32) ( pIn.pFG->pFc[m] * ONE_IN_Q16 ); + pOut->pAcoustic_rt60_fx[m] = (Word32) ( pIn.pRT60[m] * ONE_IN_Q26 ); + pOut->pAcoustic_dsr_fx[m] = (Word32) ( pIn.pDSR[m] * ONE_IN_Q30 ); + } + + /* 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; + pOut->dimensions.x_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x * ONE_IN_Q22 ); + pOut->dimensions.y_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.y * ONE_IN_Q22 ); + pOut->dimensions.z_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.z * ONE_IN_Q22 ); + + /* Use default listener origin position if non provided */ + if ( pIn.pEarlyReflections->pListenerOrigin == NULL ) + { + + pOut->ListenerOrigin.x_fx = IVAS_ER_LIST_ORIGIN_X_FX; + pOut->ListenerOrigin.y_fx = IVAS_ER_LIST_ORIGIN_Y_FX; + pOut->ListenerOrigin.z_fx = IVAS_ER_LIST_HEIGHT_FX; + pOut->ListenerOrigin.q_fact = Q22; + } + else + { + pOut->ListenerOrigin.x_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x_fx; + pOut->ListenerOrigin.y_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y_fx; + pOut->ListenerOrigin.z_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z_fx; + } + + for ( j = 0; j < IVAS_ROOM_ABS_COEFF; j++ ) + { + pOut->AbsCoeff_fx[j] = (Word32) ( pIn.pEarlyReflections->pAbsCoeff[j] * ONE_IN_Q30 ); + } + } + else + { + pOut->use_er = false; + } + } + + return IVAS_ERR_OK; +} +#endif + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getAcousticEnvironment() + * + * Gets Acoustic environment with a given ID + *------------------------------------------------------------------------------------------*/ + ivas_error RenderConfigReader_getAcousticEnvironment( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ uint16_t id, /* i : Acoustic environment ID */ @@ -2847,7 +2943,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; } diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 58946eca6..b3cdd3f11 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -51,6 +51,19 @@ 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 */ -- GitLab From 9190533ac56931c4181d0157edbbbdbb9dba4fb3 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Fri, 7 Nov 2025 10:57:35 +0100 Subject: [PATCH 02/14] Clang cleanup --- lib_util/ivas_rtp_pi_data.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_util/ivas_rtp_pi_data.h b/lib_util/ivas_rtp_pi_data.h index ae40afbff..f66f7e19a 100644 --- a/lib_util/ivas_rtp_pi_data.h +++ b/lib_util/ivas_rtp_pi_data.h @@ -162,9 +162,9 @@ typedef struct /* only valid if availEarlyReflections==true */ #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - IVAS_VECTOR3 roomDimensions; /* room dimensions in meters length (x), width (y), height (z) */ + IVAS_VECTOR3 roomDimensions; /* room dimensions in meters length (x), width (y), height (z) */ #else - IVAS_COORDINATE roomDimensions; /* room dimensions in meters length (x), width (y), height (z) */ + IVAS_COORDINATE roomDimensions; /* room dimensions in meters length (x), width (y), height (z) */ #endif float absorbCoeffs[IVAS_PI_AE_NUM_SURFACE]; /* absorption coefficients for all surfaces */ #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT -- GitLab From c096dbaa1e16b58fd37ac12ce604186221a905e5 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Fri, 7 Nov 2025 11:05:12 +0100 Subject: [PATCH 03/14] Typecast to resolve Linux compilation issues --- lib_dec/lib_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index da4860bd5..8dd90473f 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -3051,7 +3051,7 @@ ivas_error IVAS_DEC_GetAcousticEnvironment( /* In case of default AE ID, select the first one available */ test(); - IF( aeID == IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) + IF( aeID == (Word16) IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) { aeID = (uint16_t) st_ivas->pAcousticEnvironments[0].aeID; move32(); -- GitLab From c67dfae921c0239e1e2d84a4d6fad0ae20ec2f2d Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Fri, 7 Nov 2025 11:14:49 +0100 Subject: [PATCH 04/14] Typecast to resolve Linux compilation issues --- lib_rend/ivas_render_config_fx.c | 2 +- lib_util/render_config_reader.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_render_config_fx.c b/lib_rend/ivas_render_config_fx.c index 23a54d355..25c1aa4d4 100644 --- a/lib_rend/ivas_render_config_fx.c +++ b/lib_rend/ivas_render_config_fx.c @@ -108,7 +108,7 @@ ivas_error ivas_render_config_init_from_rom_fx( return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "Unexpected null pointer while attempting to fill renderer configuration from ROM" ); } #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - ( *hRenderConfig )->roomAcoustics.aeID = IVAS_DEFAULT_AEID; + ( *hRenderConfig )->roomAcoustics.aeID = (Word16) IVAS_DEFAULT_AEID; move16(); #endif ( *hRenderConfig )->roomAcoustics.nBands = IVAS_REVERB_DEFAULT_N_BANDS; diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 49c5fe49a..1fb664954 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2944,7 +2944,7 @@ 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 ) + if ( id == (Word16) IVAS_DEFAULT_AEID && pRenderConfigReader->nAE > 0 ) #else if ( id == 65535 && pRenderConfigReader->nAE > 0 ) #endif -- GitLab From 2492c9f7d558d3b0d376fcaa4cfbe61e2d52142d Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Fri, 7 Nov 2025 12:58:07 +0100 Subject: [PATCH 05/14] AE ID type changed from Word16 to UWord16 --- lib_com/common_api_types.h | 2 +- lib_dec/lib_dec.h | 2 +- lib_dec/lib_dec_fx.c | 12 ++++++++---- lib_rend/ivas_render_config_fx.c | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index d78ea5cef..43166628d 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -331,7 +331,7 @@ typedef enum typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - Word16 aeID; /* Acoustic environment ID */ + UWord16 aeID; /* Acoustic environment ID */ #endif Word16 nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ Word32 pFc_input_fx[IVAS_CLDFB_NO_CHANNELS_MAX]; /*Q16 Center frequencies for which following values are provided: */ diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 4a15804fd..6f38b2688 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -454,7 +454,7 @@ ivas_error IVAS_DEC_AddAcousticEnvironment( ivas_error IVAS_DEC_GetAcousticEnvironment( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - Word16 aeID, /* i : Acoustic environment ID */ + UWord16 aeID, /* i : Acoustic environment ID */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcEnv /* o : Room acoustic environment data pointer */ ); #endif diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 8dd90473f..9edc65c52 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -596,7 +596,11 @@ ivas_error IVAS_DEC_Configure( hDecoderConfig->Opt_delay_comp = (Word16) delayCompensationEnabled; hDecoderConfig->Opt_ExternalOrientation = enableExternalOrientation; hDecoderConfig->Opt_dpid_on = (Word16) dpidEnabled; +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + IF( NE_32( (UWord16) acousticEnvironmentId, IVAS_DEFAULT_AEID ) ) +#else IF( NE_32( (Word32) acousticEnvironmentId, 65535 ) ) +#endif { hDecoderConfig->Opt_aeid_on = TRUE; } @@ -3032,7 +3036,7 @@ ivas_error IVAS_DEC_AddAcousticEnvironment( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetAcousticEnvironment( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - Word16 aeID, /* i : Acoustic environment ID */ + UWord16 aeID, /* i : Acoustic environment ID */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcEnv /* o : Room acoustic environment data pointer */ ) { @@ -3051,9 +3055,9 @@ ivas_error IVAS_DEC_GetAcousticEnvironment( /* In case of default AE ID, select the first one available */ test(); - IF( aeID == (Word16) IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) + IF( aeID == (UWord16) IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) { - aeID = (uint16_t) st_ivas->pAcousticEnvironments[0].aeID; + aeID = (UWord16) st_ivas->pAcousticEnvironments[0].aeID; move32(); } @@ -6785,7 +6789,7 @@ ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *pi #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT case IVAS_PI_ACOUSTIC_ENVIRONMENT: { - Word16 aeid = piData->data.acousticEnv.aeid; + UWord16 aeid = piData->data.acousticEnv.aeid; #ifdef DEBUGGING fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); #endif diff --git a/lib_rend/ivas_render_config_fx.c b/lib_rend/ivas_render_config_fx.c index 25c1aa4d4..5bca8f1b3 100644 --- a/lib_rend/ivas_render_config_fx.c +++ b/lib_rend/ivas_render_config_fx.c @@ -108,7 +108,7 @@ ivas_error ivas_render_config_init_from_rom_fx( return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "Unexpected null pointer while attempting to fill renderer configuration from ROM" ); } #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - ( *hRenderConfig )->roomAcoustics.aeID = (Word16) IVAS_DEFAULT_AEID; + ( *hRenderConfig )->roomAcoustics.aeID = (UWord16) IVAS_DEFAULT_AEID; move16(); #endif ( *hRenderConfig )->roomAcoustics.nBands = IVAS_REVERB_DEFAULT_N_BANDS; -- GitLab From 97987082ae70f1d565b7cfd19b881ae628361ed4 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Fri, 7 Nov 2025 13:10:33 +0100 Subject: [PATCH 06/14] AE ID type changed from Word16 to UWord16 --- lib_util/render_config_reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 1fb664954..5311b54c5 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2944,7 +2944,7 @@ ivas_error RenderConfigReader_getAcousticEnvironment( /* case when -aeid is not specified, select first ID from config file */ #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - if ( id == (Word16) IVAS_DEFAULT_AEID && pRenderConfigReader->nAE > 0 ) + if ( id == (UWord16) IVAS_DEFAULT_AEID && pRenderConfigReader->nAE > 0 ) #else if ( id == 65535 && pRenderConfigReader->nAE > 0 ) #endif -- GitLab From a310905006ab85003e2f340fd12dc649310dcd66 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 10 Nov 2025 14:23:32 +0100 Subject: [PATCH 07/14] Moving #include to the top of the header file --- lib_dec/lib_dec.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 6f38b2688..70a6bb624 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -36,6 +36,10 @@ #include "common_api_types.h" #include #include "typedef.h" +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +#include "ivas_rtp_pi_data.h" +#endif + /*---------------------------------------------------------------------* * Decoder enums @@ -526,7 +530,9 @@ void IVAS_DEC_PrintDisclaimer( ); #ifdef IVAS_RTPDUMP +#ifndef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT #include "ivas_rtp_pi_data.h" +#endif ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *piData, UWord32 numPiData ); #endif -- GitLab From 81758bc3a5b277c6325e0423530e969e7f2aef20 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 10 Nov 2025 15:22:07 +0100 Subject: [PATCH 08/14] Clang check --- lib_dec/lib_dec_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 13dd59cdc..3ce7d68fc 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -6578,10 +6578,10 @@ ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *pi IVAS_QUATERNION *quat = &piData->data.scene.orientation; #ifdef DEBUGGING fprintf( stdout, "PI_SCENE_ORIENTATION : %f, %f, %f, %f\n", - fixedToFloat( quat->w_fx, Q15 ), - fixedToFloat( quat->x_fx, Q15 ), - fixedToFloat( quat->y_fx, Q15 ), - fixedToFloat( quat->z_fx, Q15 ) ); + fixedToFloat( quat->w_fx, Q15 ), + fixedToFloat( quat->x_fx, Q15 ), + fixedToFloat( quat->y_fx, Q15 ), + fixedToFloat( quat->z_fx, Q15 ) ); #endif error = IVAS_DEC_feedSinglePIorientation( hIvasDec, true, quat ); } -- GitLab From cd108b361af457ff1d9bc5463c93ac7d82e35a96 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 10 Nov 2025 17:57:53 +0100 Subject: [PATCH 09/14] Fix for defaulting early reflection parameters --- lib_util/render_config_reader.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 5311b54c5..0aa342bf6 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1308,31 +1308,49 @@ ivas_error RenderConfigReader_checkValues( if ( pRoom_acoustics->dimensions.x < ER_MIN_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.x = ER_MIN_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.x_fx < ER_MIN_ROOM_DIMENSION_FX ) + { pRoom_acoustics->dimensions.x_fx = ER_MIN_ROOM_DIMENSION_FX; } if ( pRoom_acoustics->dimensions.x > ER_MAX_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.x = ER_MAX_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.x_fx > ER_MAX_ROOM_DIMENSION_FX ) + { pRoom_acoustics->dimensions.x_fx = ER_MAX_ROOM_DIMENSION_FX; } if ( pRoom_acoustics->dimensions.y < ER_MIN_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.y = ER_MIN_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.y_fx < ER_MIN_ROOM_DIMENSION_FX ) + { pRoom_acoustics->dimensions.y_fx = ER_MIN_ROOM_DIMENSION_FX; } if ( pRoom_acoustics->dimensions.y > ER_MAX_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.y = ER_MAX_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.y_fx > ER_MAX_ROOM_DIMENSION_FX ) + { pRoom_acoustics->dimensions.y_fx = ER_MAX_ROOM_DIMENSION_FX; } if ( pRoom_acoustics->dimensions.z < ER_MIN_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.z = ER_MIN_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.z_fx < ER_MIN_ROOM_DIMENSION_FX ) + { pRoom_acoustics->dimensions.z_fx = ER_MIN_ROOM_DIMENSION_FX; } if ( pRoom_acoustics->dimensions.z > ER_MAX_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.z = ER_MAX_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.z_fx > ER_MAX_ROOM_DIMENSION_FX ) + { pRoom_acoustics->dimensions.z_fx = ER_MAX_ROOM_DIMENSION_FX; } @@ -1342,11 +1360,17 @@ ivas_error RenderConfigReader_checkValues( if ( pRoom_acoustics->AbsCoeff[wall_idx] < ER_MIN_ABS_COEFF ) { pRoom_acoustics->AbsCoeff[wall_idx] = ER_MIN_ABS_COEFF; + } + if ( pRoom_acoustics->AbsCoeff_fx[wall_idx] < ER_MIN_ABS_COEFF_FX ) + { pRoom_acoustics->AbsCoeff_fx[wall_idx] = ER_MIN_ABS_COEFF_FX; } if ( pRoom_acoustics->AbsCoeff[wall_idx] > ER_MAX_ABS_COEFF ) { pRoom_acoustics->AbsCoeff[wall_idx] = ER_MAX_ABS_COEFF; + } + if ( pRoom_acoustics->AbsCoeff_fx[wall_idx] > ER_MAX_ABS_COEFF_FX ) + { pRoom_acoustics->AbsCoeff_fx[wall_idx] = ER_MAX_ABS_COEFF_FX; } } -- GitLab From eb6fc88fd829a86bedf9145fb1f53c0c00a562c6 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 10 Nov 2025 18:52:08 +0100 Subject: [PATCH 10/14] Fixes for memory handling, listener origin --- .../render_config_reader.c | 3226 +++++++++++++++++ lib_dec/ivas_init_dec_fx.c | 15 +- lib_util/render_config_reader.c | 13 + 3 files changed, 3249 insertions(+), 5 deletions(-) create mode 100644 Workspace_msvc/enc_temp_folder/b685e51a257c31d9ba90c87bcc18d2c/render_config_reader.c diff --git a/Workspace_msvc/enc_temp_folder/b685e51a257c31d9ba90c87bcc18d2c/render_config_reader.c b/Workspace_msvc/enc_temp_folder/b685e51a257c31d9ba90c87bcc18d2c/render_config_reader.c new file mode 100644 index 000000000..0aa342bf6 --- /dev/null +++ b/Workspace_msvc/enc_temp_folder/b685e51a257c31d9ba90c87bcc18d2c/render_config_reader.c @@ -0,0 +1,3226 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "render_config_reader.h" +#include +#include +#include +#include +#include +#include "cmdl_tools.h" +#include "prot_fx.h" +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +#include "ivas_cnst.h" +#endif + +/*------------------------------------------------------------------------------------------* + * PreProc Local Macros + *------------------------------------------------------------------------------------------*/ + +#define MAX_ITEM_LENGTH ( 64 ) +#define N_ABS_COEFFS ( 6 ) + +#define SHORTEST_REV_DEL_LINE ( 0.015f ) +#define N_BANDS_MIN ( 2 ) +#define N_BANDS_MAX ( 60 ) +#define FC_INPUT_MIN ( 0.0f ) +#define FC_INPUT_MAX ( 1.0e+5f ) +#define ACOUSTIC_RT60_MIN ( 1.0e-3f ) +#define ACOUSTIC_RT60_MAX ( 1.0e+2f ) +#define ACOUSTIC_DSR_MIN ( 0.0f ) +#define ACOUSTIC_DSR_MAX ( 1.0e+2f ) +#define ACOUSTIC_DSR_EPSILON ( 1.0e-15f ) +#define ACOUSTIC_DSR_EPSILON_FX ( 1 ) +#define ACOUSTICPREDELAY_JOTREV_MIN ( SHORTEST_REV_DEL_LINE ) +#define ACOUSTICPREDELAY_JOTREV_MAX ( SHORTEST_REV_DEL_LINE + 1.0f / (float) IVAS_NUM_FRAMES_PER_SEC ) +#define ACOUSTICPREDELAY_FDREV_MIN ( 1.0f / (float) ( 16 * IVAS_NUM_FRAMES_PER_SEC ) ) +#define ACOUSTICPREDELAY_FDREV_MAX ( (float) ( IVAS_REVERB_PREDELAY_MAX ) / (float) ( 16 * IVAS_NUM_FRAMES_PER_SEC ) ) +#define INPUTPREDELAY_MIN ( 0.0f ) +#define INPUTPREDELAY_MAX ( 1.0e+2f ) + +#define ER_MIN_ROOM_DIMENSION ( 1.0f ) +#define ER_MIN_ROOM_DIMENSION_FX ( 4194304 ) +#define ER_MAX_ROOM_DIMENSION ( 999.0f ) +#define ER_MAX_ROOM_DIMENSION_FX ( 2095054848 ) +#define ER_MIN_ABS_COEFF ( 0.0f ) +#define ER_MIN_ABS_COEFF_FX ( 0 ) +#define ER_MAX_ABS_COEFF ( 1.0f ) +#define ER_MAX_ABS_COEFF_FX ( 1073741824 ) + +#define IVAS_ER_LIST_ORIGIN_X 0.0f +#define IVAS_ER_LIST_ORIGIN_Y 0.0f +#define IVAS_ER_LIST_ORIGIN_X_FX 0 +#define IVAS_ER_LIST_ORIGIN_Y_FX 0 + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef min +#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef max +#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) +#endif + + +/*------------------------------------------------------------------------------------------* + * Local Type definitions + *------------------------------------------------------------------------------------------*/ + +typedef struct +{ + uint32_t nrBands; /* Number of frequency bands */ + float *pFc; /* Center frequencies */ +} FrequencyGrid; + +typedef enum _FREQ_GRID_MODE +{ + FREQ_GRID_MODE_UNKNOWN = -1, + FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES = 0, + FREQ_GRID_MODE_START_HOP_AMOUNT = 1, + FREQ_GRID_MODE_DEFAULT_BANDING = 2 +} FREQ_GRID_MODE; + +typedef struct +{ + uint16_t use_er; /* Activation Flag */ + IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ + float pAbsCoeff[N_ABS_COEFFS]; /* Absorption coeffs table */ + IVAS_VECTOR3 *pListenerOrigin; /* Listener origin */ + uint32_t lowComplexity; /* Low complexity mode flag */ +} EarlyReflectionsConfig; + +typedef struct +{ + uint32_t id; /* Acoustic environment ID */ + FrequencyGrid *pFG; /* Pointer into Frequency grids table for late reverb coeffs */ + float *pRT60; /* RT60 table */ + float *pDSR; /* DSR table */ + float preDelay; /* Pre-delay */ + EarlyReflectionsConfig *pEarlyReflections; /* Early reflections configuration */ +} AcousticEnv; + +typedef struct +{ + uint32_t id; /* Pattern ID */ + float *pDirectivity; /* Source directivity */ +} DirectrivityPat; + +struct RenderConfigReader +{ + FILE *pConfigFile; + uint8_t *pBitstream; /* Renderer config bitstream */ + size_t length; /* Bitstream length */ + size_t readOffset; /* Bitstream read offset */ + uint32_t nFG; /* Number of frequency grids */ + FrequencyGrid *pFG; /* Frequency grids */ + uint32_t nAE; /* Number of acoustic environments */ + AcousticEnv *pAE; /* Acoustic environments */ + uint32_t nDP; /* Number of directivity patterns */ + DirectrivityPat *pDP; /* Directivity Pattern */ + float distAtt[3]; /* [MaxDist Q30, RefDist Q30, Rolloff Q30] */ +}; + + +typedef enum _RC_LUT +{ + RC_LUT_INVALID = 0x00, + RC_LUT_COUNT_IDX_LO, + RC_LUT_COUNT_IDX_HI, + RC_LUT_DECI_SEC, + RC_LUT_SEC, + RC_LUT_MILLI_SEC, + RC_LUT_MICRO_SEC, + RC_LUT_FREQ, + RC_LUT_FREQ_HOP, + RC_LUT_DSR, + RC_LUT_METERS, + RC_LUT_HECTOMETERS, + RC_LUT_KILOMETERS, + RC_LUT_CENTIMETERS, + RC_LUT_ABSORPTION +} RC_LUT; + +/*------------------------------------------------------------------------------------------* + * Lookup tables + *------------------------------------------------------------------------------------------*/ + +const float lutCountIdxLo_Value[] = { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, 30.0f, 31.0f, + 32.0f, 33.0f, 34.0f, 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, 40.0f, 41.0f, 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, + 48.0f, 49.0f, 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, 56.0f, 57.0f, 58.0f, 59.0f, 60.0f, 61.0f, 62.0f, 63.0f +}; +const uint16_t lutCountIdxLo_Code[] = { + 7, 4, 12, 13, 10, 11, 8, 9, 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0, 63, 62, 61, 60, 59, 58, 57, 56, + 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, + 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80 +}; +const uint8_t lutCountIdxLo_Len[] = { + 4, 3, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 +}; + +const float lutCountIdxHi_Value[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f }; +const uint16_t lutCountIdxHi_Code[] = { 1, 0, 6, 5, 4, 7, 5, 15, 14, 13, 9, 8, 25, 49, 48 }; +const uint8_t lutCountIdxHi_Len[] = { 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 7, 7 }; + +const float lutDeciSec_Value[] = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f }; +const uint16_t lutDeciSec_Code[] = { 6, 4, 5, 6, 7, 7, 4, 5, 2, 3, 0 }; +const uint8_t lutDeciSec_Len[] = { 3, 3, 3, 4, 4, 3, 4, 4, 4, 4, 3 }; + +const float lutSec_Value[] = { + 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, + 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, + 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, 30.0f +}; +const uint16_t lutSec_Code[] = { 3, 1, 0, 15, 13, 12, 11, 9, 8, 14, 13, 12, 11, 9, 8, 5, 29, 28, 21, 31, 30, 21, 9, 8, 41, 41, 40, 81, 161, 160 }; +const uint8_t lutSec_Len[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 8, 8 }; + +const float lutMilliSec_Value[] = { + 0.00f, 0.001f, 0.002f, 0.003f, 0.004f, 0.005f, 0.006f, 0.007f, 0.008f, 0.009f, + 0.01f, 0.011f, 0.012f, 0.013f, 0.014f, 0.015f, 0.016f, 0.017f, 0.018f, 0.019f, + 0.02f, 0.021f, 0.022f, 0.023f, 0.024f, 0.025f, 0.026f, 0.027f, 0.028f, 0.029f, + 0.03f, 0.031f, 0.032f, 0.033f, 0.034f, 0.035f, 0.036f, 0.037f, 0.038f, 0.039f, + 0.04f, 0.041f, 0.042f, 0.043f, 0.044f, 0.045f, 0.046f, 0.047f, 0.048f, 0.049f, + 0.05f, 0.051f, 0.052f, 0.053f, 0.054f, 0.055f, 0.056f, 0.057f, 0.058f, 0.059f, + 0.06f, 0.061f, 0.062f, 0.063f, 0.064f, 0.065f, 0.066f, 0.067f, 0.068f, 0.069f, + 0.07f, 0.071f, 0.072f, 0.073f, 0.074f, 0.075f, 0.076f, 0.077f, 0.078f, 0.079f, + 0.08f, 0.081f, 0.082f, 0.083f, 0.084f, 0.085f, 0.086f, 0.087f, 0.088f, 0.089f, + 0.09f, 0.091f, 0.092f, 0.093f, 0.094f, 0.095f, 0.096f, 0.097f, 0.098f, 0.099f +}; +const uint16_t lutMilliSec_Code[] = { + 122, 123, 120, 121, 126, 127, 124, 125, 114, 115, 25, 112, 113, 118, 119, 116, 117, 42, 43, 40, + 18, 41, 46, 47, 44, 45, 34, 35, 32, 33, 19, 38, 39, 36, 37, 58, 59, 56, 57, 62, + 16, 63, 60, 61, 50, 51, 48, 49, 54, 55, 17, 52, 53, 10, 11, 8, 9, 14, 15, 12, + 22, 13, 2, 3, 0, 1, 6, 7, 4, 5, 23, 26, 27, 24, 25, 30, 31, 28, 29, 18, + 20, 19, 16, 17, 22, 23, 20, 21, 106, 107, 21, 104, 105, 110, 111, 108, 109, 98, 99, 48 +}; +const uint8_t lutMilliSec_Len[] = { + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 6 +}; + +const float lutMicroSec_Value[] = { + 0.00001f, 0.00002f, 0.00003f, 0.00004f, 0.00005f, 0.00006f, 0.00007f, 0.00008f, 0.00009f, 0.0001f, + 0.00011f, 0.00012f, 0.00013f, 0.00014f, 0.00015f, 0.00016f, 0.00017f, 0.00018f, 0.00019f, 0.0002f, + 0.00021f, 0.00022f, 0.00023f, 0.00024f, 0.00025f, 0.00026f, 0.00027f, 0.00028f, 0.00029f, 0.0003f, + 0.00031f, 0.00032f, 0.00033f, 0.00034f, 0.00035f, 0.00036f, 0.00037f, 0.00038f, 0.00039f, 0.0004f, + 0.00041f, 0.00042f, 0.00043f, 0.00044f, 0.00045f, 0.00046f, 0.00047f, 0.00048f, 0.00049f, 0.0005f, + 0.00051f, 0.00052f, 0.00053f, 0.00054f, 0.00055f, 0.00056f, 0.00057f, 0.00058f, 0.00059f, 0.0006f, + 0.00061f, 0.00062f, 0.00063f, 0.00064f, 0.00065f, 0.00066f, 0.00067f, 0.00068f, 0.00069f, 0.0007f, + 0.00071f, 0.00072f, 0.00073f, 0.00074f, 0.00075f, 0.00076f, 0.00077f, 0.00078f, 0.00079f, 0.0008f, + 0.00081f, 0.00082f, 0.00083f, 0.00084f, 0.00085f, 0.00086f, 0.00087f, 0.00088f, 0.00089f, 0.0009f, + 0.00091f, 0.00092f, 0.00093f, 0.00094f, 0.00095f, 0.00096f, 0.00097f, 0.00098f, 0.00099f +}; +const uint16_t lutMicroSec_Code[] = { + 444, 18, 445, 19, 894, 16, 895, 17, 892, 22, 893, 23, 434, 20, 435, 21, 432, 10, 433, 11, + 438, 8, 439, 9, 436, 14, 437, 15, 410, 12, 411, 13, 408, 2, 409, 3, 414, 0, 415, 1, + 412, 6, 413, 7, 402, 4, 403, 5, 400, 26, 401, 27, 406, 24, 407, 25, 404, 30, 405, 31, + 426, 28, 427, 29, 424, 18, 425, 19, 430, 16, 431, 17, 428, 22, 429, 23, 418, 20, 419, 21, + 416, 58, 417, 59, 422, 56, 423, 57, 420, 62, 421, 63, 442, 60, 443, 61, 440, 24, 441 +}; +const uint8_t lutMicroSec_Len[] = { + 9, 5, 9, 5, 10, 5, 10, 5, 10, 5, 10, 5, 9, 5, 9, 5, 9, 6, 9, 6, + 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, + 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, + 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, + 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 5, 9 +}; + +const float lutFreq_Value[] = { + 16.0f, 20.0f, 25.0f, 31.5f, 40.0f, 50.0f, 63.0f, 80.0f, 100.0f, 125.0f, + 160.0f, 200.0f, 250.0f, 315.0f, 400.0f, 500.0f, 630.0f, 800.0f, 1000.0f, 1250.0f, + 1600.0f, 2000.0f, 2500.0f, 3150.0f, 4000.0f, 5000.0f, 6300.0f, 8000.0f, 10000.0f, 12500.0f, + 16000.0f, 20000.0f, 25000.0f, 31500.0f, 40000.0f +}; +const uint16_t lutFreq_Code[] = { 35, 14, 15, 9, 12, 13, 0, 26, 27, 1, 24, 25, 14, 30, 31, 15, 28, 29, 12, 18, 19, 13, 16, 17, 10, 22, 23, 11, 20, 21, 2, 16, 138, 139, 68 }; +const uint8_t lutFreq_Len[] = { 6, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 5, 8, 8, 7 }; + +const float lutFreqHop_Value[] = { 1.059463094f, 1.122462048f, 1.189207115f, 1.259921050f, 1.414213562f, 2.0f, 4.0f }; +const uint16_t lutFreqHop_Code[] = { 2, 3, 0, 1, 1, 3, 2 }; +const uint8_t lutFreqHop_Len[] = { 4, 4, 4, 2, 4, 2, 2 }; + +const float lutDsr_Value[] = { + -150.0f, -149.0f, -148.0f, -147.0f, -146.0f, -145.0f, -144.0f, -143.0f, -142.0f, -141.0f, + -140.0f, -139.0f, -138.0f, -137.0f, -136.0f, -135.0f, -134.0f, -133.0f, -132.0f, -131.0f, + -130.0f, -129.0f, -128.0f, -127.0f, -126.0f, -125.0f, -124.0f, -123.0f, -122.0f, -121.0f, + -120.0f, -119.0f, -118.0f, -117.0f, -116.0f, -115.0f, -114.0f, -113.0f, -112.0f, -111.0f, + -110.0f, -109.0f, -108.0f, -107.0f, -106.0f, -105.0f, -104.0f, -103.0f, -102.0f, -101.0f, + -100.0f, -99.0f, -98.0f, -97.0f, -96.0f, -95.0f, -94.0f, -93.0f, -92.0f, -91.0f, + -90.0f, -89.0f, -88.0f, -87.0f, -86.0f, -85.0f, -84.0f, -83.0f, -82.0f, -81.0f, + -80.0f, -79.0f, -78.0f, -77.0f, -76.0f, -75.0f, -74.0f, -73.0f, -72.0f, -71.0f, + -70.0f, -69.0f, -68.0f, -67.0f, -66.0f, -65.0f, -64.0f, -63.0f, -62.0f, -61.0f, + -60.0f, -59.0f, -58.0f, -57.0f, -56.0f, -55.0f, -54.0f, -53.0f, -52.0f, -51.0f, + -50.0f, -49.0f, -48.0f, -47.0f, -46.0f, -45.0f, -44.0f, -43.0f, -42.0f, -41.0f, + -40.0f, -39.0f, -38.0f, -37.0f, -36.0f, -35.0f, -34.0f, -33.0f, -32.0f, -31.0f, + -30.0f, -29.0f, -28.0f, -27.0f, -26.0f, -25.0f, -24.0f, -23.0f, -22.0f, -21.0f, + -20.0f, -19.0f, -18.0f, -17.0f, -16.0f, -15.0f, -14.0f, -13.0f, -12.0f, -11.0f, + -10.0f +}; +const uint16_t lutDsr_Code[] = { + 140, 141, 286, 287, 284, 285, 130, 131, 128, 129, 134, 135, 132, 133, 234, 235, 232, 233, 238, 239, + 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 251, 248, 249, 254, 255, 252, 253, 242, 243, + 240, 241, 246, 247, 244, 245, 202, 203, 200, 201, 206, 207, 204, 205, 194, 195, 192, 193, 198, 199, + 196, 197, 218, 219, 216, 217, 222, 223, 220, 221, 20, 21, 38, 39, 36, 37, 58, 59, 56, 57, + 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53, 10, 11, 8, 9, 14, 15, 12, 13, + 2, 3, 0, 1, 6, 7, 4, 5, 42, 43, 40, 41, 46, 47, 44, 45, 18, 19, 16, 17, + 22, 210, 211, 208, 209, 214, 215, 212, 213, 186, 187, 184, 185, 190, 191, 188, 189, 138, 139, 136, + 137 +}; +const uint8_t lutDsr_Len[] = { + 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, + 8 +}; + +const float lutMeters_Value[] = { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, + 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, + 20.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, + 30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, + 40.0f, 41.0f, 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, 48.0f, 49.0f, + 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, 56.0f, 57.0f, 58.0f, 59.0f, + 60.0f, 61.0f, 62.0f, 63.0f, 64.0f, 65.0f, 66.0f, 67.0f, 68.0f, 69.0f, + 70.0f, 71.0f, 72.0f, 73.0f, 74.0f, 75.0f, 76.0f, 77.0f, 78.0f, 79.0f, + 80.0f, 81.0f, 82.0f, 83.0f, 84.0f, 85.0f, 86.0f, 87.0f, 88.0f, 89.0f, + 90.0f, 91.0f, 92.0f, 93.0f, 94.0f, 95.0f, 96.0f, 97.0f, 98.0f, 99.0f +}; + +const uint16_t lutMeters_Code[] = { + 61, 50, 51, 48, 49, 54, 55, 52, 53, 10, + 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, + 1, 6, 7, 4, 5, 26, 27, 24, 25, 30, + 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, + 21, 42, 43, 40, 41, 46, 47, 44, 45, 16, + 68, 69, 142, 143, 140, 141, 154, 155, 152, 153, + 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, + 148, 149, 234, 235, 232, 233, 238, 239, 236, 237, + 226, 227, 224, 225, 230, 231, 228, 229, 250, 251, + 248, 249, 254, 255, 252, 253, 242, 243, 240, 241 +}; + +const uint8_t lutMeters_Len[] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, + 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 +}; + +const float lutHectometers_Value[] = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f }; +const uint16_t lutHectometers_Code[] = { 0, 1, 6, 7, 4, 5, 6, 7, 4, 5 }; +const uint8_t lutHectometers_Len[] = { 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 }; + +const float lutKilometers_Value[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f }; +const uint16_t lutKilometers_Code[] = { 2, 3, 1, 0, 7, 5, 4, 13, 25, 24 }; +const uint8_t lutKilometers_Len[] = { 2, 3, 3, 3, 3, 4, 4, 4, 5, 5 }; + +const float lutCentimeters_Value[] = { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, + 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, + 20.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, + 30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, + 40.0f, 41.0f, 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, 48.0f, 49.0f, + 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, 56.0f, 57.0f, 58.0f, 59.0f, + 60.0f, 61.0f, 62.0f, 63.0f, 64.0f, 65.0f, 66.0f, 67.0f, 68.0f, 69.0f, + 70.0f, 71.0f, 72.0f, 73.0f, 74.0f, 75.0f, 76.0f, 77.0f, 78.0f, 79.0f, + 80.0f, 81.0f, 82.0f, 83.0f, 84.0f, 85.0f, 86.0f, 87.0f, 88.0f, 89.0f, + 90.0f, 91.0f, 92.0f, 93.0f, 94.0f, 95.0f, 96.0f, 97.0f, 98.0f, 99.0f +}; + +const uint16_t lutCentimeters_Code[] = { + 50, 51, 48, 49, 54, 55, 52, 53, 42, 43, + 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, + 38, 39, 36, 37, 58, 59, 56, 57, 62, 63, + 60, 61, 50, 51, 48, 49, 54, 55, 52, 53, + 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, + 0, 1, 6, 7, 4, 5, 26, 27, 24, 25, + 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, + 20, 21, 42, 43, 40, 41, 46, 47, 44, 45, + 34, 35, 32, 33, 38, 39, 36, 37, 122, 123, + 120, 121, 126, 127, 124, 125, 58, 59, 56, 57 +}; + +const uint8_t lutCentimeters_Len[] = { + 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 6, 6, 6, 6 +}; + +const float lutAbsorption_Value[] = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f }; +const uint16_t lutAbsorption_Code[] = { 6, 4, 5, 6, 7, 7, 4, 5, 2, 3, 0 }; +const uint8_t lutAbsorption_Len[] = { 3, 3, 3, 4, 4, 3, 4, 4, 4, 4, 3 }; + +/*------------------------------------------------------------------------------------------* + * Default frequency grids + *------------------------------------------------------------------------------------------*/ + +const float defaultFrequencyGrid_0[] = { 31.5f, 63.0f, 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, 4000.0f, 8000.0f, 16000.0f }; +const float defaultFrequencyGrid_1[] = { 25.0f, 50.0f, 100.0f, 200.0f, 400.0f, 800.0f, 1600.0f, 3150.0f, 6300.0f, 12500.0f }; +const float defaultFrequencyGrid_2[] = { + 20.0f, 25.0f, 31.5f, 40.0f, 50.0f, 63.0f, 80.0f, 100.0f, 125.0f, 160.0f, + 200.0f, 250.0f, 315.0f, 400.0f, 500.0f, 630.0f, 800.0f, 1000.0f, 1250.0f, 1600.0f, + 2000.0f, 2500.0f, 3150.0f, 4000.0f, 5000.0f, 6300.0f, 8000.0f, 10000.0f, 12500.0f, 16000.0f, 20000.0f +}; +const float defaultFrequencyGrid_3[] = { 25.0f, 100.0f, 400.0f, 1600.0f, 6300.0f }; +const float defaultFrequencyGrid_4[] = { 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, 4000.0f }; +const float defaultFrequencyGrid_5[] = { 25.0f, 250.0f, 2500.0f }; +const float defaultFrequencyGrid_6[] = { + 27.0f, 56.0f, 89.0f, 126.0f, 168.0f, 214.0f, 265.0f, 323.0f, 387.0f, 459.0f, + 539.0f, 628.0f, 727.0f, 839.0f, 963.0f, 1101.0f, 1256.0f, 1429.0f, 1621.0f, 1836.0f, + 2077.0f, 2345.0f, 2644.0f, 2978.0f, 3351.0f, 3767.0f, 4232.0f, 4750.0f, 5329.0f, 5975.0f, + 6697.0f, 7502.0f, 8401.0f, 9405.0f, 10525.0f, 11775.0f, 13171.0f, 14729.0f, 16468.0f, 18410.0f, 20577.0f +}; +const float defaultFrequencyGrid_7[] = { + 27.0f, 89.0f, 168.0f, 265.0f, 387.0f, 539.0f, 727.0f, 963.0f, 1256.0f, 1621.0f, + 2077.0f, 2644.0f, 3351.0f, 4232.0f, 5329.0f, 6697.0f, 8401.0f, 10525.0f, 13171.0f, 16468.0f, 20577.0f +}; +const float defaultFrequencyGrid_8[] = { + 50.0f, 150.0f, 250.0f, 350.0f, 450.0f, 570.0f, 700.0f, 840.0f, 1000.0f, 1170.0f, + 1370.0f, 1600.0f, 1850.0f, 2150.0f, 2150.0f, 2500.0f, 2900.0f, 3400.0f, 4000.0f, 4800.0f, + 5800.0f, 7000.0f, 8500.0f, 10500.0f, 13500.0f +}; + + +/*-----------------------------------------------------------------------------------------* + * Function read_bin_bits() + * Reads a given number of bits from the bitstream + *-----------------------------------------------------------------------------------------*/ + +static ivas_error read_bin_bits( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + uint32_t *pTarget, /* o : Target read data pointer */ + const size_t nBits /* i : Number of bits to read */ +) +{ + uint8_t n; + uint32_t nByte; + uint8_t bit; + + if ( this == NULL || this->pBitstream == NULL || pTarget == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( this->readOffset + nBits > this->length * 8 ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + *pTarget = 0; + for ( n = 0; n < nBits; n++ ) + { + nByte = (uint32_t) ( ( this->readOffset + n ) >> 3 ); + bit = this->pBitstream[nByte] >> ( 7 - ( ( this->readOffset + n ) % 8 ) ) & 1; + *pTarget = ( *pTarget << 1 ) + bit; + } + + this->readOffset += nBits; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function read_bin_bool() + * Reads a boolean value from a bitstream + *-----------------------------------------------------------------------------------------*/ + +static ivas_error read_bin_bool( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + uint32_t *pResult /* o : Target read data pointer */ +) +{ + return read_bin_bits( this, pResult, 1 ); +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_id() + * Reads an ID from a bitstream + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_id( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + uint32_t *pResult /* o : Target read data pointer */ +) +{ + ivas_error error; + uint32_t id; + uint32_t cont; + + *pResult = 0; + id = 0; + cont = true; + + if ( pResult == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + while ( cont ) + { + if ( ( error = read_bin_bits( this, &id, 7 ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = ( *pResult << 7 ) | id; + + if ( ( error = read_bin_bool( this, &cont ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function read_bin_code_word() + * Reads a code word from a LUT + *-----------------------------------------------------------------------------------------*/ + +static ivas_error read_bin_code_word( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + const RC_LUT table, /* i : Table enum */ + float *pResult /* o : Code value */ +) +{ + ivas_error error; + const float *pValues; + const uint16_t *pCodes; + const uint8_t *pLengths; + uint8_t minLen; + uint8_t maxLen; + uint8_t size; + uint8_t n; + uint32_t code; + uint32_t bits; + uint32_t nr_bits; + uint8_t len; + + minLen = 255; + maxLen = 0; + bits = 0; + nr_bits = 0; + code = 0; + + if ( pResult == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* Select the right tables */ + switch ( table ) + { + case RC_LUT_COUNT_IDX_LO: + pValues = lutCountIdxLo_Value; + pCodes = lutCountIdxLo_Code; + pLengths = lutCountIdxLo_Len; + size = sizeof lutCountIdxLo_Len / sizeof( uint8_t ); + break; + case RC_LUT_COUNT_IDX_HI: + pValues = lutCountIdxHi_Value; + pCodes = lutCountIdxHi_Code; + pLengths = lutCountIdxHi_Len; + size = sizeof lutCountIdxHi_Len / sizeof( uint8_t ); + break; + case RC_LUT_DECI_SEC: + pValues = lutDeciSec_Value; + pCodes = lutDeciSec_Code; + pLengths = lutDeciSec_Len; + size = sizeof lutDeciSec_Len / sizeof( uint8_t ); + break; + case RC_LUT_SEC: + pValues = lutSec_Value; + pCodes = lutSec_Code; + pLengths = lutSec_Len; + size = sizeof lutSec_Len / sizeof( uint8_t ); + break; + case RC_LUT_MILLI_SEC: + pValues = lutMilliSec_Value; + pCodes = lutMilliSec_Code; + pLengths = lutMilliSec_Len; + size = sizeof lutMilliSec_Len / sizeof( uint8_t ); + break; + case RC_LUT_MICRO_SEC: + pValues = lutMicroSec_Value; + pCodes = lutMicroSec_Code; + pLengths = lutMicroSec_Len; + size = sizeof lutMicroSec_Len / sizeof( uint8_t ); + break; + case RC_LUT_FREQ: + pValues = lutFreq_Value; + pCodes = lutFreq_Code; + pLengths = lutFreq_Len; + size = sizeof lutFreq_Len / sizeof( uint8_t ); + break; + case RC_LUT_FREQ_HOP: + pValues = lutFreqHop_Value; + pCodes = lutFreqHop_Code; + pLengths = lutFreqHop_Len; + size = sizeof lutFreqHop_Len / sizeof( uint8_t ); + break; + case RC_LUT_DSR: + pValues = lutDsr_Value; + pCodes = lutDsr_Code; + pLengths = lutDsr_Len; + size = sizeof lutDsr_Len / sizeof( uint8_t ); + break; + case RC_LUT_METERS: + pValues = lutMeters_Value; + pCodes = lutMeters_Code; + pLengths = lutMeters_Len; + size = sizeof lutMeters_Len / sizeof( uint8_t ); + break; + case RC_LUT_HECTOMETERS: + pValues = lutHectometers_Value; + pCodes = lutHectometers_Code; + pLengths = lutHectometers_Len; + size = sizeof lutHectometers_Len / sizeof( uint8_t ); + break; + case RC_LUT_KILOMETERS: + pValues = lutKilometers_Value; + pCodes = lutKilometers_Code; + pLengths = lutKilometers_Len; + size = sizeof lutKilometers_Len / sizeof( uint8_t ); + break; + case RC_LUT_CENTIMETERS: + pValues = lutCentimeters_Value; + pCodes = lutCentimeters_Code; + pLengths = lutCentimeters_Len; + size = sizeof lutCentimeters_Len / sizeof( uint8_t ); + break; + case RC_LUT_ABSORPTION: + pValues = lutAbsorption_Value; + pCodes = lutAbsorption_Code; + pLengths = lutAbsorption_Len; + size = sizeof lutAbsorption_Len / sizeof( uint8_t ); + break; + case RC_LUT_INVALID: + default: + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + /* First read minLen bits, then add one bit per iteration to find the correct value */ + for ( n = 0; n < size; n++ ) + { + minLen = min( minLen, pLengths[n] ); + maxLen = max( maxLen, pLengths[n] ); + } + for ( len = minLen; len <= maxLen; len++ ) + { + nr_bits = ( len == minLen ) ? minLen : 1; + if ( ( error = read_bin_bits( this, &bits, nr_bits ) ) != IVAS_ERR_OK ) + { + return error; + } + code = ( code << nr_bits ) | bits; + for ( n = 0; n < size; n++ ) + { + if ( code == pCodes[n] && len == pLengths[n] ) + { + *pResult = pValues[n]; + return IVAS_ERR_OK; + } + } + } + return IVAS_ERR_INVALID_RENDER_CONFIG; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_count_or_index() + * Gets a count or index + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_count_or_index( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + uint32_t *pResult /* o : Count or index value */ +) +{ + ivas_error error; + float value; + uint32_t isLarge; + + if ( pResult == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = read_bin_code_word( this, RC_LUT_COUNT_IDX_LO, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = (uint32_t) value; + + if ( ( error = read_bin_bool( this, &isLarge ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( isLarge ) + { + if ( ( error = read_bin_code_word( this, RC_LUT_COUNT_IDX_HI, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += (uint32_t) value << 6; + } + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_duration() + * Gets a duration value + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_duration( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + float *pResult /* o : Duration value */ +) +{ + ivas_error error; + float value; + uint32_t addFlag; + + /* Deciseconds */ + if ( ( error = read_bin_code_word( this, RC_LUT_DECI_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = value; + + /* Milliseconds */ + if ( ( error = read_bin_bool( this, &addFlag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( addFlag ) + { + if ( ( error = read_bin_code_word( this, RC_LUT_MILLI_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value; + + /* Microseconds */ + if ( ( error = read_bin_bool( this, &addFlag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( addFlag ) + { + if ( ( error = read_bin_code_word( this, RC_LUT_MICRO_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value; + } + } + + /* Seconds */ + if ( ( error = read_bin_bool( this, &addFlag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( addFlag ) + { + if ( ( error = read_bin_code_word( this, RC_LUT_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value; + } + + /* Correct rounding errors due to multiple additions: */ + *pResult = roundf( *pResult * 100000.0f ) / 100000.0f; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_frequency() + * Gets a frequency value + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_frequency( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + float *pResult /* o : Frequency value */ +) +{ + ivas_error error; + uint32_t hiRes; + uint32_t refine; + + hiRes = 0; + refine = 0; + + if ( ( error = read_bin_code_word( this, RC_LUT_FREQ, pResult ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = read_bin_bool( this, &hiRes ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hiRes ) + { + if ( ( error = read_bin_bits( this, &refine, 4 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult *= powf( 2.0f, ( (float) refine + 1.0f ) / 51.0f ); + } + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_dsr() + * Gets a DSR value + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_dsr( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + float *pResult /* o : DSR value */ +) +{ + ivas_error error; + float value; + + if ( ( error = read_bin_code_word( this, RC_LUT_DSR, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = powf( 10.0f, value / 10.0f ); + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_distance() + * Gets a distance value (in meters) + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_distance( + RenderConfigReader *this, /* i/o : Render config reader handle */ + uint16_t isSmall, /* i : Flag indicating a small distance */ + float *pResult /* o : Distance value */ +) +{ + ivas_error error; + float value; + uint32_t flag; + + if ( ( error = read_bin_code_word( this, RC_LUT_METERS, pResult ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( isSmall == false ) + { + /* addHectometers flag */ + if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( flag == true ) + { + /* Hectometers */ + if ( ( error = read_bin_code_word( this, RC_LUT_HECTOMETERS, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value * 100.0f; + + /* addKilometers flag */ + if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) + { + return error; + } + + while ( flag == true ) + { + /* Kilometers */ + if ( ( error = read_bin_code_word( this, RC_LUT_KILOMETERS, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value * 1000.0f; + + /* addKilometers flag */ + if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + } + + /* addCentimeters flag */ + if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( flag == true ) + { + /* Centimeters */ + if ( ( error = read_bin_code_word( this, RC_LUT_CENTIMETERS, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value * 0.01f; + } + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_absorption() + * Gets an absorption value + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_absorption( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Absorption value */ +) +{ + ivas_error error; + + if ( ( error = read_bin_code_word( this, RC_LUT_ABSORPTION, pResult ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function read_txt_bool() + * Reads a boolean value from a line + *-----------------------------------------------------------------------------------------*/ + +static ivas_error read_txt_bool( + const char *pLine, /* i : String to read from */ + uint32_t *pTarget /* o : Output pointer */ +) +{ + char value[8 + 1]; + + if ( sscanf( pLine, "%8s", (char *) &value ) != 1 ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + if ( strcmp( value, "TRUE" ) == 0 ) + { + *pTarget = TRUE; + return IVAS_ERR_OK; + } + if ( strcmp( value, "FALSE" ) == 0 ) + { + *pTarget = FALSE; + return IVAS_ERR_OK; + } + + return IVAS_ERR_INVALID_RENDER_CONFIG; +} + + +/*-------------------------------------------------------------------* + * usdequant_rend_cfg() + * + * Uniform scalar de-quantizer routine + *-------------------------------------------------------------------*/ + +static float usdequant_rend_cfg( + const uint32_t idx, /* i : quantizer index */ + const float qlow, /* i : lowest codebook entry (index 0) */ + const float delta /* i : quantization step */ +) +{ + float g; + + g = idx * delta + qlow; + + return ( g ); +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_angle() + * Gets an angle value in degrees [0,360] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_angle( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Angle value */ +) +{ + ivas_error error; + uint32_t value; + + if ( ( error = read_bin_bits( this, &value, 5 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult = usdequant_rend_cfg( value, 0.0f, 20.0f ); + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_outer_attenuation () + * Gets an outer attenuation value [3.1623e-05,1.0], or in dB: [-90,0] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_outer_attenuation( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Attenuation value */ +) +{ + ivas_error error; + uint32_t value; + float logval, att; + + if ( ( error = read_bin_bits( this, &value, 5 ) ) != IVAS_ERR_OK ) + { + return error; + } + + logval = usdequant_rend_cfg( value, -90.0f, 3.0f ); + att = powf( 10, logval / 20.0f ); + + *pResult = att; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_max_dist () + * Gets a Maximum Distance value [1.0, 64.0] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_max_dist( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Attenuation value */ +) +{ + ivas_error error; + uint32_t value; + + if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult = usdequant_rend_cfg( value, 1.0f, 1.0f ); + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_ref_dist () + * Gets a Reference Distance value [0.1, 6.4] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_ref_dist( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Attenuation value */ +) +{ + ivas_error error; + uint32_t value; + + if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult = usdequant_rend_cfg( value, 0.1f, 0.1f ); + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_rolloff () + * Gets a Rollof Factor [0.0, 4.0] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_rolloff( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Attenuation value */ +) +{ + ivas_error error; + uint32_t value; + + if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult = usdequant_rend_cfg( value, 0.0f, 0.1f ); + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function read_txt_vector() + * + * Reads a vector value from a line + *-----------------------------------------------------------------------------------------*/ + +static int16_t read_txt_vector( + char *pLine, /* i : String to read from */ + const uint32_t length, /* i : Number of expected vector elements */ + float *pTarget /* o : Output vector pointer */ +) +{ + char *tmp; + uint16_t n; + uint16_t count; + + n = (int16_t) sscanf( pLine, "[%s", pLine ); + if ( n == 0 ) + { + return true; + } + + /* Additional comma to make parsing easier */ + pLine[strlen( pLine ) - 1] = ','; + + tmp = pLine; + /* Count # of commas to determine vector length */ + for ( n = 0; tmp[n]; tmp[n] == ',' ? n++ : *tmp++ ) + ; + + count = n; + + tmp = pLine; + + /* Check for maximum vector length */ + if ( n != length ) + { + return true; + } + + for ( n = 0; n < count; n++ ) + { + if ( (int16_t) sscanf( tmp, "%f,", &pTarget[n] ) != 1 ) + { + return true; + } + + tmp = strchr( tmp, ',' ) + 1; + } + + return false; +} + + +/*-----------------------------------------------------------------------------------------* + * Function strip_spaces() + * + * Strips the spaces from a buffer + *-----------------------------------------------------------------------------------------*/ + +static void strip_spaces( + char *pStr /* i : String to read from */ +) +{ + int32_t read_idx = 0, write_idx = 0; + + while ( pStr[read_idx] ) + { + if ( !isspace( (int32_t) pStr[read_idx] ) && !iscntrl( (int32_t) pStr[read_idx] ) ) + { + pStr[write_idx++] = pStr[read_idx]; + } + read_idx++; + } + pStr[write_idx] = '\0'; + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function errorHandler() + * + * Prints error message and exits + *-----------------------------------------------------------------------------------------*/ + +/*! r: error accumulation */ +static int32_t errorHandler( + const char *badStr, /* i : String to complain about */ + const ERROR_CODES_t error ) +{ + static int32_t numErrors = 0; + + switch ( error ) + { + case ERROR_NONE: + break; + case ERROR_ITEM_UNKNOWN: + numErrors++; + fprintf( stderr, "Unknown variable %s in renderer configuration file.\n\n", badStr ); + break; + case ERROR_VALUE_INVALID: + numErrors++; + fprintf( stderr, "Invalid value %s in renderer configuration file.\n\n", badStr ); + break; + default: + numErrors++; + fprintf( stderr, "Unknown error while reading configuration file.\n\n" ); + } + + return numErrors; +} + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_checkValues() + * + * Verifies if the configuration parameters lie within acceptable limits + *------------------------------------------------------------------------------------------*/ +ivas_error RenderConfigReader_checkValues( + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ +) +{ + int16_t band_idx, tab_value_err_count; + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pRoom_acoustics; + pRoom_acoustics = &hRenderConfig->roomAcoustics; + tab_value_err_count = 0; + int16_t wall_idx; +#ifndef FIX_1999_TEMPORARY_DISABLE_DIST_ATT_CHECK + int16_t i; +#endif + + /* Verify the number of frequency bands in the config input data */ + if ( ( pRoom_acoustics->nBands > N_BANDS_MAX ) || ( pRoom_acoustics->nBands < N_BANDS_MIN ) ) + { + return IVAS_ERR_WRONG_PARAMS; + } + + /* Verify data per band in the acoustic properties table */ + for ( band_idx = 0; band_idx < pRoom_acoustics->nBands; band_idx++ ) + { + /* Verify if the frequencies are in the ascending order (required for interpolation) */ + if ( band_idx != 0 ) + { + if ( pRoom_acoustics->pFc_input_fx[band_idx] <= pRoom_acoustics->pFc_input_fx[band_idx - 1] ) + { + tab_value_err_count++; + } + } + + /* Replace zero DSR values with very small positive values, to avoid issues with coloration filter design */ + if ( pRoom_acoustics->pAcoustic_dsr_fx[band_idx] == 0 ) + { + pRoom_acoustics->pAcoustic_dsr_fx[band_idx] = ACOUSTIC_DSR_EPSILON_FX; + } + } + + if ( tab_value_err_count != 0 ) + { + return IVAS_ERR_WRONG_PARAMS; + } + + + if ( pRoom_acoustics->use_er == 1 ) + { + /* Room dimensions */ + if ( pRoom_acoustics->dimensions.x < ER_MIN_ROOM_DIMENSION ) + { + pRoom_acoustics->dimensions.x = ER_MIN_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.x_fx < ER_MIN_ROOM_DIMENSION_FX ) + { + pRoom_acoustics->dimensions.x_fx = ER_MIN_ROOM_DIMENSION_FX; + } + if ( pRoom_acoustics->dimensions.x > ER_MAX_ROOM_DIMENSION ) + { + pRoom_acoustics->dimensions.x = ER_MAX_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.x_fx > ER_MAX_ROOM_DIMENSION_FX ) + { + pRoom_acoustics->dimensions.x_fx = ER_MAX_ROOM_DIMENSION_FX; + } + if ( pRoom_acoustics->dimensions.y < ER_MIN_ROOM_DIMENSION ) + { + pRoom_acoustics->dimensions.y = ER_MIN_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.y_fx < ER_MIN_ROOM_DIMENSION_FX ) + { + pRoom_acoustics->dimensions.y_fx = ER_MIN_ROOM_DIMENSION_FX; + } + if ( pRoom_acoustics->dimensions.y > ER_MAX_ROOM_DIMENSION ) + { + pRoom_acoustics->dimensions.y = ER_MAX_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.y_fx > ER_MAX_ROOM_DIMENSION_FX ) + { + pRoom_acoustics->dimensions.y_fx = ER_MAX_ROOM_DIMENSION_FX; + } + if ( pRoom_acoustics->dimensions.z < ER_MIN_ROOM_DIMENSION ) + { + pRoom_acoustics->dimensions.z = ER_MIN_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.z_fx < ER_MIN_ROOM_DIMENSION_FX ) + { + pRoom_acoustics->dimensions.z_fx = ER_MIN_ROOM_DIMENSION_FX; + } + if ( pRoom_acoustics->dimensions.z > ER_MAX_ROOM_DIMENSION ) + { + pRoom_acoustics->dimensions.z = ER_MAX_ROOM_DIMENSION; + } + if ( pRoom_acoustics->dimensions.z_fx > ER_MAX_ROOM_DIMENSION_FX ) + { + pRoom_acoustics->dimensions.z_fx = ER_MAX_ROOM_DIMENSION_FX; + } + + /* Abs Coeff */ + for ( wall_idx = 0; wall_idx < IVAS_ROOM_ABS_COEFF; wall_idx++ ) + { + if ( pRoom_acoustics->AbsCoeff[wall_idx] < ER_MIN_ABS_COEFF ) + { + pRoom_acoustics->AbsCoeff[wall_idx] = ER_MIN_ABS_COEFF; + } + if ( pRoom_acoustics->AbsCoeff_fx[wall_idx] < ER_MIN_ABS_COEFF_FX ) + { + pRoom_acoustics->AbsCoeff_fx[wall_idx] = ER_MIN_ABS_COEFF_FX; + } + if ( pRoom_acoustics->AbsCoeff[wall_idx] > ER_MAX_ABS_COEFF ) + { + pRoom_acoustics->AbsCoeff[wall_idx] = ER_MAX_ABS_COEFF; + } + if ( pRoom_acoustics->AbsCoeff_fx[wall_idx] > ER_MAX_ABS_COEFF_FX ) + { + pRoom_acoustics->AbsCoeff_fx[wall_idx] = ER_MAX_ABS_COEFF_FX; + } + } +#ifndef FIX_1999_TEMPORARY_DISABLE_DIST_ATT_CHECK + /* Verify range of distance attenuation parameters: 0.1 <= distAtt[0] <= distAtt[1] */ + /* 0.0 <= distAtt[2] <= 10.0 */ + hRenderConfig->distAtt[0] = max( 0.1f, hRenderConfig->distAtt[0] ); + hRenderConfig->distAtt[1] = max( hRenderConfig->distAtt[0], hRenderConfig->distAtt[1] ); + hRenderConfig->distAtt[2] = max( 0.0f, min( 10.0f, hRenderConfig->distAtt[2] ) ); + + /* Verify range of directivity patterns */ + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) + { + hRenderConfig->directivity[i * 3] = max( 0.0f, min( 360.0f, hRenderConfig->directivity[i * 3] ) ); + hRenderConfig->directivity[i * 3 + 1] = max( 0.0f, min( 360.0f, hRenderConfig->directivity[i * 3 + 1] ) ); + hRenderConfig->directivity[i * 3 + 2] = max( 0.0f, min( 1.0f, hRenderConfig->directivity[i * 3 + 2] ) ); + } +#endif + } + + + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_open() + * + * Allocates and initializes a renderer configuration reader instance + *------------------------------------------------------------------------------------------*/ + +ivas_error RenderConfigReader_open( + char *pConfigPath, /* i : renderer configuration file path */ + RenderConfigReader **ppRenderConfigReader /* o : RenderConfigReader handle */ +) +{ + RenderConfigReader *pSelf; + FILE *pConfigFile; + + /* Open the configuration file */ + if ( strlen( pConfigPath ) < 1 ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + pConfigFile = fopen( pConfigPath, "r" ); + + if ( !pConfigFile ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + pSelf = calloc( 1, sizeof( RenderConfigReader ) ); + pSelf->pConfigFile = pConfigFile; + pSelf->nFG = 0; + pSelf->pFG = NULL; + pSelf->nAE = 0; + pSelf->pAE = NULL; + pSelf->nDP = 0; + pSelf->pDP = NULL; + pSelf->distAtt[0] = -1; + + *ppRenderConfigReader = pSelf; + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_readBinary() + * + * Reads the binary configuration from a file + *------------------------------------------------------------------------------------------*/ + +static ivas_error RenderConfigReader_readBinary( + const char *pReverbConfigPath, /* i : Configuration file path */ + RenderConfigReader *pRenderConfigReader /* i/o: RenderConfigReader handle */ +) +{ + uint32_t file_size; + uint32_t value; + uint32_t signx, signy, k; + uint32_t i, m, n; + uint32_t nFG, nAE; + uint32_t nDP; + ivas_error error; + float freqHop; + uint32_t gridLen; + uint32_t subGridLen; + const float *pGrid; + FILE *pReverbConfigFile; + + /* Open the configuration file */ + pReverbConfigFile = fopen( pReverbConfigPath, "rb" ); + + if ( !pReverbConfigFile ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + /* Read the bitstream */ + fseek( pReverbConfigFile, 0, SEEK_END ); + file_size = ftell( pReverbConfigFile ); + rewind( pReverbConfigFile ); + + pRenderConfigReader->pBitstream = (uint8_t *) malloc( file_size * sizeof( uint8_t ) ); + if ( pRenderConfigReader->pBitstream == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + fread( pRenderConfigReader->pBitstream, sizeof( uint8_t ), file_size, pReverbConfigFile ); + pRenderConfigReader->length = file_size; + /* we read the config twice in the decoder, so reset the read offset here */ + pRenderConfigReader->readOffset = 0; + + /****************************/ + /* Read the presence flag */ + /****************************/ + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + /* acoustic environment data available */ + if ( value == true ) + { + /****************************/ + /* Read the frequency grids */ + /****************************/ + + /* Number of frequency grids */ + if ( ( error = get_bin_count_or_index( pRenderConfigReader, &nFG ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Allocate memory for the frequency grids */ + if ( nFG > 0 ) + { + if ( pRenderConfigReader->nFG > 0 ) + { + for ( n = 0; n < pRenderConfigReader->nFG; n++ ) + { + free( pRenderConfigReader->pFG[n].pFc ); + } + free( pRenderConfigReader->pFG ); + } + pRenderConfigReader->nFG = nFG; + if ( ( pRenderConfigReader->pFG = (FrequencyGrid *) malloc( pRenderConfigReader->nFG * sizeof( FrequencyGrid ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + for ( n = 0; n < nFG; n++ ) + { + /* Initialize memory pointers to allow safe freeing ico errors */ + pRenderConfigReader->pFG[n].pFc = NULL; + } + } + + /* Loop through the frequency grids read from the binary stream */ + for ( n = 0; n < nFG; n++ ) + { + /* Read the representation method */ + value = 0; + if ( ( error = read_bin_bits( pRenderConfigReader, &value, 2 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Process depending on the representation method */ + switch ( value ) + { + case FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES: + if ( ( error = get_bin_count_or_index( pRenderConfigReader, &pRenderConfigReader->pFG[n].nrBands ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Allocate memory for the center frequency array */ + if ( ( pRenderConfigReader->pFG[n].pFc = (float *) malloc( pRenderConfigReader->pFG[n].nrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + /* Read the individual frequencies */ + for ( m = 0; m < pRenderConfigReader->pFG[n].nrBands; m++ ) + { + if ( ( error = get_bin_frequency( pRenderConfigReader, &pRenderConfigReader->pFG[n].pFc[m] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + break; + case FREQ_GRID_MODE_START_HOP_AMOUNT: + if ( ( error = get_bin_count_or_index( pRenderConfigReader, &pRenderConfigReader->pFG[n].nrBands ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Allocate memory for the center frequency array */ + if ( ( pRenderConfigReader->pFG[n].pFc = (float *) malloc( pRenderConfigReader->pFG[n].nrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + /* Read the first frequency */ + if ( ( error = get_bin_frequency( pRenderConfigReader, &pRenderConfigReader->pFG[n].pFc[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Read frequency hop from LUT */ + if ( ( error = read_bin_code_word( pRenderConfigReader, RC_LUT_FREQ_HOP, &freqHop ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Fill up the center frequency array */ + for ( m = 1; m < pRenderConfigReader->pFG[n].nrBands; m++ ) + { + pRenderConfigReader->pFG[n].pFc[m] = pRenderConfigReader->pFG[n].pFc[m - 1] * freqHop; + } + break; + case FREQ_GRID_MODE_DEFAULT_BANDING: + /* Read the default grid ID */ + value = 0; + if ( ( error = read_bin_bits( pRenderConfigReader, &value, 4 ) ) != IVAS_ERR_OK ) + { + return error; + } + switch ( value ) + { + case 0: + gridLen = sizeof( defaultFrequencyGrid_0 ) / sizeof( defaultFrequencyGrid_0[0] ); + pGrid = defaultFrequencyGrid_0; + break; + case 1: + gridLen = sizeof( defaultFrequencyGrid_1 ) / sizeof( defaultFrequencyGrid_1[0] ); + pGrid = defaultFrequencyGrid_1; + break; + case 2: + gridLen = sizeof( defaultFrequencyGrid_2 ) / sizeof( defaultFrequencyGrid_2[0] ); + pGrid = defaultFrequencyGrid_2; + break; + case 3: + gridLen = sizeof( defaultFrequencyGrid_3 ) / sizeof( defaultFrequencyGrid_3[0] ); + pGrid = defaultFrequencyGrid_3; + break; + case 4: + gridLen = sizeof( defaultFrequencyGrid_4 ) / sizeof( defaultFrequencyGrid_4[0] ); + pGrid = defaultFrequencyGrid_4; + break; + case 5: + gridLen = sizeof( defaultFrequencyGrid_5 ) / sizeof( defaultFrequencyGrid_5[0] ); + pGrid = defaultFrequencyGrid_5; + break; + case 6: + gridLen = sizeof( defaultFrequencyGrid_6 ) / sizeof( defaultFrequencyGrid_6[0] ); + pGrid = defaultFrequencyGrid_6; + break; + case 7: + gridLen = sizeof( defaultFrequencyGrid_7 ) / sizeof( defaultFrequencyGrid_7[0] ); + pGrid = defaultFrequencyGrid_7; + break; + case 8: + gridLen = sizeof( defaultFrequencyGrid_8 ) / sizeof( defaultFrequencyGrid_8[0] ); + pGrid = defaultFrequencyGrid_8; + break; + default: + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + m = 0; + /* Read sub-grid flag */ + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( value != false ) + { + /* Read the sub-grid offset */ + if ( ( error = read_bin_bits( pRenderConfigReader, &m, 3 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Read the sub-grid length */ + subGridLen = 0; + if ( ( error = read_bin_bits( pRenderConfigReader, &subGridLen, 6 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( m + subGridLen > gridLen ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + gridLen = subGridLen; + } + pRenderConfigReader->pFG[n].nrBands = gridLen; + /* Allocate memory for the center frequency array */ + if ( ( pRenderConfigReader->pFG[n].pFc = (float *) malloc( gridLen * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + /* Copy the ROM content to the frequency grid*/ + for ( i = 0; i < gridLen; i++ ) + { + pRenderConfigReader->pFG[n].pFc[i] = pGrid[m + i]; + } + + break; + default: + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + /* Initialize memory pointers to allow safe freeing ico errors */ + pRenderConfigReader->pFG[n].pFc = NULL; + } + + /**********************************/ + /* Read the acoustic environments */ + /**********************************/ + + /* Number of acoustic environments */ + if ( ( error = get_bin_count_or_index( pRenderConfigReader, &nAE ) ) != IVAS_ERR_OK ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + /* Allocate memory for the acoustic environments array */ + if ( nAE > 0 ) + { + if ( pRenderConfigReader->nAE > 0 ) + { + for ( n = 0; n < pRenderConfigReader->nAE; n++ ) + { + free( pRenderConfigReader->pAE[n].pRT60 ); + free( pRenderConfigReader->pAE[n].pDSR ); + if ( pRenderConfigReader->pAE[n].pEarlyReflections != NULL ) + { + free( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin ); + free( pRenderConfigReader->pAE[n].pEarlyReflections ); + } + } + free( pRenderConfigReader->pAE ); + } + pRenderConfigReader->nAE = nAE; + + if ( ( pRenderConfigReader->pAE = (AcousticEnv *) malloc( pRenderConfigReader->nAE * sizeof( AcousticEnv ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + /* Initialize memory pointers to allow safe freeing ico errors */ + for ( n = 0; n < nAE; n++ ) + { + pRenderConfigReader->pAE[n].pRT60 = NULL; + pRenderConfigReader->pAE[n].pDSR = NULL; + pRenderConfigReader->pAE[n].pEarlyReflections = NULL; + } + } + + /* Loop through the acoustic environments from the binary stream */ + for ( n = 0; n < nAE; n++ ) + { + /* Read the AE ID */ + if ( ( error = get_bin_id( pRenderConfigReader, &pRenderConfigReader->pAE[n].id ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Read the frequency grid ID */ + if ( ( error = get_bin_count_or_index( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Associate the frequency grid */ + if ( value >= pRenderConfigReader->nFG ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + pRenderConfigReader->pAE[n].pFG = &( pRenderConfigReader->pFG[value] ); + + /* Allocate memory for RT60 and DSR arrays */ + if ( ( pRenderConfigReader->pAE[n].pRT60 = (float *) malloc( pRenderConfigReader->pAE[n].pFG->nrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + if ( ( pRenderConfigReader->pAE[n].pDSR = (float *) malloc( pRenderConfigReader->pAE[n].pFG->nrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + /* Read the values */ + if ( ( error = get_bin_duration( pRenderConfigReader, &pRenderConfigReader->pAE[n].preDelay ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( m = 0; m < pRenderConfigReader->pAE[n].pFG->nrBands; m++ ) + { + if ( ( error = get_bin_duration( pRenderConfigReader, &pRenderConfigReader->pAE[n].pRT60[m] ) ) != IVAS_ERR_OK ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + for ( m = 0; m < pRenderConfigReader->pAE[n].pFG->nrBands; m++ ) + { + if ( ( error = get_bin_dsr( pRenderConfigReader, &pRenderConfigReader->pAE[n].pDSR[m] ) ) != IVAS_ERR_OK ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + + /*****************************************/ + /* Read the early reflections parameters */ + /*****************************************/ + + /* Has early reflections */ + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( value == true ) + { + if ( ( pRenderConfigReader->pAE[n].pEarlyReflections = (EarlyReflectionsConfig *) malloc( sizeof( EarlyReflectionsConfig ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + /* Initialize memory pointers to allow safe freeing ico eg errors */ + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = NULL; + + pRenderConfigReader->pAE[n].pEarlyReflections->use_er = 1; + + /* Room sizes */ + if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.y ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.z ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( k = 0; k < N_ABS_COEFFS; k++ ) + { + if ( ( error = get_bin_absorption( pRenderConfigReader, &pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[k] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* Has listener origin */ + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( value == true ) + { + if ( ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + if ( ( error = read_bin_bits( pRenderConfigReader, &signx, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = read_bin_bits( pRenderConfigReader, &signy, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( signx == 0 ) + { + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x *= -1.0f; + } + if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( signy == 0 ) + { + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y *= -1.0f; + } + if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else /* load defaults if origin is not specified in config */ + { + if ( ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x = IVAS_ER_LIST_ORIGIN_X; + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y = IVAS_ER_LIST_ORIGIN_Y; + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z = IVAS_ER_LIST_HEIGHT; + } + + /* Low complexity mode */ + if ( ( error = read_bin_bool( pRenderConfigReader, &pRenderConfigReader->pAE[n].pEarlyReflections->lowComplexity ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + } + /**********************************/ + /* Read the directivity patterns */ + /**********************************/ + + /* Has source directivity */ + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( value == true ) + { + + /* Number of directivity patterns */ + if ( ( error = get_bin_id( pRenderConfigReader, &nDP ) ) != IVAS_ERR_OK ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + if ( nDP > 0 ) + { + if ( pRenderConfigReader->nDP > 0 ) + { + for ( n = 0; n < pRenderConfigReader->nDP; n++ ) + { + free( pRenderConfigReader->pDP[n].pDirectivity ); + } + free( pRenderConfigReader->pDP ); + } + + pRenderConfigReader->nDP = nDP; + + if ( ( pRenderConfigReader->pDP = (DirectrivityPat *) malloc( pRenderConfigReader->nDP * sizeof( DirectrivityPat ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + for ( n = 0; n < nDP; n++ ) + { + /* Allocate memory for directivity arrays*/ + if ( ( pRenderConfigReader->pDP[n].pDirectivity = (float *) malloc( 3 * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + } + } + /* Loop through the directivity patterns from the binary stream */ + for ( n = 0; n < nDP; n++ ) + { + + /* Read the Directivity ID */ + if ( ( error = get_bin_id( pRenderConfigReader, &pRenderConfigReader->pDP[n].id ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_bin_angle( pRenderConfigReader, &pRenderConfigReader->pDP[n].pDirectivity[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_bin_angle( pRenderConfigReader, &pRenderConfigReader->pDP[n].pDirectivity[1] ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_bin_outer_attenuation( pRenderConfigReader, &pRenderConfigReader->pDP[n].pDirectivity[2] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + /**********************************/ + /* Read the distance attenuation */ + /**********************************/ + + /* Has distance attenuation */ + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( value == true ) + { + /* Read the Max Distance */ + if ( ( error = get_bin_max_dist( pRenderConfigReader, &pRenderConfigReader->distAtt[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Read the Ref Distance */ + if ( ( error = get_bin_ref_dist( pRenderConfigReader, &pRenderConfigReader->distAtt[1] ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Read the Rolloff Facto r*/ + if ( ( error = get_bin_rolloff( pRenderConfigReader, &pRenderConfigReader->distAtt[2] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + + /* Cleanup */ + free( pRenderConfigReader->pBitstream ); + + return IVAS_ERR_OK; +} + + +ivas_error RenderConfigReader_read( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + const char *pRenderConfigPath, /* i : Renderer configuration file path */ + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ +) +{ + int32_t file_size; + char *pConfig_str; + char *pParams; + char *pTemp; + int32_t read_idx; + int32_t params_idx; + char item[MAX_ITEM_LENGTH + 1]; + char chapter[MAX_ITEM_LENGTH + 1]; + char *pValue; + ivas_error error; + int32_t params_length; + int32_t length; + uint32_t i, idx; + uint32_t nFG, nAE; + char *pToken; + FREQ_GRID_MODE fgMode; + float freqHop; + uint32_t acIdx; + uint32_t defGridId, defGridLen, defGridOffset, defGridNrBands; + const float *pDefGrid; + float erTemp[N_ABS_COEFFS]; + uint32_t roomAcHasFgCount, roomAcHasAcEnvCount; + uint32_t fgHasMethod, fgHasNBands, fgHasFreqs, fgHasDefaultGrid, fgHasStartFreq, fgHasFreqHop; + uint32_t aeHasFgIdx, aeHasPredelay, aeHasRt60, aeHasDsr; + uint32_t aeHasERsize, aeHasERabs; + bool dofProvided = false; + bool poseCorrProvided = false; + + uint32_t nDP; + uint32_t accDPIdx; + accDPIdx = 0; + + fseek( pRenderConfigReader->pConfigFile, 0, SEEK_END ); + file_size = ftell( pRenderConfigReader->pConfigFile ); + rewind( pRenderConfigReader->pConfigFile ); + pConfig_str = (char *) calloc( file_size + 1, sizeof( char ) ); + pParams = (char *) calloc( file_size + 1, sizeof( char ) ); + pTemp = (char *) calloc( file_size + 1, sizeof( char ) ); + acIdx = 0; + roomAcHasFgCount = roomAcHasAcEnvCount = FALSE; + setvbuf( pRenderConfigReader->pConfigFile, pConfig_str, _IONBF, sizeof( char ) ); /* Work-around for VS bug that gives incorrect ftell for UNIX-style line endings */ + + /* read file line by line */ + while ( fgets( pConfig_str, file_size, pRenderConfigReader->pConfigFile ) != NULL ) + { + + if ( sscanf( pConfig_str, "[%64[^]]]", chapter ) == 1 ) + { + /* read line by line (except comments) until next chapter or EOF */ + pParams[0] = '\0'; + do + { + read_idx = ftell( pRenderConfigReader->pConfigFile ); + if ( fgets( pTemp, file_size, pRenderConfigReader->pConfigFile ) == NULL ) + { + break; + } + + if ( ( pTemp[0] != '#' ) && ( sscanf( pTemp, "[%64[^]]]", item ) != 1 ) ) + { + /* ignore inline comments */ + sscanf( pTemp, "%[^#]", pTemp ); + strcat( pParams, pTemp ); + } + } while ( sscanf( pTemp, "[%64[^]]]", item ) != 1 ); + + /* go back one line */ + fseek( pRenderConfigReader->pConfigFile, read_idx, SEEK_SET ); + + strip_spaces( pParams ); + strcpy( pTemp, pParams ); + to_upper( pParams ); + to_upper( chapter ); + + /* interpret params */ + pToken = strtok( chapter, ":" ); + if ( strcmp( chapter, "ROOMACOUSTICS" ) == 0 && strlen( pParams ) != 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + if ( strcmp( item, "FREQUENCYGRIDCOUNT" ) == 0 ) + { + /* Read the number of frequency grids */ + if ( !sscanf( pValue, "%u", &nFG ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( nFG > 0 ) + { + for ( idx = 0; idx < pRenderConfigReader->nFG; idx++ ) + { + free( pRenderConfigReader->pFG[idx].pFc ); + } + free( pRenderConfigReader->pFG ); + + pRenderConfigReader->nFG = nFG; + + /* Allocate memory for the frequency grids */ + if ( ( pRenderConfigReader->pFG = (FrequencyGrid *) malloc( pRenderConfigReader->nFG * sizeof( FrequencyGrid ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + for ( idx = 0; idx < nFG; idx++ ) + { + pRenderConfigReader->pFG[idx].nrBands = 0; + pRenderConfigReader->pFG[idx].pFc = NULL; + } + } + roomAcHasFgCount = TRUE; + } + else if ( strcmp( item, "ACOUSTICENVIRONMENTCOUNT" ) == 0 ) + { + /* Read the number of acoustic environments */ + if ( !sscanf( pValue, "%u", &nAE ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( nAE > 0 ) + { + for ( idx = 0; idx < pRenderConfigReader->nAE; idx++ ) + { + free( pRenderConfigReader->pAE[idx].pRT60 ); + free( pRenderConfigReader->pAE[idx].pDSR ); + if ( pRenderConfigReader->pAE[idx].pEarlyReflections != NULL ) + { + free( pRenderConfigReader->pAE[idx].pEarlyReflections->pListenerOrigin ); + free( pRenderConfigReader->pAE[idx].pEarlyReflections ); + } + } + free( pRenderConfigReader->pAE ); + + pRenderConfigReader->nAE = nAE; + + /* Allocate memory for the acoustic environments array */ + if ( ( pRenderConfigReader->pAE = (AcousticEnv *) malloc( pRenderConfigReader->nAE * sizeof( AcousticEnv ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + /* Initialize memory pointers to allow for safe freeing */ + for ( acIdx = 0; acIdx < pRenderConfigReader->nAE; acIdx++ ) + { + pRenderConfigReader->pAE[acIdx].pRT60 = NULL; + pRenderConfigReader->pAE[acIdx].pDSR = NULL; + pRenderConfigReader->pAE[acIdx].pEarlyReflections = NULL; + } + } + acIdx = 0; + roomAcHasAcEnvCount = TRUE; + } + } + if ( roomAcHasFgCount == FALSE || roomAcHasAcEnvCount == FALSE ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + free( pValue ); + } + else if ( strcmp( pToken, "FREQUENCYGRID" ) == 0 ) + { + if ( pRenderConfigReader->pFG == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + idx = strtol( strtok( NULL, ":" ), NULL, 0 ); + if ( idx >= pRenderConfigReader->nFG ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + fgHasMethod = fgHasNBands = fgHasFreqs = fgHasDefaultGrid = fgHasStartFreq = fgHasFreqHop = FALSE; + fgMode = FREQ_GRID_MODE_UNKNOWN; + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + if ( strcmp( item, "METHOD" ) == 0 ) + { + if ( strcmp( pValue, "INDIVIDUALFREQUENCIES" ) == 0 ) + { + fgMode = FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES; + } + else if ( strcmp( pValue, "STARTHOPAMOUNT" ) == 0 ) + { + fgMode = FREQ_GRID_MODE_START_HOP_AMOUNT; + } + else if ( strcmp( pValue, "DEFAULTBANDING" ) == 0 ) + { + fgMode = FREQ_GRID_MODE_DEFAULT_BANDING; + } + fgHasMethod = TRUE; + } + /* Read number of bands for individual frequency, start-hop-amount mode */ + else if ( strcmp( item, "NRBANDS" ) == 0 ) + { + if ( fgMode != FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES && fgMode != FREQ_GRID_MODE_START_HOP_AMOUNT ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( !sscanf( pValue, "%u", &pRenderConfigReader->pFG[idx].nrBands ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + /* Allocate memory for the center frequency array */ + if ( ( pRenderConfigReader->pFG[idx].pFc = (float *) malloc( pRenderConfigReader->pFG[idx].nrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + fgHasNBands = TRUE; + } + else if ( strcmp( item, "FREQUENCIES" ) == 0 ) + { + if ( fgMode != FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES || pRenderConfigReader->pFG[idx].nrBands == 0 || pRenderConfigReader->pFG[idx].pFc == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + /* Read the individual frequencies */ + if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pFG[idx].pFc ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + fgHasFreqs = TRUE; + } + else if ( strcmp( item, "STARTFREQUENCY" ) == 0 ) + { + if ( fgMode != FREQ_GRID_MODE_START_HOP_AMOUNT || pRenderConfigReader->pFG[idx].nrBands == 0 || pRenderConfigReader->pFG[idx].pFc == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( !sscanf( pValue, "%f", &pRenderConfigReader->pFG[idx].pFc[0] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + fgHasStartFreq = TRUE; + } + else if ( strcmp( item, "FREQUENCYHOP" ) == 0 ) + { + if ( fgMode != FREQ_GRID_MODE_START_HOP_AMOUNT || pRenderConfigReader->pFG[idx].nrBands == 0 || pRenderConfigReader->pFG[idx].pFc == NULL || pRenderConfigReader->pFG[idx].pFc[0] == 0.0f ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( !sscanf( pValue, "%f", &freqHop ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + /* Fill up the center frequency array */ + for ( i = 1; i < pRenderConfigReader->pFG[idx].nrBands; i++ ) + { + pRenderConfigReader->pFG[idx].pFc[i] = pRenderConfigReader->pFG[idx].pFc[i - 1] * freqHop; + } + fgHasFreqHop = TRUE; + } + /* Handle default grids, with optional sub-grids */ + else if ( strcmp( item, "DEFAULTGRID" ) == 0 ) + { + if ( !sscanf( pValue, "%u", &defGridId ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + switch ( defGridId ) + { + case 0: + defGridLen = sizeof( defaultFrequencyGrid_0 ) / sizeof( defaultFrequencyGrid_0[0] ); + pDefGrid = defaultFrequencyGrid_0; + break; + case 1: + defGridLen = sizeof( defaultFrequencyGrid_1 ) / sizeof( defaultFrequencyGrid_1[0] ); + pDefGrid = defaultFrequencyGrid_1; + break; + case 2: + defGridLen = sizeof( defaultFrequencyGrid_2 ) / sizeof( defaultFrequencyGrid_2[0] ); + pDefGrid = defaultFrequencyGrid_2; + break; + case 3: + defGridLen = sizeof( defaultFrequencyGrid_3 ) / sizeof( defaultFrequencyGrid_3[0] ); + pDefGrid = defaultFrequencyGrid_3; + break; + case 4: + defGridLen = sizeof( defaultFrequencyGrid_4 ) / sizeof( defaultFrequencyGrid_4[0] ); + pDefGrid = defaultFrequencyGrid_4; + break; + case 5: + defGridLen = sizeof( defaultFrequencyGrid_5 ) / sizeof( defaultFrequencyGrid_5[0] ); + pDefGrid = defaultFrequencyGrid_5; + break; + case 6: + defGridLen = sizeof( defaultFrequencyGrid_6 ) / sizeof( defaultFrequencyGrid_6[0] ); + pDefGrid = defaultFrequencyGrid_6; + break; + case 7: + defGridLen = sizeof( defaultFrequencyGrid_7 ) / sizeof( defaultFrequencyGrid_7[0] ); + pDefGrid = defaultFrequencyGrid_7; + break; + case 8: + defGridLen = sizeof( defaultFrequencyGrid_8 ) / sizeof( defaultFrequencyGrid_8[0] ); + pDefGrid = defaultFrequencyGrid_8; + break; + default: + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + fgHasDefaultGrid = TRUE; + + /* Handle sub-grids */ + defGridOffset = 0; + defGridNrBands = defGridLen; + + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + if ( strcmp( item, "DEFAULTGRIDOFFSET" ) == 0 ) + { + if ( !sscanf( pValue, "%u", &defGridOffset ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + else if ( strcmp( item, "DEFAULTGRIDNRBANDS" ) == 0 ) + { + if ( !sscanf( pValue, "%u", &defGridNrBands ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + else + { + break; + } + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + } + + if ( defGridOffset + defGridNrBands > defGridLen ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + pRenderConfigReader->pFG[idx].nrBands = defGridNrBands; + + /* Allocate memory for the center frequency array */ + if ( ( pRenderConfigReader->pFG[idx].pFc = (float *) malloc( defGridNrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + /* Copy the ROM content to the frequency grid*/ + for ( i = 0; i < defGridNrBands; i++ ) + { + pRenderConfigReader->pFG[idx].pFc[i] = pDefGrid[defGridOffset + i]; + } + } + } + if ( fgHasMethod == FALSE || + ( fgMode == FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES && ( fgHasFreqs == FALSE || fgHasNBands == FALSE ) ) || + ( fgMode == FREQ_GRID_MODE_DEFAULT_BANDING && fgHasDefaultGrid == FALSE ) || + ( fgMode == FREQ_GRID_MODE_START_HOP_AMOUNT && ( fgHasStartFreq == FALSE || fgHasFreqHop == FALSE || fgHasNBands == FALSE ) ) ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + free( pValue ); + } + /* Handle multiple acoustic environments */ + else if ( strcmp( pToken, "ACOUSTICENVIRONMENT" ) == 0 ) + { + if ( pRenderConfigReader->pAE == NULL || acIdx >= pRenderConfigReader->nAE ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + idx = strtol( strtok( NULL, ":" ), NULL, 0 ); + pRenderConfigReader->pAE[acIdx].id = idx; + + aeHasFgIdx = aeHasPredelay = aeHasRt60 = aeHasDsr = FALSE; + aeHasERsize = aeHasERabs = FALSE; + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + /* Frequency grid index */ + if ( strcmp( item, "FREQUENCYGRIDINDEX" ) == 0 ) + { + if ( !sscanf( pValue, "%u", &i ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( i >= pRenderConfigReader->nFG || pRenderConfigReader->pFG[i].pFc == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + pRenderConfigReader->pAE[acIdx].pFG = &pRenderConfigReader->pFG[i]; + + /* Allocate memory for RT60 and DSR arrays */ + if ( ( pRenderConfigReader->pAE[acIdx].pRT60 = (float *) malloc( pRenderConfigReader->pAE[acIdx].pFG->nrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + if ( ( pRenderConfigReader->pAE[acIdx].pDSR = (float *) malloc( pRenderConfigReader->pAE[acIdx].pFG->nrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + aeHasFgIdx = TRUE; + } + + /* Acoustic pre-delay */ + else if ( strcmp( item, "ACOUSTICPREDELAY" ) == 0 ) + { + float f; + if ( !sscanf( pValue, "%f", &f ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + hRenderConfig->roomAcoustics.acousticPreDelay_fx = (Word32) ( f * ONE_IN_Q27 ); + } + /* Pre-delay */ + else if ( strcmp( item, "PREDELAY" ) == 0 ) + { + if ( !sscanf( pValue, "%f", &pRenderConfigReader->pAE[acIdx].preDelay ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + aeHasPredelay = TRUE; + } + /* RT60 */ + else if ( strcmp( item, "RT60" ) == 0 ) + { + if ( read_txt_vector( pValue, pRenderConfigReader->pAE[acIdx].pFG->nrBands, pRenderConfigReader->pAE[acIdx].pRT60 ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + aeHasRt60 = TRUE; + } + /* DSR */ + else if ( strcmp( item, "DSR" ) == 0 ) + { + if ( read_txt_vector( pValue, pRenderConfigReader->pAE[acIdx].pFG->nrBands, pRenderConfigReader->pAE[acIdx].pDSR ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + aeHasDsr = TRUE; + } + else if ( strcmp( item, "EARLYREFLECTIONSSIZE" ) == 0 ) + { + if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) + { + if ( ( pRenderConfigReader->pAE[acIdx].pEarlyReflections = (EarlyReflectionsConfig *) malloc( sizeof( EarlyReflectionsConfig ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin = NULL; + pRenderConfigReader->pAE[acIdx].pEarlyReflections->lowComplexity = FALSE; + } + if ( strcmp( item, "EARLYREFLECTIONSSIZE" ) == 0 ) + { + if ( read_txt_vector( pValue, 3, erTemp ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.x = erTemp[0]; + pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.y = erTemp[1]; + pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.z = erTemp[2]; + aeHasERsize = TRUE; + } + } + else if ( strcmp( item, "ABSORPTIONCOEFFS" ) == 0 ) + { + if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( read_txt_vector( pValue, N_ABS_COEFFS, erTemp ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + for ( i = 0; i < N_ABS_COEFFS; i++ ) + { + pRenderConfigReader->pAE[acIdx].pEarlyReflections->pAbsCoeff[i] = erTemp[i]; + } + aeHasERabs = TRUE; + } + else if ( strcmp( item, "LISTENERORIGIN" ) == 0 ) + { + if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( read_txt_vector( pValue, 3, erTemp ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( ( pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->x = erTemp[0]; + pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->y = erTemp[1]; + pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->z = erTemp[2]; + } + else if ( strcmp( item, "LOWCOMPLEXITY" ) == 0 ) + { + if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( read_txt_bool( pValue, &pRenderConfigReader->pAE[acIdx].pEarlyReflections->lowComplexity ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + } + if ( aeHasFgIdx == FALSE || aeHasPredelay == FALSE || aeHasRt60 == FALSE || aeHasDsr == FALSE ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( aeHasERsize == TRUE && aeHasERabs == FALSE ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + else if ( aeHasERsize == TRUE && aeHasERabs == TRUE ) + { + pRenderConfigReader->pAE[acIdx].pEarlyReflections->use_er = 1; + } + + free( pValue ); + acIdx++; + } + else if ( strcmp( chapter, "SPLITREND" ) == 0 && strlen( pParams ) != 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif + if ( strcmp( item, "CODECDELAY" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.codec_delay_ms ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "HQMODE" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.hq_mode ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "BITRATE" ) == 0 ) + { + if ( !sscanf( pValue, "%d", &hRenderConfig->split_rend_config.splitRendBitRate ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "DOF" ) == 0 ) + { + dofProvided = true; + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.dof ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + /* 0 DOF implies no pose correction */ + if ( hRenderConfig->split_rend_config.dof == 0 && !poseCorrProvided ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } + } + else if ( strcmp( item, "CODEC" ) == 0 ) + { + if ( strcmp( pValue, "LCLD" ) == 0 ) + { + hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LCLD; + } + else if ( strcmp( pValue, "LC3PLUS" ) == 0 ) + { + hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LC3PLUS; + } + else + { + errorHandler( pValue, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "FRAMESIZE" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.codec_frame_size_ms ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + if ( hRenderConfig->split_rend_config.codec_frame_size_ms != 5 && + hRenderConfig->split_rend_config.codec_frame_size_ms != 10 && + hRenderConfig->split_rend_config.codec_frame_size_ms != 20 ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "POSECORRECTION" ) == 0 ) + { + poseCorrProvided = true; + if ( strcmp( pValue, "CLDFB" ) == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + } + else if ( strcmp( pValue, "NONE" ) == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + /* no pose correction implies 0 DOF */ + if ( !dofProvided ) + { + hRenderConfig->split_rend_config.dof = 0; + } + } + else + { + errorHandler( pValue, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "RENDERER" ) == 0 ) + { + if ( strcmp( pValue, "CREND" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_CREND; + } + else if ( strcmp( pValue, "FASTCONV" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_FASTCONV; + } + else if ( strcmp( pValue, "PARAMBIN" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_PARAMBIN; + } + else if ( strcmp( pValue, "TDREND" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_TDREND; + } + else + { + errorHandler( pValue, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "LC3PLUS_HIGHRES" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.lc3plus_highres ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } +#ifdef DEBUGGING + else + { + fprintf( stderr, "Unsupported configuration property %s\n", item ); + } +#endif + } + free( pValue ); + } + else if ( strcmp( chapter, "DIRECTIVITYSETTING" ) == 0 && strlen( pParams ) != 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + if ( strcmp( item, "DIRECTIVITYCOUNT" ) == 0 ) + { + /* Read the number of directivity chapters */ + if ( !sscanf( pValue, "%u", &nDP ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( nDP > 0 ) + { + for ( idx = 0; idx < pRenderConfigReader->nDP; idx++ ) + { + free( pRenderConfigReader->pDP[idx].pDirectivity ); + } + + free( pRenderConfigReader->pDP ); + pRenderConfigReader->nDP = nDP; + + /* Allocate memory for the directivity pattern*/ + if ( ( pRenderConfigReader->pDP = (DirectrivityPat *) malloc( pRenderConfigReader->nDP * sizeof( DirectrivityPat ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + for ( idx = 0; idx < nDP; idx++ ) + { + pRenderConfigReader->pDP[idx].pDirectivity = NULL; + } + } + accDPIdx = 0; + } + } + free( pValue ); + } + else if ( strcmp( pToken, "DIRECTIVITYPATTERN" ) == 0 ) + { + if ( pRenderConfigReader->pDP == NULL || accDPIdx >= pRenderConfigReader->nDP ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + idx = strtol( strtok( NULL, ":" ), NULL, 0 ); + + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + /* Allocate memory for directivity arrays*/ + if ( ( pRenderConfigReader->pDP[accDPIdx].pDirectivity = (float *) malloc( 3 * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + pRenderConfigReader->pDP[accDPIdx].id = idx; + + if ( strcmp( item, "DIRECTIVITY" ) == 0 ) + { + if ( read_txt_vector( pValue, 3, pRenderConfigReader->pDP[accDPIdx].pDirectivity ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + } + free( pValue ); + accDPIdx++; + } + else if ( strcmp( chapter, "DISTANCEATTENUATION" ) == 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + + /* Set default values if parameters are only partially specified */ + pRenderConfigReader->distAtt[0] = 15.75f; + pRenderConfigReader->distAtt[1] = 1.0f; + pRenderConfigReader->distAtt[2] = 1.0f; + + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + + if ( strcmp( item, "MAXDIST" ) == 0 ) + { + /* Read the Maximum distance */ + if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[0] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + if ( strcmp( item, "REFDIST" ) == 0 ) + { + /* Read the Reference distance */ + if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[1] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + if ( strcmp( item, "ROLLOFFFACTOR" ) == 0 ) + { + /* Read the Rolloff Factor */ + if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[2] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + } + + free( pValue ); + } + else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_length = (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + if ( strcmp( item, "BINARYCONFIG" ) == 0 ) + { + /* get correct case reverb configuration file path */ + sscanf( pTemp + params_idx, "%*[^=] = %[^;];", pValue ); + + /* make reverb configuration file path relative to render configuration file path */ + for ( length = (int32_t) strlen( pRenderConfigPath ) - 1; length >= 0; length-- ) + { + if ( pRenderConfigPath[length] == '\\' || pRenderConfigPath[length] == '/' ) + { + length++; + break; + } + } + if ( length < 0 ) + { + /* no slash found */ + length = 0; + } + char *pCombinedName = calloc( length + (int32_t) strlen( pValue ) + 1, sizeof( char ) ); + strncpy( pCombinedName, pRenderConfigPath, length ); + strcpy( pCombinedName + length, pValue ); + + if ( ( error = RenderConfigReader_readBinary( pCombinedName, pRenderConfigReader ) ) != IVAS_ERR_OK ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + free( pCombinedName ); + } + else if ( strcmp( item, "DIRECTIVITY" ) == 0 ) + { + if ( read_txt_vector( pValue, 3, hRenderConfig->directivity ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + params_idx += params_length; + } + free( pValue ); + } + else + { + fprintf( stderr, "Unknown chapter: %s\n", chapter ); + } + } + else if ( pConfig_str[0] == '#' ) + { + /* comment lines are to be ignored */ + } + } + + free( pConfig_str ); + free( pParams ); + free( pTemp ); + + if ( errorHandler( "", ERROR_NONE ) > 0 ) + { + fprintf( stderr, "Errors occurred\n" ); + return IVAS_ERR_FAILED_FILE_PARSE; + } + return IVAS_ERR_OK; +} + +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getAcousticEnvironmentCount() + * + * Gets number of acoustic environments available + *------------------------------------------------------------------------------------------*/ +uint32_t RenderConfigReader_getAcousticEnvironmentCount( + RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ +) +{ + return pRenderConfigReader->nAE; +} + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getAcousticEnvironments() + * + * Gets all acoustic environments + *------------------------------------------------------------------------------------------*/ +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->aeID = (Word16) pIn.id; + pOut->nBands = (Word16) pIn.pFG->nrBands; + pOut->inputPreDelay_fx = (Word32) ( pIn.preDelay * ONE_IN_Q27 ); + + for ( m = 0; m < pOut->nBands; m++ ) + { + pOut->pFc_input_fx[m] = (Word32) ( pIn.pFG->pFc[m] * ONE_IN_Q16 ); + pOut->pAcoustic_rt60_fx[m] = (Word32) ( pIn.pRT60[m] * ONE_IN_Q26 ); + pOut->pAcoustic_dsr_fx[m] = (Word32) ( pIn.pDSR[m] * ONE_IN_Q30 ); + } + + /* 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; + pOut->dimensions.x_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x * ONE_IN_Q22 ); + pOut->dimensions.y_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.y * ONE_IN_Q22 ); + pOut->dimensions.z_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.z * ONE_IN_Q22 ); + + /* Use default listener origin position if non provided */ + if ( pIn.pEarlyReflections->pListenerOrigin == NULL ) + { + + pOut->ListenerOrigin.x_fx = IVAS_ER_LIST_ORIGIN_X_FX; + pOut->ListenerOrigin.y_fx = IVAS_ER_LIST_ORIGIN_Y_FX; + pOut->ListenerOrigin.z_fx = IVAS_ER_LIST_HEIGHT_FX; + pOut->ListenerOrigin.q_fact = Q22; + } + else + { + pOut->ListenerOrigin.x_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x_fx; + pOut->ListenerOrigin.y_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y_fx; + pOut->ListenerOrigin.z_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z_fx; + } + + for ( j = 0; j < IVAS_ROOM_ABS_COEFF; j++ ) + { + pOut->AbsCoeff_fx[j] = (Word32) ( pIn.pEarlyReflections->pAbsCoeff[j] * ONE_IN_Q30 ); + } + } + else + { + pOut->use_er = false; + } + } + + return IVAS_ERR_OK; +} +#endif + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getAcousticEnvironment() + * + * Gets Acoustic environment with a given ID + *------------------------------------------------------------------------------------------*/ + +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 */ +) +{ + uint16_t n, m; + uint16_t j; + + if ( pRenderConfigReader == NULL || pAcEnv == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* case when -aeid is not specified, select first ID from config file */ +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + if ( id == (UWord16) IVAS_DEFAULT_AEID && pRenderConfigReader->nAE > 0 ) +#else + if ( id == 65535 && pRenderConfigReader->nAE > 0 ) +#endif + { + id = (uint16_t) pRenderConfigReader->pAE[0].id; + } + + for ( n = 0; n < pRenderConfigReader->nAE; n++ ) + { + if ( id == pRenderConfigReader->pAE[n].id ) + { + pAcEnv->nBands = (int16_t) pRenderConfigReader->pAE[n].pFG->nrBands; + pAcEnv->inputPreDelay_fx = (Word32) ( pRenderConfigReader->pAE[n].preDelay * ONE_IN_Q27 ); + if ( pRenderConfigReader->pAE[n].preDelay > INPUTPREDELAY_MAX || + pRenderConfigReader->pAE[n].preDelay < INPUTPREDELAY_MIN ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + for ( m = 0; m < pAcEnv->nBands; m++ ) + { + if ( pRenderConfigReader->pAE[n].pFG->pFc[m] > FC_INPUT_MAX || + pRenderConfigReader->pAE[n].pFG->pFc[m] < FC_INPUT_MIN || + pRenderConfigReader->pAE[n].pRT60[m] > ACOUSTIC_RT60_MAX || + pRenderConfigReader->pAE[n].pRT60[m] < ACOUSTIC_RT60_MIN || + pRenderConfigReader->pAE[n].pDSR[m] > ACOUSTIC_DSR_MAX || + pRenderConfigReader->pAE[n].pDSR[m] < ACOUSTIC_DSR_MIN ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + pAcEnv->pFc_input_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pFG->pFc[m] * ONE_IN_Q16 ); + pAcEnv->pAcoustic_rt60_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pRT60[m] * ONE_IN_Q26 ); + pAcEnv->pAcoustic_dsr_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pDSR[m] * ONE_IN_Q30 ); + } + + /* If ER are allocated then propagate parameters */ + if ( pRenderConfigReader->pAE[n].pEarlyReflections != 0 ) + { + pAcEnv->use_er = pRenderConfigReader->pAE[n].pEarlyReflections->use_er; /* ER activation flag */ + pAcEnv->lowComplexity = pRenderConfigReader->pAE[n].pEarlyReflections->lowComplexity; /* Low complexity flag */ + pAcEnv->dimensions = pRenderConfigReader->pAE[n].pEarlyReflections->dimensions; + pAcEnv->dimensions.x_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x * ONE_IN_Q22 ); + pAcEnv->dimensions.y_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.y * ONE_IN_Q22 ); + pAcEnv->dimensions.z_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.z * ONE_IN_Q22 ); + /* Use default listener origin position if non provided */ + if ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin == NULL ) + { + if ( ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x = IVAS_ER_LIST_ORIGIN_X; + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y = IVAS_ER_LIST_ORIGIN_Y; + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z = IVAS_ER_LIST_HEIGHT; + + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x_fx = IVAS_ER_LIST_ORIGIN_X_FX; + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y_fx = IVAS_ER_LIST_ORIGIN_Y_FX; + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z_fx = IVAS_ER_LIST_HEIGHT_FX; + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->q_fact = Q22; + } + else + { + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x * ONE_IN_Q22 ); + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y * ONE_IN_Q22 ); + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z * ONE_IN_Q22 ); + } + pAcEnv->ListenerOrigin = *pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin; + for ( j = 0; j < IVAS_ROOM_ABS_COEFF; j++ ) + { + pAcEnv->AbsCoeff[j] = pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[j]; + pAcEnv->AbsCoeff_fx[j] = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[j] * ONE_IN_Q30 ); + } + } + else + { + pAcEnv->use_er = false; + } + return IVAS_ERR_OK; + } + } + return IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING; +} + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getDirectivity() + * + * Gets Directivity DirectrivityPatern with a given ID + *------------------------------------------------------------------------------------------*/ + +ivas_error RenderConfigReader_getDirectivity( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + uint16_t *id, /* i : Directivity pattern ID */ + Word16 *directivity_fx /* o : Target directivity */ +) +{ + uint16_t n, m, i; + uint16_t last_specified_id; + bool idExists; + float directivity[12]; + + if ( pRenderConfigReader == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( pRenderConfigReader->pDP == NULL ) + { + for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) + { + directivity[n * 3] = 360.0f; + directivity[n * 3 + 1] = 360.0f; + directivity[n * 3 + 2] = 1.0f; + } + } + else + { + last_specified_id = id[0]; + + /* set unpspecified Directivity Patterns ID to last specified ID */ + for ( n = MAX_NUM_OBJECTS - 1; n > 0; n-- ) + { + if ( id[n] != 65535 ) + { + last_specified_id = id[n]; + break; + } + } + /* case when -dpid is not specified, select first directivity pattern from config file */ + move16(); + if ( last_specified_id == 65535 ) + { + last_specified_id = (uint16_t) pRenderConfigReader->pDP[0].id; + } + + for ( ; n < IVAS_MAX_NUM_OBJECTS; n++ ) + { + id[n] = last_specified_id; + } + + for ( n = 0; n < IVAS_MAX_NUM_OBJECTS; n++ ) + { + idExists = false; + for ( m = 0; m < pRenderConfigReader->nDP; m++ ) + { + if ( id[n] == pRenderConfigReader->pDP[m].id ) + { + idExists = true; + for ( i = 0; i < 3; i++ ) + { + directivity[n * 3 + i] = pRenderConfigReader->pDP[m].pDirectivity[i]; + } + + break; + } + } + if ( !idExists ) + { + return IVAS_ERR_DIRECTIVITY_PATTERN_ID_MISSING; + } + } + } + + /* Convert to Word16 */ + FOR( n = 0; n < 4; n++ ) + { + directivity_fx[n * 3] = (Word16) ( directivity[n * 3] * ( 1u << 6 ) ); + directivity_fx[n * 3 + 1] = (Word16) ( directivity[n * 3 + 1] * ( 1u << 6 ) ); + directivity_fx[n * 3 + 2] = (Word16) ( directivity[n * 3 + 2] * ( ( 1u << 15 ) - 1 ) ); + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getDistanceAttenuation() + * + * Gets Distance Attenuation + *------------------------------------------------------------------------------------------*/ + +ivas_error RenderConfigReader_getDistanceAttenuation( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + + Word32 *distAtt_fx /* o : Distance attenuation */ +) +{ + float distAtt[3]; + + if ( pRenderConfigReader->distAtt[0] == -1 ) + { + distAtt[0] = 15.75f; + distAtt[1] = 1.0f; + distAtt[2] = 1.0f; + } + else + { + distAtt[0] = pRenderConfigReader->distAtt[0]; + distAtt[1] = pRenderConfigReader->distAtt[1]; + distAtt[2] = pRenderConfigReader->distAtt[2]; + } + + /* Convert to Word32 */ + distAtt_fx[0] = (Word32) ( distAtt[0] * ( 1u << 27 ) ); + distAtt_fx[1] = (Word32) ( distAtt[1] * ( 1u << 30 ) ); + distAtt_fx[2] = (Word32) ( distAtt[2] * ( 1u << 30 ) ); + + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_close() + * + * Closes the renderer configuration reader and deallocates memory + *------------------------------------------------------------------------------------------*/ + +void RenderConfigReader_close( + RenderConfigReader **ppRenderConfigReader /* i : RenderConfigReader handle */ +) +{ + uint32_t n; + + if ( ppRenderConfigReader == NULL || *ppRenderConfigReader == NULL ) + { + return; + } + + /* Free the acoustic environments */ + for ( n = 0; n < ( *ppRenderConfigReader )->nAE; n++ ) + { + if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections != NULL ) + { + free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin ); + free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections ); + } + free( ( *ppRenderConfigReader )->pAE[n].pRT60 ); + free( ( *ppRenderConfigReader )->pAE[n].pDSR ); + } + free( ( *ppRenderConfigReader )->pAE ); + + /* Free the frequency grids */ + for ( n = 0; n < ( *ppRenderConfigReader )->nFG; n++ ) + { + free( ( *ppRenderConfigReader )->pFG[n].pFc ); + } + free( ( *ppRenderConfigReader )->pFG ); + /* Free the directivity patterns */ + for ( n = 0; n < ( *ppRenderConfigReader )->nDP; n++ ) + { + free( ( *ppRenderConfigReader )->pDP[n].pDirectivity ); + } + free( ( *ppRenderConfigReader )->pDP ); + fclose( ( *ppRenderConfigReader )->pConfigFile ); + free( *ppRenderConfigReader ); + + return; +} diff --git a/lib_dec/ivas_init_dec_fx.c b/lib_dec/ivas_init_dec_fx.c index 9f9e222c5..784ef1e20 100644 --- a/lib_dec/ivas_init_dec_fx.c +++ b/lib_dec/ivas_init_dec_fx.c @@ -3225,11 +3225,6 @@ void ivas_initialize_handles_dec( st_ivas->p_output_fx[i] = NULL; } -#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - /* Acoustic environments */ - st_ivas->pAcousticEnvironments = NULL; -#endif - return; } @@ -3468,6 +3463,16 @@ void ivas_destroy_dec_fx( #endif } +#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT + /* Acoustic environments */ + IF( st_ivas->pAcousticEnvironments != NULL ) + { + free( st_ivas->pAcousticEnvironments ); + st_ivas->pAcousticEnvironments = NULL; + } +#endif + + /* main IVAS handle */ free( st_ivas ); diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 0aa342bf6..a212c79b7 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2896,6 +2896,11 @@ ivas_error RenderConfigReader_getAcousticEnvironments( pOut->aeID = (Word16) pIn.id; pOut->nBands = (Word16) pIn.pFG->nrBands; + if ( pRenderConfigReader->pAE[n].preDelay > INPUTPREDELAY_MAX || + pRenderConfigReader->pAE[n].preDelay < INPUTPREDELAY_MIN ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } pOut->inputPreDelay_fx = (Word32) ( pIn.preDelay * ONE_IN_Q27 ); for ( m = 0; m < pOut->nBands; m++ ) @@ -2918,6 +2923,9 @@ ivas_error RenderConfigReader_getAcousticEnvironments( /* Use default listener origin position if non provided */ if ( pIn.pEarlyReflections->pListenerOrigin == NULL ) { + pOut->ListenerOrigin.x = IVAS_ER_LIST_ORIGIN_X; + pOut->ListenerOrigin.y = IVAS_ER_LIST_ORIGIN_Y; + pOut->ListenerOrigin.z = IVAS_ER_LIST_HEIGHT; pOut->ListenerOrigin.x_fx = IVAS_ER_LIST_ORIGIN_X_FX; pOut->ListenerOrigin.y_fx = IVAS_ER_LIST_ORIGIN_Y_FX; @@ -2926,6 +2934,10 @@ ivas_error RenderConfigReader_getAcousticEnvironments( } else { + pOut->ListenerOrigin.x = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x; + pOut->ListenerOrigin.y = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y; + pOut->ListenerOrigin.z = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z; + pOut->ListenerOrigin.x_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x_fx; pOut->ListenerOrigin.y_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y_fx; pOut->ListenerOrigin.z_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z_fx; @@ -2933,6 +2945,7 @@ ivas_error RenderConfigReader_getAcousticEnvironments( for ( j = 0; j < IVAS_ROOM_ABS_COEFF; j++ ) { + pOut->AbsCoeff[j] = (Word32) ( pIn.pEarlyReflections->pAbsCoeff[j] ); pOut->AbsCoeff_fx[j] = (Word32) ( pIn.pEarlyReflections->pAbsCoeff[j] * ONE_IN_Q30 ); } } -- GitLab From 8064809300c6beb572be02a7092861a4010cde11 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 10 Nov 2025 20:09:48 +0100 Subject: [PATCH 11/14] Fixed absorption coeff assignment --- .../render_config_reader.c | 3226 ----------------- lib_util/render_config_reader.c | 2 +- 2 files changed, 1 insertion(+), 3227 deletions(-) delete mode 100644 Workspace_msvc/enc_temp_folder/b685e51a257c31d9ba90c87bcc18d2c/render_config_reader.c diff --git a/Workspace_msvc/enc_temp_folder/b685e51a257c31d9ba90c87bcc18d2c/render_config_reader.c b/Workspace_msvc/enc_temp_folder/b685e51a257c31d9ba90c87bcc18d2c/render_config_reader.c deleted file mode 100644 index 0aa342bf6..000000000 --- a/Workspace_msvc/enc_temp_folder/b685e51a257c31d9ba90c87bcc18d2c/render_config_reader.c +++ /dev/null @@ -1,3226 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include "render_config_reader.h" -#include -#include -#include -#include -#include -#include "cmdl_tools.h" -#include "prot_fx.h" -#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT -#include "ivas_cnst.h" -#endif - -/*------------------------------------------------------------------------------------------* - * PreProc Local Macros - *------------------------------------------------------------------------------------------*/ - -#define MAX_ITEM_LENGTH ( 64 ) -#define N_ABS_COEFFS ( 6 ) - -#define SHORTEST_REV_DEL_LINE ( 0.015f ) -#define N_BANDS_MIN ( 2 ) -#define N_BANDS_MAX ( 60 ) -#define FC_INPUT_MIN ( 0.0f ) -#define FC_INPUT_MAX ( 1.0e+5f ) -#define ACOUSTIC_RT60_MIN ( 1.0e-3f ) -#define ACOUSTIC_RT60_MAX ( 1.0e+2f ) -#define ACOUSTIC_DSR_MIN ( 0.0f ) -#define ACOUSTIC_DSR_MAX ( 1.0e+2f ) -#define ACOUSTIC_DSR_EPSILON ( 1.0e-15f ) -#define ACOUSTIC_DSR_EPSILON_FX ( 1 ) -#define ACOUSTICPREDELAY_JOTREV_MIN ( SHORTEST_REV_DEL_LINE ) -#define ACOUSTICPREDELAY_JOTREV_MAX ( SHORTEST_REV_DEL_LINE + 1.0f / (float) IVAS_NUM_FRAMES_PER_SEC ) -#define ACOUSTICPREDELAY_FDREV_MIN ( 1.0f / (float) ( 16 * IVAS_NUM_FRAMES_PER_SEC ) ) -#define ACOUSTICPREDELAY_FDREV_MAX ( (float) ( IVAS_REVERB_PREDELAY_MAX ) / (float) ( 16 * IVAS_NUM_FRAMES_PER_SEC ) ) -#define INPUTPREDELAY_MIN ( 0.0f ) -#define INPUTPREDELAY_MAX ( 1.0e+2f ) - -#define ER_MIN_ROOM_DIMENSION ( 1.0f ) -#define ER_MIN_ROOM_DIMENSION_FX ( 4194304 ) -#define ER_MAX_ROOM_DIMENSION ( 999.0f ) -#define ER_MAX_ROOM_DIMENSION_FX ( 2095054848 ) -#define ER_MIN_ABS_COEFF ( 0.0f ) -#define ER_MIN_ABS_COEFF_FX ( 0 ) -#define ER_MAX_ABS_COEFF ( 1.0f ) -#define ER_MAX_ABS_COEFF_FX ( 1073741824 ) - -#define IVAS_ER_LIST_ORIGIN_X 0.0f -#define IVAS_ER_LIST_ORIGIN_Y 0.0f -#define IVAS_ER_LIST_ORIGIN_X_FX 0 -#define IVAS_ER_LIST_ORIGIN_Y_FX 0 - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef min -#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) -#endif - -#ifndef max -#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) -#endif - - -/*------------------------------------------------------------------------------------------* - * Local Type definitions - *------------------------------------------------------------------------------------------*/ - -typedef struct -{ - uint32_t nrBands; /* Number of frequency bands */ - float *pFc; /* Center frequencies */ -} FrequencyGrid; - -typedef enum _FREQ_GRID_MODE -{ - FREQ_GRID_MODE_UNKNOWN = -1, - FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES = 0, - FREQ_GRID_MODE_START_HOP_AMOUNT = 1, - FREQ_GRID_MODE_DEFAULT_BANDING = 2 -} FREQ_GRID_MODE; - -typedef struct -{ - uint16_t use_er; /* Activation Flag */ - IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ - float pAbsCoeff[N_ABS_COEFFS]; /* Absorption coeffs table */ - IVAS_VECTOR3 *pListenerOrigin; /* Listener origin */ - uint32_t lowComplexity; /* Low complexity mode flag */ -} EarlyReflectionsConfig; - -typedef struct -{ - uint32_t id; /* Acoustic environment ID */ - FrequencyGrid *pFG; /* Pointer into Frequency grids table for late reverb coeffs */ - float *pRT60; /* RT60 table */ - float *pDSR; /* DSR table */ - float preDelay; /* Pre-delay */ - EarlyReflectionsConfig *pEarlyReflections; /* Early reflections configuration */ -} AcousticEnv; - -typedef struct -{ - uint32_t id; /* Pattern ID */ - float *pDirectivity; /* Source directivity */ -} DirectrivityPat; - -struct RenderConfigReader -{ - FILE *pConfigFile; - uint8_t *pBitstream; /* Renderer config bitstream */ - size_t length; /* Bitstream length */ - size_t readOffset; /* Bitstream read offset */ - uint32_t nFG; /* Number of frequency grids */ - FrequencyGrid *pFG; /* Frequency grids */ - uint32_t nAE; /* Number of acoustic environments */ - AcousticEnv *pAE; /* Acoustic environments */ - uint32_t nDP; /* Number of directivity patterns */ - DirectrivityPat *pDP; /* Directivity Pattern */ - float distAtt[3]; /* [MaxDist Q30, RefDist Q30, Rolloff Q30] */ -}; - - -typedef enum _RC_LUT -{ - RC_LUT_INVALID = 0x00, - RC_LUT_COUNT_IDX_LO, - RC_LUT_COUNT_IDX_HI, - RC_LUT_DECI_SEC, - RC_LUT_SEC, - RC_LUT_MILLI_SEC, - RC_LUT_MICRO_SEC, - RC_LUT_FREQ, - RC_LUT_FREQ_HOP, - RC_LUT_DSR, - RC_LUT_METERS, - RC_LUT_HECTOMETERS, - RC_LUT_KILOMETERS, - RC_LUT_CENTIMETERS, - RC_LUT_ABSORPTION -} RC_LUT; - -/*------------------------------------------------------------------------------------------* - * Lookup tables - *------------------------------------------------------------------------------------------*/ - -const float lutCountIdxLo_Value[] = { - 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, - 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, 30.0f, 31.0f, - 32.0f, 33.0f, 34.0f, 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, 40.0f, 41.0f, 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, - 48.0f, 49.0f, 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, 56.0f, 57.0f, 58.0f, 59.0f, 60.0f, 61.0f, 62.0f, 63.0f -}; -const uint16_t lutCountIdxLo_Code[] = { - 7, 4, 12, 13, 10, 11, 8, 9, 15, 14, 13, 12, 11, 10, 9, 8, - 7, 6, 5, 4, 3, 2, 1, 0, 63, 62, 61, 60, 59, 58, 57, 56, - 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, - 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80 -}; -const uint8_t lutCountIdxLo_Len[] = { - 4, 3, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -}; - -const float lutCountIdxHi_Value[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f }; -const uint16_t lutCountIdxHi_Code[] = { 1, 0, 6, 5, 4, 7, 5, 15, 14, 13, 9, 8, 25, 49, 48 }; -const uint8_t lutCountIdxHi_Len[] = { 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 7, 7 }; - -const float lutDeciSec_Value[] = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f }; -const uint16_t lutDeciSec_Code[] = { 6, 4, 5, 6, 7, 7, 4, 5, 2, 3, 0 }; -const uint8_t lutDeciSec_Len[] = { 3, 3, 3, 4, 4, 3, 4, 4, 4, 4, 3 }; - -const float lutSec_Value[] = { - 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, - 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, - 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, 30.0f -}; -const uint16_t lutSec_Code[] = { 3, 1, 0, 15, 13, 12, 11, 9, 8, 14, 13, 12, 11, 9, 8, 5, 29, 28, 21, 31, 30, 21, 9, 8, 41, 41, 40, 81, 161, 160 }; -const uint8_t lutSec_Len[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 8, 8 }; - -const float lutMilliSec_Value[] = { - 0.00f, 0.001f, 0.002f, 0.003f, 0.004f, 0.005f, 0.006f, 0.007f, 0.008f, 0.009f, - 0.01f, 0.011f, 0.012f, 0.013f, 0.014f, 0.015f, 0.016f, 0.017f, 0.018f, 0.019f, - 0.02f, 0.021f, 0.022f, 0.023f, 0.024f, 0.025f, 0.026f, 0.027f, 0.028f, 0.029f, - 0.03f, 0.031f, 0.032f, 0.033f, 0.034f, 0.035f, 0.036f, 0.037f, 0.038f, 0.039f, - 0.04f, 0.041f, 0.042f, 0.043f, 0.044f, 0.045f, 0.046f, 0.047f, 0.048f, 0.049f, - 0.05f, 0.051f, 0.052f, 0.053f, 0.054f, 0.055f, 0.056f, 0.057f, 0.058f, 0.059f, - 0.06f, 0.061f, 0.062f, 0.063f, 0.064f, 0.065f, 0.066f, 0.067f, 0.068f, 0.069f, - 0.07f, 0.071f, 0.072f, 0.073f, 0.074f, 0.075f, 0.076f, 0.077f, 0.078f, 0.079f, - 0.08f, 0.081f, 0.082f, 0.083f, 0.084f, 0.085f, 0.086f, 0.087f, 0.088f, 0.089f, - 0.09f, 0.091f, 0.092f, 0.093f, 0.094f, 0.095f, 0.096f, 0.097f, 0.098f, 0.099f -}; -const uint16_t lutMilliSec_Code[] = { - 122, 123, 120, 121, 126, 127, 124, 125, 114, 115, 25, 112, 113, 118, 119, 116, 117, 42, 43, 40, - 18, 41, 46, 47, 44, 45, 34, 35, 32, 33, 19, 38, 39, 36, 37, 58, 59, 56, 57, 62, - 16, 63, 60, 61, 50, 51, 48, 49, 54, 55, 17, 52, 53, 10, 11, 8, 9, 14, 15, 12, - 22, 13, 2, 3, 0, 1, 6, 7, 4, 5, 23, 26, 27, 24, 25, 30, 31, 28, 29, 18, - 20, 19, 16, 17, 22, 23, 20, 21, 106, 107, 21, 104, 105, 110, 111, 108, 109, 98, 99, 48 -}; -const uint8_t lutMilliSec_Len[] = { - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 6 -}; - -const float lutMicroSec_Value[] = { - 0.00001f, 0.00002f, 0.00003f, 0.00004f, 0.00005f, 0.00006f, 0.00007f, 0.00008f, 0.00009f, 0.0001f, - 0.00011f, 0.00012f, 0.00013f, 0.00014f, 0.00015f, 0.00016f, 0.00017f, 0.00018f, 0.00019f, 0.0002f, - 0.00021f, 0.00022f, 0.00023f, 0.00024f, 0.00025f, 0.00026f, 0.00027f, 0.00028f, 0.00029f, 0.0003f, - 0.00031f, 0.00032f, 0.00033f, 0.00034f, 0.00035f, 0.00036f, 0.00037f, 0.00038f, 0.00039f, 0.0004f, - 0.00041f, 0.00042f, 0.00043f, 0.00044f, 0.00045f, 0.00046f, 0.00047f, 0.00048f, 0.00049f, 0.0005f, - 0.00051f, 0.00052f, 0.00053f, 0.00054f, 0.00055f, 0.00056f, 0.00057f, 0.00058f, 0.00059f, 0.0006f, - 0.00061f, 0.00062f, 0.00063f, 0.00064f, 0.00065f, 0.00066f, 0.00067f, 0.00068f, 0.00069f, 0.0007f, - 0.00071f, 0.00072f, 0.00073f, 0.00074f, 0.00075f, 0.00076f, 0.00077f, 0.00078f, 0.00079f, 0.0008f, - 0.00081f, 0.00082f, 0.00083f, 0.00084f, 0.00085f, 0.00086f, 0.00087f, 0.00088f, 0.00089f, 0.0009f, - 0.00091f, 0.00092f, 0.00093f, 0.00094f, 0.00095f, 0.00096f, 0.00097f, 0.00098f, 0.00099f -}; -const uint16_t lutMicroSec_Code[] = { - 444, 18, 445, 19, 894, 16, 895, 17, 892, 22, 893, 23, 434, 20, 435, 21, 432, 10, 433, 11, - 438, 8, 439, 9, 436, 14, 437, 15, 410, 12, 411, 13, 408, 2, 409, 3, 414, 0, 415, 1, - 412, 6, 413, 7, 402, 4, 403, 5, 400, 26, 401, 27, 406, 24, 407, 25, 404, 30, 405, 31, - 426, 28, 427, 29, 424, 18, 425, 19, 430, 16, 431, 17, 428, 22, 429, 23, 418, 20, 419, 21, - 416, 58, 417, 59, 422, 56, 423, 57, 420, 62, 421, 63, 442, 60, 443, 61, 440, 24, 441 -}; -const uint8_t lutMicroSec_Len[] = { - 9, 5, 9, 5, 10, 5, 10, 5, 10, 5, 10, 5, 9, 5, 9, 5, 9, 6, 9, 6, - 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, - 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, - 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, - 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 5, 9 -}; - -const float lutFreq_Value[] = { - 16.0f, 20.0f, 25.0f, 31.5f, 40.0f, 50.0f, 63.0f, 80.0f, 100.0f, 125.0f, - 160.0f, 200.0f, 250.0f, 315.0f, 400.0f, 500.0f, 630.0f, 800.0f, 1000.0f, 1250.0f, - 1600.0f, 2000.0f, 2500.0f, 3150.0f, 4000.0f, 5000.0f, 6300.0f, 8000.0f, 10000.0f, 12500.0f, - 16000.0f, 20000.0f, 25000.0f, 31500.0f, 40000.0f -}; -const uint16_t lutFreq_Code[] = { 35, 14, 15, 9, 12, 13, 0, 26, 27, 1, 24, 25, 14, 30, 31, 15, 28, 29, 12, 18, 19, 13, 16, 17, 10, 22, 23, 11, 20, 21, 2, 16, 138, 139, 68 }; -const uint8_t lutFreq_Len[] = { 6, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 5, 8, 8, 7 }; - -const float lutFreqHop_Value[] = { 1.059463094f, 1.122462048f, 1.189207115f, 1.259921050f, 1.414213562f, 2.0f, 4.0f }; -const uint16_t lutFreqHop_Code[] = { 2, 3, 0, 1, 1, 3, 2 }; -const uint8_t lutFreqHop_Len[] = { 4, 4, 4, 2, 4, 2, 2 }; - -const float lutDsr_Value[] = { - -150.0f, -149.0f, -148.0f, -147.0f, -146.0f, -145.0f, -144.0f, -143.0f, -142.0f, -141.0f, - -140.0f, -139.0f, -138.0f, -137.0f, -136.0f, -135.0f, -134.0f, -133.0f, -132.0f, -131.0f, - -130.0f, -129.0f, -128.0f, -127.0f, -126.0f, -125.0f, -124.0f, -123.0f, -122.0f, -121.0f, - -120.0f, -119.0f, -118.0f, -117.0f, -116.0f, -115.0f, -114.0f, -113.0f, -112.0f, -111.0f, - -110.0f, -109.0f, -108.0f, -107.0f, -106.0f, -105.0f, -104.0f, -103.0f, -102.0f, -101.0f, - -100.0f, -99.0f, -98.0f, -97.0f, -96.0f, -95.0f, -94.0f, -93.0f, -92.0f, -91.0f, - -90.0f, -89.0f, -88.0f, -87.0f, -86.0f, -85.0f, -84.0f, -83.0f, -82.0f, -81.0f, - -80.0f, -79.0f, -78.0f, -77.0f, -76.0f, -75.0f, -74.0f, -73.0f, -72.0f, -71.0f, - -70.0f, -69.0f, -68.0f, -67.0f, -66.0f, -65.0f, -64.0f, -63.0f, -62.0f, -61.0f, - -60.0f, -59.0f, -58.0f, -57.0f, -56.0f, -55.0f, -54.0f, -53.0f, -52.0f, -51.0f, - -50.0f, -49.0f, -48.0f, -47.0f, -46.0f, -45.0f, -44.0f, -43.0f, -42.0f, -41.0f, - -40.0f, -39.0f, -38.0f, -37.0f, -36.0f, -35.0f, -34.0f, -33.0f, -32.0f, -31.0f, - -30.0f, -29.0f, -28.0f, -27.0f, -26.0f, -25.0f, -24.0f, -23.0f, -22.0f, -21.0f, - -20.0f, -19.0f, -18.0f, -17.0f, -16.0f, -15.0f, -14.0f, -13.0f, -12.0f, -11.0f, - -10.0f -}; -const uint16_t lutDsr_Code[] = { - 140, 141, 286, 287, 284, 285, 130, 131, 128, 129, 134, 135, 132, 133, 234, 235, 232, 233, 238, 239, - 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 251, 248, 249, 254, 255, 252, 253, 242, 243, - 240, 241, 246, 247, 244, 245, 202, 203, 200, 201, 206, 207, 204, 205, 194, 195, 192, 193, 198, 199, - 196, 197, 218, 219, 216, 217, 222, 223, 220, 221, 20, 21, 38, 39, 36, 37, 58, 59, 56, 57, - 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53, 10, 11, 8, 9, 14, 15, 12, 13, - 2, 3, 0, 1, 6, 7, 4, 5, 42, 43, 40, 41, 46, 47, 44, 45, 18, 19, 16, 17, - 22, 210, 211, 208, 209, 214, 215, 212, 213, 186, 187, 184, 185, 190, 191, 188, 189, 138, 139, 136, - 137 -}; -const uint8_t lutDsr_Len[] = { - 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, - 8 -}; - -const float lutMeters_Value[] = { - 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, - 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, - 20.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, - 30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, - 40.0f, 41.0f, 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, 48.0f, 49.0f, - 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, 56.0f, 57.0f, 58.0f, 59.0f, - 60.0f, 61.0f, 62.0f, 63.0f, 64.0f, 65.0f, 66.0f, 67.0f, 68.0f, 69.0f, - 70.0f, 71.0f, 72.0f, 73.0f, 74.0f, 75.0f, 76.0f, 77.0f, 78.0f, 79.0f, - 80.0f, 81.0f, 82.0f, 83.0f, 84.0f, 85.0f, 86.0f, 87.0f, 88.0f, 89.0f, - 90.0f, 91.0f, 92.0f, 93.0f, 94.0f, 95.0f, 96.0f, 97.0f, 98.0f, 99.0f -}; - -const uint16_t lutMeters_Code[] = { - 61, 50, 51, 48, 49, 54, 55, 52, 53, 10, - 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, - 1, 6, 7, 4, 5, 26, 27, 24, 25, 30, - 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, - 21, 42, 43, 40, 41, 46, 47, 44, 45, 16, - 68, 69, 142, 143, 140, 141, 154, 155, 152, 153, - 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, - 148, 149, 234, 235, 232, 233, 238, 239, 236, 237, - 226, 227, 224, 225, 230, 231, 228, 229, 250, 251, - 248, 249, 254, 255, 252, 253, 242, 243, 240, 241 -}; - -const uint8_t lutMeters_Len[] = { - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, - 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 -}; - -const float lutHectometers_Value[] = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f }; -const uint16_t lutHectometers_Code[] = { 0, 1, 6, 7, 4, 5, 6, 7, 4, 5 }; -const uint8_t lutHectometers_Len[] = { 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 }; - -const float lutKilometers_Value[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f }; -const uint16_t lutKilometers_Code[] = { 2, 3, 1, 0, 7, 5, 4, 13, 25, 24 }; -const uint8_t lutKilometers_Len[] = { 2, 3, 3, 3, 3, 4, 4, 4, 5, 5 }; - -const float lutCentimeters_Value[] = { - 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, - 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, - 20.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, - 30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, - 40.0f, 41.0f, 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, 48.0f, 49.0f, - 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, 56.0f, 57.0f, 58.0f, 59.0f, - 60.0f, 61.0f, 62.0f, 63.0f, 64.0f, 65.0f, 66.0f, 67.0f, 68.0f, 69.0f, - 70.0f, 71.0f, 72.0f, 73.0f, 74.0f, 75.0f, 76.0f, 77.0f, 78.0f, 79.0f, - 80.0f, 81.0f, 82.0f, 83.0f, 84.0f, 85.0f, 86.0f, 87.0f, 88.0f, 89.0f, - 90.0f, 91.0f, 92.0f, 93.0f, 94.0f, 95.0f, 96.0f, 97.0f, 98.0f, 99.0f -}; - -const uint16_t lutCentimeters_Code[] = { - 50, 51, 48, 49, 54, 55, 52, 53, 42, 43, - 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, - 38, 39, 36, 37, 58, 59, 56, 57, 62, 63, - 60, 61, 50, 51, 48, 49, 54, 55, 52, 53, - 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, - 0, 1, 6, 7, 4, 5, 26, 27, 24, 25, - 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, - 20, 21, 42, 43, 40, 41, 46, 47, 44, 45, - 34, 35, 32, 33, 38, 39, 36, 37, 122, 123, - 120, 121, 126, 127, 124, 125, 58, 59, 56, 57 -}; - -const uint8_t lutCentimeters_Len[] = { - 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 6, 6, 6, 6 -}; - -const float lutAbsorption_Value[] = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f }; -const uint16_t lutAbsorption_Code[] = { 6, 4, 5, 6, 7, 7, 4, 5, 2, 3, 0 }; -const uint8_t lutAbsorption_Len[] = { 3, 3, 3, 4, 4, 3, 4, 4, 4, 4, 3 }; - -/*------------------------------------------------------------------------------------------* - * Default frequency grids - *------------------------------------------------------------------------------------------*/ - -const float defaultFrequencyGrid_0[] = { 31.5f, 63.0f, 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, 4000.0f, 8000.0f, 16000.0f }; -const float defaultFrequencyGrid_1[] = { 25.0f, 50.0f, 100.0f, 200.0f, 400.0f, 800.0f, 1600.0f, 3150.0f, 6300.0f, 12500.0f }; -const float defaultFrequencyGrid_2[] = { - 20.0f, 25.0f, 31.5f, 40.0f, 50.0f, 63.0f, 80.0f, 100.0f, 125.0f, 160.0f, - 200.0f, 250.0f, 315.0f, 400.0f, 500.0f, 630.0f, 800.0f, 1000.0f, 1250.0f, 1600.0f, - 2000.0f, 2500.0f, 3150.0f, 4000.0f, 5000.0f, 6300.0f, 8000.0f, 10000.0f, 12500.0f, 16000.0f, 20000.0f -}; -const float defaultFrequencyGrid_3[] = { 25.0f, 100.0f, 400.0f, 1600.0f, 6300.0f }; -const float defaultFrequencyGrid_4[] = { 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, 4000.0f }; -const float defaultFrequencyGrid_5[] = { 25.0f, 250.0f, 2500.0f }; -const float defaultFrequencyGrid_6[] = { - 27.0f, 56.0f, 89.0f, 126.0f, 168.0f, 214.0f, 265.0f, 323.0f, 387.0f, 459.0f, - 539.0f, 628.0f, 727.0f, 839.0f, 963.0f, 1101.0f, 1256.0f, 1429.0f, 1621.0f, 1836.0f, - 2077.0f, 2345.0f, 2644.0f, 2978.0f, 3351.0f, 3767.0f, 4232.0f, 4750.0f, 5329.0f, 5975.0f, - 6697.0f, 7502.0f, 8401.0f, 9405.0f, 10525.0f, 11775.0f, 13171.0f, 14729.0f, 16468.0f, 18410.0f, 20577.0f -}; -const float defaultFrequencyGrid_7[] = { - 27.0f, 89.0f, 168.0f, 265.0f, 387.0f, 539.0f, 727.0f, 963.0f, 1256.0f, 1621.0f, - 2077.0f, 2644.0f, 3351.0f, 4232.0f, 5329.0f, 6697.0f, 8401.0f, 10525.0f, 13171.0f, 16468.0f, 20577.0f -}; -const float defaultFrequencyGrid_8[] = { - 50.0f, 150.0f, 250.0f, 350.0f, 450.0f, 570.0f, 700.0f, 840.0f, 1000.0f, 1170.0f, - 1370.0f, 1600.0f, 1850.0f, 2150.0f, 2150.0f, 2500.0f, 2900.0f, 3400.0f, 4000.0f, 4800.0f, - 5800.0f, 7000.0f, 8500.0f, 10500.0f, 13500.0f -}; - - -/*-----------------------------------------------------------------------------------------* - * Function read_bin_bits() - * Reads a given number of bits from the bitstream - *-----------------------------------------------------------------------------------------*/ - -static ivas_error read_bin_bits( - RenderConfigReader *this, /* i/o : Renderer config reader handle */ - uint32_t *pTarget, /* o : Target read data pointer */ - const size_t nBits /* i : Number of bits to read */ -) -{ - uint8_t n; - uint32_t nByte; - uint8_t bit; - - if ( this == NULL || this->pBitstream == NULL || pTarget == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - if ( this->readOffset + nBits > this->length * 8 ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - *pTarget = 0; - for ( n = 0; n < nBits; n++ ) - { - nByte = (uint32_t) ( ( this->readOffset + n ) >> 3 ); - bit = this->pBitstream[nByte] >> ( 7 - ( ( this->readOffset + n ) % 8 ) ) & 1; - *pTarget = ( *pTarget << 1 ) + bit; - } - - this->readOffset += nBits; - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function read_bin_bool() - * Reads a boolean value from a bitstream - *-----------------------------------------------------------------------------------------*/ - -static ivas_error read_bin_bool( - RenderConfigReader *this, /* i/o : Renderer config reader handle */ - uint32_t *pResult /* o : Target read data pointer */ -) -{ - return read_bin_bits( this, pResult, 1 ); -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_id() - * Reads an ID from a bitstream - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_id( - RenderConfigReader *this, /* i/o : Renderer config reader handle */ - uint32_t *pResult /* o : Target read data pointer */ -) -{ - ivas_error error; - uint32_t id; - uint32_t cont; - - *pResult = 0; - id = 0; - cont = true; - - if ( pResult == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - while ( cont ) - { - if ( ( error = read_bin_bits( this, &id, 7 ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult = ( *pResult << 7 ) | id; - - if ( ( error = read_bin_bool( this, &cont ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function read_bin_code_word() - * Reads a code word from a LUT - *-----------------------------------------------------------------------------------------*/ - -static ivas_error read_bin_code_word( - RenderConfigReader *this, /* i/o : Renderer config reader handle */ - const RC_LUT table, /* i : Table enum */ - float *pResult /* o : Code value */ -) -{ - ivas_error error; - const float *pValues; - const uint16_t *pCodes; - const uint8_t *pLengths; - uint8_t minLen; - uint8_t maxLen; - uint8_t size; - uint8_t n; - uint32_t code; - uint32_t bits; - uint32_t nr_bits; - uint8_t len; - - minLen = 255; - maxLen = 0; - bits = 0; - nr_bits = 0; - code = 0; - - if ( pResult == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - /* Select the right tables */ - switch ( table ) - { - case RC_LUT_COUNT_IDX_LO: - pValues = lutCountIdxLo_Value; - pCodes = lutCountIdxLo_Code; - pLengths = lutCountIdxLo_Len; - size = sizeof lutCountIdxLo_Len / sizeof( uint8_t ); - break; - case RC_LUT_COUNT_IDX_HI: - pValues = lutCountIdxHi_Value; - pCodes = lutCountIdxHi_Code; - pLengths = lutCountIdxHi_Len; - size = sizeof lutCountIdxHi_Len / sizeof( uint8_t ); - break; - case RC_LUT_DECI_SEC: - pValues = lutDeciSec_Value; - pCodes = lutDeciSec_Code; - pLengths = lutDeciSec_Len; - size = sizeof lutDeciSec_Len / sizeof( uint8_t ); - break; - case RC_LUT_SEC: - pValues = lutSec_Value; - pCodes = lutSec_Code; - pLengths = lutSec_Len; - size = sizeof lutSec_Len / sizeof( uint8_t ); - break; - case RC_LUT_MILLI_SEC: - pValues = lutMilliSec_Value; - pCodes = lutMilliSec_Code; - pLengths = lutMilliSec_Len; - size = sizeof lutMilliSec_Len / sizeof( uint8_t ); - break; - case RC_LUT_MICRO_SEC: - pValues = lutMicroSec_Value; - pCodes = lutMicroSec_Code; - pLengths = lutMicroSec_Len; - size = sizeof lutMicroSec_Len / sizeof( uint8_t ); - break; - case RC_LUT_FREQ: - pValues = lutFreq_Value; - pCodes = lutFreq_Code; - pLengths = lutFreq_Len; - size = sizeof lutFreq_Len / sizeof( uint8_t ); - break; - case RC_LUT_FREQ_HOP: - pValues = lutFreqHop_Value; - pCodes = lutFreqHop_Code; - pLengths = lutFreqHop_Len; - size = sizeof lutFreqHop_Len / sizeof( uint8_t ); - break; - case RC_LUT_DSR: - pValues = lutDsr_Value; - pCodes = lutDsr_Code; - pLengths = lutDsr_Len; - size = sizeof lutDsr_Len / sizeof( uint8_t ); - break; - case RC_LUT_METERS: - pValues = lutMeters_Value; - pCodes = lutMeters_Code; - pLengths = lutMeters_Len; - size = sizeof lutMeters_Len / sizeof( uint8_t ); - break; - case RC_LUT_HECTOMETERS: - pValues = lutHectometers_Value; - pCodes = lutHectometers_Code; - pLengths = lutHectometers_Len; - size = sizeof lutHectometers_Len / sizeof( uint8_t ); - break; - case RC_LUT_KILOMETERS: - pValues = lutKilometers_Value; - pCodes = lutKilometers_Code; - pLengths = lutKilometers_Len; - size = sizeof lutKilometers_Len / sizeof( uint8_t ); - break; - case RC_LUT_CENTIMETERS: - pValues = lutCentimeters_Value; - pCodes = lutCentimeters_Code; - pLengths = lutCentimeters_Len; - size = sizeof lutCentimeters_Len / sizeof( uint8_t ); - break; - case RC_LUT_ABSORPTION: - pValues = lutAbsorption_Value; - pCodes = lutAbsorption_Code; - pLengths = lutAbsorption_Len; - size = sizeof lutAbsorption_Len / sizeof( uint8_t ); - break; - case RC_LUT_INVALID: - default: - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - /* First read minLen bits, then add one bit per iteration to find the correct value */ - for ( n = 0; n < size; n++ ) - { - minLen = min( minLen, pLengths[n] ); - maxLen = max( maxLen, pLengths[n] ); - } - for ( len = minLen; len <= maxLen; len++ ) - { - nr_bits = ( len == minLen ) ? minLen : 1; - if ( ( error = read_bin_bits( this, &bits, nr_bits ) ) != IVAS_ERR_OK ) - { - return error; - } - code = ( code << nr_bits ) | bits; - for ( n = 0; n < size; n++ ) - { - if ( code == pCodes[n] && len == pLengths[n] ) - { - *pResult = pValues[n]; - return IVAS_ERR_OK; - } - } - } - return IVAS_ERR_INVALID_RENDER_CONFIG; -} - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_count_or_index() - * Gets a count or index - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_count_or_index( - RenderConfigReader *this, /* i/o : Renderer config reader handle */ - uint32_t *pResult /* o : Count or index value */ -) -{ - ivas_error error; - float value; - uint32_t isLarge; - - if ( pResult == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - if ( ( error = read_bin_code_word( this, RC_LUT_COUNT_IDX_LO, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult = (uint32_t) value; - - if ( ( error = read_bin_bool( this, &isLarge ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( isLarge ) - { - if ( ( error = read_bin_code_word( this, RC_LUT_COUNT_IDX_HI, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult += (uint32_t) value << 6; - } - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_duration() - * Gets a duration value - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_duration( - RenderConfigReader *this, /* i/o : Renderer config reader handle */ - float *pResult /* o : Duration value */ -) -{ - ivas_error error; - float value; - uint32_t addFlag; - - /* Deciseconds */ - if ( ( error = read_bin_code_word( this, RC_LUT_DECI_SEC, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult = value; - - /* Milliseconds */ - if ( ( error = read_bin_bool( this, &addFlag ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( addFlag ) - { - if ( ( error = read_bin_code_word( this, RC_LUT_MILLI_SEC, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult += value; - - /* Microseconds */ - if ( ( error = read_bin_bool( this, &addFlag ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( addFlag ) - { - if ( ( error = read_bin_code_word( this, RC_LUT_MICRO_SEC, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult += value; - } - } - - /* Seconds */ - if ( ( error = read_bin_bool( this, &addFlag ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( addFlag ) - { - if ( ( error = read_bin_code_word( this, RC_LUT_SEC, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult += value; - } - - /* Correct rounding errors due to multiple additions: */ - *pResult = roundf( *pResult * 100000.0f ) / 100000.0f; - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_frequency() - * Gets a frequency value - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_frequency( - RenderConfigReader *this, /* i/o : Renderer config reader handle */ - float *pResult /* o : Frequency value */ -) -{ - ivas_error error; - uint32_t hiRes; - uint32_t refine; - - hiRes = 0; - refine = 0; - - if ( ( error = read_bin_code_word( this, RC_LUT_FREQ, pResult ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( error = read_bin_bool( this, &hiRes ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( hiRes ) - { - if ( ( error = read_bin_bits( this, &refine, 4 ) ) != IVAS_ERR_OK ) - { - return error; - } - - *pResult *= powf( 2.0f, ( (float) refine + 1.0f ) / 51.0f ); - } - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_dsr() - * Gets a DSR value - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_dsr( - RenderConfigReader *this, /* i/o : Renderer config reader handle */ - float *pResult /* o : DSR value */ -) -{ - ivas_error error; - float value; - - if ( ( error = read_bin_code_word( this, RC_LUT_DSR, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult = powf( 10.0f, value / 10.0f ); - - return IVAS_ERR_OK; -} - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_distance() - * Gets a distance value (in meters) - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_distance( - RenderConfigReader *this, /* i/o : Render config reader handle */ - uint16_t isSmall, /* i : Flag indicating a small distance */ - float *pResult /* o : Distance value */ -) -{ - ivas_error error; - float value; - uint32_t flag; - - if ( ( error = read_bin_code_word( this, RC_LUT_METERS, pResult ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( isSmall == false ) - { - /* addHectometers flag */ - if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( flag == true ) - { - /* Hectometers */ - if ( ( error = read_bin_code_word( this, RC_LUT_HECTOMETERS, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult += value * 100.0f; - - /* addKilometers flag */ - if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) - { - return error; - } - - while ( flag == true ) - { - /* Kilometers */ - if ( ( error = read_bin_code_word( this, RC_LUT_KILOMETERS, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult += value * 1000.0f; - - /* addKilometers flag */ - if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - } - - /* addCentimeters flag */ - if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( flag == true ) - { - /* Centimeters */ - if ( ( error = read_bin_code_word( this, RC_LUT_CENTIMETERS, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult += value * 0.01f; - } - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_absorption() - * Gets an absorption value - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_absorption( - RenderConfigReader *this, /* i/o : Render config reader handle */ - float *pResult /* o : Absorption value */ -) -{ - ivas_error error; - - if ( ( error = read_bin_code_word( this, RC_LUT_ABSORPTION, pResult ) ) != IVAS_ERR_OK ) - { - return error; - } - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function read_txt_bool() - * Reads a boolean value from a line - *-----------------------------------------------------------------------------------------*/ - -static ivas_error read_txt_bool( - const char *pLine, /* i : String to read from */ - uint32_t *pTarget /* o : Output pointer */ -) -{ - char value[8 + 1]; - - if ( sscanf( pLine, "%8s", (char *) &value ) != 1 ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - if ( strcmp( value, "TRUE" ) == 0 ) - { - *pTarget = TRUE; - return IVAS_ERR_OK; - } - if ( strcmp( value, "FALSE" ) == 0 ) - { - *pTarget = FALSE; - return IVAS_ERR_OK; - } - - return IVAS_ERR_INVALID_RENDER_CONFIG; -} - - -/*-------------------------------------------------------------------* - * usdequant_rend_cfg() - * - * Uniform scalar de-quantizer routine - *-------------------------------------------------------------------*/ - -static float usdequant_rend_cfg( - const uint32_t idx, /* i : quantizer index */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta /* i : quantization step */ -) -{ - float g; - - g = idx * delta + qlow; - - return ( g ); -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_angle() - * Gets an angle value in degrees [0,360] - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_angle( - RenderConfigReader *this, /* i/o : Render config reader handle */ - float *pResult /* o : Angle value */ -) -{ - ivas_error error; - uint32_t value; - - if ( ( error = read_bin_bits( this, &value, 5 ) ) != IVAS_ERR_OK ) - { - return error; - } - - *pResult = usdequant_rend_cfg( value, 0.0f, 20.0f ); - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_outer_attenuation () - * Gets an outer attenuation value [3.1623e-05,1.0], or in dB: [-90,0] - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_outer_attenuation( - RenderConfigReader *this, /* i/o : Render config reader handle */ - float *pResult /* o : Attenuation value */ -) -{ - ivas_error error; - uint32_t value; - float logval, att; - - if ( ( error = read_bin_bits( this, &value, 5 ) ) != IVAS_ERR_OK ) - { - return error; - } - - logval = usdequant_rend_cfg( value, -90.0f, 3.0f ); - att = powf( 10, logval / 20.0f ); - - *pResult = att; - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_max_dist () - * Gets a Maximum Distance value [1.0, 64.0] - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_max_dist( - RenderConfigReader *this, /* i/o : Render config reader handle */ - float *pResult /* o : Attenuation value */ -) -{ - ivas_error error; - uint32_t value; - - if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) - { - return error; - } - - *pResult = usdequant_rend_cfg( value, 1.0f, 1.0f ); - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_ref_dist () - * Gets a Reference Distance value [0.1, 6.4] - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_ref_dist( - RenderConfigReader *this, /* i/o : Render config reader handle */ - float *pResult /* o : Attenuation value */ -) -{ - ivas_error error; - uint32_t value; - - if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) - { - return error; - } - - *pResult = usdequant_rend_cfg( value, 0.1f, 0.1f ); - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_bin_rolloff () - * Gets a Rollof Factor [0.0, 4.0] - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_bin_rolloff( - RenderConfigReader *this, /* i/o : Render config reader handle */ - float *pResult /* o : Attenuation value */ -) -{ - ivas_error error; - uint32_t value; - - if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) - { - return error; - } - - *pResult = usdequant_rend_cfg( value, 0.0f, 0.1f ); - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function read_txt_vector() - * - * Reads a vector value from a line - *-----------------------------------------------------------------------------------------*/ - -static int16_t read_txt_vector( - char *pLine, /* i : String to read from */ - const uint32_t length, /* i : Number of expected vector elements */ - float *pTarget /* o : Output vector pointer */ -) -{ - char *tmp; - uint16_t n; - uint16_t count; - - n = (int16_t) sscanf( pLine, "[%s", pLine ); - if ( n == 0 ) - { - return true; - } - - /* Additional comma to make parsing easier */ - pLine[strlen( pLine ) - 1] = ','; - - tmp = pLine; - /* Count # of commas to determine vector length */ - for ( n = 0; tmp[n]; tmp[n] == ',' ? n++ : *tmp++ ) - ; - - count = n; - - tmp = pLine; - - /* Check for maximum vector length */ - if ( n != length ) - { - return true; - } - - for ( n = 0; n < count; n++ ) - { - if ( (int16_t) sscanf( tmp, "%f,", &pTarget[n] ) != 1 ) - { - return true; - } - - tmp = strchr( tmp, ',' ) + 1; - } - - return false; -} - - -/*-----------------------------------------------------------------------------------------* - * Function strip_spaces() - * - * Strips the spaces from a buffer - *-----------------------------------------------------------------------------------------*/ - -static void strip_spaces( - char *pStr /* i : String to read from */ -) -{ - int32_t read_idx = 0, write_idx = 0; - - while ( pStr[read_idx] ) - { - if ( !isspace( (int32_t) pStr[read_idx] ) && !iscntrl( (int32_t) pStr[read_idx] ) ) - { - pStr[write_idx++] = pStr[read_idx]; - } - read_idx++; - } - pStr[write_idx] = '\0'; - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function errorHandler() - * - * Prints error message and exits - *-----------------------------------------------------------------------------------------*/ - -/*! r: error accumulation */ -static int32_t errorHandler( - const char *badStr, /* i : String to complain about */ - const ERROR_CODES_t error ) -{ - static int32_t numErrors = 0; - - switch ( error ) - { - case ERROR_NONE: - break; - case ERROR_ITEM_UNKNOWN: - numErrors++; - fprintf( stderr, "Unknown variable %s in renderer configuration file.\n\n", badStr ); - break; - case ERROR_VALUE_INVALID: - numErrors++; - fprintf( stderr, "Invalid value %s in renderer configuration file.\n\n", badStr ); - break; - default: - numErrors++; - fprintf( stderr, "Unknown error while reading configuration file.\n\n" ); - } - - return numErrors; -} - -/*------------------------------------------------------------------------------------------* - * RenderConfigReader_checkValues() - * - * Verifies if the configuration parameters lie within acceptable limits - *------------------------------------------------------------------------------------------*/ -ivas_error RenderConfigReader_checkValues( - IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ -) -{ - int16_t band_idx, tab_value_err_count; - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pRoom_acoustics; - pRoom_acoustics = &hRenderConfig->roomAcoustics; - tab_value_err_count = 0; - int16_t wall_idx; -#ifndef FIX_1999_TEMPORARY_DISABLE_DIST_ATT_CHECK - int16_t i; -#endif - - /* Verify the number of frequency bands in the config input data */ - if ( ( pRoom_acoustics->nBands > N_BANDS_MAX ) || ( pRoom_acoustics->nBands < N_BANDS_MIN ) ) - { - return IVAS_ERR_WRONG_PARAMS; - } - - /* Verify data per band in the acoustic properties table */ - for ( band_idx = 0; band_idx < pRoom_acoustics->nBands; band_idx++ ) - { - /* Verify if the frequencies are in the ascending order (required for interpolation) */ - if ( band_idx != 0 ) - { - if ( pRoom_acoustics->pFc_input_fx[band_idx] <= pRoom_acoustics->pFc_input_fx[band_idx - 1] ) - { - tab_value_err_count++; - } - } - - /* Replace zero DSR values with very small positive values, to avoid issues with coloration filter design */ - if ( pRoom_acoustics->pAcoustic_dsr_fx[band_idx] == 0 ) - { - pRoom_acoustics->pAcoustic_dsr_fx[band_idx] = ACOUSTIC_DSR_EPSILON_FX; - } - } - - if ( tab_value_err_count != 0 ) - { - return IVAS_ERR_WRONG_PARAMS; - } - - - if ( pRoom_acoustics->use_er == 1 ) - { - /* Room dimensions */ - if ( pRoom_acoustics->dimensions.x < ER_MIN_ROOM_DIMENSION ) - { - pRoom_acoustics->dimensions.x = ER_MIN_ROOM_DIMENSION; - } - if ( pRoom_acoustics->dimensions.x_fx < ER_MIN_ROOM_DIMENSION_FX ) - { - pRoom_acoustics->dimensions.x_fx = ER_MIN_ROOM_DIMENSION_FX; - } - if ( pRoom_acoustics->dimensions.x > ER_MAX_ROOM_DIMENSION ) - { - pRoom_acoustics->dimensions.x = ER_MAX_ROOM_DIMENSION; - } - if ( pRoom_acoustics->dimensions.x_fx > ER_MAX_ROOM_DIMENSION_FX ) - { - pRoom_acoustics->dimensions.x_fx = ER_MAX_ROOM_DIMENSION_FX; - } - if ( pRoom_acoustics->dimensions.y < ER_MIN_ROOM_DIMENSION ) - { - pRoom_acoustics->dimensions.y = ER_MIN_ROOM_DIMENSION; - } - if ( pRoom_acoustics->dimensions.y_fx < ER_MIN_ROOM_DIMENSION_FX ) - { - pRoom_acoustics->dimensions.y_fx = ER_MIN_ROOM_DIMENSION_FX; - } - if ( pRoom_acoustics->dimensions.y > ER_MAX_ROOM_DIMENSION ) - { - pRoom_acoustics->dimensions.y = ER_MAX_ROOM_DIMENSION; - } - if ( pRoom_acoustics->dimensions.y_fx > ER_MAX_ROOM_DIMENSION_FX ) - { - pRoom_acoustics->dimensions.y_fx = ER_MAX_ROOM_DIMENSION_FX; - } - if ( pRoom_acoustics->dimensions.z < ER_MIN_ROOM_DIMENSION ) - { - pRoom_acoustics->dimensions.z = ER_MIN_ROOM_DIMENSION; - } - if ( pRoom_acoustics->dimensions.z_fx < ER_MIN_ROOM_DIMENSION_FX ) - { - pRoom_acoustics->dimensions.z_fx = ER_MIN_ROOM_DIMENSION_FX; - } - if ( pRoom_acoustics->dimensions.z > ER_MAX_ROOM_DIMENSION ) - { - pRoom_acoustics->dimensions.z = ER_MAX_ROOM_DIMENSION; - } - if ( pRoom_acoustics->dimensions.z_fx > ER_MAX_ROOM_DIMENSION_FX ) - { - pRoom_acoustics->dimensions.z_fx = ER_MAX_ROOM_DIMENSION_FX; - } - - /* Abs Coeff */ - for ( wall_idx = 0; wall_idx < IVAS_ROOM_ABS_COEFF; wall_idx++ ) - { - if ( pRoom_acoustics->AbsCoeff[wall_idx] < ER_MIN_ABS_COEFF ) - { - pRoom_acoustics->AbsCoeff[wall_idx] = ER_MIN_ABS_COEFF; - } - if ( pRoom_acoustics->AbsCoeff_fx[wall_idx] < ER_MIN_ABS_COEFF_FX ) - { - pRoom_acoustics->AbsCoeff_fx[wall_idx] = ER_MIN_ABS_COEFF_FX; - } - if ( pRoom_acoustics->AbsCoeff[wall_idx] > ER_MAX_ABS_COEFF ) - { - pRoom_acoustics->AbsCoeff[wall_idx] = ER_MAX_ABS_COEFF; - } - if ( pRoom_acoustics->AbsCoeff_fx[wall_idx] > ER_MAX_ABS_COEFF_FX ) - { - pRoom_acoustics->AbsCoeff_fx[wall_idx] = ER_MAX_ABS_COEFF_FX; - } - } -#ifndef FIX_1999_TEMPORARY_DISABLE_DIST_ATT_CHECK - /* Verify range of distance attenuation parameters: 0.1 <= distAtt[0] <= distAtt[1] */ - /* 0.0 <= distAtt[2] <= 10.0 */ - hRenderConfig->distAtt[0] = max( 0.1f, hRenderConfig->distAtt[0] ); - hRenderConfig->distAtt[1] = max( hRenderConfig->distAtt[0], hRenderConfig->distAtt[1] ); - hRenderConfig->distAtt[2] = max( 0.0f, min( 10.0f, hRenderConfig->distAtt[2] ) ); - - /* Verify range of directivity patterns */ - for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) - { - hRenderConfig->directivity[i * 3] = max( 0.0f, min( 360.0f, hRenderConfig->directivity[i * 3] ) ); - hRenderConfig->directivity[i * 3 + 1] = max( 0.0f, min( 360.0f, hRenderConfig->directivity[i * 3 + 1] ) ); - hRenderConfig->directivity[i * 3 + 2] = max( 0.0f, min( 1.0f, hRenderConfig->directivity[i * 3 + 2] ) ); - } -#endif - } - - - return IVAS_ERR_OK; -} - -/*------------------------------------------------------------------------------------------* - * RenderConfigReader_open() - * - * Allocates and initializes a renderer configuration reader instance - *------------------------------------------------------------------------------------------*/ - -ivas_error RenderConfigReader_open( - char *pConfigPath, /* i : renderer configuration file path */ - RenderConfigReader **ppRenderConfigReader /* o : RenderConfigReader handle */ -) -{ - RenderConfigReader *pSelf; - FILE *pConfigFile; - - /* Open the configuration file */ - if ( strlen( pConfigPath ) < 1 ) - { - return IVAS_ERR_FAILED_FILE_OPEN; - } - - pConfigFile = fopen( pConfigPath, "r" ); - - if ( !pConfigFile ) - { - return IVAS_ERR_FAILED_FILE_OPEN; - } - - pSelf = calloc( 1, sizeof( RenderConfigReader ) ); - pSelf->pConfigFile = pConfigFile; - pSelf->nFG = 0; - pSelf->pFG = NULL; - pSelf->nAE = 0; - pSelf->pAE = NULL; - pSelf->nDP = 0; - pSelf->pDP = NULL; - pSelf->distAtt[0] = -1; - - *ppRenderConfigReader = pSelf; - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------------------------* - * RenderConfigReader_readBinary() - * - * Reads the binary configuration from a file - *------------------------------------------------------------------------------------------*/ - -static ivas_error RenderConfigReader_readBinary( - const char *pReverbConfigPath, /* i : Configuration file path */ - RenderConfigReader *pRenderConfigReader /* i/o: RenderConfigReader handle */ -) -{ - uint32_t file_size; - uint32_t value; - uint32_t signx, signy, k; - uint32_t i, m, n; - uint32_t nFG, nAE; - uint32_t nDP; - ivas_error error; - float freqHop; - uint32_t gridLen; - uint32_t subGridLen; - const float *pGrid; - FILE *pReverbConfigFile; - - /* Open the configuration file */ - pReverbConfigFile = fopen( pReverbConfigPath, "rb" ); - - if ( !pReverbConfigFile ) - { - return IVAS_ERR_FAILED_FILE_OPEN; - } - - /* Read the bitstream */ - fseek( pReverbConfigFile, 0, SEEK_END ); - file_size = ftell( pReverbConfigFile ); - rewind( pReverbConfigFile ); - - pRenderConfigReader->pBitstream = (uint8_t *) malloc( file_size * sizeof( uint8_t ) ); - if ( pRenderConfigReader->pBitstream == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - - fread( pRenderConfigReader->pBitstream, sizeof( uint8_t ), file_size, pReverbConfigFile ); - pRenderConfigReader->length = file_size; - /* we read the config twice in the decoder, so reset the read offset here */ - pRenderConfigReader->readOffset = 0; - - /****************************/ - /* Read the presence flag */ - /****************************/ - if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - /* acoustic environment data available */ - if ( value == true ) - { - /****************************/ - /* Read the frequency grids */ - /****************************/ - - /* Number of frequency grids */ - if ( ( error = get_bin_count_or_index( pRenderConfigReader, &nFG ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Allocate memory for the frequency grids */ - if ( nFG > 0 ) - { - if ( pRenderConfigReader->nFG > 0 ) - { - for ( n = 0; n < pRenderConfigReader->nFG; n++ ) - { - free( pRenderConfigReader->pFG[n].pFc ); - } - free( pRenderConfigReader->pFG ); - } - pRenderConfigReader->nFG = nFG; - if ( ( pRenderConfigReader->pFG = (FrequencyGrid *) malloc( pRenderConfigReader->nFG * sizeof( FrequencyGrid ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - for ( n = 0; n < nFG; n++ ) - { - /* Initialize memory pointers to allow safe freeing ico errors */ - pRenderConfigReader->pFG[n].pFc = NULL; - } - } - - /* Loop through the frequency grids read from the binary stream */ - for ( n = 0; n < nFG; n++ ) - { - /* Read the representation method */ - value = 0; - if ( ( error = read_bin_bits( pRenderConfigReader, &value, 2 ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Process depending on the representation method */ - switch ( value ) - { - case FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES: - if ( ( error = get_bin_count_or_index( pRenderConfigReader, &pRenderConfigReader->pFG[n].nrBands ) ) != IVAS_ERR_OK ) - { - return error; - } - /* Allocate memory for the center frequency array */ - if ( ( pRenderConfigReader->pFG[n].pFc = (float *) malloc( pRenderConfigReader->pFG[n].nrBands * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - /* Read the individual frequencies */ - for ( m = 0; m < pRenderConfigReader->pFG[n].nrBands; m++ ) - { - if ( ( error = get_bin_frequency( pRenderConfigReader, &pRenderConfigReader->pFG[n].pFc[m] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - break; - case FREQ_GRID_MODE_START_HOP_AMOUNT: - if ( ( error = get_bin_count_or_index( pRenderConfigReader, &pRenderConfigReader->pFG[n].nrBands ) ) != IVAS_ERR_OK ) - { - return error; - } - /* Allocate memory for the center frequency array */ - if ( ( pRenderConfigReader->pFG[n].pFc = (float *) malloc( pRenderConfigReader->pFG[n].nrBands * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - /* Read the first frequency */ - if ( ( error = get_bin_frequency( pRenderConfigReader, &pRenderConfigReader->pFG[n].pFc[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - /* Read frequency hop from LUT */ - if ( ( error = read_bin_code_word( pRenderConfigReader, RC_LUT_FREQ_HOP, &freqHop ) ) != IVAS_ERR_OK ) - { - return error; - } - /* Fill up the center frequency array */ - for ( m = 1; m < pRenderConfigReader->pFG[n].nrBands; m++ ) - { - pRenderConfigReader->pFG[n].pFc[m] = pRenderConfigReader->pFG[n].pFc[m - 1] * freqHop; - } - break; - case FREQ_GRID_MODE_DEFAULT_BANDING: - /* Read the default grid ID */ - value = 0; - if ( ( error = read_bin_bits( pRenderConfigReader, &value, 4 ) ) != IVAS_ERR_OK ) - { - return error; - } - switch ( value ) - { - case 0: - gridLen = sizeof( defaultFrequencyGrid_0 ) / sizeof( defaultFrequencyGrid_0[0] ); - pGrid = defaultFrequencyGrid_0; - break; - case 1: - gridLen = sizeof( defaultFrequencyGrid_1 ) / sizeof( defaultFrequencyGrid_1[0] ); - pGrid = defaultFrequencyGrid_1; - break; - case 2: - gridLen = sizeof( defaultFrequencyGrid_2 ) / sizeof( defaultFrequencyGrid_2[0] ); - pGrid = defaultFrequencyGrid_2; - break; - case 3: - gridLen = sizeof( defaultFrequencyGrid_3 ) / sizeof( defaultFrequencyGrid_3[0] ); - pGrid = defaultFrequencyGrid_3; - break; - case 4: - gridLen = sizeof( defaultFrequencyGrid_4 ) / sizeof( defaultFrequencyGrid_4[0] ); - pGrid = defaultFrequencyGrid_4; - break; - case 5: - gridLen = sizeof( defaultFrequencyGrid_5 ) / sizeof( defaultFrequencyGrid_5[0] ); - pGrid = defaultFrequencyGrid_5; - break; - case 6: - gridLen = sizeof( defaultFrequencyGrid_6 ) / sizeof( defaultFrequencyGrid_6[0] ); - pGrid = defaultFrequencyGrid_6; - break; - case 7: - gridLen = sizeof( defaultFrequencyGrid_7 ) / sizeof( defaultFrequencyGrid_7[0] ); - pGrid = defaultFrequencyGrid_7; - break; - case 8: - gridLen = sizeof( defaultFrequencyGrid_8 ) / sizeof( defaultFrequencyGrid_8[0] ); - pGrid = defaultFrequencyGrid_8; - break; - default: - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - m = 0; - /* Read sub-grid flag */ - if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( value != false ) - { - /* Read the sub-grid offset */ - if ( ( error = read_bin_bits( pRenderConfigReader, &m, 3 ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Read the sub-grid length */ - subGridLen = 0; - if ( ( error = read_bin_bits( pRenderConfigReader, &subGridLen, 6 ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( m + subGridLen > gridLen ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - gridLen = subGridLen; - } - pRenderConfigReader->pFG[n].nrBands = gridLen; - /* Allocate memory for the center frequency array */ - if ( ( pRenderConfigReader->pFG[n].pFc = (float *) malloc( gridLen * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - - /* Copy the ROM content to the frequency grid*/ - for ( i = 0; i < gridLen; i++ ) - { - pRenderConfigReader->pFG[n].pFc[i] = pGrid[m + i]; - } - - break; - default: - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - /* Initialize memory pointers to allow safe freeing ico errors */ - pRenderConfigReader->pFG[n].pFc = NULL; - } - - /**********************************/ - /* Read the acoustic environments */ - /**********************************/ - - /* Number of acoustic environments */ - if ( ( error = get_bin_count_or_index( pRenderConfigReader, &nAE ) ) != IVAS_ERR_OK ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - /* Allocate memory for the acoustic environments array */ - if ( nAE > 0 ) - { - if ( pRenderConfigReader->nAE > 0 ) - { - for ( n = 0; n < pRenderConfigReader->nAE; n++ ) - { - free( pRenderConfigReader->pAE[n].pRT60 ); - free( pRenderConfigReader->pAE[n].pDSR ); - if ( pRenderConfigReader->pAE[n].pEarlyReflections != NULL ) - { - free( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin ); - free( pRenderConfigReader->pAE[n].pEarlyReflections ); - } - } - free( pRenderConfigReader->pAE ); - } - pRenderConfigReader->nAE = nAE; - - if ( ( pRenderConfigReader->pAE = (AcousticEnv *) malloc( pRenderConfigReader->nAE * sizeof( AcousticEnv ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - /* Initialize memory pointers to allow safe freeing ico errors */ - for ( n = 0; n < nAE; n++ ) - { - pRenderConfigReader->pAE[n].pRT60 = NULL; - pRenderConfigReader->pAE[n].pDSR = NULL; - pRenderConfigReader->pAE[n].pEarlyReflections = NULL; - } - } - - /* Loop through the acoustic environments from the binary stream */ - for ( n = 0; n < nAE; n++ ) - { - /* Read the AE ID */ - if ( ( error = get_bin_id( pRenderConfigReader, &pRenderConfigReader->pAE[n].id ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Read the frequency grid ID */ - if ( ( error = get_bin_count_or_index( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Associate the frequency grid */ - if ( value >= pRenderConfigReader->nFG ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - pRenderConfigReader->pAE[n].pFG = &( pRenderConfigReader->pFG[value] ); - - /* Allocate memory for RT60 and DSR arrays */ - if ( ( pRenderConfigReader->pAE[n].pRT60 = (float *) malloc( pRenderConfigReader->pAE[n].pFG->nrBands * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - - if ( ( pRenderConfigReader->pAE[n].pDSR = (float *) malloc( pRenderConfigReader->pAE[n].pFG->nrBands * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - - /* Read the values */ - if ( ( error = get_bin_duration( pRenderConfigReader, &pRenderConfigReader->pAE[n].preDelay ) ) != IVAS_ERR_OK ) - { - return error; - } - - for ( m = 0; m < pRenderConfigReader->pAE[n].pFG->nrBands; m++ ) - { - if ( ( error = get_bin_duration( pRenderConfigReader, &pRenderConfigReader->pAE[n].pRT60[m] ) ) != IVAS_ERR_OK ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - } - for ( m = 0; m < pRenderConfigReader->pAE[n].pFG->nrBands; m++ ) - { - if ( ( error = get_bin_dsr( pRenderConfigReader, &pRenderConfigReader->pAE[n].pDSR[m] ) ) != IVAS_ERR_OK ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - } - - /*****************************************/ - /* Read the early reflections parameters */ - /*****************************************/ - - /* Has early reflections */ - if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( value == true ) - { - if ( ( pRenderConfigReader->pAE[n].pEarlyReflections = (EarlyReflectionsConfig *) malloc( sizeof( EarlyReflectionsConfig ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - /* Initialize memory pointers to allow safe freeing ico eg errors */ - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = NULL; - - pRenderConfigReader->pAE[n].pEarlyReflections->use_er = 1; - - /* Room sizes */ - if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.y ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.z ) ) != IVAS_ERR_OK ) - { - return error; - } - - for ( k = 0; k < N_ABS_COEFFS; k++ ) - { - if ( ( error = get_bin_absorption( pRenderConfigReader, &pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[k] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* Has listener origin */ - if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( value == true ) - { - if ( ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - - if ( ( error = read_bin_bits( pRenderConfigReader, &signx, 1 ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = read_bin_bits( pRenderConfigReader, &signy, 1 ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( signx == 0 ) - { - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x *= -1.0f; - } - if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( signy == 0 ) - { - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y *= -1.0f; - } - if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else /* load defaults if origin is not specified in config */ - { - if ( ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x = IVAS_ER_LIST_ORIGIN_X; - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y = IVAS_ER_LIST_ORIGIN_Y; - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z = IVAS_ER_LIST_HEIGHT; - } - - /* Low complexity mode */ - if ( ( error = read_bin_bool( pRenderConfigReader, &pRenderConfigReader->pAE[n].pEarlyReflections->lowComplexity ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - } - /**********************************/ - /* Read the directivity patterns */ - /**********************************/ - - /* Has source directivity */ - if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( value == true ) - { - - /* Number of directivity patterns */ - if ( ( error = get_bin_id( pRenderConfigReader, &nDP ) ) != IVAS_ERR_OK ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - if ( nDP > 0 ) - { - if ( pRenderConfigReader->nDP > 0 ) - { - for ( n = 0; n < pRenderConfigReader->nDP; n++ ) - { - free( pRenderConfigReader->pDP[n].pDirectivity ); - } - free( pRenderConfigReader->pDP ); - } - - pRenderConfigReader->nDP = nDP; - - if ( ( pRenderConfigReader->pDP = (DirectrivityPat *) malloc( pRenderConfigReader->nDP * sizeof( DirectrivityPat ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - - for ( n = 0; n < nDP; n++ ) - { - /* Allocate memory for directivity arrays*/ - if ( ( pRenderConfigReader->pDP[n].pDirectivity = (float *) malloc( 3 * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - } - } - /* Loop through the directivity patterns from the binary stream */ - for ( n = 0; n < nDP; n++ ) - { - - /* Read the Directivity ID */ - if ( ( error = get_bin_id( pRenderConfigReader, &pRenderConfigReader->pDP[n].id ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = get_bin_angle( pRenderConfigReader, &pRenderConfigReader->pDP[n].pDirectivity[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = get_bin_angle( pRenderConfigReader, &pRenderConfigReader->pDP[n].pDirectivity[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = get_bin_outer_attenuation( pRenderConfigReader, &pRenderConfigReader->pDP[n].pDirectivity[2] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - /**********************************/ - /* Read the distance attenuation */ - /**********************************/ - - /* Has distance attenuation */ - if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( value == true ) - { - /* Read the Max Distance */ - if ( ( error = get_bin_max_dist( pRenderConfigReader, &pRenderConfigReader->distAtt[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - /* Read the Ref Distance */ - if ( ( error = get_bin_ref_dist( pRenderConfigReader, &pRenderConfigReader->distAtt[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - /* Read the Rolloff Facto r*/ - if ( ( error = get_bin_rolloff( pRenderConfigReader, &pRenderConfigReader->distAtt[2] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - - /* Cleanup */ - free( pRenderConfigReader->pBitstream ); - - return IVAS_ERR_OK; -} - - -ivas_error RenderConfigReader_read( - RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ - const char *pRenderConfigPath, /* i : Renderer configuration file path */ - IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ -) -{ - int32_t file_size; - char *pConfig_str; - char *pParams; - char *pTemp; - int32_t read_idx; - int32_t params_idx; - char item[MAX_ITEM_LENGTH + 1]; - char chapter[MAX_ITEM_LENGTH + 1]; - char *pValue; - ivas_error error; - int32_t params_length; - int32_t length; - uint32_t i, idx; - uint32_t nFG, nAE; - char *pToken; - FREQ_GRID_MODE fgMode; - float freqHop; - uint32_t acIdx; - uint32_t defGridId, defGridLen, defGridOffset, defGridNrBands; - const float *pDefGrid; - float erTemp[N_ABS_COEFFS]; - uint32_t roomAcHasFgCount, roomAcHasAcEnvCount; - uint32_t fgHasMethod, fgHasNBands, fgHasFreqs, fgHasDefaultGrid, fgHasStartFreq, fgHasFreqHop; - uint32_t aeHasFgIdx, aeHasPredelay, aeHasRt60, aeHasDsr; - uint32_t aeHasERsize, aeHasERabs; - bool dofProvided = false; - bool poseCorrProvided = false; - - uint32_t nDP; - uint32_t accDPIdx; - accDPIdx = 0; - - fseek( pRenderConfigReader->pConfigFile, 0, SEEK_END ); - file_size = ftell( pRenderConfigReader->pConfigFile ); - rewind( pRenderConfigReader->pConfigFile ); - pConfig_str = (char *) calloc( file_size + 1, sizeof( char ) ); - pParams = (char *) calloc( file_size + 1, sizeof( char ) ); - pTemp = (char *) calloc( file_size + 1, sizeof( char ) ); - acIdx = 0; - roomAcHasFgCount = roomAcHasAcEnvCount = FALSE; - setvbuf( pRenderConfigReader->pConfigFile, pConfig_str, _IONBF, sizeof( char ) ); /* Work-around for VS bug that gives incorrect ftell for UNIX-style line endings */ - - /* read file line by line */ - while ( fgets( pConfig_str, file_size, pRenderConfigReader->pConfigFile ) != NULL ) - { - - if ( sscanf( pConfig_str, "[%64[^]]]", chapter ) == 1 ) - { - /* read line by line (except comments) until next chapter or EOF */ - pParams[0] = '\0'; - do - { - read_idx = ftell( pRenderConfigReader->pConfigFile ); - if ( fgets( pTemp, file_size, pRenderConfigReader->pConfigFile ) == NULL ) - { - break; - } - - if ( ( pTemp[0] != '#' ) && ( sscanf( pTemp, "[%64[^]]]", item ) != 1 ) ) - { - /* ignore inline comments */ - sscanf( pTemp, "%[^#]", pTemp ); - strcat( pParams, pTemp ); - } - } while ( sscanf( pTemp, "[%64[^]]]", item ) != 1 ); - - /* go back one line */ - fseek( pRenderConfigReader->pConfigFile, read_idx, SEEK_SET ); - - strip_spaces( pParams ); - strcpy( pTemp, pParams ); - to_upper( pParams ); - to_upper( chapter ); - - /* interpret params */ - pToken = strtok( chapter, ":" ); - if ( strcmp( chapter, "ROOMACOUSTICS" ) == 0 && strlen( pParams ) != 0 ) - { - params_idx = 0; - pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); - - while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) - { - params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); - if ( strcmp( item, "FREQUENCYGRIDCOUNT" ) == 0 ) - { - /* Read the number of frequency grids */ - if ( !sscanf( pValue, "%u", &nFG ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( nFG > 0 ) - { - for ( idx = 0; idx < pRenderConfigReader->nFG; idx++ ) - { - free( pRenderConfigReader->pFG[idx].pFc ); - } - free( pRenderConfigReader->pFG ); - - pRenderConfigReader->nFG = nFG; - - /* Allocate memory for the frequency grids */ - if ( ( pRenderConfigReader->pFG = (FrequencyGrid *) malloc( pRenderConfigReader->nFG * sizeof( FrequencyGrid ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - for ( idx = 0; idx < nFG; idx++ ) - { - pRenderConfigReader->pFG[idx].nrBands = 0; - pRenderConfigReader->pFG[idx].pFc = NULL; - } - } - roomAcHasFgCount = TRUE; - } - else if ( strcmp( item, "ACOUSTICENVIRONMENTCOUNT" ) == 0 ) - { - /* Read the number of acoustic environments */ - if ( !sscanf( pValue, "%u", &nAE ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( nAE > 0 ) - { - for ( idx = 0; idx < pRenderConfigReader->nAE; idx++ ) - { - free( pRenderConfigReader->pAE[idx].pRT60 ); - free( pRenderConfigReader->pAE[idx].pDSR ); - if ( pRenderConfigReader->pAE[idx].pEarlyReflections != NULL ) - { - free( pRenderConfigReader->pAE[idx].pEarlyReflections->pListenerOrigin ); - free( pRenderConfigReader->pAE[idx].pEarlyReflections ); - } - } - free( pRenderConfigReader->pAE ); - - pRenderConfigReader->nAE = nAE; - - /* Allocate memory for the acoustic environments array */ - if ( ( pRenderConfigReader->pAE = (AcousticEnv *) malloc( pRenderConfigReader->nAE * sizeof( AcousticEnv ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - /* Initialize memory pointers to allow for safe freeing */ - for ( acIdx = 0; acIdx < pRenderConfigReader->nAE; acIdx++ ) - { - pRenderConfigReader->pAE[acIdx].pRT60 = NULL; - pRenderConfigReader->pAE[acIdx].pDSR = NULL; - pRenderConfigReader->pAE[acIdx].pEarlyReflections = NULL; - } - } - acIdx = 0; - roomAcHasAcEnvCount = TRUE; - } - } - if ( roomAcHasFgCount == FALSE || roomAcHasAcEnvCount == FALSE ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - free( pValue ); - } - else if ( strcmp( pToken, "FREQUENCYGRID" ) == 0 ) - { - if ( pRenderConfigReader->pFG == NULL ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - idx = strtol( strtok( NULL, ":" ), NULL, 0 ); - if ( idx >= pRenderConfigReader->nFG ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - fgHasMethod = fgHasNBands = fgHasFreqs = fgHasDefaultGrid = fgHasStartFreq = fgHasFreqHop = FALSE; - fgMode = FREQ_GRID_MODE_UNKNOWN; - params_idx = 0; - pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); - while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) - { - params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); - if ( strcmp( item, "METHOD" ) == 0 ) - { - if ( strcmp( pValue, "INDIVIDUALFREQUENCIES" ) == 0 ) - { - fgMode = FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES; - } - else if ( strcmp( pValue, "STARTHOPAMOUNT" ) == 0 ) - { - fgMode = FREQ_GRID_MODE_START_HOP_AMOUNT; - } - else if ( strcmp( pValue, "DEFAULTBANDING" ) == 0 ) - { - fgMode = FREQ_GRID_MODE_DEFAULT_BANDING; - } - fgHasMethod = TRUE; - } - /* Read number of bands for individual frequency, start-hop-amount mode */ - else if ( strcmp( item, "NRBANDS" ) == 0 ) - { - if ( fgMode != FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES && fgMode != FREQ_GRID_MODE_START_HOP_AMOUNT ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( !sscanf( pValue, "%u", &pRenderConfigReader->pFG[idx].nrBands ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - /* Allocate memory for the center frequency array */ - if ( ( pRenderConfigReader->pFG[idx].pFc = (float *) malloc( pRenderConfigReader->pFG[idx].nrBands * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - fgHasNBands = TRUE; - } - else if ( strcmp( item, "FREQUENCIES" ) == 0 ) - { - if ( fgMode != FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES || pRenderConfigReader->pFG[idx].nrBands == 0 || pRenderConfigReader->pFG[idx].pFc == NULL ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - /* Read the individual frequencies */ - if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pFG[idx].pFc ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - fgHasFreqs = TRUE; - } - else if ( strcmp( item, "STARTFREQUENCY" ) == 0 ) - { - if ( fgMode != FREQ_GRID_MODE_START_HOP_AMOUNT || pRenderConfigReader->pFG[idx].nrBands == 0 || pRenderConfigReader->pFG[idx].pFc == NULL ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( !sscanf( pValue, "%f", &pRenderConfigReader->pFG[idx].pFc[0] ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - fgHasStartFreq = TRUE; - } - else if ( strcmp( item, "FREQUENCYHOP" ) == 0 ) - { - if ( fgMode != FREQ_GRID_MODE_START_HOP_AMOUNT || pRenderConfigReader->pFG[idx].nrBands == 0 || pRenderConfigReader->pFG[idx].pFc == NULL || pRenderConfigReader->pFG[idx].pFc[0] == 0.0f ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( !sscanf( pValue, "%f", &freqHop ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - /* Fill up the center frequency array */ - for ( i = 1; i < pRenderConfigReader->pFG[idx].nrBands; i++ ) - { - pRenderConfigReader->pFG[idx].pFc[i] = pRenderConfigReader->pFG[idx].pFc[i - 1] * freqHop; - } - fgHasFreqHop = TRUE; - } - /* Handle default grids, with optional sub-grids */ - else if ( strcmp( item, "DEFAULTGRID" ) == 0 ) - { - if ( !sscanf( pValue, "%u", &defGridId ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - switch ( defGridId ) - { - case 0: - defGridLen = sizeof( defaultFrequencyGrid_0 ) / sizeof( defaultFrequencyGrid_0[0] ); - pDefGrid = defaultFrequencyGrid_0; - break; - case 1: - defGridLen = sizeof( defaultFrequencyGrid_1 ) / sizeof( defaultFrequencyGrid_1[0] ); - pDefGrid = defaultFrequencyGrid_1; - break; - case 2: - defGridLen = sizeof( defaultFrequencyGrid_2 ) / sizeof( defaultFrequencyGrid_2[0] ); - pDefGrid = defaultFrequencyGrid_2; - break; - case 3: - defGridLen = sizeof( defaultFrequencyGrid_3 ) / sizeof( defaultFrequencyGrid_3[0] ); - pDefGrid = defaultFrequencyGrid_3; - break; - case 4: - defGridLen = sizeof( defaultFrequencyGrid_4 ) / sizeof( defaultFrequencyGrid_4[0] ); - pDefGrid = defaultFrequencyGrid_4; - break; - case 5: - defGridLen = sizeof( defaultFrequencyGrid_5 ) / sizeof( defaultFrequencyGrid_5[0] ); - pDefGrid = defaultFrequencyGrid_5; - break; - case 6: - defGridLen = sizeof( defaultFrequencyGrid_6 ) / sizeof( defaultFrequencyGrid_6[0] ); - pDefGrid = defaultFrequencyGrid_6; - break; - case 7: - defGridLen = sizeof( defaultFrequencyGrid_7 ) / sizeof( defaultFrequencyGrid_7[0] ); - pDefGrid = defaultFrequencyGrid_7; - break; - case 8: - defGridLen = sizeof( defaultFrequencyGrid_8 ) / sizeof( defaultFrequencyGrid_8[0] ); - pDefGrid = defaultFrequencyGrid_8; - break; - default: - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - fgHasDefaultGrid = TRUE; - - /* Handle sub-grids */ - defGridOffset = 0; - defGridNrBands = defGridLen; - - while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) - { - if ( strcmp( item, "DEFAULTGRIDOFFSET" ) == 0 ) - { - if ( !sscanf( pValue, "%u", &defGridOffset ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - } - else if ( strcmp( item, "DEFAULTGRIDNRBANDS" ) == 0 ) - { - if ( !sscanf( pValue, "%u", &defGridNrBands ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - } - else - { - break; - } - params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); - } - - if ( defGridOffset + defGridNrBands > defGridLen ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - pRenderConfigReader->pFG[idx].nrBands = defGridNrBands; - - /* Allocate memory for the center frequency array */ - if ( ( pRenderConfigReader->pFG[idx].pFc = (float *) malloc( defGridNrBands * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - - /* Copy the ROM content to the frequency grid*/ - for ( i = 0; i < defGridNrBands; i++ ) - { - pRenderConfigReader->pFG[idx].pFc[i] = pDefGrid[defGridOffset + i]; - } - } - } - if ( fgHasMethod == FALSE || - ( fgMode == FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES && ( fgHasFreqs == FALSE || fgHasNBands == FALSE ) ) || - ( fgMode == FREQ_GRID_MODE_DEFAULT_BANDING && fgHasDefaultGrid == FALSE ) || - ( fgMode == FREQ_GRID_MODE_START_HOP_AMOUNT && ( fgHasStartFreq == FALSE || fgHasFreqHop == FALSE || fgHasNBands == FALSE ) ) ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - free( pValue ); - } - /* Handle multiple acoustic environments */ - else if ( strcmp( pToken, "ACOUSTICENVIRONMENT" ) == 0 ) - { - if ( pRenderConfigReader->pAE == NULL || acIdx >= pRenderConfigReader->nAE ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - idx = strtol( strtok( NULL, ":" ), NULL, 0 ); - pRenderConfigReader->pAE[acIdx].id = idx; - - aeHasFgIdx = aeHasPredelay = aeHasRt60 = aeHasDsr = FALSE; - aeHasERsize = aeHasERabs = FALSE; - params_idx = 0; - pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); - while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) - { - params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); - /* Frequency grid index */ - if ( strcmp( item, "FREQUENCYGRIDINDEX" ) == 0 ) - { - if ( !sscanf( pValue, "%u", &i ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( i >= pRenderConfigReader->nFG || pRenderConfigReader->pFG[i].pFc == NULL ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - pRenderConfigReader->pAE[acIdx].pFG = &pRenderConfigReader->pFG[i]; - - /* Allocate memory for RT60 and DSR arrays */ - if ( ( pRenderConfigReader->pAE[acIdx].pRT60 = (float *) malloc( pRenderConfigReader->pAE[acIdx].pFG->nrBands * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - - if ( ( pRenderConfigReader->pAE[acIdx].pDSR = (float *) malloc( pRenderConfigReader->pAE[acIdx].pFG->nrBands * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - aeHasFgIdx = TRUE; - } - - /* Acoustic pre-delay */ - else if ( strcmp( item, "ACOUSTICPREDELAY" ) == 0 ) - { - float f; - if ( !sscanf( pValue, "%f", &f ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - } - hRenderConfig->roomAcoustics.acousticPreDelay_fx = (Word32) ( f * ONE_IN_Q27 ); - } - /* Pre-delay */ - else if ( strcmp( item, "PREDELAY" ) == 0 ) - { - if ( !sscanf( pValue, "%f", &pRenderConfigReader->pAE[acIdx].preDelay ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - aeHasPredelay = TRUE; - } - /* RT60 */ - else if ( strcmp( item, "RT60" ) == 0 ) - { - if ( read_txt_vector( pValue, pRenderConfigReader->pAE[acIdx].pFG->nrBands, pRenderConfigReader->pAE[acIdx].pRT60 ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - aeHasRt60 = TRUE; - } - /* DSR */ - else if ( strcmp( item, "DSR" ) == 0 ) - { - if ( read_txt_vector( pValue, pRenderConfigReader->pAE[acIdx].pFG->nrBands, pRenderConfigReader->pAE[acIdx].pDSR ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - aeHasDsr = TRUE; - } - else if ( strcmp( item, "EARLYREFLECTIONSSIZE" ) == 0 ) - { - if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) - { - if ( ( pRenderConfigReader->pAE[acIdx].pEarlyReflections = (EarlyReflectionsConfig *) malloc( sizeof( EarlyReflectionsConfig ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin = NULL; - pRenderConfigReader->pAE[acIdx].pEarlyReflections->lowComplexity = FALSE; - } - if ( strcmp( item, "EARLYREFLECTIONSSIZE" ) == 0 ) - { - if ( read_txt_vector( pValue, 3, erTemp ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.x = erTemp[0]; - pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.y = erTemp[1]; - pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.z = erTemp[2]; - aeHasERsize = TRUE; - } - } - else if ( strcmp( item, "ABSORPTIONCOEFFS" ) == 0 ) - { - if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( read_txt_vector( pValue, N_ABS_COEFFS, erTemp ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - for ( i = 0; i < N_ABS_COEFFS; i++ ) - { - pRenderConfigReader->pAE[acIdx].pEarlyReflections->pAbsCoeff[i] = erTemp[i]; - } - aeHasERabs = TRUE; - } - else if ( strcmp( item, "LISTENERORIGIN" ) == 0 ) - { - if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( read_txt_vector( pValue, 3, erTemp ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( ( pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->x = erTemp[0]; - pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->y = erTemp[1]; - pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->z = erTemp[2]; - } - else if ( strcmp( item, "LOWCOMPLEXITY" ) == 0 ) - { - if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( read_txt_bool( pValue, &pRenderConfigReader->pAE[acIdx].pEarlyReflections->lowComplexity ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - } - } - if ( aeHasFgIdx == FALSE || aeHasPredelay == FALSE || aeHasRt60 == FALSE || aeHasDsr == FALSE ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( aeHasERsize == TRUE && aeHasERabs == FALSE ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - else if ( aeHasERsize == TRUE && aeHasERabs == TRUE ) - { - pRenderConfigReader->pAE[acIdx].pEarlyReflections->use_er = 1; - } - - free( pValue ); - acIdx++; - } - else if ( strcmp( chapter, "SPLITREND" ) == 0 && strlen( pParams ) != 0 ) - { - params_idx = 0; - pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); - while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) - { - params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); -#endif - if ( strcmp( item, "CODECDELAY" ) == 0 ) - { - if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.codec_delay_ms ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - } - } - else if ( strcmp( item, "HQMODE" ) == 0 ) - { - if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.hq_mode ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - } - } - else if ( strcmp( item, "BITRATE" ) == 0 ) - { - if ( !sscanf( pValue, "%d", &hRenderConfig->split_rend_config.splitRendBitRate ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - } - } - else if ( strcmp( item, "DOF" ) == 0 ) - { - dofProvided = true; - if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.dof ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - } - /* 0 DOF implies no pose correction */ - if ( hRenderConfig->split_rend_config.dof == 0 && !poseCorrProvided ) - { - hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - } - } - else if ( strcmp( item, "CODEC" ) == 0 ) - { - if ( strcmp( pValue, "LCLD" ) == 0 ) - { - hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LCLD; - } - else if ( strcmp( pValue, "LC3PLUS" ) == 0 ) - { - hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LC3PLUS; - } - else - { - errorHandler( pValue, ERROR_VALUE_INVALID ); - } - } - else if ( strcmp( item, "FRAMESIZE" ) == 0 ) - { - if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.codec_frame_size_ms ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - } - if ( hRenderConfig->split_rend_config.codec_frame_size_ms != 5 && - hRenderConfig->split_rend_config.codec_frame_size_ms != 10 && - hRenderConfig->split_rend_config.codec_frame_size_ms != 20 ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - } - } - else if ( strcmp( item, "POSECORRECTION" ) == 0 ) - { - poseCorrProvided = true; - if ( strcmp( pValue, "CLDFB" ) == 0 ) - { - hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; - } - else if ( strcmp( pValue, "NONE" ) == 0 ) - { - hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - /* no pose correction implies 0 DOF */ - if ( !dofProvided ) - { - hRenderConfig->split_rend_config.dof = 0; - } - } - else - { - errorHandler( pValue, ERROR_VALUE_INVALID ); - } - } - else if ( strcmp( item, "RENDERER" ) == 0 ) - { - if ( strcmp( pValue, "CREND" ) == 0 ) - { - hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_CREND; - } - else if ( strcmp( pValue, "FASTCONV" ) == 0 ) - { - hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_FASTCONV; - } - else if ( strcmp( pValue, "PARAMBIN" ) == 0 ) - { - hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_PARAMBIN; - } - else if ( strcmp( pValue, "TDREND" ) == 0 ) - { - hRenderConfig->split_rend_config.rendererSelection = IVAS_BIN_RENDERER_TYPE_TDREND; - } - else - { - errorHandler( pValue, ERROR_VALUE_INVALID ); - } - } - else if ( strcmp( item, "LC3PLUS_HIGHRES" ) == 0 ) - { - if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.lc3plus_highres ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - } - } -#ifdef DEBUGGING - else - { - fprintf( stderr, "Unsupported configuration property %s\n", item ); - } -#endif - } - free( pValue ); - } - else if ( strcmp( chapter, "DIRECTIVITYSETTING" ) == 0 && strlen( pParams ) != 0 ) - { - params_idx = 0; - pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); - - while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) - { - params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); - if ( strcmp( item, "DIRECTIVITYCOUNT" ) == 0 ) - { - /* Read the number of directivity chapters */ - if ( !sscanf( pValue, "%u", &nDP ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - if ( nDP > 0 ) - { - for ( idx = 0; idx < pRenderConfigReader->nDP; idx++ ) - { - free( pRenderConfigReader->pDP[idx].pDirectivity ); - } - - free( pRenderConfigReader->pDP ); - pRenderConfigReader->nDP = nDP; - - /* Allocate memory for the directivity pattern*/ - if ( ( pRenderConfigReader->pDP = (DirectrivityPat *) malloc( pRenderConfigReader->nDP * sizeof( DirectrivityPat ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - - for ( idx = 0; idx < nDP; idx++ ) - { - pRenderConfigReader->pDP[idx].pDirectivity = NULL; - } - } - accDPIdx = 0; - } - } - free( pValue ); - } - else if ( strcmp( pToken, "DIRECTIVITYPATTERN" ) == 0 ) - { - if ( pRenderConfigReader->pDP == NULL || accDPIdx >= pRenderConfigReader->nDP ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - idx = strtol( strtok( NULL, ":" ), NULL, 0 ); - - params_idx = 0; - pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); - while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) - { - params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); - /* Allocate memory for directivity arrays*/ - if ( ( pRenderConfigReader->pDP[accDPIdx].pDirectivity = (float *) malloc( 3 * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - - pRenderConfigReader->pDP[accDPIdx].id = idx; - - if ( strcmp( item, "DIRECTIVITY" ) == 0 ) - { - if ( read_txt_vector( pValue, 3, pRenderConfigReader->pDP[accDPIdx].pDirectivity ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - } - } - free( pValue ); - accDPIdx++; - } - else if ( strcmp( chapter, "DISTANCEATTENUATION" ) == 0 ) - { - params_idx = 0; - pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); - - /* Set default values if parameters are only partially specified */ - pRenderConfigReader->distAtt[0] = 15.75f; - pRenderConfigReader->distAtt[1] = 1.0f; - pRenderConfigReader->distAtt[2] = 1.0f; - - while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) - { - params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); - - if ( strcmp( item, "MAXDIST" ) == 0 ) - { - /* Read the Maximum distance */ - if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[0] ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - } - if ( strcmp( item, "REFDIST" ) == 0 ) - { - /* Read the Reference distance */ - if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[1] ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - } - if ( strcmp( item, "ROLLOFFFACTOR" ) == 0 ) - { - /* Read the Rolloff Factor */ - if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[2] ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - } - } - - free( pValue ); - } - else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) - { - params_idx = 0; - pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); - while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) - { - params_length = (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); - if ( strcmp( item, "BINARYCONFIG" ) == 0 ) - { - /* get correct case reverb configuration file path */ - sscanf( pTemp + params_idx, "%*[^=] = %[^;];", pValue ); - - /* make reverb configuration file path relative to render configuration file path */ - for ( length = (int32_t) strlen( pRenderConfigPath ) - 1; length >= 0; length-- ) - { - if ( pRenderConfigPath[length] == '\\' || pRenderConfigPath[length] == '/' ) - { - length++; - break; - } - } - if ( length < 0 ) - { - /* no slash found */ - length = 0; - } - char *pCombinedName = calloc( length + (int32_t) strlen( pValue ) + 1, sizeof( char ) ); - strncpy( pCombinedName, pRenderConfigPath, length ); - strcpy( pCombinedName + length, pValue ); - - if ( ( error = RenderConfigReader_readBinary( pCombinedName, pRenderConfigReader ) ) != IVAS_ERR_OK ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - free( pCombinedName ); - } - else if ( strcmp( item, "DIRECTIVITY" ) == 0 ) - { - if ( read_txt_vector( pValue, 3, hRenderConfig->directivity ) ) - { - errorHandler( item, ERROR_VALUE_INVALID ); - } - } - params_idx += params_length; - } - free( pValue ); - } - else - { - fprintf( stderr, "Unknown chapter: %s\n", chapter ); - } - } - else if ( pConfig_str[0] == '#' ) - { - /* comment lines are to be ignored */ - } - } - - free( pConfig_str ); - free( pParams ); - free( pTemp ); - - if ( errorHandler( "", ERROR_NONE ) > 0 ) - { - fprintf( stderr, "Errors occurred\n" ); - return IVAS_ERR_FAILED_FILE_PARSE; - } - return IVAS_ERR_OK; -} - -#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT -/*------------------------------------------------------------------------------------------* - * RenderConfigReader_getAcousticEnvironmentCount() - * - * Gets number of acoustic environments available - *------------------------------------------------------------------------------------------*/ -uint32_t RenderConfigReader_getAcousticEnvironmentCount( - RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ -) -{ - return pRenderConfigReader->nAE; -} - -/*------------------------------------------------------------------------------------------* - * RenderConfigReader_getAcousticEnvironments() - * - * Gets all acoustic environments - *------------------------------------------------------------------------------------------*/ -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->aeID = (Word16) pIn.id; - pOut->nBands = (Word16) pIn.pFG->nrBands; - pOut->inputPreDelay_fx = (Word32) ( pIn.preDelay * ONE_IN_Q27 ); - - for ( m = 0; m < pOut->nBands; m++ ) - { - pOut->pFc_input_fx[m] = (Word32) ( pIn.pFG->pFc[m] * ONE_IN_Q16 ); - pOut->pAcoustic_rt60_fx[m] = (Word32) ( pIn.pRT60[m] * ONE_IN_Q26 ); - pOut->pAcoustic_dsr_fx[m] = (Word32) ( pIn.pDSR[m] * ONE_IN_Q30 ); - } - - /* 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; - pOut->dimensions.x_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x * ONE_IN_Q22 ); - pOut->dimensions.y_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.y * ONE_IN_Q22 ); - pOut->dimensions.z_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.z * ONE_IN_Q22 ); - - /* Use default listener origin position if non provided */ - if ( pIn.pEarlyReflections->pListenerOrigin == NULL ) - { - - pOut->ListenerOrigin.x_fx = IVAS_ER_LIST_ORIGIN_X_FX; - pOut->ListenerOrigin.y_fx = IVAS_ER_LIST_ORIGIN_Y_FX; - pOut->ListenerOrigin.z_fx = IVAS_ER_LIST_HEIGHT_FX; - pOut->ListenerOrigin.q_fact = Q22; - } - else - { - pOut->ListenerOrigin.x_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x_fx; - pOut->ListenerOrigin.y_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y_fx; - pOut->ListenerOrigin.z_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z_fx; - } - - for ( j = 0; j < IVAS_ROOM_ABS_COEFF; j++ ) - { - pOut->AbsCoeff_fx[j] = (Word32) ( pIn.pEarlyReflections->pAbsCoeff[j] * ONE_IN_Q30 ); - } - } - else - { - pOut->use_er = false; - } - } - - return IVAS_ERR_OK; -} -#endif - -/*------------------------------------------------------------------------------------------* - * RenderConfigReader_getAcousticEnvironment() - * - * Gets Acoustic environment with a given ID - *------------------------------------------------------------------------------------------*/ - -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 */ -) -{ - uint16_t n, m; - uint16_t j; - - if ( pRenderConfigReader == NULL || pAcEnv == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - /* case when -aeid is not specified, select first ID from config file */ -#ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT - if ( id == (UWord16) IVAS_DEFAULT_AEID && pRenderConfigReader->nAE > 0 ) -#else - if ( id == 65535 && pRenderConfigReader->nAE > 0 ) -#endif - { - id = (uint16_t) pRenderConfigReader->pAE[0].id; - } - - for ( n = 0; n < pRenderConfigReader->nAE; n++ ) - { - if ( id == pRenderConfigReader->pAE[n].id ) - { - pAcEnv->nBands = (int16_t) pRenderConfigReader->pAE[n].pFG->nrBands; - pAcEnv->inputPreDelay_fx = (Word32) ( pRenderConfigReader->pAE[n].preDelay * ONE_IN_Q27 ); - if ( pRenderConfigReader->pAE[n].preDelay > INPUTPREDELAY_MAX || - pRenderConfigReader->pAE[n].preDelay < INPUTPREDELAY_MIN ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - for ( m = 0; m < pAcEnv->nBands; m++ ) - { - if ( pRenderConfigReader->pAE[n].pFG->pFc[m] > FC_INPUT_MAX || - pRenderConfigReader->pAE[n].pFG->pFc[m] < FC_INPUT_MIN || - pRenderConfigReader->pAE[n].pRT60[m] > ACOUSTIC_RT60_MAX || - pRenderConfigReader->pAE[n].pRT60[m] < ACOUSTIC_RT60_MIN || - pRenderConfigReader->pAE[n].pDSR[m] > ACOUSTIC_DSR_MAX || - pRenderConfigReader->pAE[n].pDSR[m] < ACOUSTIC_DSR_MIN ) - { - return IVAS_ERR_INVALID_RENDER_CONFIG; - } - - pAcEnv->pFc_input_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pFG->pFc[m] * ONE_IN_Q16 ); - pAcEnv->pAcoustic_rt60_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pRT60[m] * ONE_IN_Q26 ); - pAcEnv->pAcoustic_dsr_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pDSR[m] * ONE_IN_Q30 ); - } - - /* If ER are allocated then propagate parameters */ - if ( pRenderConfigReader->pAE[n].pEarlyReflections != 0 ) - { - pAcEnv->use_er = pRenderConfigReader->pAE[n].pEarlyReflections->use_er; /* ER activation flag */ - pAcEnv->lowComplexity = pRenderConfigReader->pAE[n].pEarlyReflections->lowComplexity; /* Low complexity flag */ - pAcEnv->dimensions = pRenderConfigReader->pAE[n].pEarlyReflections->dimensions; - pAcEnv->dimensions.x_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x * ONE_IN_Q22 ); - pAcEnv->dimensions.y_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.y * ONE_IN_Q22 ); - pAcEnv->dimensions.z_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.z * ONE_IN_Q22 ); - /* Use default listener origin position if non provided */ - if ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin == NULL ) - { - if ( ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x = IVAS_ER_LIST_ORIGIN_X; - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y = IVAS_ER_LIST_ORIGIN_Y; - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z = IVAS_ER_LIST_HEIGHT; - - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x_fx = IVAS_ER_LIST_ORIGIN_X_FX; - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y_fx = IVAS_ER_LIST_ORIGIN_Y_FX; - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z_fx = IVAS_ER_LIST_HEIGHT_FX; - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->q_fact = Q22; - } - else - { - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x * ONE_IN_Q22 ); - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y * ONE_IN_Q22 ); - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z * ONE_IN_Q22 ); - } - pAcEnv->ListenerOrigin = *pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin; - for ( j = 0; j < IVAS_ROOM_ABS_COEFF; j++ ) - { - pAcEnv->AbsCoeff[j] = pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[j]; - pAcEnv->AbsCoeff_fx[j] = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[j] * ONE_IN_Q30 ); - } - } - else - { - pAcEnv->use_er = false; - } - return IVAS_ERR_OK; - } - } - return IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING; -} - -/*------------------------------------------------------------------------------------------* - * RenderConfigReader_getDirectivity() - * - * Gets Directivity DirectrivityPatern with a given ID - *------------------------------------------------------------------------------------------*/ - -ivas_error RenderConfigReader_getDirectivity( - RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ - uint16_t *id, /* i : Directivity pattern ID */ - Word16 *directivity_fx /* o : Target directivity */ -) -{ - uint16_t n, m, i; - uint16_t last_specified_id; - bool idExists; - float directivity[12]; - - if ( pRenderConfigReader == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - if ( pRenderConfigReader->pDP == NULL ) - { - for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) - { - directivity[n * 3] = 360.0f; - directivity[n * 3 + 1] = 360.0f; - directivity[n * 3 + 2] = 1.0f; - } - } - else - { - last_specified_id = id[0]; - - /* set unpspecified Directivity Patterns ID to last specified ID */ - for ( n = MAX_NUM_OBJECTS - 1; n > 0; n-- ) - { - if ( id[n] != 65535 ) - { - last_specified_id = id[n]; - break; - } - } - /* case when -dpid is not specified, select first directivity pattern from config file */ - move16(); - if ( last_specified_id == 65535 ) - { - last_specified_id = (uint16_t) pRenderConfigReader->pDP[0].id; - } - - for ( ; n < IVAS_MAX_NUM_OBJECTS; n++ ) - { - id[n] = last_specified_id; - } - - for ( n = 0; n < IVAS_MAX_NUM_OBJECTS; n++ ) - { - idExists = false; - for ( m = 0; m < pRenderConfigReader->nDP; m++ ) - { - if ( id[n] == pRenderConfigReader->pDP[m].id ) - { - idExists = true; - for ( i = 0; i < 3; i++ ) - { - directivity[n * 3 + i] = pRenderConfigReader->pDP[m].pDirectivity[i]; - } - - break; - } - } - if ( !idExists ) - { - return IVAS_ERR_DIRECTIVITY_PATTERN_ID_MISSING; - } - } - } - - /* Convert to Word16 */ - FOR( n = 0; n < 4; n++ ) - { - directivity_fx[n * 3] = (Word16) ( directivity[n * 3] * ( 1u << 6 ) ); - directivity_fx[n * 3 + 1] = (Word16) ( directivity[n * 3 + 1] * ( 1u << 6 ) ); - directivity_fx[n * 3 + 2] = (Word16) ( directivity[n * 3 + 2] * ( ( 1u << 15 ) - 1 ) ); - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------------------------* - * RenderConfigReader_getDistanceAttenuation() - * - * Gets Distance Attenuation - *------------------------------------------------------------------------------------------*/ - -ivas_error RenderConfigReader_getDistanceAttenuation( - RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ - - Word32 *distAtt_fx /* o : Distance attenuation */ -) -{ - float distAtt[3]; - - if ( pRenderConfigReader->distAtt[0] == -1 ) - { - distAtt[0] = 15.75f; - distAtt[1] = 1.0f; - distAtt[2] = 1.0f; - } - else - { - distAtt[0] = pRenderConfigReader->distAtt[0]; - distAtt[1] = pRenderConfigReader->distAtt[1]; - distAtt[2] = pRenderConfigReader->distAtt[2]; - } - - /* Convert to Word32 */ - distAtt_fx[0] = (Word32) ( distAtt[0] * ( 1u << 27 ) ); - distAtt_fx[1] = (Word32) ( distAtt[1] * ( 1u << 30 ) ); - distAtt_fx[2] = (Word32) ( distAtt[2] * ( 1u << 30 ) ); - - return IVAS_ERR_OK; -} - -/*------------------------------------------------------------------------------------------* - * RenderConfigReader_close() - * - * Closes the renderer configuration reader and deallocates memory - *------------------------------------------------------------------------------------------*/ - -void RenderConfigReader_close( - RenderConfigReader **ppRenderConfigReader /* i : RenderConfigReader handle */ -) -{ - uint32_t n; - - if ( ppRenderConfigReader == NULL || *ppRenderConfigReader == NULL ) - { - return; - } - - /* Free the acoustic environments */ - for ( n = 0; n < ( *ppRenderConfigReader )->nAE; n++ ) - { - if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections != NULL ) - { - free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin ); - free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections ); - } - free( ( *ppRenderConfigReader )->pAE[n].pRT60 ); - free( ( *ppRenderConfigReader )->pAE[n].pDSR ); - } - free( ( *ppRenderConfigReader )->pAE ); - - /* Free the frequency grids */ - for ( n = 0; n < ( *ppRenderConfigReader )->nFG; n++ ) - { - free( ( *ppRenderConfigReader )->pFG[n].pFc ); - } - free( ( *ppRenderConfigReader )->pFG ); - /* Free the directivity patterns */ - for ( n = 0; n < ( *ppRenderConfigReader )->nDP; n++ ) - { - free( ( *ppRenderConfigReader )->pDP[n].pDirectivity ); - } - free( ( *ppRenderConfigReader )->pDP ); - fclose( ( *ppRenderConfigReader )->pConfigFile ); - free( *ppRenderConfigReader ); - - return; -} diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index a212c79b7..1efe5d2b4 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2945,7 +2945,7 @@ ivas_error RenderConfigReader_getAcousticEnvironments( for ( j = 0; j < IVAS_ROOM_ABS_COEFF; j++ ) { - pOut->AbsCoeff[j] = (Word32) ( pIn.pEarlyReflections->pAbsCoeff[j] ); + pOut->AbsCoeff[j] = pIn.pEarlyReflections->pAbsCoeff[j]; pOut->AbsCoeff_fx[j] = (Word32) ( pIn.pEarlyReflections->pAbsCoeff[j] * ONE_IN_Q30 ); } } -- GitLab From de277821623e419795f1a9b7e176bfe7ac235aa6 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 10 Nov 2025 21:17:28 +0100 Subject: [PATCH 12/14] Fix for early reflections listener origin --- lib_util/render_config_reader.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 1efe5d2b4..28dd6abf6 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2886,7 +2886,7 @@ ivas_error RenderConfigReader_getAcousticEnvironments( if ( pRenderConfigReader == NULL || ppAcEnv == NULL || pRenderConfigReader->nAE == 0 || pRenderConfigReader->pAE == NULL ) { - return 0; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } for ( n = 0; n < pRenderConfigReader->nAE; n++ ) @@ -2938,9 +2938,9 @@ ivas_error RenderConfigReader_getAcousticEnvironments( pOut->ListenerOrigin.y = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y; pOut->ListenerOrigin.z = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z; - pOut->ListenerOrigin.x_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x_fx; - pOut->ListenerOrigin.y_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y_fx; - pOut->ListenerOrigin.z_fx = pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z_fx; + pOut->ListenerOrigin.x_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x * ONE_IN_Q22 ); + pOut->ListenerOrigin.y_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y * ONE_IN_Q22 ); + pOut->ListenerOrigin.z_fx = (Word32) ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z * ONE_IN_Q22 ); } for ( j = 0; j < IVAS_ROOM_ABS_COEFF; j++ ) -- GitLab From a6d3fa31dd90902eb9e5115c5b4f9cffcf46b690 Mon Sep 17 00:00:00 2001 From: Lauros Pajunen Date: Mon, 10 Nov 2025 23:13:18 +0200 Subject: [PATCH 13/14] General basop fixes --- lib_dec/ivas_init_dec_fx.c | 1 + lib_dec/lib_dec_fx.c | 25 ++++++++----------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/lib_dec/ivas_init_dec_fx.c b/lib_dec/ivas_init_dec_fx.c index 453861bb4..5300b598b 100644 --- a/lib_dec/ivas_init_dec_fx.c +++ b/lib_dec/ivas_init_dec_fx.c @@ -3281,6 +3281,7 @@ void ivas_initialize_handles_dec( st_ivas->hCombinedOrientationData = NULL; #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT st_ivas->acousticEnvironmentsCount = 0; + move16(); st_ivas->pAcousticEnvironments = NULL; #endif diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index be99da3ae..5ae845a46 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -2986,6 +2986,8 @@ ivas_error IVAS_DEC_AddAcousticEnvironment( Decoder_Struct *st_ivas; IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAE = NULL; + test(); + test(); test(); IF( hIvasDec == NULL || hIvasDec->st_ivas == NULL || ( hIvasDec->st_ivas->acousticEnvironmentsCount > 0 && hIvasDec->st_ivas->pAcousticEnvironments == NULL ) ) { @@ -2997,7 +2999,6 @@ ivas_error IVAS_DEC_AddAcousticEnvironment( /* Check if already there */ FOR( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) { - test(); IF( st_ivas->pAcousticEnvironments[n].aeID == roomAcousticsConfig.aeID ) { move32(); @@ -3007,7 +3008,6 @@ ivas_error IVAS_DEC_AddAcousticEnvironment( } /* If not found */ - test(); IF( pAE == NULL ) { IVAS_ROOM_ACOUSTICS_CONFIG_DATA *ppAE = realloc( st_ivas->pAcousticEnvironments, ( st_ivas->acousticEnvironmentsCount + 1 ) * sizeof( IVAS_ROOM_ACOUSTICS_CONFIG_DATA ) ); @@ -3041,7 +3041,6 @@ ivas_error IVAS_DEC_AddAcousticEnvironment( move32(); move16(); - test(); IF( pAE->use_er == 1 ) { pAE->lowComplexity = roomAcousticsConfig.lowComplexity; @@ -3103,7 +3102,6 @@ ivas_error IVAS_DEC_GetAcousticEnvironment( { IVAS_ROOM_ACOUSTICS_CONFIG_DATA ae = st_ivas->pAcousticEnvironments[n]; move32(); - test(); IF( aeID == ae.aeID ) { found = 1; @@ -3128,7 +3126,6 @@ ivas_error IVAS_DEC_GetAcousticEnvironment( /* If ER are allocated then propagate parameters */ pAcEnv->use_er = ae.use_er; move16(); - test(); IF( ae.use_er != 0 ) { pAcEnv->lowComplexity = ae.lowComplexity; @@ -3153,7 +3150,6 @@ ivas_error IVAS_DEC_GetAcousticEnvironment( } } - test(); return found ? IVAS_ERR_OK : IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING; } #endif @@ -3403,14 +3399,12 @@ static ivas_error IVAS_DEC_FeedAcousticEnvPI( move32(); /* Ignore if AE ID already in use */ - test(); IF( hRenderConfig->roomAcoustics.aeID == hAcoustEnvPI.aeid ) { return IVAS_ERR_OK; } /* Attempt to load the one already available */ - test(); IF( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) == IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) { /* Add the new compact room environment */ @@ -3447,7 +3441,6 @@ static ivas_error IVAS_DEC_FeedAcousticEnvPI( acEnv.use_er = hAcoustEnvPI.availEarlyReflections; move16(); - test(); IF( hAcoustEnvPI.availEarlyReflections ) { hRenderConfig->roomAcoustics.dimensions.x_fx = hAcoustEnvPI.roomDimensions.x_fx; @@ -3460,13 +3453,11 @@ static ivas_error IVAS_DEC_FeedAcousticEnvPI( mvr2r( hAcoustEnvPI.absorbCoeffs, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); } - test(); IF( ( error = IVAS_DEC_AddAcousticEnvironment( hIvasDec, acEnv ) ) != IVAS_ERR_OK ) { return error; } - test(); IF( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) != IVAS_ERR_OK ) { return error; @@ -3476,10 +3467,8 @@ static ivas_error IVAS_DEC_FeedAcousticEnvPI( /* Re-initialize reverb instance if already available */ /* TD renderer Jot reverberator */ - test(); IF( st_ivas->hReverb != NULL ) { - test(); IF( ( error = ivas_reverb_open_fx( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; @@ -3488,9 +3477,9 @@ static ivas_error IVAS_DEC_FeedAcousticEnvPI( /* CREND Jot reverberator */ test(); + test(); IF( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) { - test(); IF( ( error = ivas_reverb_open_fx( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; @@ -3498,11 +3487,11 @@ static ivas_error IVAS_DEC_FeedAcousticEnvPI( } /* Parametric renderer reverberator */ + test(); IF( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) { ivas_binaural_reverb_close_fx( &( st_ivas->hDiracDecBin[0]->hReverb ) ); - test(); IF( ( error = ivas_binaural_reverb_init_fx( &( 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 ) { @@ -3516,7 +3505,6 @@ static ivas_error IVAS_DEC_FeedAcousticEnvPI( { ivas_binaural_reverb_close_fx( &( st_ivas->hBinRenderer->hReverb ) ); - test(); IF( ( error = ivas_binaural_reverb_init_fx( &( 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 ) { @@ -7006,10 +6994,13 @@ ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *pi #ifdef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT case IVAS_PI_ACOUSTIC_ENVIRONMENT: { - UWord16 aeid = piData->data.acousticEnv.aeid; + UWord16 aeid; + aeid = piData->data.acousticEnv.aeid; + move16(); #ifdef DEBUGGING fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); #endif + test(); test(); IF( piData->data.acousticEnv.availLateReverb && hIvasDec->st_ivas->hRenderConfig != NULL && aeid != hIvasDec->st_ivas->hRenderConfig->roomAcoustics.aeID ) { -- GitLab From 676f09d6e20523c664575bc73f99dc43f1ea6990 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 11 Nov 2025 09:28:37 +0100 Subject: [PATCH 14/14] Render config: disabling float value checks --- lib_util/render_config_reader.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 28dd6abf6..c56ab9df9 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1305,50 +1305,62 @@ ivas_error RenderConfigReader_checkValues( if ( pRoom_acoustics->use_er == 1 ) { /* Room dimensions */ +#ifndef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT if ( pRoom_acoustics->dimensions.x < ER_MIN_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.x = ER_MIN_ROOM_DIMENSION; } +#endif if ( pRoom_acoustics->dimensions.x_fx < ER_MIN_ROOM_DIMENSION_FX ) { pRoom_acoustics->dimensions.x_fx = ER_MIN_ROOM_DIMENSION_FX; } +#ifndef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT if ( pRoom_acoustics->dimensions.x > ER_MAX_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.x = ER_MAX_ROOM_DIMENSION; } +#endif if ( pRoom_acoustics->dimensions.x_fx > ER_MAX_ROOM_DIMENSION_FX ) { pRoom_acoustics->dimensions.x_fx = ER_MAX_ROOM_DIMENSION_FX; } +#ifndef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT if ( pRoom_acoustics->dimensions.y < ER_MIN_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.y = ER_MIN_ROOM_DIMENSION; } +#endif if ( pRoom_acoustics->dimensions.y_fx < ER_MIN_ROOM_DIMENSION_FX ) { pRoom_acoustics->dimensions.y_fx = ER_MIN_ROOM_DIMENSION_FX; } +#ifndef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT if ( pRoom_acoustics->dimensions.y > ER_MAX_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.y = ER_MAX_ROOM_DIMENSION; } +#endif if ( pRoom_acoustics->dimensions.y_fx > ER_MAX_ROOM_DIMENSION_FX ) { pRoom_acoustics->dimensions.y_fx = ER_MAX_ROOM_DIMENSION_FX; } +#ifndef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT if ( pRoom_acoustics->dimensions.z < ER_MIN_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.z = ER_MIN_ROOM_DIMENSION; } +#endif if ( pRoom_acoustics->dimensions.z_fx < ER_MIN_ROOM_DIMENSION_FX ) { pRoom_acoustics->dimensions.z_fx = ER_MIN_ROOM_DIMENSION_FX; } +#ifndef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT if ( pRoom_acoustics->dimensions.z > ER_MAX_ROOM_DIMENSION ) { pRoom_acoustics->dimensions.z = ER_MAX_ROOM_DIMENSION; } +#endif if ( pRoom_acoustics->dimensions.z_fx > ER_MAX_ROOM_DIMENSION_FX ) { pRoom_acoustics->dimensions.z_fx = ER_MAX_ROOM_DIMENSION_FX; @@ -1357,18 +1369,22 @@ ivas_error RenderConfigReader_checkValues( /* Abs Coeff */ for ( wall_idx = 0; wall_idx < IVAS_ROOM_ABS_COEFF; wall_idx++ ) { +#ifndef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT if ( pRoom_acoustics->AbsCoeff[wall_idx] < ER_MIN_ABS_COEFF ) { pRoom_acoustics->AbsCoeff[wall_idx] = ER_MIN_ABS_COEFF; } +#endif if ( pRoom_acoustics->AbsCoeff_fx[wall_idx] < ER_MIN_ABS_COEFF_FX ) { pRoom_acoustics->AbsCoeff_fx[wall_idx] = ER_MIN_ABS_COEFF_FX; } +#ifndef IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT if ( pRoom_acoustics->AbsCoeff[wall_idx] > ER_MAX_ABS_COEFF ) { pRoom_acoustics->AbsCoeff[wall_idx] = ER_MAX_ABS_COEFF; } +#endif if ( pRoom_acoustics->AbsCoeff_fx[wall_idx] > ER_MAX_ABS_COEFF_FX ) { pRoom_acoustics->AbsCoeff_fx[wall_idx] = ER_MAX_ABS_COEFF_FX; -- GitLab