diff --git a/apps/decoder.c b/apps/decoder.c index 0d795633f17acc67769f50458857da7bc60275df..be1d6bdd9a2fc4ac4f034757de51952f3526647a 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -90,6 +90,17 @@ static * Local structure for storing cmdln arguments *------------------------------------------------------------------------------------------*/ +#ifdef FIX_1053_REVERB_RECONFIGURATION +typedef struct +{ + uint16_t *pID; + uint16_t *pValidity; + uint16_t count; + uint16_t selected; + uint16_t frameCounter; +} AcousticEnvironmentSequence; +#endif + typedef struct { char *inputBitstreamFilename; @@ -141,7 +152,11 @@ typedef struct uint16_t tsmScale; #endif #endif +#ifdef FIX_1053_REVERB_RECONFIGURATION + AcousticEnvironmentSequence aeSequence; +#else uint16_t acousticEnvironmentId; +#endif int16_t Opt_dpid_on; uint16_t directivityPatternId[IVAS_MAX_NUM_OBJECTS]; @@ -432,9 +447,14 @@ int main( *------------------------------------------------------------------------------------------*/ asked_frame_size = arg.renderFramesize; +#ifdef FIX_1053_REVERB_RECONFIGURATION + uint16_t aeID = arg.aeSequence.count > 0 ? arg.aeSequence.pID[0] : 65535; + if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.tsmEnabled, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, + arg.Opt_dpid_on, aeID, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.tsmEnabled, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.Opt_dpid_on, arg.acousticEnvironmentId, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) - +#endif { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -658,7 +678,11 @@ int main( if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, aeID, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) +#else if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, arg.acousticEnvironmentId, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) +#endif { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { @@ -668,7 +692,11 @@ int main( } else { +#ifdef FIX_1053_REVERB_RECONFIGURATION + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", aeID ); +#else fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", arg.acousticEnvironmentId ); +#endif goto cleanup; } renderConfig.roomAcoustics.override = true; @@ -875,6 +903,13 @@ cleanup: free( pcmBuf ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( arg.aeSequence.count > 0 ) + { + free( arg.aeSequence.pID ); + free( arg.aeSequence.pValidity ); + } +#endif #ifdef DEBUG_SBA_AUDIO_DUMP IVAS_DEC_GetSbaDebugParams( hIvasDec, &numOutChannels, &numTransportChannels, &pca_ingest_channels ); @@ -1090,7 +1125,15 @@ static bool parseCmdlIVAS_dec( arg->tsmScaleFileName = NULL; #endif #endif +#ifdef FIX_1053_REVERB_RECONFIGURATION + arg->aeSequence.count = 0; + arg->aeSequence.pID = NULL; + arg->aeSequence.pValidity = NULL; + arg->aeSequence.selected = 0; + arg->aeSequence.frameCounter = 0; +#else arg->acousticEnvironmentId = 65535; +#endif for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { arg->directivityPatternId[i] = 65535; @@ -1474,11 +1517,90 @@ static bool parseCmdlIVAS_dec( if ( !is_digits_only( argv[i] ) ) { +#ifdef FIX_1053_REVERB_RECONFIGURATION + uint16_t k; + char *s = argv[i]; + char *token = argv[i]; + + for ( k = 0; s[k]; ) + { + s[k] == ',' ? k++ : *s++; + } + k++; + + if ( k == 0 ) + { + fprintf( stdout, "Error: Invalid acoustic environment sequence specified: %s\n\n", argv[i] ); + usage_dec(); + return false; + } + + if ( NULL == ( arg->aeSequence.pID = malloc( sizeof( uint16_t ) * k ) ) || + NULL == ( arg->aeSequence.pValidity = malloc( sizeof( uint16_t ) * k ) ) ) + { + fprintf( stdout, "Error: Unable to allocate memory for acoustic environment sequence: %s\n\n", argv[i] ); + usage_dec(); + return false; + } + + arg->aeSequence.count = k; + + k = 0; + token = strtok( argv[i++], ":" ); + + while ( token != NULL ) + { + if ( !is_number( token ) ) + { + fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, argv[i] ); + usage_dec(); + return false; + } + arg->aeSequence.pID[k] = (uint16_t) atoi( token ); + + token = strtok( NULL, "," ); + if ( !is_number( token ) ) + { + fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, argv[i] ); + usage_dec(); + return false; + } + arg->aeSequence.pValidity[k] = (uint16_t) atoi( token ); + + token = strtok( NULL, ":" ); + k++; + } + + if ( k != arg->aeSequence.count ) + { + fprintf( stdout, "Error while parsing acoustic environment sequence: %s\n\n", argv[i] ); + usage_dec(); + return false; + } +#else fprintf( stdout, "Error: Invalid acoustic environment ID specified: %s\n\n", argv[i] ); usage_dec(); return false; +#endif } +#ifdef FIX_1053_REVERB_RECONFIGURATION + else + { + /* A single acoustic environment */ + if ( NULL == ( arg->aeSequence.pID = malloc( sizeof( uint16_t ) ) ) || + NULL == ( arg->aeSequence.pValidity = malloc( sizeof( uint16_t ) ) ) ) + { + fprintf( stdout, "Error: Unable to allocate memory for acoustic environment sequence: %s\n\n", argv[i] ); + usage_dec(); + return false; + } + arg->aeSequence.count = 1; + arg->aeSequence.pID[0] = (int16_t) atoi( argv[i++] ); + arg->aeSequence.pValidity[0] = 0; + } +#else arg->acousticEnvironmentId = (int16_t) atoi( argv[i++] ); +#endif } else if ( strcmp( argv_to_upper, "-DPID" ) == 0 ) { @@ -1717,7 +1839,15 @@ static void usage_dec( void ) fprintf( stdout, " output configuration. ID1, ID2, ID3, ID4 specify the directivity pattern IDs used for\n" ); fprintf( stdout, " ISMs 1,2,3 and 4 respectively. This options needs to be accompanied by a render_config file,\n" ); fprintf( stdout, " otherwise a default directivity pattern is used.\n" ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + fprintf( stdout, "-aeid ID : Acoustic environment ID (number > 0) or\n" ); + fprintf( stdout, " a sequence thereof in the format [ID1:duration1,ID2:duration2...]\n" ); + fprintf( stdout, " without braces and spaces, with ':' character separating ID from duration and ',' separating\n" ); + fprintf( stdout, " ID and duration pairs, where duration is specified in frames\n" ); + fprintf( stdout, " for BINAURAL_ROOM_REVERB output configuration.\n" ); +#else fprintf( stdout, "-aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output configuration\n" ); +#endif fprintf( stdout, "-level level : Complexity level, level = (1, 2, 3), will be defined after characterisation. \n" ); fprintf( stdout, " Currently, all values default to level 3 (full functionality).\n" ); fprintf( stdout, "-q : Quiet mode, no frame counter\n" ); @@ -2082,6 +2212,31 @@ static ivas_error decodeG192( SplitFileReadWrite *splitRendWriter = NULL; #endif +#ifdef FIX_1053_REVERB_RECONFIGURATION + IVAS_RENDER_CONFIG_DATA renderConfig; + RenderConfigReader *renderConfigReader = NULL; + + if ( arg.renderConfigEnabled ) + { + if ( ( error = RenderConfigReader_open( arg.renderConfigFilename, &renderConfigReader ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: Can't open Renderer configuration file %s \n\n", arg.renderConfigFilename ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_GetRenderConfig( hIvasDec, &renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + 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; + } + } +#endif for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { ismWriters[i] = NULL; @@ -2291,6 +2446,38 @@ static ivas_error decodeG192( { if ( needNewFrame ) { +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && renderConfigReader != NULL && + arg.aeSequence.count > 0 && arg.aeSequence.pValidity[arg.aeSequence.selected] != 0 ) + { + if ( ++arg.aeSequence.frameCounter >= arg.aeSequence.pValidity[arg.aeSequence.selected] ) + { + if ( ++arg.aeSequence.selected >= arg.aeSequence.count ) + { + arg.aeSequence.selected = 0; + } + arg.aeSequence.frameCounter = 0; + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, arg.aeSequence.pID[arg.aeSequence.selected], &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) + { + if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Invalid acoustic environment configuratoin parameters\n\n" ); + goto cleanup; + } + } + else + { + fprintf( stderr, "Failed to get acoustic environment with ID %d\n\n", arg.aeSequence.pID[arg.aeSequence.selected] ); + goto cleanup; + } + if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + } +#endif #ifdef DEBUGGING #ifdef VARIABLE_SPEED_DECODING if ( arg.tsmScaleFileEnabled ) @@ -2738,6 +2925,9 @@ static ivas_error decodeG192( cleanup: +#ifdef FIX_1053_REVERB_RECONFIGURATION + RenderConfigReader_close( &renderConfigReader ); +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT split_rend_reader_writer_close( &splitRendWriter ); #endif diff --git a/apps/renderer.c b/apps/renderer.c index 8a9e0b48f84f0745af9cdf84ecc08a362669c8fc..6aaa359af4d6db51fb56ad8d44e5fbefd6deb991 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -150,6 +150,17 @@ typedef struct IVAS_CUSTOM_LS_DATA outSetupCustom; } OutputConfig; +#ifdef FIX_1053_REVERB_RECONFIGURATION +typedef struct +{ + uint16_t *pID; + uint16_t *pValidity; + uint16_t count; + uint16_t selected; + uint16_t frameCounter; +} AcousticEnvironmentSequence; +#endif + typedef struct { char executableName[RENDERER_MAX_CLI_ARG_LENGTH]; @@ -189,7 +200,11 @@ typedef struct float syncMdDelay; IVAS_RENDER_FRAMESIZE render_framesize; uint16_t directivityPatternId[RENDERER_MAX_ISM_INPUTS]; +#ifdef FIX_1053_REVERB_RECONFIGURATION + AcousticEnvironmentSequence aeSequence; +#else uint16_t acousticEnvironmentId; +#endif } CmdlnArgs; typedef enum @@ -322,10 +337,12 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "lp", .description = "Output LFE position. Comma-delimited triplet of [gain, azimuth, elevation] where gain is linear (like --gain, -g) and azimuth, elevation are in degrees.\nIf specified, overrides the default behavior which attempts to map input to output LFE channel(s)", }, - { .id = CmdlnOptionId_lfeMatrix, - .match = "lfe_matrix", - .matchShort = "lm", - .description = "LFE panning matrix. File (CSV table) containing a matrix of dimensions [ num_input_lfe x num_output_channels ] with elements specifying linear routing gain (like --gain, -g). \nIf specified, overrides the output LFE position option and the default behavior which attempts to map input to output LFE channel(s)" }, + { + .id = CmdlnOptionId_lfeMatrix, + .match = "lfe_matrix", + .matchShort = "lm", + .description = "LFE panning matrix. File (CSV table) containing a matrix of dimensions [ num_input_lfe x num_output_channels ] with elements specifying linear routing gain (like --gain, -g). \nIf specified, overrides the output LFE position option and the default behavior which attempts to map input to output LFE channel(s)", + }, { .id = CmdLnOptionId_noDelayCmp, .match = "no_delay_compensation", @@ -390,7 +407,11 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_acousticEnvironmentId, .match = "acoustic_environment_id", .matchShort = "aeid", +#ifdef FIX_1053_REVERB_RECONFIGURATION + .description = "Acoustic environment ID( number > 0 ) or a sequence thereof in the format [ID1:duration1,ID2:duration2...] without braces and spaces, with ':' character separating ID from duration and ',' separating ID and duration pairs, where duration is specified in frames for BINAURAL_ROOM_REVERB output configuration.", +#else .description = "Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output configuration", +#endif }, }; @@ -784,6 +805,9 @@ int main( int16_t zeroPadToWrite = 0; int32_t delayTimeScale = 0; int16_t i, numChannels; +#ifdef FIX_1053_REVERB_RECONFIGURATION + uint16_t aeID; +#endif ivas_error error = IVAS_ERR_OK; bool splitBinNeedsNewFrame = true; @@ -1160,7 +1184,12 @@ int main( if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { +#ifdef FIX_1053_REVERB_RECONFIGURATION + aeID = args.aeSequence.count > 0 ? args.aeSequence.pID[0] : 65535; + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, aeID, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) +#else if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, args.acousticEnvironmentId, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) +#endif { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { @@ -1170,7 +1199,11 @@ int main( } else { +#ifdef FIX_1053_REVERB_RECONFIGURATION + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", aeID ); +#else fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", args.acousticEnvironmentId ); +#endif exit( -1 ); } renderConfig.roomAcoustics.override = 1; @@ -1601,6 +1634,40 @@ int main( num_in_channels = inBuffer.config.numChannels; const bool isCurrentFrameMultipleOf20ms = frame % ( 4 / args.render_framesize ) == 0; +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && renderConfigReader != NULL && + args.aeSequence.count > 0 && args.aeSequence.pValidity[args.aeSequence.selected] != 0 ) + { + if ( ++args.aeSequence.frameCounter >= args.aeSequence.pValidity[args.aeSequence.selected] ) + { + IVAS_RENDER_CONFIG_DATA renderConfig; + + if ( ++args.aeSequence.selected >= args.aeSequence.count ) + { + args.aeSequence.selected = 0; + } + args.aeSequence.frameCounter = 0; + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, args.aeSequence.pID[args.aeSequence.selected], &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) + { + if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Invalid acoustic environment configuratoin parameters\n\n" ); + goto cleanup; + } + } + else + { + fprintf( stderr, "Failed to get acoustic environment with ID %d\n\n", args.aeSequence.pID[args.aeSequence.selected] ); + goto cleanup; + } + if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_REND_FeedRenderConfig failed: %s\n\n", ivas_error_to_string( error ) ); + goto cleanup; + } + } + } +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT numSamplesRead = 0; if ( ( hSplitRendFileReadWrite != NULL ) && is_split_post_rend_mode( &args ) && splitBinNeedsNewFrame ) @@ -2192,6 +2259,13 @@ cleanup: { free( bitsBufferData ); } +#endif +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( args.aeSequence.count > 0 ) + { + free( args.aeSequence.pID ); + free( args.aeSequence.pValidity ); + } #endif for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { @@ -2673,6 +2747,94 @@ static bool parseLfePositionConfig( } +#ifdef FIX_1053_REVERB_RECONFIGURATION +static bool parseAcousticEnvironmentIds( + const char *value, + AcousticEnvironmentSequence *aeSequence ) +{ + uint16_t k; + char config_string[RENDERER_MAX_METADATA_LINE_LENGTH]; + char *s; + char *token; + + strncpy( config_string, value, RENDERER_MAX_METADATA_LINE_LENGTH ); + s = config_string; + token = config_string; + + if ( !is_digits_only( config_string ) ) + { + + for ( k = 0; s[k]; ) + { + s[k] == ',' ? k++ : *s++; + } + k++; + + if ( k == 0 ) + { + fprintf( stdout, "Error: Invalid acoustic environment sequence specified: %s\n\n", config_string ); + return false; + } + + if ( NULL == ( aeSequence->pID = malloc( sizeof( uint16_t ) * k ) ) || + NULL == ( aeSequence->pValidity = malloc( sizeof( uint16_t ) * k ) ) ) + { + fprintf( stdout, "Error: Unable to allocate memory for acoustic environment sequence: %s\n\n", config_string ); + return false; + } + + aeSequence->count = k; + + k = 0; + + token = strtok( config_string, ":" ); + + while ( token != NULL ) + { + if ( !is_number( token ) ) + { + fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, config_string ); + return false; + } + aeSequence->pID[k] = (uint16_t) atoi( token ); + + token = strtok( NULL, "," ); + if ( !is_number( token ) ) + { + fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, config_string ); + return false; + } + aeSequence->pValidity[k] = (uint16_t) atoi( token ); + + token = strtok( NULL, ":" ); + k++; + } + + if ( k != aeSequence->count ) + { + fprintf( stdout, "Error while parsing acoustic environment sequence: %s\n\n", config_string ); + return false; + } + } + else + { + /* A single acoustic environment */ + if ( NULL == ( aeSequence->pID = malloc( sizeof( uint16_t ) ) ) || + NULL == ( aeSequence->pValidity = malloc( sizeof( uint16_t ) ) ) ) + { + fprintf( stdout, "Error: Unable to allocate memory for acoustic environment sequence: %s\n\n", config_string ); + return false; + } + aeSequence->count = 1; + aeSequence->pID[0] = (int16_t) atoi( config_string ); + aeSequence->pValidity[0] = 0; + } + + return true; +} +#endif + + static bool checkRequiredArgs( CmdlnArgs args ) { @@ -2789,7 +2951,15 @@ static CmdlnArgs defaultArgs( args.directivityPatternId[i] = 65535; } +#ifdef FIX_1053_REVERB_RECONFIGURATION + args.aeSequence.count = 0; + args.aeSequence.pID = NULL; + args.aeSequence.pValidity = NULL; + args.aeSequence.selected = 0; + args.aeSequence.frameCounter = 0; +#else args.acousticEnvironmentId = 65535; +#endif return args; } @@ -2961,12 +3131,19 @@ static void parseOption( break; case CmdLnOptionId_acousticEnvironmentId: assert( numOptionValues == 1 ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( !parseAcousticEnvironmentIds( optionValues[0], &args->aeSequence ) ) + { + fprintf( stderr, "Invalid acoustic environment ID specified: %s\n", optionValues[0] ); + } +#else if ( !is_digits_only( optionValues[0] ) ) { fprintf( stderr, "Invalid acousting environment ID specified: %s\n", optionValues[0] ); exit( -1 ); } args->acousticEnvironmentId = (int16_t) strtol( optionValues[0], NULL, 10 ); +#endif break; case CmdLnOptionId_syncMdDelay: assert( numOptionValues == 1 ); diff --git a/lib_com/options.h b/lib_com/options.h index f417a679526265a01751dda47282793648dde493..efe7b79a0bdd4c4597f797afd704a09af122c66b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -156,6 +156,7 @@ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ /*#define SPLIT_REND_WITH_HEAD_ROT */ /* Dlb,FhG: Split Rendering contributions 21 and 35 */ +#define FIX_1053_REVERB_RECONFIGURATION /* Philips: issue 1053: fix for dynamic switching of acoustic environment */ #define FIX_1060_USAN_ARRAY_BOUNDS /* FhG: issue 1060: USAN array-bounds errors */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 0b005615dda02cda6fb6c684da6a1d40590e220b..065f0e24113a8f5e0018cd7d2f833153e314cbfa 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -51,6 +51,19 @@ #endif #include "wmc_auto.h" +#ifdef FIX_1053_REVERB_RECONFIGURATION + +/*------------------------------------------------------------------------- + * Local constants + *------------------------------------------------------------------------*/ + +#define REVERB_INPUT_DOWNMIX_CHANNELS ( 11 ) +/* Downmix table for sparse frequency domain reverberator */ +const float dmxmtx_table[BINAURAL_CHANNELS][REVERB_INPUT_DOWNMIX_CHANNELS] = { + { 1.0f, 0.0f, 0.70709997f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, + { 0.0f, 1.0f, 0.70709997f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +}; +#endif /*------------------------------------------------------------------------- * ivas_binRenderer_filterModule() @@ -895,7 +908,11 @@ static void ivas_binaural_obtain_DMX( for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { +#ifdef FIX_1053_REVERB_RECONFIGURATION + float dmxConst = dmxmtx_table[chOutIdx][chIdx]; +#else float dmxConst = hBinRenderer->hReverb->dmxmtx[chOutIdx][chIdx]; +#endif for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -1104,7 +1121,11 @@ ivas_error ivas_binRenderer_open( ) { BINAURAL_RENDERER_HANDLE hBinRenderer; +#ifdef FIX_1053_REVERB_RECONFIGURATION + int16_t convBand, k; +#else int16_t convBand, chIdx, k; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -1259,7 +1280,7 @@ ivas_error ivas_binRenderer_open( { return error; } - +#ifndef FIX_1053_REVERB_RECONFIGURATION /* initialize the dmx matrix */ if ( hBinRenderer->nInChannels != HOA3_CHANNELS ) { @@ -1271,6 +1292,7 @@ ivas_error ivas_binRenderer_open( } } } +#endif } else { diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 30779c35de49e3c87b73c9a8dcadafaf65695a40..50e6ed16da3fe60824e380ad82507c0eab84117c 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -390,6 +390,7 @@ const float dirac_dithering_ele_scale[DIRAC_DIFFUSE_LEVELS] = 6.716062e-01f, 1.011804e+00f, 1.796875e+00f, 2.804382e+00f, 4.623130e+00f, 7.802667e+00f, 1.045446e+01f, 1.379538e+01f }; +#ifndef FIX_1053_REVERB_RECONFIGURATION /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ @@ -399,7 +400,7 @@ const float dmxmtx_table[BINAURAL_CHANNELS][11] = { 1.0f, 0.0f, 0.70709997f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.70709997f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }, }; - +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT /*----------------------------------------------------------------------* diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index d7c5f9c596d01bc241a9fe4dc1805ba9a2ac6221..a5cba2f22a7eae3dbb9a132bcfa04ddd9a9a1e81 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -96,12 +96,13 @@ extern const uint16_t *const sym_freq_ECSQ_tab_abs_lsbs[1 + 4]; extern const float dirac_dithering_azi_scale[DIRAC_DIFFUSE_LEVELS]; extern const float dirac_dithering_ele_scale[DIRAC_DIFFUSE_LEVELS]; - +#ifndef FIX_1053_REVERB_RECONFIGURATION /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ extern const float dmxmtx_table[BINAURAL_CHANNELS][11]; +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT /*----------------------------------------------------------------------* diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index aeb8f84303e8ec6dac28f5c3e9ddecfe84829f8c..1d7e19c5710d0b7fab4505cb8a8a86e25c292368 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -2099,8 +2099,12 @@ ivas_error IVAS_DEC_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef FIX_1053_REVERB_RECONFIGURATION + ivas_error error; +#else #ifdef SPLIT_REND_WITH_HEAD_ROT ivas_error error; +#endif #endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) @@ -2140,6 +2144,77 @@ ivas_error IVAS_DEC_FeedRenderConfig( mvr2r( renderConfig.roomAcoustics.pAcoustic_rt60, hRenderConfig->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( renderConfig.roomAcoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + /* Re-initialize reverb instance if already available */ + +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* TD renderer Jot reverberator */ + if ( hIvasDec->st_ivas->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &hIvasDec->st_ivas->hReverb, hIvasDec->st_ivas->hHrtfStatistics, hRenderConfig, hIvasDec->st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* CREND Jot reverberator */ + if ( hIvasDec->st_ivas->hCrendWrapper != NULL && hIvasDec->st_ivas->hCrendWrapper->hCrend[0] != NULL && hIvasDec->st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &hIvasDec->st_ivas->hCrendWrapper->hCrend[0]->hReverb, hIvasDec->st_ivas->hHrtfStatistics, hRenderConfig, hIvasDec->st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* FB reverberator */ + if ( hIvasDec->st_ivas->hDiracDecBin[0] != NULL && hIvasDec->st_ivas->hDiracDecBin[0]->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( hIvasDec->st_ivas->hDiracDecBin[0]->hReverb ) ); + if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hDiracDecBin[0]->hReverb ), hIvasDec->st_ivas->hHrtfStatistics, hIvasDec->st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), hIvasDec->st_ivas->hDecoderConfig->output_Fs, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else + /* TD renderer Jot reverberator */ + if ( hIvasDec->st_ivas->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &hIvasDec->st_ivas->hReverb, hIvasDec->st_ivas->hHrtfStatistics, hRenderConfig, hIvasDec->st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* CREND Jot reverberator */ + if ( hIvasDec->st_ivas->hCrendWrapper != NULL && hIvasDec->st_ivas->hCrendWrapper->hCrend != NULL && hIvasDec->st_ivas->hCrendWrapper->hCrend->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &hIvasDec->st_ivas->hCrendWrapper->hCrend->hReverb, hIvasDec->st_ivas->hHrtfStatistics, hRenderConfig, hIvasDec->st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* DirAC CLDFB reverberator */ + if ( hIvasDec->st_ivas->hDiracDecBin != NULL && hIvasDec->st_ivas->hDiracDecBin->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( hIvasDec->st_ivas->hDiracDecBin->hReverb ) ); + if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hDiracDecBin->hReverb ), hIvasDec->st_ivas->hHrtfStatistics, hIvasDec->st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), hIvasDec->st_ivas->hDecoderConfig->output_Fs, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + /* Fastconv CLDFB reverberator */ + if ( hIvasDec->st_ivas->hBinRenderer != NULL && hIvasDec->st_ivas->hBinRenderer->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( hIvasDec->st_ivas->hBinRenderer->hReverb ) ); + if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hBinRenderer->hReverb ), hIvasDec->st_ivas->hHrtfStatistics, hIvasDec->st_ivas->hBinRenderer->conv_band, hIvasDec->st_ivas->hBinRenderer->timeSlots, &( hRenderConfig->roomAcoustics ), hIvasDec->st_ivas->hDecoderConfig->output_Fs, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); #ifdef SPLIT_REND_WITH_HEAD_ROT diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 7de4ed3e8cdc05d65c964f100061f33b45b5cad5..070a3ae67c22f07213a8fc18eafae64dbad79d90 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -980,7 +980,7 @@ void ivas_binaural_reverb_processSubframe( ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ - const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ + const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ RENDER_CONFIG_DATA *pConfig, /* i : Reverb configuration */ const int32_t output_Fs /* i : output sampling rate */ ); diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 1f791df39c484abd42569ba74715776fb8e7886d..74b3acd3825bcd0ef5cd2cc917e40ed5c3b711b3 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -105,12 +105,14 @@ typedef struct ivas_reverb_params_t float *pFc; /* Center frequencies for FFT filter design */ float *pRt60; /* RT60 values at these frequencies */ float *pDsr; /* DSR values at these frequencies */ - float *pHrtf_avg_pwr_response_l; /* The HRTF set's average left ear power response */ - float *pHrtf_avg_pwr_response_r; /* The HRTF set's average right ear power response */ - float *pHrtf_inter_aural_coherence; /* The HRTF set's inter-aural coherence for diffuse sound */ - const float *pHrtf_avg_pwr_response_l_const; /* The HRTF set's average left ear power response */ - const float *pHrtf_avg_pwr_response_r_const; /* The HRTF set's average right ear power response */ - const float *pHrtf_inter_aural_coherence_const; /* The HRTF set's inter-aural coherence for diffuse sound */ +#ifndef FIX_1053_REVERB_RECONFIGURATION + float *pHrtf_avg_pwr_response_l; /* The HRTF set's average left ear power response */ + float *pHrtf_avg_pwr_response_r; /* The HRTF set's average right ear power response */ + float *pHrtf_inter_aural_coherence; /* The HRTF set's inter-aural coherence for diffuse sound */ +#endif + const float *pHrtf_avg_pwr_response_l_const; /* The HRTF set's average left ear power response */ + const float *pHrtf_avg_pwr_response_r_const; /* The HRTF set's average right ear power response */ + const float *pHrtf_inter_aural_coherence_const; /* The HRTF set's inter-aural coherence for diffuse sound */ int16_t do_corr_filter; /* Flag indicating whether correlation filters should be used. */ /* Correlation only supported and needed for binaural playback (i.e. */ @@ -977,7 +979,9 @@ static ivas_error setup_FDN_branches( { int16_t nr_coefs, branch_idx, channel_idx; ivas_error error; +#ifndef FIX_1053_REVERB_RECONFIGURATION float *pCoef_a, *pCoef_b; +#endif error = IVAS_ERR_OK; /* initialize feedback branches */ @@ -999,6 +1003,7 @@ static ivas_error setup_FDN_branches( { for ( branch_idx = 0; branch_idx < pParams->nr_loops; branch_idx++ ) { +#ifndef FIX_1053_REVERB_RECONFIGURATION pCoef_a = &pParams->pT60_filter_coeff[2 * nr_coefs * branch_idx + nr_coefs]; pCoef_b = &pParams->pT60_filter_coeff[2 * nr_coefs * branch_idx]; @@ -1006,7 +1011,7 @@ static ivas_error setup_FDN_branches( { return error; } - +#endif if ( ( error = set_feedback_delay( hReverb, branch_idx, pParams->pLoop_delays[branch_idx] ) ) != IVAS_ERR_OK ) { return error; @@ -1031,11 +1036,19 @@ static ivas_error setup_FDN_branches( } +#ifdef FIX_1053_REVERB_RECONFIGURATION +/*------------------------------------------------------------------------- + * ivas_reverb_open() + * + * Allocate and initialize FDN reverberation handle + *------------------------------------------------------------------------*/ +#else /*------------------------------------------------------------------------- * ivas_reverb_open() * * Allocate and initialize Crend reverberation handle *------------------------------------------------------------------------*/ +#endif ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ @@ -1045,7 +1058,13 @@ ivas_error ivas_reverb_open( ) { ivas_error error; +#ifdef FIX_1053_REVERB_RECONFIGURATION + REVERB_HANDLE pState = *hReverb; + int16_t nr_coefs, branch_idx; + float *pCoef_a, *pCoef_b; +#else REVERB_HANDLE pState = NULL; +#endif int16_t bin_idx, subframe_len, output_frame, predelay_bf_len, loop_idx; ivas_reverb_params_t params; rv_fftwf_type_complex pFft_wf_filter_ch0[RV_LENGTH_NR_FC]; @@ -1063,17 +1082,47 @@ ivas_error ivas_reverb_open( predelay_bf_len = output_frame; nr_fc_input = hRenderConfig->roomAcoustics.nBands; +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + /* Allocate main reverb. handle */ + if ( ( pState = (REVERB_HANDLE) malloc( sizeof( REVERB_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator " ); + } + } +#else /* Allocate main reverb. handle */ if ( ( pState = (REVERB_HANDLE) malloc( sizeof( REVERB_DATA ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Reverberator " ); } +#endif if ( ( error = set_base_config( ¶ms, output_Fs ) ) != IVAS_ERR_OK ) { return error; } +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + /* Allocate memory for feedback delay lines */ + for ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) + { + if ( ( pState->loop_delay_buffer[loop_idx] = (float *) malloc( params.pLoop_delays[loop_idx] * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator" ); + } + } + + /* Allocate memory for the pre-delay delay line */ + if ( ( pState->pPredelay_buffer = (float *) malloc( output_frame * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator" ); + } + } +#else /* Allocate memory for feedback delay lines */ for ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) { @@ -1088,20 +1137,26 @@ ivas_error ivas_reverb_open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CREND Reverberator" ); } +#endif pState->nr_of_branches = IVAS_REV_MAX_NR_BRANCHES; set_fft_and_datablock_sizes( pState, subframe_len ); + nr_fc_fft_filter = ( pState->fft_size >> 1 ) + 1; /* === 'Control logic': compute the reverb processing parameters from the === */ /* === room, source and listener acoustic information provided in the reverb config === */ /* Setting up shared temporary buffers for fc, RT60, DSR, etc. */ +#ifndef FIX_1053_REVERB_RECONFIGURATION params.pHrtf_avg_pwr_response_l = &pFft_wf_filter_ch0[0][0]; params.pHrtf_avg_pwr_response_r = params.pHrtf_avg_pwr_response_l + nr_fc_fft_filter; +#endif params.pRt60 = &pFft_wf_filter_ch1[0][0]; params.pDsr = params.pRt60 + nr_fc_fft_filter; params.pFc = &pState->fft_filter_color_0.fft_spectrum[0]; +#ifndef FIX_1053_REVERB_RECONFIGURATION params.pHrtf_inter_aural_coherence = &pState->fft_filter_color_1.fft_spectrum[0]; +#endif /* Note: these temp buffers can only be used before the final step of the FFT filter design : */ /* before calls to ivas_reverb_calc_correl_filters(...) or to ivas_reverb_calc_color_filters(...) */ @@ -1132,7 +1187,15 @@ ivas_error ivas_reverb_open( } /* set up input downmix */ +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + pState->dmx_gain = calc_dmx_gain(); + } +#else + /* set up input downmix */ pState->dmx_gain = calc_dmx_gain(); +#endif /* set up predelay - must be after set_base_config() and before compute_t60_coeffs() */ calc_predelay( ¶ms, hRenderConfig->roomAcoustics.acousticPreDelay, output_Fs ); @@ -1156,7 +1219,20 @@ ivas_error ivas_reverb_open( /* Compute the window used for FFT filters */ ivas_reverb_define_window_fft( pTime_window, transition_start, transition_length, nr_fc_fft_filter ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + /* === Copy parameters from ivas_reverb_params_t into DSP blocks === */ + /* === to be used for subsequent audio signal processing === */ + if ( *hReverb == NULL ) + { + pState->do_corr_filter = params.do_corr_filter; + /* clear & init jot reverb fft filters */ + if ( ( error = initialize_reverb_filters( pState ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else /* === Now, copy parameters from ivas_reverb_params_t into DSP blocks === */ /* === to be used for subsequent audio signal processing === */ @@ -1167,6 +1243,7 @@ ivas_error ivas_reverb_open( { return error; } +#endif if ( pState->do_corr_filter ) { @@ -1199,6 +1276,36 @@ ivas_error ivas_reverb_open( return error; } +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + /* init predelay */ + ivas_rev_delay_line_init( &( pState->predelay_line ), pState->pPredelay_buffer, params.pre_delay, predelay_bf_len ); + + /* set up feedback delay network */ + if ( ( error = setup_FDN_branches( pState, ¶ms ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + pState->predelay_line.Delay = params.pre_delay; + } + + nr_coefs = params.t60_filter_order + 1; + + for ( branch_idx = 0; branch_idx < params.nr_loops; branch_idx++ ) + { + pCoef_a = ¶ms.pT60_filter_coeff[2 * nr_coefs * branch_idx + nr_coefs]; + pCoef_b = ¶ms.pT60_filter_coeff[2 * nr_coefs * branch_idx]; + + if ( ( error = set_t60_filter( pState, branch_idx, nr_coefs, pCoef_a, pCoef_b ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else /* init predelay */ ivas_rev_delay_line_init( &( pState->predelay_line ), pState->pPredelay_buffer, params.pre_delay, predelay_bf_len ); @@ -1207,6 +1314,7 @@ ivas_error ivas_reverb_open( { return error; } +#endif *hReverb = pState; diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 672f2642119b7153f3d589794f208e8714600508..25d14766950797bc076c6b1df785ba926518b094 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -485,7 +485,9 @@ typedef struct ivas_binaural_reverb_struct uint32_t binRend_RandNext; int16_t highestBinauralCoherenceBin; +#ifndef FIX_1053_REVERB_RECONFIGURATION float dmxmtx[BINAURAL_CHANNELS][MAX_OUTPUT_CHANNELS]; +#endif float foa_enc[MAX_OUTPUT_CHANNELS][FOA_CHANNELS]; } REVERB_STRUCT, *REVERB_STRUCT_HANDLE; @@ -839,7 +841,6 @@ typedef struct ivas_reverb_state_t uint16_t fft_subblock_size; /* fft block processing size */ uint16_t num_fft_subblocks; /* number of fft subblocks */ uint16_t full_block_size; /* full block processing size */ - } REVERB_DATA, *REVERB_HANDLE; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index a6ddac23a9ccd562ac7b1b3671447f9a3479ff86..439a4fd113c2bf453c20080790d7909872774b3b 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4616,8 +4616,17 @@ int16_t IVAS_REND_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef FIX_1053_REVERB_RECONFIGURATION + uint16_t i; + input_ism *pIsmInput; + input_masa *pMasaInput; + input_mc *pMcInput; + input_sba *pSbaInput; + ivas_error error; +#else #ifdef SPLIT_REND_WITH_HEAD_ROT ivas_error error; +#endif #endif if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) @@ -4649,6 +4658,141 @@ int16_t IVAS_REND_FeedRenderConfig( mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); } +#ifdef FIX_1053_REVERB_RECONFIGURATION + /* Re-initialize reverb instance if already available */ + /* ISM inputs */ + for ( i = 0, pIsmInput = hIvasRend->inputsIsm; i < RENDERER_MAX_ISM_INPUTS; ++i, ++pIsmInput ) + { + if ( pIsmInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + if ( pIsmInput->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pIsmInput->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + if ( pIsmInput->crendWrapper != NULL && pIsmInput->crendWrapper->hCrend != NULL ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_reverb_open( &pIsmInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_reverb_open( &pIsmInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } + } + + /* MASA inputs */ + for ( i = 0, pMasaInput = hIvasRend->inputsMasa; i < RENDERER_MAX_MASA_INPUTS; ++i, ++pMasaInput ) + { + if ( pMasaInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( pMasaInput->hMasaExtRend != NULL ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pMasaInput->hMasaExtRend->hDiracDecBin != NULL && pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb != NULL ) + { + ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb ); + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else + if ( pMasaInput->hMasaExtRend->hDiracDecBin != NULL && pMasaInput->hMasaExtRend->hDiracDecBin->hReverb != NULL ) + { + ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hDiracDecBin->hReverb ); + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + if ( pMasaInput->hMasaExtRend->hReverb != NULL ) + { + ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hReverb ); + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + } + + /* Multi-channel inputs */ + for ( i = 0, pMcInput = hIvasRend->inputsMc; i < RENDERER_MAX_MC_INPUTS; ++i, ++pMcInput ) + { + if ( pMcInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( pMcInput->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pMcInput->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pMcInput->crendWrapper != NULL && pMcInput->crendWrapper->hCrend && pMcInput->crendWrapper->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pMcInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else + if ( pMcInput->crendWrapper != NULL && pMcInput->crendWrapper->hCrend && pMcInput->crendWrapper->hCrend->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pMcInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } + + /* SBA inputs */ + for ( i = 0, pSbaInput = hIvasRend->inputsSba; i < RENDERER_MAX_SBA_INPUTS; ++i, ++pSbaInput ) + { + if ( pSbaInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pSbaInput->crendWrapper != NULL && pSbaInput->crendWrapper->hCrend != NULL && pSbaInput->crendWrapper->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pSbaInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pSbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else + if ( pSbaInput->crendWrapper != NULL && pSbaInput->crendWrapper->hCrend != NULL && pSbaInput->crendWrapper->hCrend->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pSbaInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pSbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } +#endif + #ifdef SPLIT_REND_WITH_HEAD_ROT hRenderConfig->split_rend_config = renderConfig.split_rend_config; /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index decafb0a46dbc19e5de42df5fd09436c54d9eaa9..ffcb1d992a7236d4eba909037e097ac12a6bd3c7 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2821,6 +2821,12 @@ ivas_error RenderConfigReader_getAcousticEnvironment( pAcEnv->AbsCoeff[j] = pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[j]; } } +#ifdef FIX_1053_REVERB_RECONFIGURATION + else + { + pAcEnv->use_er = false; + } +#endif return IVAS_ERR_OK; } } diff --git a/readme.txt b/readme.txt index 25275a79516b91aa8a0d3fa8131155cd441f5e68..415ae41cc9a4d9f9402a1731995f67f9ef2da1ad 100644 --- a/readme.txt +++ b/readme.txt @@ -314,7 +314,11 @@ Options: -exof File : External orientation trajectory File for simulation of external orientations -dpid ID : Directivity pattern ID(s) (space-separated list of up to 4 numbers can be specified) for binaural output configuration --aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output config. +-aeid ID : Acoustic environment ID (number > 0) or + a sequence thereof in the format [ID1:duration1,ID2:duration2...] + without braces and spaces, with ':' character separating ID from duration and ',' separating + ID and duration pairs, where duration is specified in frames + for BINAURAL_ROOM_REVERB output configuration. -lp Position : Output LFE position. Comma-delimited triplet of [gain, azimuth, elevation] where gain is linear (like --gain, -g) and azimuth, elevation are in degrees. If specified, overrides the default behavior which attempts to map input to output LFE channel(s) diff --git a/scripts/config/self_test.prm b/scripts/config/self_test.prm index 2e9886b9ffcfd1343b478c46bce31b7a5a3beffd..025323d17579792d1f28f3cd1103be5ed70bce14 100644 --- a/scripts/config/self_test.prm +++ b/scripts/config/self_test.prm @@ -1292,6 +1292,18 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../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_ROOM_REVERB out custom acoustic environment with a sequence (CREND) +//../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:200,0:100,2:500 BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_reverb_sequence.tst + +// Multi-channel 5_1 at 64 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (FastConv) +//../IVAS_cod -mc 5_1 64000 48 testv/stv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:500,2:100,0:300 BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_64000_48-48_MC_reverb_sequence.tst + +// Multi-channel 5_1 at 32 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (ParamBin) +//../IVAS_cod -mc 5_1 32000 48 testv/stv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 0:100,2:500,1:200 BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_32000_48-48_MC_reverb_sequence.tst + // Multi-channel 5_1 at 32 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config hospital_patientroom ../IVAS_cod -mc 5_1 32000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_32000_48-48_MC_Config_hospital_patientroom.tst diff --git a/scripts/config/self_test_ltv.prm b/scripts/config/self_test_ltv.prm index 690d3ed897cfe6bf0831b51aefd2bd5a14944323..079021ba603cce4b66caf371761a7f1705384e7f 100644 --- a/scripts/config/self_test_ltv.prm +++ b/scripts/config/self_test_ltv.prm @@ -1291,6 +1291,18 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 512000 48 testv/ltv48_MC51.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 16 bit testv/ltv48_MC51.wav_MC51_512000_48-16_MC_Config_renderer.tst +// Multi-channel 5_1 at 512 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (CREND) +//../IVAS_cod -mc 5_1 512000 48 testv/ltv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:500,0:1000,2:500 BINAURAL_ROOM_REVERB 48 bit testv/ltv51MC48c.wav_MC51_512000_48-48_MC_reverb_sequence.tst + +// Multi-channel 5_1 at 64 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (FastConv) +//../IVAS_cod -mc 5_1 64000 48 testv/ltv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:500,2:500,0:500 BINAURAL_ROOM_REVERB 48 bit testv/ltv51MC48c.wav_MC51_64000_48-48_MC_reverb_sequence.tst + +// Multi-channel 5_1 at 32 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (ParamBin) +//../IVAS_cod -mc 5_1 32000 48 testv/ltv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 0:1000,2:500,1:500 BINAURAL_ROOM_REVERB 48 bit testv/ltv51MC48c.wav_MC51_32000_48-48_MC_reverb_sequence.tst + // Multi-channel 5_1 at 32 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config hospital_patientroom ../IVAS_cod -mc 5_1 32000 48 testv/ltv48_MC51.wav bit ../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC51.wav_MC51_80000_48-48_MC_Config_hospital_patientroom.tst