From e75295863c886f2d18b663e3bfadaf05b8568f30 Mon Sep 17 00:00:00 2001 From: szczerba Date: Thu, 6 Apr 2023 10:41:20 +0200 Subject: [PATCH 001/101] Contribution 37 - Control metadata for reverb --- apps/decoder.c | 62 +- apps/renderer.c | 72 ++ lib_com/ivas_cnst.h | 3 + lib_com/ivas_error.h | 4 + lib_com/options.h | 2 + lib_dec/ivas_init_dec.c | 12 + lib_dec/ivas_ism_dec.c | 8 + lib_dec/ivas_ism_metadata_dec.c | 1 - lib_dec/ivas_ism_param_dec.c | 16 + lib_dec/ivas_mct_dec.c | 4 + lib_dec/ivas_output_config.c | 8 + lib_dec/ivas_spar_decoder.c | 4 + lib_dec/lib_dec.c | 12 + lib_dec/lib_dec.h | 3 + lib_enc/ivas_ism_metadata_enc.c | 1 - lib_rend/ivas_crend.c | 7 + lib_rend/ivas_output_init.c | 6 + lib_rend/lib_rend.c | 52 +- lib_rend/lib_rend.h | 3 + lib_util/render_config_reader.c | 981 +++++++++++++++++- lib_util/render_config_reader.h | 14 + scripts/config/self_test.prm | 16 +- scripts/pyivastest/constants.py | 3 +- .../rend_config_hospital_patientroom.cfg | 37 +- scripts/testv/rend_config_recreation.cfg | 37 +- scripts/testv/rend_config_renderer.cfg | 16 +- 26 files changed, 1312 insertions(+), 72 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index d2260713c2..d3aa314f5f 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -76,6 +76,10 @@ static #define IVAS_PUBLIC_ORIENT_TRK_REF_VEC ( 3 ) #define IVAS_PUBLIC_ORIENT_TRK_REF_VEC_LEV ( 4 ) +#ifdef CONTROL_METADATA_REVERB +#define ACOUSTIC_ENVIRONMENT_ID 0 +#endif + typedef struct { char *inputBitstreamFilename; @@ -229,7 +233,11 @@ int main( if ( arg.hrtfReaderEnabled ) { /* sanity check */ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_REVERB ) +#else if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM ) +#endif { arg.hrtfReaderEnabled = false; fprintf( stderr, "\nError: HRTF binary file cannot be used in this output configuration.\n\n" ); @@ -251,7 +259,11 @@ int main( if ( arg.enableHeadRotation ) { /* sanity check */ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_REVERB ) +#else if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM ) +#endif { fprintf( stderr, "\nError: Head-rotation file file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -271,7 +283,7 @@ int main( if ( arg.enableReferenceRotation ) { /* sanity check */ - if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM ) + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_REVERB ) { fprintf( stderr, "\nError: Reference rotation file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -298,7 +310,7 @@ int main( if ( arg.enableReferenceVectorTracking ) { /* sanity check */ - if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM ) + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_REVERB ) { fprintf( stderr, "\nError: Reference vector trajectory file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -338,7 +350,11 @@ int main( if ( arg.renderConfigEnabled ) { /* sanity check */ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_REVERB ) +#else if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM ) +#endif { fprintf( stderr, "\nError: Renderer configuration file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -461,9 +477,17 @@ int main( IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_REVERB && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL ) +#else if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL ) +#endif { +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + fprintf( stderr, "\nExternal Renderer Config is supported only for BINAURAL, BINAURAL_ROOM, and BINAURAL_REVERB. Exiting. \n\n" ); +#else fprintf( stderr, "\nExternal Renderer Config is supported only for BINAURAL and BINAURAL_ROOM. Exiting. \n\n" ); +#endif goto cleanup; } @@ -473,12 +497,36 @@ int main( goto cleanup; } +#ifdef CONTROL_METADATA_REVERB + if ( RenderConfigReader_read( renderConfigReader ) != IVAS_ERR_OK ) +#else if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); goto cleanup; } +#ifdef CONTROL_METADATA_REVERB + if ( RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); + goto cleanup; + } + +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( arg.outputFormat == IVAS_DEC_OUTPUT_BINAURAL_REVERB ) + { + renderConfig.room_acoustics.late_reverb_on = true; + renderConfig.room_acoustics.override = true; + renderConfig.room_acoustics.use_brir = false; + } +#else + renderConfig.room_acoustics.late_reverb_on = true; + renderConfig.room_acoustics.override = true; +#endif +#endif + if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -721,6 +769,12 @@ static IVAS_DEC_AUDIO_CONFIG cmdline2config( { output_config = IVAS_DEC_OUTPUT_BINAURAL_ROOM; } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + else if ( strcmp( argv_to_upper, "BINAURAL_REVERB" ) == 0 ) + { + output_config = IVAS_DEC_OUTPUT_BINAURAL_REVERB; + } +#endif else { output_config = IVAS_DEC_OUTPUT_LS_CUSTOM; @@ -1152,7 +1206,11 @@ static void usage_dec( void ) fprintf( stdout, "Mandatory parameters:\n" ); fprintf( stdout, "---------------------\n" ); fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" ); +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM, BINAURAL_REVERB, EXT\n" ); +#else fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM, EXT\n" ); +#endif fprintf( stdout, " By default, channel order and loudspeaker positions are equal to the\n" ); fprintf( stdout, " encoder. For loudspeaker outputs, OutputConf can be a custom loudspeaker\n" ); fprintf( stdout, " layout file. See readme.txt for details.\n" ); diff --git a/apps/renderer.c b/apps/renderer.c index c2fb6add8a..03b2398947 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -60,6 +60,10 @@ #define RENDERER_MAX_METADATA_LENGTH 8192 #define RENDERER_MAX_METADATA_LINE_LENGTH 1024 +#ifdef CONTROL_METADATA_REVERB +#define ACOUSTIC_ENVIRONMENT_ID 0 +#endif + #if !defined( DEBUGGING ) && !defined( WMOPS ) static #endif @@ -213,25 +217,41 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_trajFile, .match = "trajectory_file", .matchShort = "tf", +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + .description = "Head rotation trajectory file for simulation of head tracking (only for BINAURAL, BINAURAL_ROOM, and BINAURAL_REVERB outputs)", +#else .description = "Head rotation trajectory file for simulation of head tracking (only for BINAURAL and BINAURAL_ROOM outputs)", +#endif }, { .id = CmdLnOptionId_refRotFile, .match = "reference_rotation_file", .matchShort = "rf", +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + .description = "Reference rotation trajectory file for simulation of head tracking (only for BINAURAL, BINAURAL_ROOM, and BINAURAL_REVERB outputs)", +#else .description = "Reference rotation trajectory file for simulation of head tracking (only for BINAURAL and BINAURAL_ROOM outputs)", +#endif }, { .id = CmdLnOptionId_customHrtfFile, .match = "custom_hrtf", .matchShort = "hrtf", +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + .description = "Custom HRTF file for binaural rendering (only for BINAURAL, BINAURAL_ROOM, and BINAURAL_REVERB outputs)", +#else .description = "Custom HRTF file for binaural rendering (only for BINAURAL and BINAURAL_ROOM outputs)", +#endif }, { .id = CmdLnOptionId_renderConfigFile, .match = "render_config", .matchShort = "rc", +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + .description = "Binaural renderer configuration file (only for BINAURAL, BINAURAL_ROOM, and BINAURAL_REVERB outputs)", +#else .description = "Binaural renderer configuration file (only for BINAURAL and BINAURAL_ROOM outputs)", +#endif }, { .id = CmdLnOptionId_noDiegeticPan, @@ -243,7 +263,11 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_orientationTracking, .match = "tracking_type", .matchShort = "otr", +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + .description = "Head orientation tracking type: 'none', 'ref', 'avg' or `ref_vec` or `ref_vec_lev` (only for BINAURAL, BINAURAL_ROOM, and BINAURAL_REVERB)", +#else .description = "Head orientation tracking type: 'none', 'ref', 'avg' or `ref_vec` or `ref_vec_lev` (only for BINAURAL and BINAURAL_ROOM)", +#endif }, { .id = CmdlnOptionId_lfePosition, @@ -283,7 +307,11 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_referenceVectorFile, .match = "reference_vector_file", .matchShort = "rvf", +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + .description = "Reference vector trajectory file for simulation of head tracking (only for BINAURAL, BINAURAL_ROOM, and BINAURAL_REVERB outputs)", +#else .description = "Reference vector trajectory file for simulation of head tracking (only for BINAURAL and BINAURAL_ROOM outputs)", +#endif }, }; @@ -673,7 +701,11 @@ int main( } /* === Configure === */ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( ( error = IVAS_REND_InitConfig( hIvasRend, ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) || ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) || ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL ) ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_REND_InitConfig( hIvasRend, ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) || ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL ) ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Error in Renderer Config Init\n" ); exit( -1 ); @@ -684,9 +716,17 @@ int main( IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) && ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) && ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL ) ) +#else if ( ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) && ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL ) ) +#endif { +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL, BINAURAL_ROOM, or BINAURAL_REVERB is used as output. Exiting. \n" ); +#else fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL or BINAURAL_ROOM is used as output. Exiting. \n" ); +#endif exit( -1 ); } @@ -696,12 +736,35 @@ int main( exit( -1 ); } +#ifdef CONTROL_METADATA_REVERB + if ( RenderConfigReader_read( renderConfigReader ) != IVAS_ERR_OK ) +#else if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFilePath ); exit( -1 ); } +#ifdef CONTROL_METADATA_REVERB + if ( RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); + exit( -1 ); + } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) + { + renderConfig.room_acoustics.late_reverb_on = TRUE; + renderConfig.room_acoustics.override = TRUE; + renderConfig.room_acoustics.use_brir = FALSE; + } +#else + renderConfig.room_acoustics.late_reverb_on = TRUE; + renderConfig.room_acoustics.override = TRUE; +#endif +#endif + if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); @@ -1482,6 +1545,12 @@ static IVAS_REND_AudioConfig parseAudioConfig( { return IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM; } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( strcmp( charBuf, "BINAURAL_REVERB" ) == 0 ) + { + return IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB; + } +#endif if ( strcmp( charBuf, "BINAURAL" ) == 0 ) { return IVAS_REND_AUDIO_CONFIG_BINAURAL; @@ -2506,6 +2575,9 @@ static void printSupportedAudioConfigs() "MASAx (input only)", "BINAURAL (output only)", "BINAURAL_ROOM (output only)", +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + "BINAURAL_REVERB (output only)", +#endif }; fprintf( stdout, "Supported audio formats:\n" ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 1da32f2145..8b02bbfa92 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -102,6 +102,9 @@ typedef enum AUDIO_CONFIG_OBA, /* object based audio */ AUDIO_CONFIG_BINAURAL, /* binaural with HRIR */ AUDIO_CONFIG_BINAURAL_ROOM, /* binaural with HRIR and BRIR */ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + AUDIO_CONFIG_BINAURAL_REVERB, /* binaural with reverberation */ +#endif AUDIO_CONFIG_ISM1, /* ISM1 */ AUDIO_CONFIG_ISM2, /* ISM2 */ AUDIO_CONFIG_ISM3, /* ISM3 */ diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 9438ad44a1..a13395d825 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -133,6 +133,10 @@ typedef enum IVAS_ERR_INVALID_INPUT_ID, IVAS_ERR_WRONG_NUM_CHANNELS, IVAS_ERR_INVALID_BUFFER_SIZE, +#ifdef CONTROL_METADATA_REVERB + IVAS_ERR_INVALID_RENDER_CONFIG, + IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING, +#endif /*----------------------------------------* * unknown error * diff --git a/lib_com/options.h b/lib_com/options.h index 6d97909f18..08ed5c4991 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -141,6 +141,8 @@ #define DISABLE_ADAP_RES_COD_TMP /* temporary fix for IVAS-403, disables adaptive residual coding */ /*#define ITD_WINNER_GAIN_MODIFY */ /* ITD optimization - WORK IN PROGRESS */ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ +#define CONTROL_METADATA_REVERB /* Philips: renderer configuration change to binary format */ +#define COMMAND_LINE_OPTION_LATE_REVERB /* Philips: late reverb command line option */ #define FIX_103_RA_PARAMS_PARAM_BIN_REND /* Issue 103: Digest room acoustics parameters for Parametric Binaural Renderer*/ /*#define SBA_HPF_TUNING_DEC*/ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index e53218d3e7..4b85e52ba4 100755 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -676,14 +676,22 @@ ivas_error ivas_init_decoder_front( * Allocate and initialize Binaural Renderer configuration handle *--------------------------------------------------------------------*/ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_REVERB ) +#else if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { if ( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ) != IVAS_ERR_OK ) { return error; } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( ( error = ivas_render_config_init_from_rom( &st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_REVERB ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_render_config_init_from_rom( &st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2109,7 +2117,11 @@ static ivas_error doSanityChecks_IVAS( if ( st_ivas->hDecoderConfig->Opt_Headrotation ) { +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( !( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM || output_config == AUDIO_CONFIG_BINAURAL_REVERB ) ) +#else if ( !( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) +#endif { return IVAS_ERROR( IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED, "Wrong set-up: Head-rotation not supported in this configuration" ); } diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index e6571e83d9..ece13ab3d5 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -148,7 +148,11 @@ static ivas_error ivas_ism_bitrate_switching( } } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_REVERB ) +#else if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { /* close the parametric binaural renderer */ ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); @@ -211,7 +215,11 @@ static ivas_error ivas_ism_bitrate_switching( } } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_REVERB ) +#else if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { /* open the parametric binaural renderer */ if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index 75b9164e1d..e60cad7ee2 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -817,7 +817,6 @@ static int16_t decode_radius( return idx_radius; } - #ifdef DISCRETE_ISM_DTX_CNG /*-------------------------------------------------------------------* * ivas_ism_metadata_sid_dec() diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index f66323d8a4..0340ca57e4 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -364,7 +364,11 @@ static ivas_error ivas_param_ism_rendering_init( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) ); } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( !( output_config == AUDIO_CONFIG_EXTERNAL || output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM || output_config == AUDIO_CONFIG_BINAURAL_REVERB ) ) +#else if ( !( output_config == AUDIO_CONFIG_EXTERNAL || output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) +#endif { /* computation of proto matrix */ ivas_ism_get_proto_matrix( hOutSetup, nchan_transport, hParamIsmRendering->proto_matrix ); @@ -519,7 +523,11 @@ ivas_error ivas_param_ism_dec_open( } } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( !( output_config == AUDIO_CONFIG_EXTERNAL || output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM || output_config == AUDIO_CONFIG_BINAURAL_REVERB || output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) ) +#else if ( !( output_config == AUDIO_CONFIG_EXTERNAL || output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM || output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) ) +#endif { /* Initialize efap handle */ if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), hOutSetup.ls_azimuth, hOutSetup.ls_elevation, hOutSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) @@ -537,7 +545,11 @@ ivas_error ivas_param_ism_dec_open( hDirAC->dirac_read_idx = 0; hDirAC->spar_to_dirac_write_idx = 0; +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM || output_config == AUDIO_CONFIG_BINAURAL_REVERB ) ) +#else if ( ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) +#endif { hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES; if ( ( hDirAC->azimuth = (int16_t **) malloc( hDirAC->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL ) @@ -680,7 +692,11 @@ void ivas_param_ism_dec_close( hDirAC->hParamIsm = NULL; } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM || output_config == AUDIO_CONFIG_BINAURAL_REVERB ) ) +#else if ( ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) +#endif { for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ ) { diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index f39951e087..e2c4c269d0 100755 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -1031,7 +1031,11 @@ static ivas_error ivas_mc_dec_reconfig( output_config = st_ivas->hDecoderConfig->output_config; /* binaural renderers*/ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM || output_config == AUDIO_CONFIG_BINAURAL_REVERB ) +#else if ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { /* remove unneeded binaural renderers */ if ( st_ivas->hBinRenderer != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV && st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) ) diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index f522a3217d..5729b79ff4 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -76,7 +76,11 @@ void ivas_renderer_select( st_ivas->hHeadTrackData->shd_rot_max_order = -1; } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM || output_config == AUDIO_CONFIG_BINAURAL_REVERB ) +#else if ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { if ( st_ivas->ivas_format == ISM_FORMAT ) { @@ -226,7 +230,11 @@ void ivas_renderer_select( } } } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + else /* AUDIO_CONFIG_BINAURAL_ROOM or AUDIO_CONFIG_BINAURAL_REVERB */ +#else else /* AUDIO_CONFIG_BINAURAL_ROOM */ +#endif { if ( st_ivas->mc_mode == MC_MODE_MCT ) { diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 01e4db2ed4..440cca8009 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -1171,7 +1171,11 @@ void ivas_spar_dec_upmixer( } else { +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( hDecoderConfig->output_config == AUDIO_CONFIG_FOA || !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_REVERB ) ) +#else if ( hDecoderConfig->output_config == AUDIO_CONFIG_FOA || !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) +#endif { for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) { diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 0497a0a713..1d293f21ef 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -334,6 +334,12 @@ static AUDIO_CONFIG mapOutputFormat( { output_config = AUDIO_CONFIG_BINAURAL_ROOM; } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + else if ( outputFormat == IVAS_DEC_OUTPUT_BINAURAL_REVERB ) + { + output_config = AUDIO_CONFIG_BINAURAL_REVERB; + } +#endif else { output_config = AUDIO_CONFIG_INVALID; @@ -1865,6 +1871,12 @@ static ivas_error get_channel_config( { strcpy( str, "Binaural_ROOM" ); } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + else if ( config == AUDIO_CONFIG_BINAURAL_REVERB ) + { + strcpy( str, "Binaural_REVERB" ); + } +#endif else if ( config == AUDIO_CONFIG_EXTERNAL ) { strcpy( str, "External renderer" ); diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index e1e5bfe9f4..20ff5a919b 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -57,6 +57,9 @@ typedef enum _IVAS_DEC_OUTPUT_CONFIG IVAS_DEC_OUTPUT_HOA3, IVAS_DEC_OUTPUT_BINAURAL, IVAS_DEC_OUTPUT_BINAURAL_ROOM, +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + IVAS_DEC_OUTPUT_BINAURAL_REVERB, +#endif IVAS_DEC_OUTPUT_EXT, IVAS_DEC_OUTPUT_UNKNOWN = 0xffff } IVAS_DEC_AUDIO_CONFIG; diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index 5b45d909f1..242bc17faf 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -937,7 +937,6 @@ static void encode_angle_indices( return; } - #ifdef DISCRETE_ISM_DTX_CNG /*-------------------------------------------------------------------* * ivas_ism_metadata_sid_enc() diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index c05ae7c262..c8b4ac8959 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -182,7 +182,11 @@ static ivas_error ivas_rend_initCrend( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Encountered unsupported input config in Crend" ); } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) +#else if ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Encountered unsupported output type in Crend" ); } @@ -197,6 +201,9 @@ static ivas_error ivas_rend_initCrend( /* set BRIR flag */ use_brir = false; +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + /* note: use_brir = false for IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB */ +#endif if ( ( ( hRendCfg != NULL ) && hRendCfg->roomAcoustics.use_brir ) || ( ( hRendCfg == NULL ) && ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) ) ) { use_brir = true; diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 193e775f22..e5f7894d77 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -92,6 +92,9 @@ int16_t audioCfg2channels( break; case AUDIO_CONFIG_BINAURAL: case AUDIO_CONFIG_BINAURAL_ROOM: +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case AUDIO_CONFIG_BINAURAL_REVERB: +#endif nchan_out = 2; break; case AUDIO_CONFIG_ISM1: @@ -218,6 +221,9 @@ void ivas_output_init( break; case AUDIO_CONFIG_BINAURAL: case AUDIO_CONFIG_BINAURAL_ROOM: +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case AUDIO_CONFIG_BINAURAL_REVERB: +#endif case AUDIO_CONFIG_ISM1: case AUDIO_CONFIG_ISM2: case AUDIO_CONFIG_ISM3: diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index e97ae461cf..555c9af5c6 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -346,6 +346,10 @@ AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( return AUDIO_CONFIG_BINAURAL; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: return AUDIO_CONFIG_BINAURAL_ROOM; +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB: + return AUDIO_CONFIG_BINAURAL_REVERB; +#endif case IVAS_REND_AUDIO_CONFIG_MASA1: return AUDIO_CONFIG_MASA1; case IVAS_REND_AUDIO_CONFIG_MASA2: @@ -376,6 +380,10 @@ IVAS_REND_AudioConfig getRendAudioConfigFromIvasAudioConfig( return IVAS_REND_AUDIO_CONFIG_BINAURAL; case AUDIO_CONFIG_BINAURAL_ROOM: return IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM; +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case AUDIO_CONFIG_BINAURAL_REVERB: + return IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB; +#endif case AUDIO_CONFIG_5_1: return IVAS_REND_AUDIO_CONFIG_5_1; case AUDIO_CONFIG_7_1: @@ -422,6 +430,9 @@ static ivas_error validateOutputAudioConfig( case IVAS_REND_AUDIO_CONFIG_HOA3: case IVAS_REND_AUDIO_CONFIG_BINAURAL: case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB: +#endif return IVAS_ERR_OK; default: break; @@ -495,6 +506,9 @@ ivas_error getAudioConfigNumChannels( case IVAS_REND_AUDIO_CONFIG_STEREO: case IVAS_REND_AUDIO_CONFIG_BINAURAL: case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB: +#endif case IVAS_REND_AUDIO_CONFIG_MASA2: *numChannels = 2; break; @@ -783,7 +797,11 @@ static ivas_error initEfap( const float *elevations; int16_t numNonLfeChannels; +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) || ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) ) +#else if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { pEfapWrapper->speakerConfig = IVAS_REND_AUDIO_CONFIG_7_1_4; } @@ -1107,7 +1125,11 @@ static ivas_error setRendInputActiveIsm( return error; } } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + else if ( ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) || ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) ) +#else else if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { if ( hRendCfg != NULL && hRendCfg->roomAcoustics.use_brir == 0 && hRendCfg->roomAcoustics.late_reverb_on ) { @@ -1737,6 +1759,9 @@ static ivas_error updateMcPanGains( case IVAS_REND_AUDIO_CONFIG_BINAURAL: break; /* Do nothing */ case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB: +#endif /* Prepare rendering to intermediate format */ error = updateMcPanGainsForMcOut( inputMc, IVAS_REND_AUDIO_CONFIG_7_1_4 ); break; @@ -1801,7 +1826,7 @@ static ivas_error initMcBinauralRendering( /* TODO tmu : needs review allocate both renderers; needed if headrotation is toggled so the renderer can be switched */ // bool initTDRend; // initTDRend = false; - // if ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + // if ( ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) && ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) ) // { // if ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) // { @@ -1937,7 +1962,11 @@ static ivas_error setRendInputActiveMc( initRotGains( inputMc->rot_gains_prev ); inputMc->lfeRouting = defaultLfeRouting( inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ); +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) +#else if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRendCfg ) ) != IVAS_ERR_OK ) { @@ -2104,6 +2133,9 @@ static ivas_error updateSbaPanGains( *rendCtx.pOutSampleRate ); break; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB: +#endif if ( ( error = initSbaPanGainsForMcOut( inputSba, IVAS_REND_AUDIO_CONFIG_7_1_4, NULL ) ) != IVAS_ERR_OK ) { return error; @@ -2458,7 +2490,11 @@ static DecoderDummy *initDecoderDummy( decDummy->hDecoderConfig->output_config = getIvasAudioConfigFromRendAudioConfig( outConfig ); decDummy->nchan_transport = numTransChannels; +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) +#else if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { decDummy->hHeadTrackData = malloc( sizeof( HEAD_TRACK_DATA ) ); /* Initialise Rmat_prev to I, Rmat will be computed later */ @@ -3190,7 +3226,11 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( return error; } +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + if ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM || hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) +#else if ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) +#endif { if ( ( error = initMcBinauralRendering( inputMc, inputMc->base.inConfig, hIvasRend->outputConfig, hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) { @@ -4602,6 +4642,9 @@ static ivas_error renderInputIsm( error = renderIsmToBinaural( ismInput, outAudio ); break; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB: +#endif error = renderIsmToBinauralRoom( ismInput, outAudio ); break; default: @@ -4994,6 +5037,9 @@ static ivas_error renderInputMc( error = renderMcToBinaural( mcInput, outConfig, outAudio ); break; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB: +#endif if ( mcInput->base.inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { error = renderMcCustomLsToBinauralRoom( mcInput, outConfig, outAudio ); @@ -5244,6 +5290,9 @@ static ivas_error renderInputSba( error = renderSbaToBinaural( sbaInput, outConfig, outAudio ); break; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + case IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB: +#endif error = renderSbaToBinauralRoom( sbaInput, outConfig, outAudio ); break; default: @@ -5417,6 +5466,7 @@ static ivas_error renderInputMasa( break; /* ToDo */ // case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + // case IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB: // renderMasaToBinauralRoom( masaInput, outConfig, outAudio ); // break; default: diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 99b33dc381..70034fc2ff 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -114,6 +114,9 @@ typedef enum IVAS_REND_AUDIO_CONFIG_BINAURAL = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 0, IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 1, +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 2, +#endif IVAS_REND_AUDIO_CONFIG_MASA1 = IVAS_REND_AUDIO_CONFIG_TYPE_MASA << 8 | 0, IVAS_REND_AUDIO_CONFIG_MASA2 = IVAS_REND_AUDIO_CONFIG_TYPE_MASA << 8 | 1, diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 54f2d012ce..c6e68eae25 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -31,21 +31,24 @@ *******************************************************************************************************/ #include "render_config_reader.h" -#include #include -#include -#include -#include "cmdl_tools.h" #include "prot.h" - +#ifdef CONTROL_METADATA_REVERB +#include +#else +#include +#include "cmdl_tools.h" +#endif /*------------------------------------------------------------------------------------------* * PreProc Macros *------------------------------------------------------------------------------------------*/ +#ifndef CONTROL_METADATA_REVERB #define MAX_LINE_LENGTH ( 1024 ) #define MAX_ITEM_LENGTH ( 64 ) #define N_REVERB_VECTORS ( 3 ) +#endif #define SHORTEST_REV_DEL_LINE ( 0.015f ) #define N_BANDS_MIN ( 2 ) @@ -68,12 +71,607 @@ * Type definitions *------------------------------------------------------------------------------------------*/ +typedef struct +{ + uint32_t nrBands; /* Number of frequency bands */ + float *pFc; /* Center frequencies */ +} FrequencyGrid; + +typedef enum _FREQ_GRID_MODE +{ + FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES = 0, + FREQ_GRID_MODE_START_HOP_AMOUNT = 1, + FREQ_GRID_MODE_DEFAULT_BANDING = 2 +} FREQ_GRID_MODE; + +typedef struct +{ + uint32_t id; /* Acoustic environment ID */ + FrequencyGrid *pFG; /* Pointer into Frequency grids table */ + float *pRT60; /* RT60 table */ + float *pDSR; /* DSR table */ + float preDelay; /* Pre-delay */ +} AcousticEnv; + struct RenderConfigReader { FILE *pConfigFile; +#ifdef CONTROL_METADATA_REVERB + 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 */ +#endif +}; + +#ifdef CONTROL_METADATA_REVERB + +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; + +/*------------------------------------------------------------------------------------------* + * 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.090507733f, 1.104089514f, 1.122462048f, 1.148698355f, 1.189207115f, 1.25992105f, 1.414213562f, 2.0f, 4.0f }; +const uint16_t lutFreqHop_Code[] = { 12, 13, 2, 3, 0, 1, 1, 2, 7 }; +const uint8_t lutFreqHop_Len[] = { 4, 4, 4, 4, 4, 2, 4, 2, 3 }; + +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 +}; + +/*------------------------------------------------------------------------------------------* + * 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_bits() + * Reads a given number of bits from the bitstream + *-----------------------------------------------------------------------------------------*/ +static ivas_error read_bits( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + uint32_t *pTarget, /* i/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; + } + + for ( n = 0; n < nBits; n++ ) + { + nByte = ( 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_bool() + * Reads a boolean value from a bitstream + *-----------------------------------------------------------------------------------------*/ +static ivas_error read_bool( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + uint32_t *pResult /* o : Target read data pointer */ +) +{ + *pResult = false; + return read_bits( this, pResult, 1 ); +} + +/*-----------------------------------------------------------------------------------------* + * Function get_id() + * Reads an ID from a bitstream + *-----------------------------------------------------------------------------------------*/ +static ivas_error get_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_bits( this, &id, 7 ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = ( *pResult << 7 ) | id; + + if ( ( error = read_bool( this, &cont ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function read_code_word() + * Reads a code word from a LUT + *-----------------------------------------------------------------------------------------*/ +static ivas_error read_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; + uint8_t len; + + minLen = 255; + maxLen = 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_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++ ) + { + if ( ( error = read_bits( this, &code, ( len == minLen ) ? minLen : 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + + 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_count_or_index() + * Gets a count or index + *-----------------------------------------------------------------------------------------*/ +static ivas_error get_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_code_word( this, RC_LUT_COUNT_IDX_LO, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = (uint32_t) value; + + if ( ( error = read_bool( this, &isLarge ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( isLarge ) + { + if ( ( error = read_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_duration() + * Gets a duration value + *-----------------------------------------------------------------------------------------*/ +static ivas_error get_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_code_word( this, RC_LUT_DECI_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = value; + + /* Milliseconds */ + if ( ( error = read_bool( this, &addFlag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( addFlag ) + { + if ( ( error = read_code_word( this, RC_LUT_MILLI_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value; + + /* Microseconds */ + if ( ( error = read_bool( this, &addFlag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( addFlag ) + { + if ( ( error = read_code_word( this, RC_LUT_MICRO_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value; + } + } + + /* Seconds */ + if ( ( error = read_bool( this, &addFlag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( addFlag ) + { + if ( ( error = read_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_frequency() + * Gets a frequency value + *-----------------------------------------------------------------------------------------*/ +static ivas_error get_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_code_word( this, RC_LUT_FREQ, pResult ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = read_bool( this, &hiRes ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hiRes ) + { + if ( ( error = read_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_dsr() + * Gets a DSR value + *-----------------------------------------------------------------------------------------*/ +static ivas_error get_dsr( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + float *pResult /* o : DSR value */ +) +{ + ivas_error error; + float value; + + if ( ( error = read_code_word( this, RC_LUT_DSR, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = powf( 10.0f, value / 10.0f ); + return IVAS_ERR_OK; +} +#else /*-----------------------------------------------------------------------------------------* * Function read_bool() * Reads a boolean value from a line @@ -105,7 +703,6 @@ static int16_t read_bool( return true; } - /*-----------------------------------------------------------------------------------------* * Function read_vector() * @@ -311,7 +908,7 @@ static ivas_error RenderConfigReader_checkValues( return IVAS_ERR_OK; } - +#endif /*------------------------------------------------------------------------------------------* * RenderConfigReader_open() @@ -326,6 +923,9 @@ ivas_error RenderConfigReader_open( { RenderConfigReader *pSelf; FILE *pConfigFile; +#ifndef CONTROL_METADATA_REVERB + int length; +#endif /* Open the configuration file */ if ( strlen( pConfigPath ) < 1 ) @@ -333,7 +933,17 @@ ivas_error RenderConfigReader_open( return IVAS_ERR_FAILED_FILE_OPEN; } +#ifdef CONTROL_METADATA_REVERB + pConfigFile = fopen( pConfigPath, "rb" ); +#else + /* use corresponding .cfg file */ + length = strlen( pConfigPath ); + if ( length >= 4 && strcmp( &pConfigPath[length - 4], ".dat" ) == 0 ) + { + strcpy( &pConfigPath[length - 4], ".cfg" ); + } pConfigFile = fopen( pConfigPath, "r" ); +#endif if ( !pConfigFile ) { @@ -354,9 +964,296 @@ ivas_error RenderConfigReader_open( * Reads the configuration from a file *------------------------------------------------------------------------------------------*/ +#ifdef CONTROL_METADATA_REVERB +ivas_error RenderConfigReader_read( + RenderConfigReader *pRenderConfigReader /* i/o : RenderConfigReader handle */ +) +{ + uint32_t file_size; + uint32_t value; + uint32_t i, n, m; + ivas_error error; + float freqHop; + uint32_t gridLen; + uint32_t subGridLen; + const float *pGrid; + + /* Read the bitstream */ + fseek( pRenderConfigReader->pConfigFile, 0, SEEK_END ); + file_size = ftell( pRenderConfigReader->pConfigFile ); + rewind( pRenderConfigReader->pConfigFile ); + + 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, pRenderConfigReader->pConfigFile ); + pRenderConfigReader->length = file_size; + + /****************************/ + /* Read the frequency grids */ + /****************************/ + + /* Number of frequency grids */ + if ( ( error = get_count_or_index( pRenderConfigReader, &pRenderConfigReader->nFG ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Allocate memory for the frequency grids */ + if ( ( pRenderConfigReader->pFG = (FrequencyGrid *) malloc( pRenderConfigReader->nFG * sizeof( FrequencyGrid ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + /* Initialize memory pointers to allow safe freeing ico errors */ + for ( n = 0; n < pRenderConfigReader->nFG; n++ ) + { + pRenderConfigReader->pFG[n].pFc = 0; + } + + for ( n = 0; n < pRenderConfigReader->nFG; n++ ) + { + /* Read the representation method */ + value = 0; + if ( ( error = read_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_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_frequency( pRenderConfigReader, &pRenderConfigReader->pFG[n].pFc[m] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + break; + case FREQ_GRID_MODE_START_HOP_AMOUNT: + if ( ( error = get_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_frequency( pRenderConfigReader, &pRenderConfigReader->pFG[n].pFc[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Read frequency hop from LUT */ + if ( ( error = read_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_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_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( value != false ) + { + /* Read the sub-grid offset */ + if ( ( error = read_bits( pRenderConfigReader, &m, 3 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Read the sub-grid length */ + subGridLen = 0; + if ( ( error = read_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; + } + } + + /**********************************/ + /* Read the acoustic environments */ + /**********************************/ + + /* Number of acoustic environments */ + if ( ( error = get_count_or_index( pRenderConfigReader, &pRenderConfigReader->nAE ) ) != IVAS_ERR_OK ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + /* 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 safe freeing ico errors */ + for ( n = 0; n < pRenderConfigReader->nAE; n++ ) + { + pRenderConfigReader->pAE[n].pRT60 = 0; + pRenderConfigReader->pAE[n].pDSR = 0; + } + + for ( n = 0; n < pRenderConfigReader->nAE; n++ ) + { + /* Read the AE ID */ + if ( ( error = get_id( pRenderConfigReader, &pRenderConfigReader->pAE[n].id ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Read the frequency grid ID */ + if ( ( error = get_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_duration( pRenderConfigReader, &pRenderConfigReader->pAE[n].preDelay ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( m = 0; m < pRenderConfigReader->pAE[n].pFG->nrBands; m++ ) + { + if ( ( error = get_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_dsr( pRenderConfigReader, &pRenderConfigReader->pAE[n].pDSR[m] ) ) != IVAS_ERR_OK ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + } + + /* Cleanup */ + free( pRenderConfigReader->pBitstream ); + + // TODO: Check the values, apply DSR epsilon + return IVAS_ERR_OK; +} + +#else ivas_error RenderConfigReader_read( - RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ - IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ + RenderConfigReader *pRenderConfigReader, /* i/o : RenderConfigReader handle */ + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ) { int32_t file_size; @@ -418,7 +1315,7 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { hRenderConfig->room_acoustics.override = TRUE; - params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + params_idx += ( int32_t )( strlen( item ) + strlen( pValue ) + 2 ); #ifdef DEBUGGING fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); #endif @@ -505,7 +1402,7 @@ ivas_error RenderConfigReader_read( 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 ); + params_idx += ( int32_t )( strlen( item ) + strlen( pValue ) + 2 ); fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); if ( strcmp( item, "RENDERER" ) == 0 ) { @@ -565,10 +1462,49 @@ ivas_error RenderConfigReader_read( fprintf( stderr, "Errors occurred\n" ); return IVAS_ERR_FAILED_FILE_PARSE; } - return RenderConfigReader_checkValues( hRenderConfig ); } +#endif +#ifdef CONTROL_METADATA_REVERB +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getEnvironment() + * + * 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; + + if ( pRenderConfigReader == NULL || pAcEnv == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + for ( n = 0; n < pRenderConfigReader->nAE; n++ ) + { + if ( id == pRenderConfigReader->pAE[n].id ) + { + pAcEnv->nBands = (int16_t) pRenderConfigReader->pAE[n].pFG->nrBands; + pAcEnv->inputPreDelay = pRenderConfigReader->pAE[n].preDelay; + + for ( m = 0; m < pAcEnv->nBands; m++ ) + { + pAcEnv->pFc_input[m] = pRenderConfigReader->pAE[n].pFG->pFc[m]; + pAcEnv->pAcoustic_rt60[m] = pRenderConfigReader->pAE[n].pRT60[m]; + pAcEnv->pAcoustic_dsr[m] = pRenderConfigReader->pAE[n].pDSR[m]; + } + return IVAS_ERR_OK; + } + } + return IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING; +} +#endif /*------------------------------------------------------------------------------------------* * RenderConfigReader_close() @@ -580,11 +1516,32 @@ void RenderConfigReader_close( RenderConfigReader **ppRenderConfigReader /* i : RenderConfigReader handle */ ) { +#ifdef CONTROL_METADATA_REVERB + uint16_t n; +#endif + if ( ppRenderConfigReader == NULL || *ppRenderConfigReader == NULL ) { return; } +#ifdef CONTROL_METADATA_REVERB + /* Free the acoustic environments */ + for ( n = 0; n < ( *ppRenderConfigReader )->nAE; n++ ) + { + 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 ); +#endif + fclose( ( *ppRenderConfigReader )->pConfigFile ); free( *ppRenderConfigReader ); diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index c2afb92e8b..53894f7043 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -52,10 +52,24 @@ ivas_error RenderConfigReader_open( ); /* Reads a configuration */ +#ifdef CONTROL_METADATA_REVERB +ivas_error RenderConfigReader_read( + RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ +); + +/* Get an acoustic environment */ +ivas_error RenderConfigReader_getAcousticEnvironment( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + uint16_t id, /* i : Acoustic environment ID */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcEnv /* o : Target acoustic environment pointer */ +); + +#else ivas_error RenderConfigReader_read( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ); +#endif /* Closes the renderer configuration reader and deallocates memory */ void RenderConfigReader_close( diff --git a/scripts/config/self_test.prm b/scripts/config/self_test.prm index 70f0ef6b36..f01861eaf3 100644 --- a/scripts/config/self_test.prm +++ b/scripts/config/self_test.prm @@ -909,35 +909,35 @@ // Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_renderer.tst // Multi-channel 5_1 at 512 kbps, 48kHz in, 32kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM 32 bit testv/stv51MC48c.wav_MC51_512000_48-32_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 32 bit testv/stv51MC48c.wav_MC51_512000_48-32_MC_Config_renderer.tst // Multi-channel 5_1 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM 16 bit testv/stv51MC48c.wav_MC51_512000_48-16_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 16 bit testv/stv51MC48c.wav_MC51_512000_48-16_MC_Config_renderer.tst // Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config hospital_patientroom ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_ROOM 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_hospital_patientroom.tst +../IVAS_dec -render_config testv/rend_config_hospital_patientroom.dat BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_hospital_patientroom.tst // Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config recreation ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_recreation.cfg BINAURAL_ROOM 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_recreation.tst +../IVAS_dec -render_config testv/rend_config_recreation.dat BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_recreation.tst // Multi-channel 5_1_2 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 5_1_2 512000 48 testv/stv512MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM 48 bit testv/stv512MC48c.wav_MC512_512000_48-48_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv512MC48c.wav_MC512_512000_48-48_MC_Config_renderer.tst // Multi-channel 5_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 5_1_4 512000 48 testv/stv514MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM 48 bit testv/stv514MC48c.wav_MC514_512000_48-48_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv514MC48c.wav_MC514_512000_48-48_MC_Config_renderer.tst // Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_Config_renderer.tst // Multi-channel 5_1 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, 7_1_4 out ../IVAS_cod -mc 5_1 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv51MC48c.wav bit diff --git a/scripts/pyivastest/constants.py b/scripts/pyivastest/constants.py index f42796376a..60d98bc54e 100644 --- a/scripts/pyivastest/constants.py +++ b/scripts/pyivastest/constants.py @@ -48,6 +48,7 @@ OC_TO_NCHANNELS = { "STEREO": 2, "BINAURAL": 2, "BINAURAL_ROOM": 2, + "BINAURAL_REVERB": 2, "5_1": 6, "7_1": 8, "5_1_2": 8, @@ -64,7 +65,7 @@ OC_TO_NCHANNELS = { "MASA1TC": 1, "MASA2TC": 2, } -DECODER_OUTPUT_CONFIGS = {"MONO", "STEREO", "BINAURAL", "BINAURAL_ROOM", "5_1", "7_1", "5_1_4", "5_1_2", +DECODER_OUTPUT_CONFIGS = {"MONO", "STEREO", "BINAURAL", "BINAURAL_ROOM", "BINAURAL_REVERB", "5_1", "7_1", "5_1_4", "5_1_2", "7_1_4", "FOA", "HOA2", "HOA3", "EXT"} LOG_FILE_EXT = ".txt" LOG_FILE_DIR ="logs" diff --git a/scripts/testv/rend_config_hospital_patientroom.cfg b/scripts/testv/rend_config_hospital_patientroom.cfg index b68ac921f9..0ce43444ed 100644 --- a/scripts/testv/rend_config_hospital_patientroom.cfg +++ b/scripts/testv/rend_config_hospital_patientroom.cfg @@ -12,24 +12,23 @@ fc = [20.0, 25.0, 31.5, 40.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, 20000.0]; -rt60 = [0.812749, 0.618878, 0.451113, 0.346723, - 0.466827, 0.539871, 0.61874, 0.702911, - 0.666569, 0.730374, 0.750904, 0.724695, - 0.754858, 0.758571, 0.768437, 0.749991, - 0.776221, 0.782269, 0.774414, 0.74688, - 0.735205, 0.737815, 0.719275, 0.71708, - 0.714652, 0.605922, 0.520307, 0.517676, - 0.521016, 0.379562, 0.307856]; +rt60 = [0.81275, 0.61888, 0.45111, 0.34672, + 0.46683, 0.53987, 0.61874, 0.70291, + 0.66657, 0.73037, 0.75090, 0.72470, + 0.75486, 0.75857, 0.76844, 0.74999, + 0.77622, 0.78227, 0.77441, 0.74688, + 0.73521, 0.73782, 0.71928, 0.71708, + 0.71465, 0.60592, 0.52031, 0.51768, + 0.52102, 0.37956, 0.30786]; -dsr = [0.000219780698, 0.000205275364, 7.18711e-05, 4.5745977e-05, - 8.381106e-06, 6.884964e-06, 6.532765e-06, 8.296928e-06, - 1.0005793e-05, 9.191127e-06, 8.635287e-06, 9.627704e-06, - 1.0806965e-05, 1.0041916e-05, 7.77047e-06, 9.695803e-06, - 9.594324e-06, 8.32215e-06, 7.564813e-06, 6.215871e-06, - 6.379496e-06, 6.358105e-06, 6.6696e-06, 6.369334e-06, - 6.378474e-06, 3.339913e-06, 3.129318e-06, 2.892564e-06, - 6.00202e-07, 3.40124e-07, 3.37705e-07]; +dsr = [0.00019952621, 0.00019952621, 7.9432844e-05, 5.0118702e-05, + 7.943284e-06 , 6.3095763e-06, 6.3095763e-06, 7.943284e-06 , + 1e-05 , 1e-05 , 7.943284e-06 , 1e-05 , + 1e-05 , 1e-05 , 7.943284e-06 , 1e-05 , + 1e-05 , 7.943284e-06 , 7.943284e-06 , 6.3095763e-06, + 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, + 6.3095763e-06, 3.1622776e-06, 3.1622776e-06, 3.1622776e-06, + 6.3095763e-07, 3.1622776e-07, 3.1622776e-07]; - -acousticPreDelay = 0.016; -inputPreDelay = 0.081625; +acousticPreDelay = 0.016; +inputPreDelay = 0.08163; \ No newline at end of file diff --git a/scripts/testv/rend_config_recreation.cfg b/scripts/testv/rend_config_recreation.cfg index afdc0f858b..cc822d630c 100644 --- a/scripts/testv/rend_config_recreation.cfg +++ b/scripts/testv/rend_config_recreation.cfg @@ -12,24 +12,23 @@ fc = [20.0, 25.0, 31.5, 40.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, 20000.0]; -rt60 = [4.519163, 4.895527, 4.832761, 5.001975, - 5.344683, 5.760259, 6.36818, 6.955033, - 7.275571, 7.625591, 8.088915, 8.160022, - 8.138999, 8.179192, 8.162802, 8.462264, - 9.618056, 9.930476, 9.813532, 8.593404, - 8.388852, 8.368234, 6.518449, 3.760885, - 3.753736, 3.574508, 1.287239, 1.221739, - 1.22448, 1.716312, 2.143427]; +rt60 = [4.51916, 4.89553, 4.83276, 5.00198, + 5.34468, 5.76026, 6.36818, 6.95503, + 7.27557, 7.62559, 8.08892, 8.16002, + 8.13900, 8.17919, 8.16280, 8.46226, + 9.61806, 9.93048, 9.81353, 8.59340, + 8.38885, 8.36823, 6.51845, 3.76089, + 3.75374, 3.57451, 1.28724, 1.22174, + 1.22448, 1.71631, 2.14343]; -dsr = [9.18578e-07, 7.63803e-07, 9.23183e-07, 1.048656e-06, - 1.61449e-06, 2.13745e-06, 2.854805e-06, 3.979651e-06, - 6.229977e-06, 7.782421e-06, 9.091754e-06, 8.545798e-06, - 7.482083e-06, 7.351071e-06, 7.947039e-06, 8.152676e-06, - 5.201189e-06, 4.744103e-06, 4.397069e-06, 3.017449e-06, - 2.958383e-06, 2.725911e-06, 7.94912e-07, 6.20198e-07, - 5.71181e-07, 5.5546e-08, 1.3987e-08, 1.338e-08, - 1.322e-09, 1.3e-11, 4e-12]; +dsr = [1e-06 , 7.943284e-07 , 1e-06 , 1e-06 , + 1.5848925e-06, 1.9952631e-06, 3.1622776e-06, 3.9810707e-06, + 6.3095763e-06, 7.943284e-06 , 1e-05 , 7.943284e-06 , + 7.943284e-06 , 7.943284e-06 , 7.943284e-06 , 7.943284e-06 , + 5.01187e-06 , 5.01187e-06 , 3.9810707e-06, 3.1622776e-06, + 3.1622776e-06, 2.511887e-06 , 7.943284e-07 , 6.3095763e-07, + 6.3095763e-07, 5.01187e-08 , 1.2589251e-08, 1.2589251e-08, + 1.2589265e-09, 1.2589266e-11, 3.981075e-12]; - -acousticPreDelay = 0.032; -inputPreDelay = 0.430312; +acousticPreDelay = 0.016; +inputPreDelay = 0.43031; diff --git a/scripts/testv/rend_config_renderer.cfg b/scripts/testv/rend_config_renderer.cfg index 8aa9dec1b2..442edf2506 100644 --- a/scripts/testv/rend_config_renderer.cfg +++ b/scripts/testv/rend_config_renderer.cfg @@ -21,14 +21,14 @@ rt60 = [1.3622, 1.4486, 1.3168, 1.5787, 1.0421, 0.97822, 0.80487, 0.75944, 0.71945, 0.61682, 0.60031]; -dsr = [1.8811e-08, 2.1428e-08, 1.3972e-08, 1.51e-08, - 1.287e-08, 1.8747e-08, 2.413e-08, 3.9927e-08, - 8.9719e-08, 1.902e-07, 3.702e-07, 6.1341e-07, - 7.1432e-07, 6.5331e-07, 4.6094e-07, 5.4683e-07, - 7.0134e-07, 6.856e-07, 7.114e-07, 6.9604e-07, - 5.2939e-07, 5.699e-07, 6.1773e-07, 5.7488e-07, - 4.7748e-07, 2.7213e-07, 1.3681e-07, 1.0941e-07, - 6.2001e-08, 2.8483e-08, 2.6267e-08]; +dsr = [1.9952632e-08, 1.9952632e-08, 1.2589251e-08, 1.5848926e-08, + 1.2589251e-08, 1.9952632e-08, 2.511887e-08 , 3.9810708e-08, + 1e-07 , 1.9952633e-07, 3.981071e-07 , 6.3095763e-07, + 7.943284e-07 , 6.3095763e-07, 5.01187e-07 , 5.01187e-07 , + 6.3095763e-07, 6.3095763e-07, 7.943284e-07 , 6.3095763e-07, + 5.01187e-07 , 6.3095763e-07, 6.3095763e-07, 6.3095763e-07, + 5.01187e-07 , 2.511887e-07 , 1.2589251e-07, 1e-07 , + 6.309576e-08 , 3.1622776e-08, 2.511887e-08]; acousticPreDelay = 0.016; inputPreDelay = 0.1; \ No newline at end of file -- GitLab From 20b558a1e51f8daf89d37ba10a328911d17e4a98 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Thu, 6 Apr 2023 17:41:30 +0200 Subject: [PATCH 002/101] Added missing files --- scripts/reverb/generate_reverb_metadata.py | 400 ++++++++++++++++++ .../rend_config_hospital_patientroom.dat | 3 + scripts/testv/rend_config_recreation.dat | 3 + scripts/testv/rend_config_renderer.dat | 3 + 4 files changed, 409 insertions(+) create mode 100644 scripts/reverb/generate_reverb_metadata.py create mode 100644 scripts/testv/rend_config_hospital_patientroom.dat create mode 100644 scripts/testv/rend_config_recreation.dat create mode 100644 scripts/testv/rend_config_renderer.dat diff --git a/scripts/reverb/generate_reverb_metadata.py b/scripts/reverb/generate_reverb_metadata.py new file mode 100644 index 0000000000..a05bbeb2d8 --- /dev/null +++ b/scripts/reverb/generate_reverb_metadata.py @@ -0,0 +1,400 @@ +#!/usr/bin/env python3 + +""" + (C) 2022-2023 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. +""" + +# +# Generate binary render configuration output files for testing purposes +# The binary code generation is based on the MPEG-I audio standard +# which defines functions to decode raw bitstream into internal parameters +# + + +from bitarray import bitarray, test as bitarray_test +import math +from enum import Enum +import numpy as np + + +# Set to True to print values suitable for inclusion into .cfg configuration files +print_cfg = False + +def get_id_code(id): + code = format(id % 128, '07b') + '0' + id //= 128 + while id > 0: + code = format(id % 128, '07b') + '1' + code + id = id // 128 + return code + + +def get_count_or_index_code(n): + # 0, 1, ... 63 + countOrIndexLoCodes = [ + '0111', '100', '01100', '01101', '01010', '01011', '01000', '01001', '001111', '001110', + '001101', '001100', '001011', '001010', '001001', '001000', '000111', '000110', '000101', '000100', + '000011', '000010', '000001', '000000', '111111', '111110', '111101', '111100', '111011', '111010', + '111001', '111000', '1101111', '1101110', '1101101', '1101100', '1101011', '1101010', '1101001', '1101000', + '1100111', '1100110', '1100101', '1100100', '1100011', '1100010', '1100001', '1100000', '1011111', '1011110', + '1011101', '1011100', '1011011', '1011010', '1011001', '1011000', '1010111', '1010110', '1010101', '1010100', + '1010011', '1010010', '1010001', '1010000'] + + # 1, 2, ... 15 + countOrIndexHiCode = [ + '001', '000', '110', '101', '100', '0111', '0101', '1111', '1110', '01101', + '01001', '01000', '011001', '0110001', '0110000'] + + assert 0 <= n < 16 * 64 + code = countOrIndexLoCodes[n % 64] + if n < 64: + code += '0' + else: + code += '1' + countOrIndexHiCode[n // 64 - 1] + return code + + +def get_duration_code(duration): + # 1, 2, ... 30 + secondsCode = [ + '0011', '0001', '0000', '1111', '1101', '1100', '1011', '1001', '1000', '01110', + '01101', '01100', '01011', '01001', '01000', '00101', '11101', '11100', '10101', '011111', + '011110', '010101', '001001', '001000', '101001', '0101001', '0101000', '1010001', '10100001', '10100000' ] + + # 0, 0.1, ... 1.0 + deciSecondsCode = [ + '110', '100', '101', '0110', '0111', '111', '0100', '0101', '0010', '0011', '000' ] + + # 0, 1, ..., 99 + millisecondsCode = [ + '1111010', '1111011', '1111000', '1111001', '1111110', '1111111', '1111100', '1111101', '1110010', '1110011', + '11001', '1110000', '1110001', '1110110', '1110111', '1110100', '1110101', '0101010', '0101011', '0101000', + '10010', '0101001', '0101110', '0101111', '0101100', '0101101', '0100010', '0100011', '0100000', '0100001', + '10011', '0100110', '0100111', '0100100', '0100101', '0111010', '0111011', '0111000', '0111001', '0111110', + '10000', '0111111', '0111100', '0111101', '0110010', '0110011', '0110000', '0110001', '0110110', '0110111', + '10001', '0110100', '0110101', '0001010', '0001011', '0001000', '0001001', '0001110', '0001111', '0001100', + '10110', '0001101', '0000010', '0000011', '0000000', '0000001', '0000110', '0000111', '0000100', '0000101', + '10111', '0011010', '0011011', '0011000', '0011001', '0011110', '0011111', '0011100', '0011101', '0010010', + '10100', '0010011', '0010000', '0010001', '0010110', '0010111', '0010100', '0010101', '1101010', '1101011', + '10101', '1101000', '1101001', '1101110', '1101111', '1101100', '1101101', '1100010', '1100011', '110000' ] + + # 10, 20, ... 990 + microsecondsCode = [ + '110111100', '10010', '110111101', '10011', '1101111110', '10000', '1101111111', '10001', '1101111100', '10110', + '1101111101', '10111', '110110010', '10100', '110110011', '10101', '110110000', '001010', '110110001', '001011', + '110110110', '001000', '110110111', '001001', '110110100', '001110', '110110101', '001111', '110011010', '001100', + '110011011', '001101', '110011000', '000010', '110011001', '000011', '110011110', '000000', '110011111', '000001', + '110011100', '000110', '110011101', '000111', '110010010', '000100', '110010011', '000101', '110010000', '011010', + '110010001', '011011', '110010110', '011000', '110010111', '011001', '110010100', '011110', '110010101', '011111', + '110101010', '011100', '110101011', '011101', '110101000', '010010', '110101001', '010011', '110101110', '010000', + '110101111', '010001', '110101100', '010110', '110101101', '010111', '110100010', '010100', '110100011', '010101', + '110100000', '111010', '110100001', '111011', '110100110', '111000', '110100111', '111001', '110100100', '111110', + '110100101', '111111', '110111010', '111100', '110111011', '111101', '110111000', '11000', '110111001' ] + + duration_dus = int(round(np.float32(duration) * np.float32(100000))) # [deca us] + if print_cfg: + print('duration: ', duration_dus) + + dus = duration_dus # [deca us] + s = dus // 100000 # 0, 1, ... 30 [s] + ms = (dus % 100000) // 100 # 0, 1, ... 999 [ms] + dus = (dus % 100) # 0, 1, ... 99 [deca us] + ds = ms // 100 # 0, 1, ... 9 [deci s] + ms = ms % 100 # 0, 1, ... 99 [ms] + if s >= 1 and ds == 0: + s -= 1 + ds = 10 # 0, 1, ... 10 [deci s] + + assert 0 <= s <= 30 + assert 0 <= ds <= 10 + assert 0 <= ms <= 99 + assert 0 <= dus <= 99 + assert duration_dus == s * 100000 + ds * 10000 + ms * 100 + dus + + code = deciSecondsCode[ds] + if ms > 0 or dus > 0: + code += '1' + millisecondsCode[ms] + if dus > 0: + code += '1' + microsecondsCode[dus - 1] + else: + code += '0' + else: + code += '0' + if s > 0: + # long range mode not implemented + code += '1' + secondsCode[s - 1] + else: + code += '0' + + return code + + +def get_frequency_code(f): + frequencyCode = { + 16 : '100011', 20 : '001110', 25 : '001111', 31.5 : '1001', 40 : '001100', + 50 : '001101', 63 : '0000', 80 : '011010', 100 : '011011', 125 : '0001', + 160 : '011000', 200 : '011001', 250 : '1110', 315 : '011110', 400 : '011111', + 500 : '1111', 630 : '011100', 800 : '011101', 1000 : '1100', 1250 : '010010', + 1600 : '010011', 2000 : '1101', 2500 : '010000', 3150 : '010001', 4000 : '1010', + 5000 : '010110', 6300 : '010111', 8000 : '1011', 10000: '010100', 12500: '010101', + 16000: '0010', 20000: '10000', 25000: '10001010', 31500: '10001011', 40000: '1000100', } + + assert 16 <= f <= 40000 + if f in frequencyCode.keys(): + if print_cfg: + print('frequency:', f) + return frequencyCode[f] + '0' + else: + # exact frequency not found, use frequency refinement to aproximate + # (largest relative deviation seen for range(16, 40000) was 0.006818) + # find frequencies enveloping f + f_low = 16 + f_high = 40000 + for key in frequencyCode.keys(): + if key < f: + f_low = max(f_low, key) + else: + f_high = min(f_high, key) + refinement = round(51 * math.log(f / f_low, 2)) - 1 + if refinement >= 16: + # choose next higer frequency + if print_cfg: + print('frequency:', list(frequencyCode)[f_high]) + return frequencyCode[f_high] + '0' + else: + if print_cfg: + print('frequency:', list(frequencyCode)[f_low], ', refined: ', f_low * 2 ** ((refinement + 1) / 51)) + return frequencyCode[f_low] + '1' + format(refinement, '04b') + + +def get_frequency_hop_code(index): + assert 0 <= index < 9 + return [ + '1100', # 2^(1/8) + '1101', # 2^(1/7) + '0010', # 2^(1/6) + '0011', # 2^(1/5) + '0000', # 2^(1/4) + '01', # 2^(1/3) + '0001', # 2^(1/2) + '10', # 2^1 + '111'][index] # 2^2 + + + +def get_dsr_code(dsr): + # -150.0, -149.0, ... -10.0 + dsrCode = [ + '10001100', '10001101', '100011110', '100011111', '100011100', '100011101', '10000010', '10000011', '10000000', '10000001', + '10000110', '10000111', '10000100', '10000101', '011101010', '011101011', '011101000', '011101001', '011101110', '011101111', + '011101100', '011101101', '011100010', '011100011', '011100000', '011100001', '011100110', '011100111', '011100100', '011100101', + '011111010', '011111011', '011111000', '011111001', '011111110', '011111111', '011111100', '011111101', '011110010', '011110011', + '011110000', '011110001', '011110110', '011110111', '011110100', '011110101', '011001010', '011001011', '011001000', '011001001', + '011001110', '011001111', '011001100', '011001101', '011000010', '011000011', '011000000', '011000001', '011000110', '011000111', + '011000100', '011000101', '011011010', '011011011', '011011000', '011011001', '011011110', '011011111', '011011100', '011011101', + '010100', '010101', '100110', '100111', '100100', '100101', '111010', '111011', '111000', '111001', + '111110', '111111', '111100', '111101', '110010', '110011', '110000', '110001', '110110', '110111', + '110100', '110101', '001010', '001011', '001000', '001001', '001110', '001111', '001100', '001101', + '000010', '000011', '000000', '000001', '000110', '000111', '000100', '000101', '101010', '101011', + '101000', '101001', '101110', '101111', '101100', '101101', '010010', '010011', '010000', '010001', + '010110', '011010010', '011010011', '011010000', '011010001', '011010110', '011010111', '011010100', '011010101', '010111010', + '010111011', '010111000', '010111001', '010111110', '010111111', '010111100', '010111101', '10001010', '10001011', '10001000', + '10001001' ] + + d = math.log10(dsr) * 10 + d = round(d + 150) + assert 0 <= d <= 140 + if print_cfg: + print('dsr:', np.float32(np.power(np.float32(10), np.float32(d - 150) / np.float32(10)))) # C decoder uses float precision math + return dsrCode[d] + + +class fgdMethod(Enum): + Individual_Frequencies = '00' + Start_Hop_Amount = '01' + Default_Banding = '10' + + +# apply function to elements of list and concatenate the resulting strings +def concatenate(function, data): + return ''.join([function(d) for d in data]) + + +def test(): + # generate binary output which can be compared with the Matlab implementation output + string = '' + + # count or index encoding + string += concatenate(get_count_or_index_code, [n for n in range(0, 16 * 64)]) + + # duration encoding + string += concatenate(get_duration_code, [d / 1000 for d in range(0, 30 * 1000)]) + string += concatenate(get_duration_code, [d / 10000 for d in range(0, 30 * 1000)]) + string += concatenate(get_duration_code, [d / 100000 for d in range(0, 30 * 1000)]) + + # frequency encoding + string += concatenate(get_frequency_code, + [16 , 20 , 25 , 31.5 , 40 , 50 , 63 , 80 , 100 , 125 , + 160 , 200 , 250 , 315 , 400 , 500 , 630 , 800 , 1000 , 1250 , + 1600 , 2000 , 2500 , 3150 , 4000 , 5000 , 6300 , 8000, 10000, 12500, + 16000, 20000, 25000, 31500, 40000]) + + # frequency hop encoding + string += concatenate(get_frequency_hop_code, [index for index in range(0, 9)]) + + # DSR encoding + string += concatenate(get_dsr_code, [math.pow(10, dsr / 10) for dsr in range(-150, -10 + 1)]) + + data = bitarray(string, endian='big') + + file = open('test_python.dat', 'wb') + data.tofile(file) + file.close() + + +def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg(): + # based on config_renderer.cfg + # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values + data = bitarray( + get_count_or_index_code(1) # fgdNrGrids + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(31) # fgdNrBands + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, + 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0, + 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, + 20000.0 ]) + + + get_count_or_index_code(1) # AcousticEnvCount + + get_id_code(0) # ID + + get_count_or_index_code(0) # FreqGridID + + get_duration_code(0.1) # (input)Predelay + + + concatenate(get_duration_code, # RT60 + [ 1.3622, 1.4486, 1.3168, 1.5787, 1.4766, 1.3954, 1.2889, 1.3462, 1.0759, 1.0401, + 1.0970, 1.0850, 1.0910, 1.0404, 1.0499, 1.0699, 1.1028, 1.1714, 1.1027, 1.0666, + 1.0550, 1.0553, 1.0521, 1.0569, 1.0421, 0.97822, 0.80487, 0.75944, 0.71945, 0.61682, + 0.60031 ]) + + + concatenate(get_dsr_code, # DSR + [ 1.8811e-08, 2.1428e-08, 1.3972e-08, 1.51e-08, 1.287e-08, 1.8747e-08, 2.413e-08, 3.9927e-08, 8.9719e-08, 1.902e-07, + 3.702e-07, 6.1341e-07, 7.1432e-07, 6.5331e-07, 4.6094e-07, 5.4683e-07, 7.0134e-07, 6.856e-07, 7.114e-07, 6.9604e-07, + 5.2939e-07, 5.699e-07, 6.1773e-07, 5.7488e-07, 4.7748e-07, 2.7213e-07, 1.3681e-07, 1.0941e-07, 6.2001e-08, 2.8483e-08, + 2.6267e-08 ]) + + , endian='big') + + file = open('rend_config_renderer.dat', 'wb') + data.tofile(file) + file.close() + + +def generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg(): + # based on config_hospital_patientroom.cfg + # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values + data = bitarray( + get_count_or_index_code(1) # fgdNrGrids + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(31) # fgdNrBands + + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, + 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0, + 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, + 20000.0 ]) + + + get_count_or_index_code(1) # AcousticEnvCount + + get_id_code(0) # ID + + get_count_or_index_code(0) # FreqGridID + + get_duration_code(0.08163) # (input)Predelay + + + concatenate(get_duration_code, # RT60 + [ 0.81275, 0.61888, 0.45111, 0.34672, 0.46683, 0.53987, 0.61874, 0.70291, 0.66657, 0.73037, + 0.75090, 0.72470, 0.75486, 0.75857, 0.76844, 0.74999, 0.77622, 0.78227, 0.77441, 0.74688, + 0.73521, 0.73782, 0.71928, 0.71708, 0.71465, 0.60592, 0.52031, 0.51768, 0.52102, 0.37956, + 0.30786 ]) + + + concatenate(get_dsr_code, # DSR + [ 0.000219780698, 0.000205275364, 7.18711e-05, 4.5745977e-05, 8.381106e-06, 6.884964e-06, 6.532765e-06, 8.296928e-06, 1.0005793e-05, 9.191127e-06, + 8.635287e-06, 9.627704e-06, 1.0806965e-05, 1.0041916e-05, 7.77047e-06, 9.695803e-06, 9.594324e-06, 8.32215e-06, 7.564813e-06, 6.215871e-06, + 6.379496e-06, 6.358105e-06, 6.6696e-06, 6.369334e-06, 6.378474e-06, 3.339913e-06, 3.129318e-06, 2.892564e-06, 6.00202e-07, 3.40124e-07, + 3.37705e-07 ]) + + , endian='big') + + file = open('rend_config_hospital_patientroom.dat', 'wb') + data.tofile(file) + file.close() + + +def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): + # based on config_recreation.cfg + # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values + data = bitarray( + get_count_or_index_code(1) # fgdNrGrids + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(31) # fgdNrBands + + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, + 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0, + 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, + 20000.0 ]) + + + get_count_or_index_code(1) # AcousticEnvCount + + get_id_code(0) # ID + + get_count_or_index_code(0) # FreqGridID + + get_duration_code(0.43031) # (input)Predelay + + + concatenate(get_duration_code, # RT60 + [ 4.51916, 4.89553, 4.83276, 5.00198, 5.34468, 5.76026, 6.36818, 6.95503, 7.27557, 7.62559, + 8.08892, 8.16002, 8.13900, 8.17919, 8.16280, 8.46226, 9.61806, 9.93048, 9.81353, 8.59340, + 8.38885, 8.36823, 6.51845, 3.76089, 3.75374, 3.57451, 1.28724, 1.22174, 1.22448, 1.71631, + 2.14343 ]) + + + concatenate(get_dsr_code, # DSR + [ 9.18578e-07, 7.63803e-07, 9.23183e-07, 1.048656e-06, 1.61449e-06, 2.13745e-06, 2.854805e-06, 3.979651e-06, 6.229977e-06, 7.782421e-06, + 9.091754e-06, 8.545798e-06, 7.482083e-06, 7.351071e-06, 7.947039e-06, 8.152676e-06, 5.201189e-06, 4.744103e-06, 4.397069e-06, 3.017449e-06, + 2.958383e-06, 2.725911e-06, 7.94912e-07, 6.20198e-07, 5.71181e-07, 5.5546e-08, 1.3987e-08, 1.338e-08, 1.322e-09, 1.3e-11, + 4e-12 ]) + + , endian='big') + + file = open('rend_config_recreation.dat', 'wb') + data.tofile(file) + file.close() + + +#test() +generate_reverb_payload_equivalent_to_rend_config_renderer_cfg() +generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg() +generate_reverb_payload_equivalent_to_rend_config_recreation_cfg() diff --git a/scripts/testv/rend_config_hospital_patientroom.dat b/scripts/testv/rend_config_hospital_patientroom.dat new file mode 100644 index 0000000000..20455a95b7 --- /dev/null +++ b/scripts/testv/rend_config_hospital_patientroom.dat @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3b4cf6b770f85bc82129901324078afc0953661b3ff753796d7d4bd15d8c468 +size 136 diff --git a/scripts/testv/rend_config_recreation.dat b/scripts/testv/rend_config_recreation.dat new file mode 100644 index 0000000000..456eedbbf7 --- /dev/null +++ b/scripts/testv/rend_config_recreation.dat @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cb9adc877960d2a7e827126c2f44612569e5554e974b5bb98d3be92cb1ee14a +size 149 diff --git a/scripts/testv/rend_config_renderer.dat b/scripts/testv/rend_config_renderer.dat new file mode 100644 index 0000000000..6ea8ed4f1d --- /dev/null +++ b/scripts/testv/rend_config_renderer.dat @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7941266900de8753e847cfef95298b5ee529e3f8f90ca5421ba46d71bc353821 +size 130 -- GitLab From 86ec9deca5a28914eea62afe973dabda01278ae0 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Thu, 6 Apr 2023 18:00:20 +0200 Subject: [PATCH 003/101] Corrected renderer.c command line parsing, added missing #ifdef guards --- apps/decoder.c | 8 ++++++++ apps/renderer.c | 5 +++++ lib_com/options.h | 2 +- scripts/config/self_test.prm | 16 ++++++++-------- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index d3aa314f5f..3357eda4b8 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -283,7 +283,11 @@ int main( if ( arg.enableReferenceRotation ) { /* sanity check */ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_REVERB ) +#else + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM ) +#endif { fprintf( stderr, "\nError: Reference rotation file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -310,7 +314,11 @@ int main( if ( arg.enableReferenceVectorTracking ) { /* sanity check */ +#ifdef COMMAND_LINE_OPTION_LATE_REVERB if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_REVERB ) +#else + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM ) +#endif { fprintf( stderr, "\nError: Reference vector trajectory file cannot be used in this output configuration.\n\n" ); goto cleanup; diff --git a/apps/renderer.c b/apps/renderer.c index 03b2398947..0a2dd702f7 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1467,8 +1467,13 @@ static bool parseOrientationTracking( static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) { +#ifdef COMMAND_LINE_OPTION_LATE_REVERB + char charBuf[16]; + charBuf[15] = '\0'; +#else char charBuf[14]; charBuf[13] = '\0'; +#endif strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); charBuf[sizeof( charBuf ) - 1] = '\0'; diff --git a/lib_com/options.h b/lib_com/options.h index 08ed5c4991..192e31e482 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -141,7 +141,7 @@ #define DISABLE_ADAP_RES_COD_TMP /* temporary fix for IVAS-403, disables adaptive residual coding */ /*#define ITD_WINNER_GAIN_MODIFY */ /* ITD optimization - WORK IN PROGRESS */ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ -#define CONTROL_METADATA_REVERB /* Philips: renderer configuration change to binary format */ +#define CONTROL_METADATA_REVERB /* Philips: renderer configuration change to binary format */ #define COMMAND_LINE_OPTION_LATE_REVERB /* Philips: late reverb command line option */ #define FIX_103_RA_PARAMS_PARAM_BIN_REND /* Issue 103: Digest room acoustics parameters for Parametric Binaural Renderer*/ /*#define SBA_HPF_TUNING_DEC*/ diff --git a/scripts/config/self_test.prm b/scripts/config/self_test.prm index f01861eaf3..b56bcff2d8 100644 --- a/scripts/config/self_test.prm +++ b/scripts/config/self_test.prm @@ -907,35 +907,35 @@ ../IVAS_cod -mc 5_1 256000 48 testv/stv51MC48c.wav bit ../IVAS_dec testv/ls_setup_16ch_8+4+4.txt 48 bit testv/stv51MC48c.wav_MC51_256000_48-48_MC_custom_setup.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer +// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 32kHz out, BINAURAL_ROOM out Config renderer +// Multi-channel 5_1 at 512 kbps, 48kHz in, 32kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 32 bit testv/stv51MC48c.wav_MC51_512000_48-32_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM out Config renderer +// Multi-channel 5_1 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 16 bit testv/stv51MC48c.wav_MC51_512000_48-16_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config hospital_patientroom +// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config hospital_patientroom ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_hospital_patientroom.dat BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_hospital_patientroom.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config recreation +// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config recreation ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_recreation.dat BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_recreation.tst -// Multi-channel 5_1_2 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer +// Multi-channel 5_1_2 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 5_1_2 512000 48 testv/stv512MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv512MC48c.wav_MC512_512000_48-48_MC_Config_renderer.tst -// Multi-channel 5_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer +// Multi-channel 5_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 5_1_4 512000 48 testv/stv514MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv514MC48c.wav_MC514_512000_48-48_MC_Config_renderer.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_Config_renderer.tst -- GitLab From f404d857adc8f4ac419154e05ec25a3b75f91074 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Wed, 19 Apr 2023 17:32:17 +0200 Subject: [PATCH 004/101] Combined the use of text-based render configuration files and binary reverb configuration files --- apps/decoder.c | 9 ++- apps/renderer.c | 9 ++- lib_util/render_config_reader.c | 80 +++++++++++++------ lib_util/render_config_reader.h | 13 ++- scripts/config/self_test.prm | 16 ++-- .../rend_config_hospital_patientroom.cfg | 36 +-------- scripts/testv/rend_config_recreation.cfg | 36 +-------- scripts/testv/rend_config_renderer.cfg | 36 +-------- tests/renderer/test_renderer.py | 1 + 9 files changed, 85 insertions(+), 151 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 3357eda4b8..f947498556 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -505,11 +505,7 @@ int main( goto cleanup; } -#ifdef CONTROL_METADATA_REVERB - if ( RenderConfigReader_read( renderConfigReader ) != IVAS_ERR_OK ) -#else if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) -#endif { fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); goto cleanup; @@ -521,6 +517,11 @@ int main( fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); goto cleanup; } + if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Invalid reverberation configuration parameters\n\n" ); + goto cleanup; + } #ifdef COMMAND_LINE_OPTION_LATE_REVERB if ( arg.outputFormat == IVAS_DEC_OUTPUT_BINAURAL_REVERB ) diff --git a/apps/renderer.c b/apps/renderer.c index 486f51b6a8..1c2f21e71f 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -742,11 +742,7 @@ int main( exit( -1 ); } -#ifdef CONTROL_METADATA_REVERB - if ( RenderConfigReader_read( renderConfigReader ) != IVAS_ERR_OK ) -#else if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) -#endif { fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFilePath ); exit( -1 ); @@ -758,6 +754,11 @@ int main( fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); exit( -1 ); } + if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Invalid reverberation configuration parameters\n\n" ); + exit( -1 ); + } #ifdef COMMAND_LINE_OPTION_LATE_REVERB if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) { diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index c6e68eae25..82ffb230a1 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -35,10 +35,9 @@ #include "prot.h" #ifdef CONTROL_METADATA_REVERB #include -#else +#endif #include #include "cmdl_tools.h" -#endif /*------------------------------------------------------------------------------------------* * PreProc Macros @@ -46,7 +45,9 @@ #ifndef CONTROL_METADATA_REVERB #define MAX_LINE_LENGTH ( 1024 ) -#define MAX_ITEM_LENGTH ( 64 ) +#endif +#define MAX_ITEM_LENGTH ( 64 ) +#ifndef CONTROL_METADATA_REVERB #define N_REVERB_VECTORS ( 3 ) #endif @@ -702,6 +703,7 @@ static int16_t read_bool( return true; } +#endif /*-----------------------------------------------------------------------------------------* * Function read_vector() @@ -823,7 +825,7 @@ static int32_t errorHandler( * Verifies if the configuration parameters lie within acceptable limits *------------------------------------------------------------------------------------------*/ -static ivas_error RenderConfigReader_checkValues( +ivas_error RenderConfigReader_checkValues( IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ) { @@ -908,7 +910,6 @@ static ivas_error RenderConfigReader_checkValues( return IVAS_ERR_OK; } -#endif /*------------------------------------------------------------------------------------------* * RenderConfigReader_open() @@ -933,17 +934,7 @@ ivas_error RenderConfigReader_open( return IVAS_ERR_FAILED_FILE_OPEN; } -#ifdef CONTROL_METADATA_REVERB - pConfigFile = fopen( pConfigPath, "rb" ); -#else - /* use corresponding .cfg file */ - length = strlen( pConfigPath ); - if ( length >= 4 && strcmp( &pConfigPath[length - 4], ".dat" ) == 0 ) - { - strcpy( &pConfigPath[length - 4], ".cfg" ); - } pConfigFile = fopen( pConfigPath, "r" ); -#endif if ( !pConfigFile ) { @@ -959,14 +950,15 @@ ivas_error RenderConfigReader_open( /*------------------------------------------------------------------------------------------* - * RenderConfigReader_read() + * RenderConfigReader_readReverb() * - * Reads the configuration from a file + * Reads the binary reverb configuration from a file *------------------------------------------------------------------------------------------*/ #ifdef CONTROL_METADATA_REVERB -ivas_error RenderConfigReader_read( - RenderConfigReader *pRenderConfigReader /* i/o : RenderConfigReader handle */ +static ivas_error RenderConfigReader_readReverb( + const char *pReverbConfigPath, /* i : Reverb configuration file path */ + RenderConfigReader *pRenderConfigReader /* i/o : RenderConfigReader handle */ ) { uint32_t file_size; @@ -977,11 +969,20 @@ ivas_error RenderConfigReader_read( 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( pRenderConfigReader->pConfigFile, 0, SEEK_END ); - file_size = ftell( pRenderConfigReader->pConfigFile ); - rewind( pRenderConfigReader->pConfigFile ); + 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 ) @@ -989,7 +990,7 @@ ivas_error RenderConfigReader_read( return IVAS_ERR_FAILED_ALLOC; } - fread( pRenderConfigReader->pBitstream, sizeof( uint8_t ), file_size, pRenderConfigReader->pConfigFile ); + fread( pRenderConfigReader->pBitstream, sizeof( uint8_t ), file_size, pReverbConfigFile ); pRenderConfigReader->length = file_size; /****************************/ @@ -1250,7 +1251,8 @@ ivas_error RenderConfigReader_read( return IVAS_ERR_OK; } -#else +#endif + ivas_error RenderConfigReader_read( RenderConfigReader *pRenderConfigReader, /* i/o : RenderConfigReader handle */ IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ @@ -1266,7 +1268,11 @@ ivas_error RenderConfigReader_read( char chapter[MAX_ITEM_LENGTH + 1]; char *pValue; int16_t nBandsInput; +#ifdef CONTROL_METADATA_REVERB + ivas_error error; +#else int16_t nVectorsMissing; +#endif fseek( pRenderConfigReader->pConfigFile, 0, SEEK_END ); file_size = ftell( pRenderConfigReader->pConfigFile ); @@ -1275,7 +1281,9 @@ ivas_error RenderConfigReader_read( pParams = (char *) calloc( file_size + 1, sizeof( char ) ); pTemp = (char *) calloc( file_size + 1, sizeof( char ) ); nBandsInput = hRenderConfig->room_acoustics.nBands; +#ifndef CONTROL_METADATA_REVERB nVectorsMissing = N_REVERB_VECTORS; +#endif /* read file line by line */ while ( fgets( pConfig_str, file_size, pRenderConfigReader->pConfigFile ) != NULL ) @@ -1308,6 +1316,7 @@ ivas_error RenderConfigReader_read( to_upper( chapter ); /* interpret params */ +#ifndef CONTROL_METADATA_REVERB if ( strcmp( chapter, "ROOMACOUSTICS" ) == 0 ) { params_idx = 0; @@ -1397,6 +1406,13 @@ ivas_error RenderConfigReader_read( } #ifdef DEBUGGING else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) +#endif +#else +#ifdef DEBUGGING + if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) +#endif +#endif +#ifdef DEBUGGING { params_idx = 0; pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); @@ -1426,6 +1442,15 @@ ivas_error RenderConfigReader_read( errorHandler( item, ERROR_VALUE_INVALID ); } } + if ( strcmp( item, "REVERBFILE" ) == 0 ) + { + // TODO: need to preserve file name case for non Windows OSes + if ( ( error = RenderConfigReader_readReverb(pValue, pRenderConfigReader) ) != IVAS_ERR_OK) + { + printf( "RenderConfigReader_readReverb(%s) returned %d\n", pValue, error ); + errorHandler( item, error ); + } + } #ifdef DEBUGGING else { @@ -1462,9 +1487,12 @@ ivas_error RenderConfigReader_read( fprintf( stderr, "Errors occurred\n" ); return IVAS_ERR_FAILED_FILE_PARSE; } - return RenderConfigReader_checkValues( hRenderConfig ); -} +#ifdef CONTROL_METADATA_REVERB + return IVAS_ERR_OK; +#else + RenderConfigReader_checkValues( hRenderConfig ); #endif +} #ifdef CONTROL_METADATA_REVERB /*------------------------------------------------------------------------------------------* diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 53894f7043..d0d37d6fc3 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -51,25 +51,24 @@ ivas_error RenderConfigReader_open( RenderConfigReader **ppRenderConfigReader /* o : RenderConfigReader handle */ ); -/* Reads a configuration */ #ifdef CONTROL_METADATA_REVERB -ivas_error RenderConfigReader_read( - RenderConfigReader *pRenderConfigReader /* i : RenderConfigReader handle */ -); - /* Get an acoustic environment */ ivas_error RenderConfigReader_getAcousticEnvironment( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ uint16_t id, /* i : Acoustic environment ID */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcEnv /* o : Target acoustic environment pointer */ ); +/* Verifies configuration parameters */ +ivas_error RenderConfigReader_checkValues( + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ +); +#endif -#else +/* Reads a configuration */ ivas_error RenderConfigReader_read( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ); -#endif /* Closes the renderer configuration reader and deallocates memory */ void RenderConfigReader_close( diff --git a/scripts/config/self_test.prm b/scripts/config/self_test.prm index b56bcff2d8..8da3550e00 100644 --- a/scripts/config/self_test.prm +++ b/scripts/config/self_test.prm @@ -909,35 +909,35 @@ // Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_renderer.tst // Multi-channel 5_1 at 512 kbps, 48kHz in, 32kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 32 bit testv/stv51MC48c.wav_MC51_512000_48-32_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_REVERB 32 bit testv/stv51MC48c.wav_MC51_512000_48-32_MC_Config_renderer.tst // Multi-channel 5_1 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 16 bit testv/stv51MC48c.wav_MC51_512000_48-16_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_REVERB 16 bit testv/stv51MC48c.wav_MC51_512000_48-16_MC_Config_renderer.tst // Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config hospital_patientroom ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_hospital_patientroom.dat BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_hospital_patientroom.tst +../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_hospital_patientroom.tst // Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config recreation ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_recreation.dat BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_recreation.tst +../IVAS_dec -render_config testv/rend_config_recreation.cfg BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_recreation.tst // Multi-channel 5_1_2 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 5_1_2 512000 48 testv/stv512MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv512MC48c.wav_MC512_512000_48-48_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_REVERB 48 bit testv/stv512MC48c.wav_MC512_512000_48-48_MC_Config_renderer.tst // Multi-channel 5_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 5_1_4 512000 48 testv/stv514MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv514MC48c.wav_MC514_512000_48-48_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_REVERB 48 bit testv/stv514MC48c.wav_MC514_512000_48-48_MC_Config_renderer.tst // Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.dat BINAURAL_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_Config_renderer.tst +../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_Config_renderer.tst // Multi-channel 5_1 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, 7_1_4 out ../IVAS_cod -mc 5_1 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv51MC48c.wav bit diff --git a/scripts/testv/rend_config_hospital_patientroom.cfg b/scripts/testv/rend_config_hospital_patientroom.cfg index 0ce43444ed..c00b642947 100644 --- a/scripts/testv/rend_config_hospital_patientroom.cfg +++ b/scripts/testv/rend_config_hospital_patientroom.cfg @@ -1,34 +1,2 @@ -[roomAcoustics] -reverb = true; -brir = false; -nBands = 31; - -fc = [20.0, 25.0, 31.5, 40.0, - 50.0, 63.0, 80.0, 100.0, - 125.0, 160.0, 200.0, 250.0, - 315.0, 400.0, 500.0, 630.0, - 800.0, 1000.0, 1250.0, 1600.0, - 2000.0, 2500.0, 3150.0, 4000.0, - 5000.0, 6300.0, 8000.0, 10000.0, - 12500.0, 16000.0, 20000.0]; - -rt60 = [0.81275, 0.61888, 0.45111, 0.34672, - 0.46683, 0.53987, 0.61874, 0.70291, - 0.66657, 0.73037, 0.75090, 0.72470, - 0.75486, 0.75857, 0.76844, 0.74999, - 0.77622, 0.78227, 0.77441, 0.74688, - 0.73521, 0.73782, 0.71928, 0.71708, - 0.71465, 0.60592, 0.52031, 0.51768, - 0.52102, 0.37956, 0.30786]; - -dsr = [0.00019952621, 0.00019952621, 7.9432844e-05, 5.0118702e-05, - 7.943284e-06 , 6.3095763e-06, 6.3095763e-06, 7.943284e-06 , - 1e-05 , 1e-05 , 7.943284e-06 , 1e-05 , - 1e-05 , 1e-05 , 7.943284e-06 , 1e-05 , - 1e-05 , 7.943284e-06 , 7.943284e-06 , 6.3095763e-06, - 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, - 6.3095763e-06, 3.1622776e-06, 3.1622776e-06, 3.1622776e-06, - 6.3095763e-07, 3.1622776e-07, 3.1622776e-07]; - -acousticPreDelay = 0.016; -inputPreDelay = 0.08163; \ No newline at end of file +[general] +reverbFile = scripts/testv/rend_config_hospital_patientroom.dat; diff --git a/scripts/testv/rend_config_recreation.cfg b/scripts/testv/rend_config_recreation.cfg index cc822d630c..cd5929919e 100644 --- a/scripts/testv/rend_config_recreation.cfg +++ b/scripts/testv/rend_config_recreation.cfg @@ -1,34 +1,2 @@ -[roomAcoustics] -reverb = true; -brir = false; -nBands = 31; - -fc = [20.0, 25.0, 31.5, 40.0, - 50.0, 63.0, 80.0, 100.0, - 125.0, 160.0, 200.0, 250.0, - 315.0, 400.0, 500.0, 630.0, - 800.0, 1000.0, 1250.0, 1600.0, - 2000.0, 2500.0, 3150.0, 4000.0, - 5000.0, 6300.0, 8000.0, 10000.0, - 12500.0, 16000.0, 20000.0]; - -rt60 = [4.51916, 4.89553, 4.83276, 5.00198, - 5.34468, 5.76026, 6.36818, 6.95503, - 7.27557, 7.62559, 8.08892, 8.16002, - 8.13900, 8.17919, 8.16280, 8.46226, - 9.61806, 9.93048, 9.81353, 8.59340, - 8.38885, 8.36823, 6.51845, 3.76089, - 3.75374, 3.57451, 1.28724, 1.22174, - 1.22448, 1.71631, 2.14343]; - -dsr = [1e-06 , 7.943284e-07 , 1e-06 , 1e-06 , - 1.5848925e-06, 1.9952631e-06, 3.1622776e-06, 3.9810707e-06, - 6.3095763e-06, 7.943284e-06 , 1e-05 , 7.943284e-06 , - 7.943284e-06 , 7.943284e-06 , 7.943284e-06 , 7.943284e-06 , - 5.01187e-06 , 5.01187e-06 , 3.9810707e-06, 3.1622776e-06, - 3.1622776e-06, 2.511887e-06 , 7.943284e-07 , 6.3095763e-07, - 6.3095763e-07, 5.01187e-08 , 1.2589251e-08, 1.2589251e-08, - 1.2589265e-09, 1.2589266e-11, 3.981075e-12]; - -acousticPreDelay = 0.016; -inputPreDelay = 0.43031; +[general] +reverbFile = scripts/testv/rend_config_recreation.dat; diff --git a/scripts/testv/rend_config_renderer.cfg b/scripts/testv/rend_config_renderer.cfg index 442edf2506..86e2f181f4 100644 --- a/scripts/testv/rend_config_renderer.cfg +++ b/scripts/testv/rend_config_renderer.cfg @@ -1,34 +1,2 @@ -[roomAcoustics] -reverb = true; # Reverb switch, in case BRIR is undefined or false, reverb flag is inherited from the room flag -brir = false; -nBands = 31; - -fc = [20.0, 25.0, 31.5, 40.0, - 50.0, 63.0, 80.0, 100.0, - 125.0, 160.0, 200.0, 250.0, - 315.0, 400.0, 500.0, 630.0, - 800.0, 1000.0, 1250.0, 1600.0, - 2000.0, 2500.0, 3150.0, 4000.0, - 5000.0, 6300.0, 8000.0, 10000.0, - 12500.0, 16000.0, 20000.0]; - -rt60 = [1.3622, 1.4486, 1.3168, 1.5787, - 1.4766, 1.3954, 1.2889, 1.3462, - 1.0759, 1.0401, 1.0970, 1.0850, - 1.0910, 1.0404, 1.0499, 1.0699, - 1.1028, 1.1714, 1.1027, 1.0666, - 1.0550, 1.0553, 1.0521, 1.0569, - 1.0421, 0.97822, 0.80487, 0.75944, - 0.71945, 0.61682, 0.60031]; - -dsr = [1.9952632e-08, 1.9952632e-08, 1.2589251e-08, 1.5848926e-08, - 1.2589251e-08, 1.9952632e-08, 2.511887e-08 , 3.9810708e-08, - 1e-07 , 1.9952633e-07, 3.981071e-07 , 6.3095763e-07, - 7.943284e-07 , 6.3095763e-07, 5.01187e-07 , 5.01187e-07 , - 6.3095763e-07, 6.3095763e-07, 7.943284e-07 , 6.3095763e-07, - 5.01187e-07 , 6.3095763e-07, 6.3095763e-07, 6.3095763e-07, - 5.01187e-07 , 2.511887e-07 , 1.2589251e-07, 1e-07 , - 6.309576e-08 , 3.1622776e-08, 2.511887e-08]; - -acousticPreDelay = 0.016; -inputPreDelay = 0.1; \ No newline at end of file +[general] +reverbFile = scripts/testv/rend_config_renderer.dat; \ No newline at end of file diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index 00ea239714..df8f67efcd 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -58,6 +58,7 @@ def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): # Test compares rendering with render config file containing just reverb defaults against rendering without config file. # These should be binary equivalent. +@pytest.mark.skip("disable until .cfg parsing is enabled again") @pytest.mark.parametrize("config_file", CONFIG_FILES_TO_TEST) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) -- GitLab From 4ca9d699225f79593671fd8bf64f9f4492724da5 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Thu, 20 Apr 2023 17:39:04 +0200 Subject: [PATCH 005/101] Preserve binary reverb file path text case --- lib_util/render_config_reader.c | 41 +++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 82ffb230a1..2a12e5f552 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -825,7 +825,11 @@ static int32_t errorHandler( * Verifies if the configuration parameters lie within acceptable limits *------------------------------------------------------------------------------------------*/ +#ifdef CONTROL_METADATA_REVERB ivas_error RenderConfigReader_checkValues( +#else +static ivas_error RenderConfigReader_checkValues( +#endif IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ) { @@ -1404,22 +1408,35 @@ ivas_error RenderConfigReader_read( fprintf( stderr, "Reverb config: number of bands changed but configuration vectors missing\n" ); } } -#ifdef DEBUGGING else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) -#endif #else -#ifdef DEBUGGING if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) #endif -#endif -#ifdef DEBUGGING { params_idx = 0; pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { +#ifndef CONTROL_METADATA_REVERB params_idx += ( int32_t )( strlen( item ) + strlen( pValue ) + 2 ); +#endif +#ifdef DEBUGGING fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif +#ifdef CONTROL_METADATA_REVERB + if ( strcmp( item, "REVERBFILE" ) == 0 ) + { + /* get correct case file path */ + sscanf( pTemp + params_idx, "%*[^=] = %[^;];", pValue ); + if ( ( error = RenderConfigReader_readReverb(pValue, pRenderConfigReader) ) != IVAS_ERR_OK) + { + printf( "RenderConfigReader_readReverb(%s) returned %d\n", pValue, error ); + errorHandler( item, error ); + } + } + else +#endif +#ifdef DEBUGGING if ( strcmp( item, "RENDERER" ) == 0 ) { if ( strcmp( pValue, "CREND" ) == 0 ) @@ -1442,25 +1459,19 @@ ivas_error RenderConfigReader_read( errorHandler( item, ERROR_VALUE_INVALID ); } } - if ( strcmp( item, "REVERBFILE" ) == 0 ) - { - // TODO: need to preserve file name case for non Windows OSes - if ( ( error = RenderConfigReader_readReverb(pValue, pRenderConfigReader) ) != IVAS_ERR_OK) - { - printf( "RenderConfigReader_readReverb(%s) returned %d\n", pValue, error ); - errorHandler( item, error ); - } - } #ifdef DEBUGGING else { fprintf( stderr, "Unsupported configuration property %s\n", item ); } +#endif +#endif +#ifdef CONTROL_METADATA_REVERB + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); #endif } free( pValue ); } -#endif else { fprintf( stderr, "Unknown chapter: %s\n", chapter ); -- GitLab From 2c8286b9473230e9f283fe73a2ef7804fe2183cb Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Mon, 24 Apr 2023 15:04:30 +0200 Subject: [PATCH 006/101] Make reverb configuration file path relative to render configuration file path --- apps/decoder.c | 2 +- apps/renderer.c | 2 +- lib_util/render_config_reader.c | 29 +++++++++++++++---- lib_util/render_config_reader.h | 1 + scripts/testv/config_directivity.cfg | 2 +- .../rend_config_hospital_patientroom.cfg | 2 +- scripts/testv/rend_config_recreation.cfg | 2 +- scripts/testv/rend_config_renderer.cfg | 2 +- 8 files changed, 31 insertions(+), 11 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index d24158a47a..f7da07e3fc 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -505,7 +505,7 @@ int main( goto cleanup; } - if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) + if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); goto cleanup; diff --git a/apps/renderer.c b/apps/renderer.c index 46714ecbda..29cfd52993 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -731,7 +731,7 @@ int main( exit( -1 ); } - if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) + if ( RenderConfigReader_read( renderConfigReader, args.renderConfigFilePath, &renderConfig ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFilePath ); exit( -1 ); diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 2a12e5f552..813916ad2e 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1259,6 +1259,7 @@ static ivas_error RenderConfigReader_readReverb( ivas_error RenderConfigReader_read( RenderConfigReader *pRenderConfigReader, /* i/o : RenderConfigReader handle */ + const char *pRenderConfigPath, /* i : Renderer configuration file path */ IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ) { @@ -1274,6 +1275,8 @@ ivas_error RenderConfigReader_read( int16_t nBandsInput; #ifdef CONTROL_METADATA_REVERB ivas_error error; + int32_t params_length; + int32_t length; #else int16_t nVectorsMissing; #endif @@ -1417,7 +1420,9 @@ ivas_error RenderConfigReader_read( pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { -#ifndef CONTROL_METADATA_REVERB +#ifdef CONTROL_METADATA_REVERB + params_length = (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#else params_idx += ( int32_t )( strlen( item ) + strlen( pValue ) + 2 ); #endif #ifdef DEBUGGING @@ -1426,13 +1431,27 @@ ivas_error RenderConfigReader_read( #ifdef CONTROL_METADATA_REVERB if ( strcmp( item, "REVERBFILE" ) == 0 ) { - /* get correct case file path */ + /* get correct case reverb configuration file path */ sscanf( pTemp + params_idx, "%*[^=] = %[^;];", pValue ); - if ( ( error = RenderConfigReader_readReverb(pValue, pRenderConfigReader) ) != IVAS_ERR_OK) + + /* 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; + } + } + char *pCombinedName = calloc( length + (int32_t) strlen( pValue ) + 1, sizeof( char ) ); + strncpy( pCombinedName, pRenderConfigPath, length ); + strcpy( pCombinedName + length, pValue ); + + if ( ( error = RenderConfigReader_readReverb( pCombinedName, pRenderConfigReader ) ) != IVAS_ERR_OK ) { - printf( "RenderConfigReader_readReverb(%s) returned %d\n", pValue, error ); errorHandler( item, error ); } + free( pCombinedName ); } else #endif @@ -1467,7 +1486,7 @@ ivas_error RenderConfigReader_read( #endif #endif #ifdef CONTROL_METADATA_REVERB - params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + params_idx += params_length; #endif } free( pValue ); diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index d0d37d6fc3..e108f0297d 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -67,6 +67,7 @@ ivas_error RenderConfigReader_checkValues( /* Reads a configuration */ 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 */ ); diff --git a/scripts/testv/config_directivity.cfg b/scripts/testv/config_directivity.cfg index 94807d688c..77f392ca7c 100644 --- a/scripts/testv/config_directivity.cfg +++ b/scripts/testv/config_directivity.cfg @@ -1,3 +1,3 @@ [general] directivity = [0.0, 360.0, 0.2512]; - +reverbFile = rend_config_renderer.dat; diff --git a/scripts/testv/rend_config_hospital_patientroom.cfg b/scripts/testv/rend_config_hospital_patientroom.cfg index c00b642947..75bfdf910f 100644 --- a/scripts/testv/rend_config_hospital_patientroom.cfg +++ b/scripts/testv/rend_config_hospital_patientroom.cfg @@ -1,2 +1,2 @@ [general] -reverbFile = scripts/testv/rend_config_hospital_patientroom.dat; +reverbFile = rend_config_hospital_patientroom.dat; diff --git a/scripts/testv/rend_config_recreation.cfg b/scripts/testv/rend_config_recreation.cfg index cd5929919e..d91064856c 100644 --- a/scripts/testv/rend_config_recreation.cfg +++ b/scripts/testv/rend_config_recreation.cfg @@ -1,2 +1,2 @@ [general] -reverbFile = scripts/testv/rend_config_recreation.dat; +reverbFile = rend_config_recreation.dat; diff --git a/scripts/testv/rend_config_renderer.cfg b/scripts/testv/rend_config_renderer.cfg index 86e2f181f4..cbada86bec 100644 --- a/scripts/testv/rend_config_renderer.cfg +++ b/scripts/testv/rend_config_renderer.cfg @@ -1,2 +1,2 @@ [general] -reverbFile = scripts/testv/rend_config_renderer.dat; \ No newline at end of file +reverbFile = rend_config_renderer.dat; \ No newline at end of file -- GitLab From ee0cb4895bc1712f029a540ed01bfab2778dbadf Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Tue, 25 Apr 2023 17:42:41 +0200 Subject: [PATCH 007/101] reverb configuration no longer required in render configuration file; test_ambisonics_binaural_headrotation_defaultrenderconfig() removed (defaults can not be achieved bit-exact via reverb configuration; does not change code coverage) --- apps/decoder.c | 13 ++++++++----- apps/renderer.c | 13 ++++++++----- scripts/testv/config_directivity.cfg | 1 - scripts/testv/just_reverb.cfg | 2 -- tests/renderer/constants.py | 4 ---- tests/renderer/test_renderer.py | 20 -------------------- 6 files changed, 16 insertions(+), 37 deletions(-) delete mode 100644 scripts/testv/just_reverb.cfg diff --git a/apps/decoder.c b/apps/decoder.c index f7da07e3fc..6843c26eff 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -512,14 +512,17 @@ int main( } #ifdef CONTROL_METADATA_REVERB - if ( RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) != IVAS_ERR_OK ) + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) ) == IVAS_ERR_OK ) { - fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); - goto cleanup; + if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Invalid reverberation configuration parameters\n\n" ); + goto cleanup; + } } - if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + else if ( error != IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) { - fprintf( stderr, "Invalid reverberation configuration parameters\n\n" ); + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); goto cleanup; } diff --git a/apps/renderer.c b/apps/renderer.c index 29cfd52993..72a8c05600 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -738,14 +738,17 @@ int main( } #ifdef CONTROL_METADATA_REVERB - if ( RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) != IVAS_ERR_OK ) + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) ) == IVAS_ERR_OK ) { - fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); - exit( -1 ); + if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Invalid reverberation configuration parameters\n\n" ); + exit( -1 ); + } } - if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + else if ( error != IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) { - fprintf( stderr, "Invalid reverberation configuration parameters\n\n" ); + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); exit( -1 ); } #ifdef COMMAND_LINE_OPTION_LATE_REVERB diff --git a/scripts/testv/config_directivity.cfg b/scripts/testv/config_directivity.cfg index 77f392ca7c..f958df1d31 100644 --- a/scripts/testv/config_directivity.cfg +++ b/scripts/testv/config_directivity.cfg @@ -1,3 +1,2 @@ [general] directivity = [0.0, 360.0, 0.2512]; -reverbFile = rend_config_renderer.dat; diff --git a/scripts/testv/just_reverb.cfg b/scripts/testv/just_reverb.cfg deleted file mode 100644 index 28acb76dc6..0000000000 --- a/scripts/testv/just_reverb.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[roomAcoustics] -reverb = true; # Reverb switch, in case BRIR is undefined or false, reverb flag is inherited from the room flag diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index e29696adec..3625a9307e 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -193,10 +193,6 @@ HR_TRAJECTORIES_TO_TEST = [ "rotate_yaw_pitch_roll1", ] -CONFIG_FILES_TO_TEST = [ - "just_reverb" -] - """ Per-testcase xfail SNR thresholds (dB) """ pass_snr = dict() # not relevant for tests anymore, should be deprecated soon _pass_snr = { diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index df8f67efcd..b4ecf611da 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -55,26 +55,6 @@ def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), ) - -# Test compares rendering with render config file containing just reverb defaults against rendering without config file. -# These should be binary equivalent. -@pytest.mark.skip("disable until .cfg parsing is enabled again") -@pytest.mark.parametrize("config_file", CONFIG_FILES_TO_TEST) -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) -@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) -def test_ambisonics_binaural_headrotation_defaultrenderconfig(test_info, in_fmt, out_fmt, config_file): - compare_renderer_args( - test_info, - in_fmt, - out_fmt, - ref_kwargs={ - "name_extension": "defaultrenderconfig" - }, - cut_kwargs={ - "config_file": TESTV_DIR.joinpath(f"{config_file}.cfg") - } - ) - # Test compares rendering with just a trajectory file against rendering with a trajectory file + a zero ref rotation. # These should be binary equivalent. @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) -- GitLab From f795b400f4964757d4601673f0c2db7753c95d8a Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Mon, 1 May 2023 14:49:42 +0200 Subject: [PATCH 008/101] RenderConfigReader_checkValues() return value was was erroneously discarded in RenderConfigReader_read() --- apps/decoder.c | 4 ++++ apps/renderer.c | 4 ++++ lib_util/render_config_reader.c | 11 +++++------ lib_util/render_config_reader.h | 6 ++++-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 6843c26eff..96e3e1b153 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -505,7 +505,11 @@ int main( goto cleanup; } +#ifdef CONTROL_METADATA_REVERB if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) +#else + if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); goto cleanup; diff --git a/apps/renderer.c b/apps/renderer.c index 72a8c05600..6b439bb991 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -731,7 +731,11 @@ int main( exit( -1 ); } +#ifdef CONTROL_METADATA_REVERB if ( RenderConfigReader_read( renderConfigReader, args.renderConfigFilePath, &renderConfig ) != IVAS_ERR_OK ) +#else + if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFilePath ); exit( -1 ); diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 813916ad2e..7ab86bab5f 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -928,9 +928,6 @@ ivas_error RenderConfigReader_open( { RenderConfigReader *pSelf; FILE *pConfigFile; -#ifndef CONTROL_METADATA_REVERB - int length; -#endif /* Open the configuration file */ if ( strlen( pConfigPath ) < 1 ) @@ -1259,8 +1256,10 @@ static ivas_error RenderConfigReader_readReverb( ivas_error RenderConfigReader_read( RenderConfigReader *pRenderConfigReader, /* i/o : RenderConfigReader handle */ - const char *pRenderConfigPath, /* i : Renderer configuration file path */ - IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ +#ifdef CONTROL_METADATA_REVERB + const char *pRenderConfigPath, /* i : Renderer configuration file path */ +#endif + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ) { int32_t file_size; @@ -1520,7 +1519,7 @@ ivas_error RenderConfigReader_read( #ifdef CONTROL_METADATA_REVERB return IVAS_ERR_OK; #else - RenderConfigReader_checkValues( hRenderConfig ); + return RenderConfigReader_checkValues( hRenderConfig ); #endif } diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index e108f0297d..70b4cf42d7 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -67,8 +67,10 @@ ivas_error RenderConfigReader_checkValues( /* Reads a configuration */ 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 */ +#ifdef CONTROL_METADATA_REVERB + const char *pRenderConfigPath, /* i : Renderer configuration file path */ +#endif + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ); /* Closes the renderer configuration reader and deallocates memory */ -- GitLab From a0678acad21784d3bdf1604e7db607912e336cd2 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Tue, 2 May 2023 15:10:45 +0200 Subject: [PATCH 009/101] solved some compiler and clang-format warnings --- lib_util/render_config_reader.c | 29 ++++++++++++++++------------- lib_util/render_config_reader.h | 11 +++++++---- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 7ab86bab5f..32a2cfb0c6 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -44,7 +44,7 @@ *------------------------------------------------------------------------------------------*/ #ifndef CONTROL_METADATA_REVERB -#define MAX_LINE_LENGTH ( 1024 ) +#define MAX_LINE_LENGTH ( 1024 ) #endif #define MAX_ITEM_LENGTH ( 64 ) #ifndef CONTROL_METADATA_REVERB @@ -477,10 +477,10 @@ static ivas_error read_code_word( } /* First read minLen bits, then add one bit per iteration to find the correct value */ - for (n = 0; n < size; n++) + for ( n = 0; n < size; n++ ) { - minLen = min(minLen, pLengths[n]); - maxLen = max(maxLen, pLengths[n]); + minLen = min( minLen, pLengths[n] ); + maxLen = max( maxLen, pLengths[n] ); } for ( len = minLen; len <= maxLen; len++ ) { @@ -1255,11 +1255,14 @@ static ivas_error RenderConfigReader_readReverb( #endif ivas_error RenderConfigReader_read( - RenderConfigReader *pRenderConfigReader, /* i/o : RenderConfigReader handle */ #ifdef CONTROL_METADATA_REVERB - const char *pRenderConfigPath, /* i : Renderer configuration file path */ + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + const char *pRenderConfigPath, /* i : Renderer configuration file path */ + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ +#else + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ #endif - IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ) { int32_t file_size; @@ -1271,12 +1274,12 @@ ivas_error RenderConfigReader_read( char item[MAX_ITEM_LENGTH + 1]; char chapter[MAX_ITEM_LENGTH + 1]; char *pValue; - int16_t nBandsInput; #ifdef CONTROL_METADATA_REVERB ivas_error error; int32_t params_length; int32_t length; #else + int16_t nBandsInput; int16_t nVectorsMissing; #endif @@ -1286,8 +1289,8 @@ ivas_error RenderConfigReader_read( 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 ) ); - nBandsInput = hRenderConfig->room_acoustics.nBands; #ifndef CONTROL_METADATA_REVERB + nBandsInput = hRenderConfig->room_acoustics.nBands; nVectorsMissing = N_REVERB_VECTORS; #endif @@ -1330,7 +1333,7 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { hRenderConfig->room_acoustics.override = TRUE; - params_idx += ( int32_t )( strlen( item ) + strlen( pValue ) + 2 ); + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); #ifdef DEBUGGING fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); #endif @@ -1422,7 +1425,7 @@ ivas_error RenderConfigReader_read( #ifdef CONTROL_METADATA_REVERB params_length = (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); #else - params_idx += ( int32_t )( strlen( item ) + strlen( pValue ) + 2 ); + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); #endif #ifdef DEBUGGING fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); @@ -1448,14 +1451,14 @@ ivas_error RenderConfigReader_read( if ( ( error = RenderConfigReader_readReverb( pCombinedName, pRenderConfigReader ) ) != IVAS_ERR_OK ) { - errorHandler( item, error ); + errorHandler( item, ERROR_VALUE_INVALID ); } free( pCombinedName ); } else #endif #ifdef DEBUGGING - if ( strcmp( item, "RENDERER" ) == 0 ) + if ( strcmp( item, "RENDERER" ) == 0 ) { if ( strcmp( pValue, "CREND" ) == 0 ) { diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 70b4cf42d7..4facb5b9cd 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -60,17 +60,20 @@ ivas_error RenderConfigReader_getAcousticEnvironment( ); /* Verifies configuration parameters */ ivas_error RenderConfigReader_checkValues( - IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ); #endif /* Reads a configuration */ ivas_error RenderConfigReader_read( - RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ #ifdef CONTROL_METADATA_REVERB - const char *pRenderConfigPath, /* i : Renderer configuration file path */ + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + const char *pRenderConfigPath, /* i : Renderer configuration file path */ + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ +#else + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ #endif - IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ ); /* Closes the renderer configuration reader and deallocates memory */ -- GitLab From fde101818c899d25b71619b9dada8ad29a8ce12c Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 2 May 2023 16:03:07 +0200 Subject: [PATCH 010/101] Script update to generate acoustic environments metadata including early reflections --- ...enerate_acoustic_environments_metadata.py} | 225 +++++++++++++++++- 1 file changed, 218 insertions(+), 7 deletions(-) rename scripts/reverb/{generate_reverb_metadata.py => generate_acoustic_environments_metadata.py} (64%) diff --git a/scripts/reverb/generate_reverb_metadata.py b/scripts/reverb/generate_acoustic_environments_metadata.py similarity index 64% rename from scripts/reverb/generate_reverb_metadata.py rename to scripts/reverb/generate_acoustic_environments_metadata.py index a05bbeb2d8..c7d49bf3f4 100644 --- a/scripts/reverb/generate_reverb_metadata.py +++ b/scripts/reverb/generate_acoustic_environments_metadata.py @@ -196,10 +196,8 @@ def get_frequency_code(f): def get_frequency_hop_code(index): assert 0 <= index < 9 return [ - '1100', # 2^(1/8) - '1101', # 2^(1/7) - '0010', # 2^(1/6) - '0011', # 2^(1/5) + '0010', # 2^(1/12) + '0011', # 2^(1/6) '0000', # 2^(1/4) '01', # 2^(1/3) '0001', # 2^(1/2) @@ -241,6 +239,93 @@ class fgdMethod(Enum): Default_Banding = '10' +def get_distance_code(dist, isSmallScene = True): + # 0, 1, ... 99 + metersCode = [ + '111101', '110010', '110011', '110000', '110001', '110110', '110111', '110100', '110101', '001010', + '001011', '001000', '001001', '001110', '001111', '001100', '001101', '000010', '000011', '000000', + '000001', '000110', '000111', '000100', '000101', '011010', '011011', '011000', '011001', '011110', + '011111', '011100', '011101', '010010', '010011', '010000', '010001', '010110', '010111', '010100', + '010101', '101010', '101011', '101000', '101001', '101110', '101111', '101100', '101101', '10000', + '1000100', '1000101', '10001110', '10001111', '10001100', '10001101', '10011010', '10011011', '10011000', '10011001', + '10011110', '10011111', '10011100', '10011101', '10010010', '10010011', '10010000', '10010001', '10010110', '10010111', + '10010100', '10010101', '11101010', '11101011', '11101000', '11101001', '11101110', '11101111', '11101100', '11101101', + '11100010', '11100011', '11100000', '11100001', '11100110', '11100111', '11100100', '11100101', '11111010', '11111011', + '11111000', '11111001', '11111110', '11111111', '11111100', '11111101', '11110010', '11110011', '11110000', '11110001' ] + + # 0, 1, ... 9 + hectometersCode = [ + '000', '001', '110', '111', '100', '101', '0110', '0111', '0100', '0101' ] + + # 1, 2, ... 10 + kilometersCode = [ + '10', '011', '001', '000', '111', '0101', '0100', '1101', '11001', '11000' ] + + # 0, 1, ... 99 + centimetersCode = [ + '110010', '110011', '110000', '110001', '110110', '110111', '110100', '110101', '0101010', '0101011', + '0101000', '0101001', '0101110', '0101111', '0101100', '0101101', '0100010', '0100011', '0100000', '0100001', + '0100110', '0100111', '0100100', '0100101', '0111010', '0111011', '0111000', '0111001', '0111110', '0111111', + '0111100', '0111101', '0110010', '0110011', '0110000', '0110001', '0110110', '0110111', '0110100', '0110101', + '0001010', '0001011', '0001000', '0001001', '0001110', '0001111', '0001100', '0001101', '0000010', '0000011', + '0000000', '0000001', '0000110', '0000111', '0000100', '0000101', '0011010', '0011011', '0011000', '0011001', + '0011110', '0011111', '0011100', '0011101', '0010010', '0010011', '0010000', '0010001', '0010110', '0010111', + '0010100', '0010101', '101010', '101011', '101000', '101001', '101110', '101111', '101100', '101101', + '100010', '100011', '100000', '100001', '100110', '100111', '100100', '100101', '1111010', '1111011', + '1111000', '1111001', '1111110', '1111111', '1111100', '1111101', '111010', '111011', '111000', '111001' ] + + distance_mm = int(round(np.float32(distance) * np.float32(1000))) # distance in mm + if print_cfg: + print('distance: ', distance_mm) + + mm = distance_mm # [mm] + cm = mm // 10 # [cm] + m = cm // 100 # [m] + hm = m // 100 # [hm] + km = hm // 10 # [km] + + mm = (mm % 10) # 0, 1, ... 9 [mm] + cm = (cm % 100) # 0, 1, ... 99 [cm] + m = (m % 100) # 0, 1, ... 99 [m] + hm = (hm % 9) # 0, 1, ... 9 [hm] + + assert 0 <= mm <= 9 + assert 0 <= cm <= 99 + assert 0 <= m <= 99 + assert 0 <= hm <= 9 + assert distance_mm == km * 1000000 + hm * 100000 + m * 1000 + cm * 10 + mm + + code = metersCode[m] + + if not isSmallScene: + # large scenes + if hm > 0 or km > 0: + # hectometers + code += '1' + hectometersCode[hm] + while km > 0: + # kilometers + code += '1' + kilometersCode[min(km, 10)] + km = km - 10 + code += '0' + else: + code += '0' + + # centimeters + if cm > 0: + code += '1' + centimetersCode[cm] + else: + code += '0' + + return code + + +def get_absorption_code(absorption): + assert 0.0 <= absorption <= 1.0 + + index = round(absorption * 10.0) + + return ['110', '100', '101', '0110', '0111', '111', '0100', '0101', '0010', '0011', '000' ][index] + # apply function to elements of list and concatenate the resulting strings def concatenate(function, data): return ''.join([function(d) for d in data]) @@ -248,6 +333,7 @@ def concatenate(function, data): def test(): # generate binary output which can be compared with the Matlab implementation output + string = '' # count or index encoding @@ -282,7 +368,8 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg(): # based on config_renderer.cfg # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values data = bitarray( - get_count_or_index_code(1) # fgdNrGrids + '1' # hasAcEnv + + get_count_or_index_code(1) # fgdNrGrids + fgdMethod.Individual_Frequencies.value # fgdMethod + get_count_or_index_code(31) # fgdNrBands @@ -308,6 +395,62 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg(): 3.702e-07, 6.1341e-07, 7.1432e-07, 6.5331e-07, 4.6094e-07, 5.4683e-07, 7.0134e-07, 6.856e-07, 7.114e-07, 6.9604e-07, 5.2939e-07, 5.699e-07, 6.1773e-07, 5.7488e-07, 4.7748e-07, 2.7213e-07, 1.3681e-07, 1.0941e-07, 6.2001e-08, 2.8483e-08, 2.6267e-08 ]) + + '0' # hasEarlyReflections + , endian='big') + + file = open('rend_config_renderer.dat', 'wb') + data.tofile(file) + file.close() + +def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_no_listener_origin(): + # based on config_renderer.cfg + # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values + data = bitarray( + '1' # hasAcEnv + + get_count_or_index_code(2) # fgdNrGrids + # frequency grid #1 + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(1) # fgdNrBands + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 10000.0 ]) + + # frequency grid #2 + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(31) # fgdNrBands + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, + 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0, + 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, + 20000.0 ]) + + + get_count_or_index_code(1) # AcousticEnvCount + + get_id_code(0) # ID + + get_count_or_index_code(1) # FreqGridID + + get_duration_code(0.1) # (input)Predelay + + + concatenate(get_duration_code, # RT60 + [ 1.3622, 1.4486, 1.3168, 1.5787, 1.4766, 1.3954, 1.2889, 1.3462, 1.0759, 1.0401, + 1.0970, 1.0850, 1.0910, 1.0404, 1.0499, 1.0699, 1.1028, 1.1714, 1.1027, 1.0666, + 1.0550, 1.0553, 1.0521, 1.0569, 1.0421, 0.97822, 0.80487, 0.75944, 0.71945, 0.61682, + 0.60031 ]) + + + concatenate(get_dsr_code, # DSR + [ 1.8811e-08, 2.1428e-08, 1.3972e-08, 1.51e-08, 1.287e-08, 1.8747e-08, 2.413e-08, 3.9927e-08, 8.9719e-08, 1.902e-07, + 3.702e-07, 6.1341e-07, 7.1432e-07, 6.5331e-07, 4.6094e-07, 5.4683e-07, 7.0134e-07, 6.856e-07, 7.114e-07, 6.9604e-07, + 5.2939e-07, 5.699e-07, 6.1773e-07, 5.7488e-07, 4.7748e-07, 2.7213e-07, 1.3681e-07, 1.0941e-07, 6.2001e-08, 2.8483e-08, + 2.6267e-08 ]) + + + '1' # hasEarlyReflections + + concatenate(get_distance_code, # room dimensions + [ 3.0, 4.0, 2.5 ]) + + + get_count_or_index_code(0) # FreqGridID + + concatenate(get_absorption_code, # absorptionCode + [ 0.8, 0.8, 0.8, 0.8, 0.2, 0.6 ]) + + + '0' # listener origin flag , endian='big') @@ -316,11 +459,74 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg(): file.close() +def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_listener_origin(): + # based on config_renderer.cfg + # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values + data = bitarray( + '1' # hasAcEnv + + get_count_or_index_code(2) # fgdNrGrids + # frequency grid #1 + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(1) # fgdNrBands + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 10000.0 ]) + + # frequency grid #2 + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(31) # fgdNrBands + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, + 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0, + 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, + 20000.0 ]) + + + get_count_or_index_code(1) # AcousticEnvCount + + get_id_code(0) # ID + + get_count_or_index_code(1) # FreqGridID + + get_duration_code(0.1) # (input)Predelay + + + concatenate(get_duration_code, # RT60 + [ 1.3622, 1.4486, 1.3168, 1.5787, 1.4766, 1.3954, 1.2889, 1.3462, 1.0759, 1.0401, + 1.0970, 1.0850, 1.0910, 1.0404, 1.0499, 1.0699, 1.1028, 1.1714, 1.1027, 1.0666, + 1.0550, 1.0553, 1.0521, 1.0569, 1.0421, 0.97822, 0.80487, 0.75944, 0.71945, 0.61682, + 0.60031 ]) + + + concatenate(get_dsr_code, # DSR + [ 1.8811e-08, 2.1428e-08, 1.3972e-08, 1.51e-08, 1.287e-08, 1.8747e-08, 2.413e-08, 3.9927e-08, 8.9719e-08, 1.902e-07, + 3.702e-07, 6.1341e-07, 7.1432e-07, 6.5331e-07, 4.6094e-07, 5.4683e-07, 7.0134e-07, 6.856e-07, 7.114e-07, 6.9604e-07, + 5.2939e-07, 5.699e-07, 6.1773e-07, 5.7488e-07, 4.7748e-07, 2.7213e-07, 1.3681e-07, 1.0941e-07, 6.2001e-08, 2.8483e-08, + 2.6267e-08 ]) + + + '1' # hasEarlyReflections + + concatenate(get_distance_code, # room dimensions + [ 3.0, 4.0, 2.5 ]) + + + get_count_or_index_code(0) # FreqGridID + + concatenate(get_absorption_code, # absorptionCode + [ 0.8, 0.8, 0.8, 0.8, 0.2, 0.6 ]) + + + '1' # listener origin flag + + '1' # positive x origin + + '0' # negative y origin + + concatenate(get_distance_code, # listener origin (x, y, z) + [ 0.5, 0.5, 1.5 ]) + + , endian='big') + + file = open('rend_config_renderer.dat', 'wb') + data.tofile(file) + file.close() + + + def generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg(): # based on config_hospital_patientroom.cfg # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values data = bitarray( - get_count_or_index_code(1) # fgdNrGrids + 1 # hasAcEnv + + get_count_or_index_code(1) # fgdNrGrids + fgdMethod.Individual_Frequencies.value # fgdMethod + get_count_or_index_code(31) # fgdNrBands @@ -348,6 +554,8 @@ def generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg() 6.379496e-06, 6.358105e-06, 6.6696e-06, 6.369334e-06, 6.378474e-06, 3.339913e-06, 3.129318e-06, 2.892564e-06, 6.00202e-07, 3.40124e-07, 3.37705e-07 ]) + + '0' # hasEarlyReflections + , endian='big') file = open('rend_config_hospital_patientroom.dat', 'wb') @@ -359,7 +567,8 @@ def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): # based on config_recreation.cfg # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values data = bitarray( - get_count_or_index_code(1) # fgdNrGrids + 1 # hasAcEnv + + get_count_or_index_code(1) # fgdNrGrids + fgdMethod.Individual_Frequencies.value # fgdMethod + get_count_or_index_code(31) # fgdNrBands @@ -387,6 +596,8 @@ def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): 2.958383e-06, 2.725911e-06, 7.94912e-07, 6.20198e-07, 5.71181e-07, 5.5546e-08, 1.3987e-08, 1.338e-08, 1.322e-09, 1.3e-11, 4e-12 ]) + + '0' # hasEarlyReflections + , endian='big') file = open('rend_config_recreation.dat', 'wb') -- GitLab From 2e820810273e7f5ec2ae8cd1976c00bfe17302b2 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Wed, 3 May 2023 10:29:47 +0200 Subject: [PATCH 011/101] Reverb control metadata parser extension to support early reflections --- lib_com/options.h | 5 +- lib_util/render_config_reader.c | 382 +++++++++++++++++++++++++++++++- 2 files changed, 375 insertions(+), 12 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 23fc0f759f..86de207929 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -141,7 +141,10 @@ #endif #define DISABLE_ADAP_RES_COD_TMP /* temporary fix for IVAS-403, disables adaptive residual coding */ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ -#define CONTROL_METADATA_REVERB /* Philips: renderer configuration change to binary format */ +#define CONTROL_METADATA_REVERB /* Philips: reverb configuration change to binary format */ +#ifdef CONTROL_METADATA_REVERB +#define CONTROL_METADATA_EARLY_REFLECTIONS /* Philips/Qualcomm: early reflections extension to reverb configuration */ +#endif #define COMMAND_LINE_OPTION_LATE_REVERB /* Philips: late reverb command line option */ #define FIX_ISM_DTX_CNG_BWIDTH_ALT /* VA: issue 396 - alternative fix for bw changes on CNG frames in ISM DTX for objects that use the decoder-side noise estimation */ diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index c6e68eae25..71dea98dc1 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -48,6 +48,8 @@ #define MAX_LINE_LENGTH ( 1024 ) #define MAX_ITEM_LENGTH ( 64 ) #define N_REVERB_VECTORS ( 3 ) +#else +#define N_ABS_COEFFS ( 6 ) #endif #define SHORTEST_REV_DEL_LINE ( 0.015f ) @@ -84,13 +86,26 @@ typedef enum _FREQ_GRID_MODE FREQ_GRID_MODE_DEFAULT_BANDING = 2 } FREQ_GRID_MODE; +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS +typedef struct +{ + IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ + FrequencyGrid *pFG; /* Pointer to a frequency grid for absorption coeffs */ + float ( *pAbsCoeff )[N_ABS_COEFFS]; /* Absorption coeffs table pointer */ + IVAS_VECTOR3 *pListenerOrigin; /* Listener origin */ +} EarlyReflectionsConfig; +#endif + typedef struct { uint32_t id; /* Acoustic environment ID */ - FrequencyGrid *pFG; /* Pointer into Frequency grids table */ + FrequencyGrid *pFG; /* Pointer into Frequency grids table for late reverb coeffs */ float *pRT60; /* RT60 table */ float *pDSR; /* DSR table */ float preDelay; /* Pre-delay */ +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + EarlyReflectionsConfig *pEarlyReflections; /* Early reflections configuration */ +#endif } AcousticEnv; struct RenderConfigReader @@ -121,6 +136,11 @@ typedef enum _RC_LUT 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; /*------------------------------------------------------------------------------------------* @@ -223,9 +243,9 @@ const float lutFreq_Value[] = { 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.090507733f, 1.104089514f, 1.122462048f, 1.148698355f, 1.189207115f, 1.25992105f, 1.414213562f, 2.0f, 4.0f }; -const uint16_t lutFreqHop_Code[] = { 12, 13, 2, 3, 0, 1, 1, 2, 7 }; -const uint8_t lutFreqHop_Len[] = { 4, 4, 4, 4, 4, 2, 4, 2, 3 }; +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, @@ -265,6 +285,96 @@ const uint8_t lutDsr_Len[] = { 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 *------------------------------------------------------------------------------------------*/ @@ -470,16 +580,46 @@ static ivas_error read_code_word( 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++) + for ( n = 0; n < size; n++ ) { - minLen = min(minLen, pLengths[n]); - maxLen = max(maxLen, pLengths[n]); + minLen = min( minLen, pLengths[n] ); + maxLen = max( maxLen, pLengths[n] ); } for ( len = minLen; len <= maxLen; len++ ) { @@ -671,6 +811,106 @@ static ivas_error get_dsr( return IVAS_ERR_OK; } +/*-----------------------------------------------------------------------------------------* + * Function get_distance() + * Gets a distance value (in meters) + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_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_code_word( this, RC_LUT_METERS, pResult ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( isSmall == false ) + { + /* addHectometers flag */ + if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( flag == true ) + { + /* Hectometers */ + if ( ( error = read_code_word( this, RC_LUT_HECTOMETERS, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value * 100.0f; + + /* addKilometers flag */ + if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + + while ( flag == true ) + { + /* Kilometers */ + if ( ( error = read_code_word( this, RC_LUT_KILOMETERS, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value * 1000.0f; + + /* addKilometers flag */ + if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + /* addCentimeters flag */ + if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( flag == true ) + { + /* Centimeters */ + /* Kilometers */ + if ( ( error = read_code_word( this, RC_LUT_CENTIMETERS, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value * 0.01f; + } + } + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_absorption() + * Gets an absorption value + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_absorption( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Distance value */ +) +{ + ivas_error error; + + if ( ( error = read_code_word( this, RC_LUT_ABSORPTION, pResult ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + #else /*-----------------------------------------------------------------------------------------* * Function read_bool() @@ -971,7 +1211,10 @@ ivas_error RenderConfigReader_read( { uint32_t file_size; uint32_t value; - uint32_t i, n, m; +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + uint32_t signx, signy, k; +#endif + uint32_t i, m, n; ivas_error error; float freqHop; uint32_t gridLen; @@ -992,6 +1235,20 @@ ivas_error RenderConfigReader_read( fread( pRenderConfigReader->pBitstream, sizeof( uint8_t ), file_size, pRenderConfigReader->pConfigFile ); pRenderConfigReader->length = file_size; + /****************************/ + /* Read the presence flag */ + /****************************/ + if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Just return in case no acoustic environment data available */ + if ( value == false ) + { + return IVAS_ERR_OK; + } + /****************************/ /* Read the frequency grids */ /****************************/ @@ -1241,6 +1498,98 @@ ivas_error RenderConfigReader_read( return IVAS_ERR_INVALID_RENDER_CONFIG; } } + +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + /* Has early reflections */ + if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( value == true ) + { + if ( ( pRenderConfigReader->pAE[n].pEarlyReflections = (EarlyReflectionsConfig *) malloc( sizeof( EarlyReflectionsConfig ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + /* Room sizes */ + if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.y ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.z ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Frequency grid ID */ + if ( ( error = get_count_or_index( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + pRenderConfigReader->pAE[n].pEarlyReflections->pFG = &pRenderConfigReader->pFG[value]; + + /* Absorption coefficients */ + if ( ( pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff = malloc( pRenderConfigReader->pAE[n].pEarlyReflections->pFG->nrBands * sizeof( float[N_ABS_COEFFS] ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + for ( m = 0; m < pRenderConfigReader->pAE[n].pEarlyReflections->pFG->nrBands; m++ ) + { + for ( k = 0; k < N_ABS_COEFFS; k++ ) + { + if ( ( error = get_absorption( pRenderConfigReader, &pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[m][k] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + /* Has listener origin */ + if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != 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_bits( pRenderConfigReader, &signx, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = read_bits( pRenderConfigReader, &signy, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_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_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; + } + } + } +#endif } /* Cleanup */ @@ -1315,7 +1664,7 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { hRenderConfig->room_acoustics.override = TRUE; - params_idx += ( int32_t )( strlen( item ) + strlen( pValue ) + 2 ); + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); #ifdef DEBUGGING fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); #endif @@ -1402,7 +1751,7 @@ ivas_error RenderConfigReader_read( 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 ); + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); if ( strcmp( item, "RENDERER" ) == 0 ) { @@ -1517,7 +1866,7 @@ void RenderConfigReader_close( ) { #ifdef CONTROL_METADATA_REVERB - uint16_t n; + uint32_t n; #endif if ( ppRenderConfigReader == NULL || *ppRenderConfigReader == NULL ) @@ -1529,6 +1878,17 @@ void RenderConfigReader_close( /* Free the acoustic environments */ for ( n = 0; n < ( *ppRenderConfigReader )->nAE; n++ ) { +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections != NULL ) + { + if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin != NULL ) + { + free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin ); + } + free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pAbsCoeff ); + free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections ); + } +#endif free( ( *ppRenderConfigReader )->pAE[n].pRT60 ); free( ( *ppRenderConfigReader )->pAE[n].pDSR ); } -- GitLab From 8537b1dd6e85c309bfe13d27b849626d490f4af3 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Wed, 3 May 2023 10:32:43 +0200 Subject: [PATCH 012/101] further updates to acoustic environments metadata including early reflections --- ...generate_acoustic_environments_metadata.py | 91 ++++++++++--------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/scripts/reverb/generate_acoustic_environments_metadata.py b/scripts/reverb/generate_acoustic_environments_metadata.py index c7d49bf3f4..77c9841b40 100644 --- a/scripts/reverb/generate_acoustic_environments_metadata.py +++ b/scripts/reverb/generate_acoustic_environments_metadata.py @@ -117,9 +117,9 @@ def get_duration_code(duration): '110100000', '111010', '110100001', '111011', '110100110', '111000', '110100111', '111001', '110100100', '111110', '110100101', '111111', '110111010', '111100', '110111011', '111101', '110111000', '11000', '110111001' ] - duration_dus = int(round(np.float32(duration) * np.float32(100000))) # [deca us] + duration_dus = round(np.float32(duration) * np.float32(100000)) # [deca us] if print_cfg: - print('duration: ', duration_dus) + print('duration: ', duration_dus, 'dus') dus = duration_dus # [deca us] s = dus // 100000 # 0, 1, ... 30 [s] @@ -168,7 +168,7 @@ def get_frequency_code(f): assert 16 <= f <= 40000 if f in frequencyCode.keys(): if print_cfg: - print('frequency:', f) + print('frequency:', f, 'Hz') return frequencyCode[f] + '0' else: # exact frequency not found, use frequency refinement to aproximate @@ -185,25 +185,24 @@ def get_frequency_code(f): if refinement >= 16: # choose next higer frequency if print_cfg: - print('frequency:', list(frequencyCode)[f_high]) + print('frequency:', list(frequencyCode)[f_high], 'Hz') return frequencyCode[f_high] + '0' else: if print_cfg: - print('frequency:', list(frequencyCode)[f_low], ', refined: ', f_low * 2 ** ((refinement + 1) / 51)) + print('frequency:', list(frequencyCode)[f_low], ', Hz, refined: ', f_low * 2 ** ((refinement + 1) / 51), 'Hz') return frequencyCode[f_low] + '1' + format(refinement, '04b') def get_frequency_hop_code(index): - assert 0 <= index < 9 + assert 0 <= index < 7 return [ - '0010', # 2^(1/12) - '0011', # 2^(1/6) - '0000', # 2^(1/4) - '01', # 2^(1/3) - '0001', # 2^(1/2) - '10', # 2^1 - '111'][index] # 2^2 - + '0010', # 2^(1/12) + '0011', # 2^(1/6) + '0000', # 2^(1/4) + '01', # 2^(1/3) + '0001', # 2^(1/2) + '11', # 2^1 + '10'][index] # 2^2 def get_dsr_code(dsr): @@ -239,7 +238,7 @@ class fgdMethod(Enum): Default_Banding = '10' -def get_distance_code(dist, isSmallScene = True): +def get_distance_code(distance, isSmallScene = True): # 0, 1, ... 99 metersCode = [ '111101', '110010', '110011', '110000', '110001', '110110', '110111', '110100', '110101', '001010', @@ -274,37 +273,36 @@ def get_distance_code(dist, isSmallScene = True): '100010', '100011', '100000', '100001', '100110', '100111', '100100', '100101', '1111010', '1111011', '1111000', '1111001', '1111110', '1111111', '1111100', '1111101', '111010', '111011', '111000', '111001' ] - distance_mm = int(round(np.float32(distance) * np.float32(1000))) # distance in mm + distance_cm = round(np.float32(distance) * np.float32(100)) # distance in cm if print_cfg: - print('distance: ', distance_mm) + print('distance: ', distance_cm, 'cm') - mm = distance_mm # [mm] - cm = mm // 10 # [cm] + cm = distance_cm # [cm] m = cm // 100 # [m] hm = m // 100 # [hm] km = hm // 10 # [km] - mm = (mm % 10) # 0, 1, ... 9 [mm] cm = (cm % 100) # 0, 1, ... 99 [cm] m = (m % 100) # 0, 1, ... 99 [m] - hm = (hm % 9) # 0, 1, ... 9 [hm] + hm = (hm % 10) # 0, 1, ... 9 [hm] - assert 0 <= mm <= 9 assert 0 <= cm <= 99 assert 0 <= m <= 99 assert 0 <= hm <= 9 - assert distance_mm == km * 1000000 + hm * 100000 + m * 1000 + cm * 10 + mm + assert distance_cm == km * 100000 + hm * 10000 + m * 100 + cm code = metersCode[m] - if not isSmallScene: + if isSmallScene: + assert(m == hm == km == 0) + else: # large scenes if hm > 0 or km > 0: # hectometers code += '1' + hectometersCode[hm] while km > 0: # kilometers - code += '1' + kilometersCode[min(km, 10)] + code += '1' + kilometersCode[min(km, 10) - 1] km = km - 10 code += '0' else: @@ -326,6 +324,7 @@ def get_absorption_code(absorption): return ['110', '100', '101', '0110', '0111', '111', '0100', '0101', '0010', '0011', '000' ][index] + # apply function to elements of list and concatenate the resulting strings def concatenate(function, data): return ''.join([function(d) for d in data]) @@ -333,16 +332,15 @@ def concatenate(function, data): def test(): # generate binary output which can be compared with the Matlab implementation output - string = '' # count or index encoding - string += concatenate(get_count_or_index_code, [n for n in range(0, 16 * 64)]) + string += concatenate(get_count_or_index_code, [n for n in range(16 * 64)]) # duration encoding - string += concatenate(get_duration_code, [d / 1000 for d in range(0, 30 * 1000)]) - string += concatenate(get_duration_code, [d / 10000 for d in range(0, 30 * 1000)]) - string += concatenate(get_duration_code, [d / 100000 for d in range(0, 30 * 1000)]) + string += concatenate(get_duration_code, [d / 1000 for d in range(30 * 1000)]) + string += concatenate(get_duration_code, [d / 10000 for d in range(30 * 1000)]) + string += concatenate(get_duration_code, [d / 100000 for d in range(30 * 1000)]) # frequency encoding string += concatenate(get_frequency_code, @@ -352,11 +350,20 @@ def test(): 16000, 20000, 25000, 31500, 40000]) # frequency hop encoding - string += concatenate(get_frequency_hop_code, [index for index in range(0, 9)]) + string += concatenate(get_frequency_hop_code, [index for index in range(7)]) # DSR encoding string += concatenate(get_dsr_code, [math.pow(10, dsr / 10) for dsr in range(-150, -10 + 1)]) + # distance encoding + string += concatenate(lambda d : get_distance_code(d, False), [d for d in range(20 * 1000)]) + string += concatenate(lambda d : get_distance_code(d, False), [d / 10 for d in range(20 * 1000)]) + string += concatenate(lambda d : get_distance_code(d, False), [d / 100 for d in range(20 * 1000)]) + string += concatenate(lambda d : get_distance_code(d, True), [d / 100 for d in range( 100)]) + + # absorption encoding + string += concatenate(get_absorption_code, [a / 100 for a in range(100 + 1)]) + data = bitarray(string, endian='big') file = open('test_python.dat', 'wb') @@ -443,8 +450,8 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re 2.6267e-08 ]) + '1' # hasEarlyReflections - + concatenate(get_distance_code, # room dimensions - [ 3.0, 4.0, 2.5 ]) + + concatenate(lambda d : get_distance_code(d, False), + [ 3.0, 4.0, 2.5 ]) # room dimensions + get_count_or_index_code(0) # FreqGridID + concatenate(get_absorption_code, # absorptionCode @@ -500,9 +507,9 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re 2.6267e-08 ]) + '1' # hasEarlyReflections - + concatenate(get_distance_code, # room dimensions - [ 3.0, 4.0, 2.5 ]) - + + concatenate(lambda code : get_distance_code(code, False), + [ 3.0, 4.0, 2.5 ]) # room dimensions + + get_count_or_index_code(0) # FreqGridID + concatenate(get_absorption_code, # absorptionCode [ 0.8, 0.8, 0.8, 0.8, 0.2, 0.6 ]) @@ -510,8 +517,8 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re + '1' # listener origin flag + '1' # positive x origin + '0' # negative y origin - + concatenate(get_distance_code, # listener origin (x, y, z) - [ 0.5, 0.5, 1.5 ]) + + concatenate(lambda d : get_distance_code(d, False), + [ 0.5, 0.5, 1.5 ]) # listener origin (x, y, z) , endian='big') @@ -520,12 +527,11 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re file.close() - def generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg(): # based on config_hospital_patientroom.cfg # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values data = bitarray( - 1 # hasAcEnv + '1' # hasAcEnv + get_count_or_index_code(1) # fgdNrGrids + fgdMethod.Individual_Frequencies.value # fgdMethod + get_count_or_index_code(31) # fgdNrBands @@ -567,7 +573,7 @@ def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): # based on config_recreation.cfg # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values data = bitarray( - 1 # hasAcEnv + '1' # hasAcEnv + get_count_or_index_code(1) # fgdNrGrids + fgdMethod.Individual_Frequencies.value # fgdMethod + get_count_or_index_code(31) # fgdNrBands @@ -609,3 +615,6 @@ def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): generate_reverb_payload_equivalent_to_rend_config_renderer_cfg() generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg() generate_reverb_payload_equivalent_to_rend_config_recreation_cfg() + +#generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_no_listener_origin() +#generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_listener_origin() -- GitLab From 63535b6d53de5a4ac5bfd5335121536e0029a1c4 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Wed, 3 May 2023 16:52:03 +0200 Subject: [PATCH 013/101] fixed a small error; generated new format binary reverb files --- lib_util/render_config_reader.c | 1 + scripts/testv/rend_config_hospital_patientroom.dat | 2 +- scripts/testv/rend_config_recreation.dat | 4 ++-- scripts/testv/rend_config_renderer.dat | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index e7002f9e61..d8edca110b 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1445,6 +1445,7 @@ static ivas_error RenderConfigReader_readReverb( { pRenderConfigReader->pAE[n].pRT60 = 0; pRenderConfigReader->pAE[n].pDSR = 0; + pRenderConfigReader->pAE[n].pEarlyReflections = 0; } for ( n = 0; n < pRenderConfigReader->nAE; n++ ) diff --git a/scripts/testv/rend_config_hospital_patientroom.dat b/scripts/testv/rend_config_hospital_patientroom.dat index 20455a95b7..dd09f2ddb4 100644 --- a/scripts/testv/rend_config_hospital_patientroom.dat +++ b/scripts/testv/rend_config_hospital_patientroom.dat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3b4cf6b770f85bc82129901324078afc0953661b3ff753796d7d4bd15d8c468 +oid sha256:84321b26550df78456eea5595f8e7d99cca2b558117cddf117b738f1d8c2e316 size 136 diff --git a/scripts/testv/rend_config_recreation.dat b/scripts/testv/rend_config_recreation.dat index 456eedbbf7..d17f39b2f1 100644 --- a/scripts/testv/rend_config_recreation.dat +++ b/scripts/testv/rend_config_recreation.dat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cb9adc877960d2a7e827126c2f44612569e5554e974b5bb98d3be92cb1ee14a -size 149 +oid sha256:6329e3e202458bfae10c8811f4018e8df2c7f2dc8789850ef2d17b72e490f23d +size 150 diff --git a/scripts/testv/rend_config_renderer.dat b/scripts/testv/rend_config_renderer.dat index 6ea8ed4f1d..979bbf9a87 100644 --- a/scripts/testv/rend_config_renderer.dat +++ b/scripts/testv/rend_config_renderer.dat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7941266900de8753e847cfef95298b5ee529e3f8f90ca5421ba46d71bc353821 -size 130 +oid sha256:24a7142edde4f689273970edc73f0ed5c9ac0bbdcc75736ce3c1604e925a6fbf +size 131 -- GitLab From 1b7ecd9898acbd07616afabc70366c2f1c0a33c7 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Thu, 4 May 2023 16:46:01 +0200 Subject: [PATCH 014/101] added missing #ifdef CONTROL_METADATA_EARLY_REFLECTIONS; removed nested #ifdef DEBUGGING --- lib_util/render_config_reader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index d8edca110b..581a240a52 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1445,7 +1445,9 @@ static ivas_error RenderConfigReader_readReverb( { pRenderConfigReader->pAE[n].pRT60 = 0; pRenderConfigReader->pAE[n].pDSR = 0; +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS pRenderConfigReader->pAE[n].pEarlyReflections = 0; +#endif } for ( n = 0; n < pRenderConfigReader->nAE; n++ ) @@ -1830,13 +1832,11 @@ ivas_error RenderConfigReader_read( errorHandler( item, ERROR_VALUE_INVALID ); } } -#ifdef DEBUGGING else { fprintf( stderr, "Unsupported configuration property %s\n", item ); } #endif -#endif #ifdef CONTROL_METADATA_REVERB params_idx += params_length; #endif -- GitLab From 81183cb776db7ae68164a3e0b1227874844dffd4 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Wed, 31 May 2023 16:12:49 +0200 Subject: [PATCH 015/101] Corrected bugs reported as part of crosscheck feedback --- lib_util/render_config_reader.c | 57 ++++++++++--------- ...generate_acoustic_environments_metadata.py | 20 +++---- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 581a240a52..68296169de 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -412,7 +412,7 @@ const float defaultFrequencyGrid_8[] = { *-----------------------------------------------------------------------------------------*/ static ivas_error read_bits( RenderConfigReader *this, /* i/o : Renderer config reader handle */ - uint32_t *pTarget, /* i/o : Target read data pointer */ + uint32_t *pTarget, /* o : Target read data pointer */ const size_t nBits /* i : Number of bits to read */ ) { @@ -430,6 +430,7 @@ static ivas_error read_bits( return IVAS_ERR_INVALID_RENDER_CONFIG; } + *pTarget = 0; for ( n = 0; n < nBits; n++ ) { nByte = ( this->readOffset + n ) >> 3; @@ -451,7 +452,6 @@ static ivas_error read_bool( uint32_t *pResult /* o : Target read data pointer */ ) { - *pResult = false; return read_bits( this, pResult, 1 ); } @@ -513,10 +513,14 @@ static ivas_error read_code_word( 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 ) @@ -624,11 +628,12 @@ static ivas_error read_code_word( } for ( len = minLen; len <= maxLen; len++ ) { - if ( ( error = read_bits( this, &code, ( len == minLen ) ? minLen : 1 ) ) != IVAS_ERR_OK ) + nr_bits = ( len == minLen ) ? minLen : 1; + if ( ( error = read_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] ) @@ -835,7 +840,7 @@ static ivas_error get_distance( if ( isSmall == false ) { /* addHectometers flag */ - if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) { return error; } @@ -850,7 +855,7 @@ static ivas_error get_distance( *pResult += value * 100.0f; /* addKilometers flag */ - if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) { return error; } @@ -865,28 +870,27 @@ static ivas_error get_distance( *pResult += value * 1000.0f; /* addKilometers flag */ - if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) { return error; } } } + } - /* addCentimeters flag */ - if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + /* addCentimeters flag */ + if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( flag == true ) + { + /* Centimeters */ + if ( ( error = read_code_word( this, RC_LUT_CENTIMETERS, &value ) ) != IVAS_ERR_OK ) { return error; } - if ( flag == true ) - { - /* Centimeters */ - /* Kilometers */ - if ( ( error = read_code_word( this, RC_LUT_CENTIMETERS, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult += value * 0.01f; - } + *pResult += value * 0.01f; } return IVAS_ERR_OK; @@ -1240,7 +1244,7 @@ static ivas_error RenderConfigReader_readReverb( /****************************/ /* Read the presence flag */ /****************************/ - if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -1506,7 +1510,7 @@ static ivas_error RenderConfigReader_readReverb( #ifdef CONTROL_METADATA_EARLY_REFLECTIONS /* Has early reflections */ - if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -1556,7 +1560,7 @@ static ivas_error RenderConfigReader_readReverb( } /* Has listener origin */ - if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -1592,6 +1596,10 @@ static ivas_error RenderConfigReader_readReverb( { pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y *= -1.0f; } + if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z ) ) != IVAS_ERR_OK ) + { + return error; + } } } #endif @@ -1942,10 +1950,7 @@ void RenderConfigReader_close( #ifdef CONTROL_METADATA_EARLY_REFLECTIONS if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections != NULL ) { - if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin != NULL ) - { - free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin ); - } + free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin ); free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pAbsCoeff ); free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections ); } diff --git a/scripts/reverb/generate_acoustic_environments_metadata.py b/scripts/reverb/generate_acoustic_environments_metadata.py index 77c9841b40..9fc9c6a3ca 100644 --- a/scripts/reverb/generate_acoustic_environments_metadata.py +++ b/scripts/reverb/generate_acoustic_environments_metadata.py @@ -294,7 +294,7 @@ def get_distance_code(distance, isSmallScene = True): code = metersCode[m] if isSmallScene: - assert(m == hm == km == 0) + assert(hm == km == 0) else: # large scenes if hm > 0 or km > 0: @@ -359,7 +359,7 @@ def test(): string += concatenate(lambda d : get_distance_code(d, False), [d for d in range(20 * 1000)]) string += concatenate(lambda d : get_distance_code(d, False), [d / 10 for d in range(20 * 1000)]) string += concatenate(lambda d : get_distance_code(d, False), [d / 100 for d in range(20 * 1000)]) - string += concatenate(lambda d : get_distance_code(d, True), [d / 100 for d in range( 100)]) + string += concatenate(lambda d : get_distance_code(d, True), [d / 100 for d in range(10 * 1000)]) # absorption encoding string += concatenate(get_absorption_code, [a / 100 for a in range(100 + 1)]) @@ -450,7 +450,7 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re 2.6267e-08 ]) + '1' # hasEarlyReflections - + concatenate(lambda d : get_distance_code(d, False), + + concatenate(lambda d : get_distance_code(d, True), [ 3.0, 4.0, 2.5 ]) # room dimensions + get_count_or_index_code(0) # FreqGridID @@ -461,7 +461,7 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re , endian='big') - file = open('rend_config_renderer.dat', 'wb') + file = open('rend_config_renderer_cfg_plus_early_reflections_no_listener_origin.dat', 'wb') data.tofile(file) file.close() @@ -507,7 +507,7 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re 2.6267e-08 ]) + '1' # hasEarlyReflections - + concatenate(lambda code : get_distance_code(code, False), + + concatenate(lambda code : get_distance_code(code, True), [ 3.0, 4.0, 2.5 ]) # room dimensions + get_count_or_index_code(0) # FreqGridID @@ -515,14 +515,14 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re [ 0.8, 0.8, 0.8, 0.8, 0.2, 0.6 ]) + '1' # listener origin flag - + '1' # positive x origin - + '0' # negative y origin - + concatenate(lambda d : get_distance_code(d, False), + + '1' # is possitive x + + '0' # is possitive y + + concatenate(lambda d : get_distance_code(d, True), [ 0.5, 0.5, 1.5 ]) # listener origin (x, y, z) , endian='big') - file = open('rend_config_renderer.dat', 'wb') + file = open('rend_config_renderer_cfg_plus_early_reflections_listener_origin.dat', 'wb') data.tofile(file) file.close() @@ -616,5 +616,5 @@ generate_reverb_payload_equivalent_to_rend_config_renderer_cfg() generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg() generate_reverb_payload_equivalent_to_rend_config_recreation_cfg() -#generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_no_listener_origin() #generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_listener_origin() +#generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_no_listener_origin() -- GitLab From b156afd1db211b069254be7b9f0fe0dd158f82cb Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 6 Jun 2023 23:25:15 +0200 Subject: [PATCH 016/101] clang formatting updates --- lib_rend/lib_rend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 2075acacbd..29f1da4482 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4571,8 +4571,8 @@ static ivas_error renderIsmToBinauralRoom( if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM, - NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM, + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) #endif { return error; -- GitLab From a240a14a392ed23a2d677ec7449fb5af87fd466d Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Fri, 9 Jun 2023 15:16:58 +0200 Subject: [PATCH 017/101] Merge conflict resolution --- apps/renderer.c | 6 ------ lib_rend/lib_rend.c | 7 ------- scripts/config/self_test.prm | 17 ++++++++--------- scripts/testv/config_directivity.cfg | 1 + tests/renderer/test_renderer.py | 1 + 5 files changed, 10 insertions(+), 22 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index b6823742e9..3b94cd45b2 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1907,12 +1907,6 @@ static IVAS_REND_AudioConfig parseAudioConfig( { return IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM; } -#ifdef COMMAND_LINE_OPTION_LATE_REVERB - if ( strcmp( charBuf, "BINAURAL_REVERB" ) == 0 ) - { - return IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB; - } -#endif if ( strcmp( charBuf, "BINAURAL" ) == 0 ) { return IVAS_REND_AUDIO_CONFIG_BINAURAL; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 004b1ec4aa..f59b49fec1 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1235,11 +1235,7 @@ static ivas_error setRendInputActiveIsm( return error; } } -#ifdef COMMAND_LINE_OPTION_LATE_REVERB - else if ( ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) || ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB ) ) -#else else if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) -#endif { if ( hRendCfg != NULL && hRendCfg->roomAcoustics.use_brir == 0 && hRendCfg->roomAcoustics.late_reverb_on ) { @@ -5342,9 +5338,6 @@ static ivas_error renderInputIsm( break; #else case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: -#ifdef COMMAND_LINE_OPTION_LATE_REVERB - case IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB: -#endif error = renderIsmToBinauralRoom( ismInput, outAudio ); break; #endif diff --git a/scripts/config/self_test.prm b/scripts/config/self_test.prm index b5701b55ce..c42fba7501 100644 --- a/scripts/config/self_test.prm +++ b/scripts/config/self_test.prm @@ -924,36 +924,35 @@ ../IVAS_cod -mc 5_1 256000 48 testv/stv51MC48c.wav bit ../IVAS_dec testv/ls_setup_16ch_8+4+4.txt 48 bit testv/stv51MC48c.wav_MC51_256000_48-48_MC_custom_setup.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer +// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_renderer.tst ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 32kHz out, BINAURAL_REVERB out Config renderer +// Multi-channel 5_1 at 512 kbps, 48kHz in, 32kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/stv51MC48c.wav_MC51_512000_48-32_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_REVERB out Config renderer +// Multi-channel 5_1 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 16 bit testv/stv51MC48c.wav_MC51_512000_48-16_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config hospital_patientroom +// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config hospital_patientroom ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_hospital_patientroom.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config recreation +// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config recreation ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_recreation.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_recreation.tst -// Multi-channel 5_1_2 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer +// Multi-channel 5_1_2 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 5_1_2 512000 48 testv/stv512MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv512MC48c.wav_MC512_512000_48-48_MC_Config_renderer.tst -// Multi-channel 5_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer +// Multi-channel 5_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 5_1_4 512000 48 testv/stv514MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv514MC48c.wav_MC514_512000_48-48_MC_Config_renderer.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_REVERB out Config renderer +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_Config_renderer.tst diff --git a/scripts/testv/config_directivity.cfg b/scripts/testv/config_directivity.cfg index f958df1d31..94807d688c 100644 --- a/scripts/testv/config_directivity.cfg +++ b/scripts/testv/config_directivity.cfg @@ -1,2 +1,3 @@ [general] directivity = [0.0, 360.0, 0.2512]; + diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index df90da7f86..806e871a2e 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -55,6 +55,7 @@ def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), ) + # Test compares rendering with just a trajectory file against rendering with a trajectory file + a zero ref rotation. # These should be binary equivalent. @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) -- GitLab From afc493736d8db10db466d489cc6a94a6ec40e660 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Fri, 9 Jun 2023 15:19:07 +0200 Subject: [PATCH 018/101] Merge conflict resolution --- apps/decoder.c | 2 +- lib_com/options.h | 1 - lib_rend/ivas_crend.c | 3 --- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 0f51903ab2..a3efbbf68a 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -85,7 +85,7 @@ static #define IVAS_PUBLIC_ORIENT_TRK_REF_VEC_LEV ( 4 ) #ifdef CONTROL_METADATA_REVERB -#define ACOUSTIC_ENVIRONMENT_ID 0 +#define ACOUSTIC_ENVIRONMENT_ID ( 0 ) #endif #ifdef VARIABLE_SPEED_DECODING diff --git a/lib_com/options.h b/lib_com/options.h index 5e39771af3..f17a34806b 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -145,7 +145,6 @@ #ifdef CONTROL_METADATA_REVERB #define CONTROL_METADATA_EARLY_REFLECTIONS /* Philips/Qualcomm: early reflections extension to reverb configuration */ #endif -#define COMMAND_LINE_OPTION_LATE_REVERB /* Philips: late reverb command line option */ #define USE_HRIR_128_METH5_IRC_53_Q10_SYML_ITRP1_48000 /* Dolby (Orange, FhG) : Contribution 36 - SBA HRIR update */ #define UPDATE_SBA_FILTER /* Dolby (Orange, FhG) : Contribution 36 - SBA HRIR update */ diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 4f28106542..367bdee3ec 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -206,9 +206,6 @@ static ivas_error ivas_rend_initCrend( #ifndef FIX_196_REFACTOR_RENDERER_OUTPUT_CONFIG /* set BRIR flag */ use_brir = false; -#ifdef COMMAND_LINE_OPTION_LATE_REVERB - /* note: use_brir = false for IVAS_REND_AUDIO_CONFIG_BINAURAL_REVERB */ -#endif if ( ( ( hRendCfg != NULL ) && hRendCfg->roomAcoustics.use_brir ) || ( ( hRendCfg == NULL ) && ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) ) ) { use_brir = true; -- GitLab From b8b402c32c1db4e1138ea5e573de52ca5aac0974 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Mon, 12 Jun 2023 11:26:24 +0200 Subject: [PATCH 019/101] Removed superfluous file --- scripts/reverb/generate_scene_metadata.py | 399 ---------------------- 1 file changed, 399 deletions(-) delete mode 100644 scripts/reverb/generate_scene_metadata.py diff --git a/scripts/reverb/generate_scene_metadata.py b/scripts/reverb/generate_scene_metadata.py deleted file mode 100644 index 5e1df7334b..0000000000 --- a/scripts/reverb/generate_scene_metadata.py +++ /dev/null @@ -1,399 +0,0 @@ -#!/usr/bin/env python3 - -""" - (C) 2022-2023 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. -""" - -# -# Generate binary render configuration output files for testing purposes -# The binary code generation is based on the MPEG-I audio standard -# which defines functions to decode raw bitstream into internal parameters -# - - -from bitarray import bitarray, test as bitarray_test -import math -from enum import Enum -import numpy as np - - -# Set to True to print values suitable for inclusion into .cfg configuration files -print_cfg = False - -def get_id_code(id): - code = format(id % 128, '07b') + '0' - id //= 128 - while id > 0: - code = format(id % 128, '07b') + '1' + code - id = id // 128 - return code - - -def get_count_or_index_code(n): - # 0, 1, ... 63 - countOrIndexLoCodes = [ - '0111', '100', '01100', '01101', '01010', '01011', '01000', '01001', '001111', '001110', - '001101', '001100', '001011', '001010', '001001', '001000', '000111', '000110', '000101', '000100', - '000011', '000010', '000001', '000000', '111111', '111110', '111101', '111100', '111011', '111010', - '111001', '111000', '1101111', '1101110', '1101101', '1101100', '1101011', '1101010', '1101001', '1101000', - '1100111', '1100110', '1100101', '1100100', '1100011', '1100010', '1100001', '1100000', '1011111', '1011110', - '1011101', '1011100', '1011011', '1011010', '1011001', '1011000', '1010111', '1010110', '1010101', '1010100', - '1010011', '1010010', '1010001', '1010000'] - - # 1, 2, ... 15 - countOrIndexHiCode = [ - '001', '000', '110', '101', '100', '0111', '0101', '1111', '1110', '01101', - '01001', '01000', '011001', '0110001', '0110000'] - - assert 0 <= n < 16 * 64 - code = countOrIndexLoCodes[n % 64] - if n < 64: - code += '0' - else: - code += '1' + countOrIndexHiCode[n // 64 - 1] - return code - - -def get_duration_code(duration): - # 1, 2, ... 30 - secondsCode = [ - '0011', '0001', '0000', '1111', '1101', '1100', '1011', '1001', '1000', '01110', - '01101', '01100', '01011', '01001', '01000', '00101', '11101', '11100', '10101', '011111', - '011110', '010101', '001001', '001000', '101001', '0101001', '0101000', '1010001', '10100001', '10100000' ] - - # 0, 0.1, ... 1.0 - deciSecondsCode = [ - '110', '100', '101', '0110', '0111', '111', '0100', '0101', '0010', '0011', '000' ] - - # 0, 1, ..., 99 - millisecondsCode = [ - '1111010', '1111011', '1111000', '1111001', '1111110', '1111111', '1111100', '1111101', '1110010', '1110011', - '11001', '1110000', '1110001', '1110110', '1110111', '1110100', '1110101', '0101010', '0101011', '0101000', - '10010', '0101001', '0101110', '0101111', '0101100', '0101101', '0100010', '0100011', '0100000', '0100001', - '10011', '0100110', '0100111', '0100100', '0100101', '0111010', '0111011', '0111000', '0111001', '0111110', - '10000', '0111111', '0111100', '0111101', '0110010', '0110011', '0110000', '0110001', '0110110', '0110111', - '10001', '0110100', '0110101', '0001010', '0001011', '0001000', '0001001', '0001110', '0001111', '0001100', - '10110', '0001101', '0000010', '0000011', '0000000', '0000001', '0000110', '0000111', '0000100', '0000101', - '10111', '0011010', '0011011', '0011000', '0011001', '0011110', '0011111', '0011100', '0011101', '0010010', - '10100', '0010011', '0010000', '0010001', '0010110', '0010111', '0010100', '0010101', '1101010', '1101011', - '10101', '1101000', '1101001', '1101110', '1101111', '1101100', '1101101', '1100010', '1100011', '110000' ] - - # 10, 20, ... 990 - microsecondsCode = [ - '110111100', '10010', '110111101', '10011', '1101111110', '10000', '1101111111', '10001', '1101111100', '10110', - '1101111101', '10111', '110110010', '10100', '110110011', '10101', '110110000', '001010', '110110001', '001011', - '110110110', '001000', '110110111', '001001', '110110100', '001110', '110110101', '001111', '110011010', '001100', - '110011011', '001101', '110011000', '000010', '110011001', '000011', '110011110', '000000', '110011111', '000001', - '110011100', '000110', '110011101', '000111', '110010010', '000100', '110010011', '000101', '110010000', '011010', - '110010001', '011011', '110010110', '011000', '110010111', '011001', '110010100', '011110', '110010101', '011111', - '110101010', '011100', '110101011', '011101', '110101000', '010010', '110101001', '010011', '110101110', '010000', - '110101111', '010001', '110101100', '010110', '110101101', '010111', '110100010', '010100', '110100011', '010101', - '110100000', '111010', '110100001', '111011', '110100110', '111000', '110100111', '111001', '110100100', '111110', - '110100101', '111111', '110111010', '111100', '110111011', '111101', '110111000', '11000', '110111001' ] - - duration_dus = int(round(np.float32(duration) * np.float32(100000))) # [deca us] - if print_cfg: - print('duration: ', duration_dus) - - dus = duration_dus # [deca us] - s = dus // 100000 # 0, 1, ... 30 [s] - ms = (dus % 100000) // 100 # 0, 1, ... 999 [ms] - dus = (dus % 100) # 0, 1, ... 99 [deca us] - ds = ms // 100 # 0, 1, ... 9 [deci s] - ms = ms % 100 # 0, 1, ... 99 [ms] - if s >= 1 and ds == 0: - s -= 1 - ds = 10 # 0, 1, ... 10 [deci s] - - assert 0 <= s <= 30 - assert 0 <= ds <= 10 - assert 0 <= ms <= 99 - assert 0 <= dus <= 99 - assert duration_dus == s * 100000 + ds * 10000 + ms * 100 + dus - - code = deciSecondsCode[ds] - if ms > 0 or dus > 0: - code += '1' + millisecondsCode[ms] - if dus > 0: - code += '1' + microsecondsCode[dus - 1] - else: - code += '0' - else: - code += '0' - if s > 0: - # long range mode not implemented - code += '1' + secondsCode[s - 1] - else: - code += '0' - - return code - - -def get_frequency_code(f): - frequencyCode = { - 16 : '100011', 20 : '001110', 25 : '001111', 31.5 : '1001', 40 : '001100', - 50 : '001101', 63 : '0000', 80 : '011010', 100 : '011011', 125 : '0001', - 160 : '011000', 200 : '011001', 250 : '1110', 315 : '011110', 400 : '011111', - 500 : '1111', 630 : '011100', 800 : '011101', 1000 : '1100', 1250 : '010010', - 1600 : '010011', 2000 : '1101', 2500 : '010000', 3150 : '010001', 4000 : '1010', - 5000 : '010110', 6300 : '010111', 8000 : '1011', 10000: '010100', 12500: '010101', - 16000: '0010', 20000: '10000', 25000: '10001010', 31500: '10001011', 40000: '1000100', } - - assert 16 <= f <= 40000 - if f in frequencyCode.keys(): - if print_cfg: - print('frequency:', f) - return frequencyCode[f] + '0' - else: - # exact frequency not found, use frequency refinement to aproximate - # (largest relative deviation seen for range(16, 40000) was 0.006818) - # find frequencies enveloping f - f_low = 16 - f_high = 40000 - for key in frequencyCode.keys(): - if key < f: - f_low = max(f_low, key) - else: - f_high = min(f_high, key) - refinement = round(51 * math.log(f / f_low, 2)) - 1 - if refinement >= 16: - # choose next higer frequency - if print_cfg: - print('frequency:', list(frequencyCode)[f_high]) - return frequencyCode[f_high] + '0' - else: - if print_cfg: - print('frequency:', list(frequencyCode)[f_low], ', refined: ', f_low * 2 ** ((refinement + 1) / 51)) - return frequencyCode[f_low] + '1' + format(refinement, '04b') - - -def get_frequency_hop_code(index): - assert 0 <= index < 9 - return [ - '1100', # 2^(1/8) - '1101', # 2^(1/7) - '0010', # 2^(1/6) - '0011', # 2^(1/5) - '0000', # 2^(1/4) - '01', # 2^(1/3) - '0001', # 2^(1/2) - '10', # 2^1 - '111'][index] # 2^2 - - -def get_dsr_code(dsr): - # -150.0, -149.0, ... -10.0 - dsrCode = [ - '10001100', '10001101', '100011110', '100011111', '100011100', '100011101', '10000010', '10000011', '10000000', '10000001', - '10000110', '10000111', '10000100', '10000101', '011101010', '011101011', '011101000', '011101001', '011101110', '011101111', - '011101100', '011101101', '011100010', '011100011', '011100000', '011100001', '011100110', '011100111', '011100100', '011100101', - '011111010', '011111011', '011111000', '011111001', '011111110', '011111111', '011111100', '011111101', '011110010', '011110011', - '011110000', '011110001', '011110110', '011110111', '011110100', '011110101', '011001010', '011001011', '011001000', '011001001', - '011001110', '011001111', '011001100', '011001101', '011000010', '011000011', '011000000', '011000001', '011000110', '011000111', - '011000100', '011000101', '011011010', '011011011', '011011000', '011011001', '011011110', '011011111', '011011100', '011011101', - '010100', '010101', '100110', '100111', '100100', '100101', '111010', '111011', '111000', '111001', - '111110', '111111', '111100', '111101', '110010', '110011', '110000', '110001', '110110', '110111', - '110100', '110101', '001010', '001011', '001000', '001001', '001110', '001111', '001100', '001101', - '000010', '000011', '000000', '000001', '000110', '000111', '000100', '000101', '101010', '101011', - '101000', '101001', '101110', '101111', '101100', '101101', '010010', '010011', '010000', '010001', - '010110', '011010010', '011010011', '011010000', '011010001', '011010110', '011010111', '011010100', '011010101', '010111010', - '010111011', '010111000', '010111001', '010111110', '010111111', '010111100', '010111101', '10001010', '10001011', '10001000', - '10001001' ] - - d = math.log10(dsr) * 10 - d = round(d + 150) - assert 0 <= d <= 140 - if print_cfg: - print('dsr:', np.float32(np.power(np.float32(10), np.float32(d - 150) / np.float32(10)))) # C decoder uses float precision math - return dsrCode[d] - - -class fgdMethod(Enum): - Individual_Frequencies = '00' - Start_Hop_Amount = '01' - Default_Banding = '10' - - -# apply function to elements of list and concatenate the resulting strings -def concatenate(function, data): - return ''.join([function(d) for d in data]) - - -def test(): - # generate binary output which can be compared with the Matlab implementation output - string = '' - - # count or index encoding - string += concatenate(get_count_or_index_code, [n for n in range(0, 16 * 64)]) - - # duration encoding - string += concatenate(get_duration_code, [d / 1000 for d in range(0, 30 * 1000)]) - string += concatenate(get_duration_code, [d / 10000 for d in range(0, 30 * 1000)]) - string += concatenate(get_duration_code, [d / 100000 for d in range(0, 30 * 1000)]) - - # frequency encoding - string += concatenate(get_frequency_code, - [16 , 20 , 25 , 31.5 , 40 , 50 , 63 , 80 , 100 , 125 , - 160 , 200 , 250 , 315 , 400 , 500 , 630 , 800 , 1000 , 1250 , - 1600 , 2000 , 2500 , 3150 , 4000 , 5000 , 6300 , 8000, 10000, 12500, - 16000, 20000, 25000, 31500, 40000]) - - # frequency hop encoding - string += concatenate(get_frequency_hop_code, [index for index in range(0, 9)]) - - # DSR encoding - string += concatenate(get_dsr_code, [math.pow(10, dsr / 10) for dsr in range(-150, -10 + 1)]) - - data = bitarray(string, endian='big') - - file = open('test_python.dat', 'wb') - data.tofile(file) - file.close() - - -def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg(): - # based on config_renderer.cfg - # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values - data = bitarray( - get_count_or_index_code(1) # fgdNrGrids - + fgdMethod.Individual_Frequencies.value # fgdMethod - + get_count_or_index_code(31) # fgdNrBands - - + concatenate(get_frequency_code, # fgdCenterFreq - [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, - 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0, - 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, - 20000.0 ]) - - + get_count_or_index_code(1) # AcousticEnvCount - + get_id_code(0) # ID - + get_count_or_index_code(0) # FreqGridID - + get_duration_code(0.1) # (input)Predelay - - + concatenate(get_duration_code, # RT60 - [ 1.3622, 1.4486, 1.3168, 1.5787, 1.4766, 1.3954, 1.2889, 1.3462, 1.0759, 1.0401, - 1.0970, 1.0850, 1.0910, 1.0404, 1.0499, 1.0699, 1.1028, 1.1714, 1.1027, 1.0666, - 1.0550, 1.0553, 1.0521, 1.0569, 1.0421, 0.97822, 0.80487, 0.75944, 0.71945, 0.61682, - 0.60031 ]) - - + concatenate(get_dsr_code, # DSR - [ 1.8811e-08, 2.1428e-08, 1.3972e-08, 1.51e-08, 1.287e-08, 1.8747e-08, 2.413e-08, 3.9927e-08, 8.9719e-08, 1.902e-07, - 3.702e-07, 6.1341e-07, 7.1432e-07, 6.5331e-07, 4.6094e-07, 5.4683e-07, 7.0134e-07, 6.856e-07, 7.114e-07, 6.9604e-07, - 5.2939e-07, 5.699e-07, 6.1773e-07, 5.7488e-07, 4.7748e-07, 2.7213e-07, 1.3681e-07, 1.0941e-07, 6.2001e-08, 2.8483e-08, - 2.6267e-08 ]) - - , endian='big') - - file = open('rend_config_renderer.dat', 'wb') - data.tofile(file) - file.close() - - -def generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg(): - # based on config_hospital_patientroom.cfg - # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values - data = bitarray( - get_count_or_index_code(1) # fgdNrGrids - + fgdMethod.Individual_Frequencies.value # fgdMethod - + get_count_or_index_code(31) # fgdNrBands - - - + concatenate(get_frequency_code, # fgdCenterFreq - [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, - 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0, - 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, - 20000.0 ]) - - + get_count_or_index_code(1) # AcousticEnvCount - + get_id_code(0) # ID - + get_count_or_index_code(0) # FreqGridID - + get_duration_code(0.08163) # (input)Predelay - - + concatenate(get_duration_code, # RT60 - [ 0.81275, 0.61888, 0.45111, 0.34672, 0.46683, 0.53987, 0.61874, 0.70291, 0.66657, 0.73037, - 0.75090, 0.72470, 0.75486, 0.75857, 0.76844, 0.74999, 0.77622, 0.78227, 0.77441, 0.74688, - 0.73521, 0.73782, 0.71928, 0.71708, 0.71465, 0.60592, 0.52031, 0.51768, 0.52102, 0.37956, - 0.30786 ]) - - + concatenate(get_dsr_code, # DSR - [ 0.000219780698, 0.000205275364, 7.18711e-05, 4.5745977e-05, 8.381106e-06, 6.884964e-06, 6.532765e-06, 8.296928e-06, 1.0005793e-05, 9.191127e-06, - 8.635287e-06, 9.627704e-06, 1.0806965e-05, 1.0041916e-05, 7.77047e-06, 9.695803e-06, 9.594324e-06, 8.32215e-06, 7.564813e-06, 6.215871e-06, - 6.379496e-06, 6.358105e-06, 6.6696e-06, 6.369334e-06, 6.378474e-06, 3.339913e-06, 3.129318e-06, 2.892564e-06, 6.00202e-07, 3.40124e-07, - 3.37705e-07 ]) - - , endian='big') - - file = open('rend_config_hospital_patientroom.dat', 'wb') - data.tofile(file) - file.close() - - -def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): - # based on config_recreation.cfg - # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values - data = bitarray( - get_count_or_index_code(1) # fgdNrGrids - + fgdMethod.Individual_Frequencies.value # fgdMethod - + get_count_or_index_code(31) # fgdNrBands - - - + concatenate(get_frequency_code, # fgdCenterFreq - [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, - 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0, - 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, - 20000.0 ]) - - + get_count_or_index_code(1) # AcousticEnvCount - + get_id_code(0) # ID - + get_count_or_index_code(0) # FreqGridID - + get_duration_code(0.43031) # (input)Predelay - - + concatenate(get_duration_code, # RT60 - [ 4.51916, 4.89553, 4.83276, 5.00198, 5.34468, 5.76026, 6.36818, 6.95503, 7.27557, 7.62559, - 8.08892, 8.16002, 8.13900, 8.17919, 8.16280, 8.46226, 9.61806, 9.93048, 9.81353, 8.59340, - 8.38885, 8.36823, 6.51845, 3.76089, 3.75374, 3.57451, 1.28724, 1.22174, 1.22448, 1.71631, - 2.14343 ]) - - + concatenate(get_dsr_code, # DSR - [ 9.18578e-07, 7.63803e-07, 9.23183e-07, 1.048656e-06, 1.61449e-06, 2.13745e-06, 2.854805e-06, 3.979651e-06, 6.229977e-06, 7.782421e-06, - 9.091754e-06, 8.545798e-06, 7.482083e-06, 7.351071e-06, 7.947039e-06, 8.152676e-06, 5.201189e-06, 4.744103e-06, 4.397069e-06, 3.017449e-06, - 2.958383e-06, 2.725911e-06, 7.94912e-07, 6.20198e-07, 5.71181e-07, 5.5546e-08, 1.3987e-08, 1.338e-08, 1.322e-09, 1.3e-11, - 4e-12 ]) - - , endian='big') - - file = open('rend_config_recreation.dat', 'wb') - data.tofile(file) - file.close() - - -#test() -generate_reverb_payload_equivalent_to_rend_config_renderer_cfg() -generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg() -generate_reverb_payload_equivalent_to_rend_config_recreation_cfg() -- GitLab From af411f1128d9128ccc903b9e5fc865966af87e5a Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Tue, 13 Jun 2023 12:33:01 +0200 Subject: [PATCH 020/101] make .cfg files support current style roomAcoustics settings as well as the new style reverbFile setting --- ...generate_acoustic_environments_metadata.py | 26 ++++++++--------- .../rend_config_hospital_patientroom.cfg | 26 +++++++++++++++++ scripts/testv/rend_config_recreation.cfg | 26 +++++++++++++++++ scripts/testv/rend_config_renderer.cfg | 29 +++++++++++++++++++ 4 files changed, 93 insertions(+), 14 deletions(-) diff --git a/scripts/reverb/generate_acoustic_environments_metadata.py b/scripts/reverb/generate_acoustic_environments_metadata.py index 9fc9c6a3ca..5ac095e5a1 100644 --- a/scripts/reverb/generate_acoustic_environments_metadata.py +++ b/scripts/reverb/generate_acoustic_environments_metadata.py @@ -398,10 +398,10 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg(): 0.60031 ]) + concatenate(get_dsr_code, # DSR - [ 1.8811e-08, 2.1428e-08, 1.3972e-08, 1.51e-08, 1.287e-08, 1.8747e-08, 2.413e-08, 3.9927e-08, 8.9719e-08, 1.902e-07, - 3.702e-07, 6.1341e-07, 7.1432e-07, 6.5331e-07, 4.6094e-07, 5.4683e-07, 7.0134e-07, 6.856e-07, 7.114e-07, 6.9604e-07, - 5.2939e-07, 5.699e-07, 6.1773e-07, 5.7488e-07, 4.7748e-07, 2.7213e-07, 1.3681e-07, 1.0941e-07, 6.2001e-08, 2.8483e-08, - 2.6267e-08 ]) + [ 1.9952632e-08, 1.9952632e-08, 1.2589251e-08, 1.5848926e-08, 1.2589251e-08, 1.9952632e-08, 2.511887e-08, 3.9810708e-08, 1e-07, 1.9952633e-07, + 3.981071e-07, 6.3095763e-07, 7.943284e-07, 6.3095763e-07, 5.01187e-07, 5.01187e-07, 6.3095763e-07, 6.3095763e-07, 7.943284e-07, 6.3095763e-07, + 5.01187e-07, 6.3095763e-07, 6.3095763e-07, 6.3095763e-07, 5.01187e-07, 2.511887e-07, 1.2589251e-07, 1e-07, 6.309576e-08, 3.1622776e-08, + 2.511887e-08 ]) + '0' # hasEarlyReflections , endian='big') @@ -555,11 +555,10 @@ def generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg() 0.30786 ]) + concatenate(get_dsr_code, # DSR - [ 0.000219780698, 0.000205275364, 7.18711e-05, 4.5745977e-05, 8.381106e-06, 6.884964e-06, 6.532765e-06, 8.296928e-06, 1.0005793e-05, 9.191127e-06, - 8.635287e-06, 9.627704e-06, 1.0806965e-05, 1.0041916e-05, 7.77047e-06, 9.695803e-06, 9.594324e-06, 8.32215e-06, 7.564813e-06, 6.215871e-06, - 6.379496e-06, 6.358105e-06, 6.6696e-06, 6.369334e-06, 6.378474e-06, 3.339913e-06, 3.129318e-06, 2.892564e-06, 6.00202e-07, 3.40124e-07, - 3.37705e-07 ]) - + [ 0.00019952621, 0.00019952621, 7.9432844e-05, 5.0118702e-05, 7.943284e-06, 6.3095763e-06, 6.3095763e-06, 7.943284e-06, 1e-05, 1e-05, + 7.943284e-06, 1e-05, 1e-05, 1e-05, 7.943284e-06, 1e-05, 1e-05, 7.943284e-06, 7.943284e-06, 6.3095763e-06, + 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 3.1622776e-06, 3.1622776e-06, 3.1622776e-06, 6.3095763e-07, 3.1622776e-07, + 3.1622776e-07 ]) + '0' # hasEarlyReflections , endian='big') @@ -597,11 +596,10 @@ def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): 2.14343 ]) + concatenate(get_dsr_code, # DSR - [ 9.18578e-07, 7.63803e-07, 9.23183e-07, 1.048656e-06, 1.61449e-06, 2.13745e-06, 2.854805e-06, 3.979651e-06, 6.229977e-06, 7.782421e-06, - 9.091754e-06, 8.545798e-06, 7.482083e-06, 7.351071e-06, 7.947039e-06, 8.152676e-06, 5.201189e-06, 4.744103e-06, 4.397069e-06, 3.017449e-06, - 2.958383e-06, 2.725911e-06, 7.94912e-07, 6.20198e-07, 5.71181e-07, 5.5546e-08, 1.3987e-08, 1.338e-08, 1.322e-09, 1.3e-11, - 4e-12 ]) - + [ 1e-06, 7.943284e-07, 1e-06, 1e-06, 1.5848925e-06, 1.9952631e-06, 3.1622776e-06, 3.9810707e-06, 6.3095763e-06, 7.943284e-06, + 1e-05, 7.943284e-06, 7.943284e-06, 7.943284e-06, 7.943284e-06, 7.943284e-06, 5.01187e-06, 5.01187e-06, 3.9810707e-06, 3.1622776e-06, + 3.1622776e-06, 2.511887e-06, 7.943284e-07, 6.3095763e-07, 6.3095763e-07, 5.01187e-08, 1.2589251e-08, 1.2589251e-08, 1.2589265e-09, 1.2589266e-11, + 3.981075e-12 ]) + '0' # hasEarlyReflections , endian='big') diff --git a/scripts/testv/rend_config_hospital_patientroom.cfg b/scripts/testv/rend_config_hospital_patientroom.cfg index 75bfdf910f..07b8614d5d 100644 --- a/scripts/testv/rend_config_hospital_patientroom.cfg +++ b/scripts/testv/rend_config_hospital_patientroom.cfg @@ -1,2 +1,28 @@ +[roomAcoustics] +nBands = 31; + +fc = [20.0, 25.0, 31.5, 40.0, + 50.0, 63.0, 80.0, 100.0, + 125.0, 160.0, 200.0, 250.0, + 315.0, 400.0, 500.0, 630.0, + 800.0, 1000.0, 1250.0, 1600.0, + 2000.0, 2500.0, 3150.0, 4000.0, + 5000.0, 6300.0, 8000.0, 10000.0, + 12500.0, 16000.0, 20000.0]; + +rt60 = [0.81275, 0.61888, 0.45111, 0.34672, 0.46683, 0.53987, 0.61874, 0.70291, 0.66657, 0.73037, + 0.75090, 0.72470, 0.75486, 0.75857, 0.76844, 0.74999, 0.77622, 0.78227, 0.77441, 0.74688, + 0.73521, 0.73782, 0.71928, 0.71708, 0.71465, 0.60592, 0.52031, 0.51768, 0.52102, 0.37956, + 0.30786]; + +dsr = [0.00019952621, 0.00019952621, 7.9432844e-05, 5.0118702e-05, 7.943284e-06, 6.3095763e-06, 6.3095763e-06, 7.943284e-06, 1e-05, 1e-05, + 7.943284e-06, 1e-05, 1e-05, 1e-05, 7.943284e-06, 1e-05, 1e-05, 7.943284e-06, 7.943284e-06, 6.3095763e-06, + 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 3.1622776e-06, 3.1622776e-06, 3.1622776e-06, 6.3095763e-07, 3.1622776e-07, + 3.1622776e-07]; + + +acousticPreDelay = 0.016; +inputPreDelay = 0.08163; + [general] reverbFile = rend_config_hospital_patientroom.dat; diff --git a/scripts/testv/rend_config_recreation.cfg b/scripts/testv/rend_config_recreation.cfg index d91064856c..43c060eab6 100644 --- a/scripts/testv/rend_config_recreation.cfg +++ b/scripts/testv/rend_config_recreation.cfg @@ -1,2 +1,28 @@ +[roomAcoustics] +nBands = 31; + +fc = [20.0, 25.0, 31.5, 40.0, + 50.0, 63.0, 80.0, 100.0, + 125.0, 160.0, 200.0, 250.0, + 315.0, 400.0, 500.0, 630.0, + 800.0, 1000.0, 1250.0, 1600.0, + 2000.0, 2500.0, 3150.0, 4000.0, + 5000.0, 6300.0, 8000.0, 10000.0, + 12500.0, 16000.0, 20000.0]; + +rt60 = [4.51916, 4.89553, 4.83276, 5.00198, 5.34468, 5.76026, 6.36818, 6.95503, 7.27557, 7.62559, + 8.08892, 8.16002, 8.13900, 8.17919, 8.16280, 8.46226, 9.61806, 9.93048, 9.81353, 8.59340, + 8.38885, 8.36823, 6.51845, 3.76089, 3.75374, 3.57451, 1.28724, 1.22174, 1.22448, 1.71631, + 2.14343]; + +dsr = [1e-06, 7.943284e-07, 1e-06, 1e-06, 1.5848925e-06, 1.9952631e-06, 3.1622776e-06, 3.9810707e-06, 6.3095763e-06, 7.943284e-06, + 1e-05, 7.943284e-06, 7.943284e-06, 7.943284e-06, 7.943284e-06, 7.943284e-06, 5.01187e-06, 5.01187e-06, 3.9810707e-06, 3.1622776e-06, + 3.1622776e-06, 2.511887e-06, 7.943284e-07, 6.3095763e-07, 6.3095763e-07, 5.01187e-08, 1.2589251e-08, 1.2589251e-08, 1.2589265e-09, 1.2589266e-11, + 3.981075e-12]; + + +acousticPreDelay = 0.016; +inputPreDelay = 0.43031; + [general] reverbFile = rend_config_recreation.dat; diff --git a/scripts/testv/rend_config_renderer.cfg b/scripts/testv/rend_config_renderer.cfg index c0c3715f58..3cd52373da 100644 --- a/scripts/testv/rend_config_renderer.cfg +++ b/scripts/testv/rend_config_renderer.cfg @@ -1,2 +1,31 @@ +[roomAcoustics] +nBands = 31; + +fc = [20.0, 25.0, 31.5, 40.0, + 50.0, 63.0, 80.0, 100.0, + 125.0, 160.0, 200.0, 250.0, + 315.0, 400.0, 500.0, 630.0, + 800.0, 1000.0, 1250.0, 1600.0, + 2000.0, 2500.0, 3150.0, 4000.0, + 5000.0, 6300.0, 8000.0, 10000.0, + 12500.0, 16000.0, 20000.0]; + +rt60 = [1.3622, 1.4486, 1.3168, 1.5787, + 1.4766, 1.3954, 1.2889, 1.3462, + 1.0759, 1.0401, 1.0970, 1.0850, + 1.0910, 1.0404, 1.0499, 1.0699, + 1.1028, 1.1714, 1.1027, 1.0666, + 1.0550, 1.0553, 1.0521, 1.0569, + 1.0421, 0.97822, 0.80487, 0.75944, + 0.71945, 0.61682, 0.60031]; + +dsr = [1.9952632e-08, 1.9952632e-08, 1.2589251e-08, 1.5848926e-08, 1.2589251e-08, 1.9952632e-08, 2.511887e-08, 3.9810708e-08, 1e-07, 1.9952633e-07, + 3.981071e-07, 6.3095763e-07, 7.943284e-07, 6.3095763e-07, 5.01187e-07, 5.01187e-07, 6.3095763e-07, 6.3095763e-07, 7.943284e-07, 6.3095763e-07, + 5.01187e-07, 6.3095763e-07, 6.3095763e-07, 6.3095763e-07, 5.01187e-07, 2.511887e-07, 1.2589251e-07, 1e-07, 6.309576e-08, 3.1622776e-08, + 2.511887e-08]; + +acousticPreDelay = 0.016; +inputPreDelay = 0.1; + [general] reverbFile = rend_config_renderer.dat; -- GitLab From fc61fe548d23cfdcd264e56d7d119636141279a1 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Wed, 5 Jul 2023 12:41:33 +0200 Subject: [PATCH 021/101] add script text_to_binary_payload.py to read a text-based configuration file and generate the equivalent binary payload --- ...generate_acoustic_environments_metadata.py | 13 +- scripts/reverb/text_to_binary_payload.py | 151 ++++++++++++++++++ 2 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 scripts/reverb/text_to_binary_payload.py diff --git a/scripts/reverb/generate_acoustic_environments_metadata.py b/scripts/reverb/generate_acoustic_environments_metadata.py index 5ac095e5a1..fc6698ef73 100644 --- a/scripts/reverb/generate_acoustic_environments_metadata.py +++ b/scripts/reverb/generate_acoustic_environments_metadata.py @@ -31,13 +31,13 @@ """ # -# Generate binary render configuration output files for testing purposes -# The binary code generation is based on the MPEG-I audio standard -# which defines functions to decode raw bitstream into internal parameters +# Generate binary render configuration output files for testing purposes. +# The binary code generation is based on the MPEG-I audio standard, +# which defines functions to decode raw bitstream into internal parameters. # -from bitarray import bitarray, test as bitarray_test +from bitarray import bitarray import math from enum import Enum import numpy as np @@ -238,6 +238,11 @@ class fgdMethod(Enum): Default_Banding = '10' +def get_default_grid_nr_bands(code): + assert 0 <= code <= 8 + return [10, 10, 31, 5, 6, 3, 41, 21, 25][code] + + def get_distance_code(distance, isSmallScene = True): # 0, 1, ... 99 metersCode = [ diff --git a/scripts/reverb/text_to_binary_payload.py b/scripts/reverb/text_to_binary_payload.py new file mode 100644 index 0000000000..2ad58c0f26 --- /dev/null +++ b/scripts/reverb/text_to_binary_payload.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 + +""" + (C) 2022-2023 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. +""" + +# +# Read a text-based configuration file and generate the equivalent binary payload. +# Makes use of the pyhton configuration file parser configparser, +# and of the payload configuration functions in generate_acoustic_environments_metadata. +# The configuration file format is as follows: +# +# [
:] +#