diff --git a/apps/decoder.c b/apps/decoder.c index 0bf171fb531089efeb49e343cf3266e1d7fac03f..968fcb2533aaa24198a3847b658cc237f2fa82a9 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -56,7 +56,11 @@ #include "debug.h" #endif #include "wmc_auto.h" - +#ifdef OBJ_EDITING_API +#ifdef OBJ_EDITING_EXAMPLE +#include +#endif +#endif #define WMC_TOOL_SKIP @@ -153,6 +157,9 @@ typedef struct AcousticEnvironmentSequence aeSequence; bool dpidEnabled; uint16_t directivityPatternId[IVAS_MAX_NUM_OBJECTS]; +#ifdef OBJ_EDITING_EXAMPLE + bool objEditEnabled; +#endif } DecArguments; @@ -1013,6 +1020,9 @@ static bool parseCmdlIVAS_dec( { arg->directivityPatternId[i] = 65535; } +#ifdef OBJ_EDITING_EXAMPLE + arg->objEditEnabled = false; +#endif /*-----------------------------------------------------------------* * Initialization @@ -1526,6 +1536,13 @@ static bool parseCmdlIVAS_dec( i += tmp; } +#ifdef OBJ_EDITING_EXAMPLE + else if ( strcmp( argv_to_upper, "-OBJ_EDIT" ) == 0 ) + { + arg->objEditEnabled = true; + i++; + } +#endif /*-----------------------------------------------------------------* * Option not recognized @@ -1737,6 +1754,9 @@ static void usage_dec( void ) fprintf( stdout, " Currently, all values default to level 3 (full functionality).\n" ); fprintf( stdout, "-q : Quiet mode, no frame counter\n" ); fprintf( stdout, " default is deactivated\n" ); +#ifdef OMASA_OBJECT_EDITING + fprintf( stdout, "-obj_edit : enable object editing\n" ); +#endif #ifdef DEBUG_MODE_INFO #ifdef DEBUG_MODE_INFO_TWEAK fprintf( stdout, "-info : specify subfolder name for debug output\n" ); @@ -2111,6 +2131,11 @@ static ivas_error decodeG192( int16_t isSplitRend, isSplitCoded; IVAS_RENDER_CONFIG_DATA renderConfig; RenderConfigReader *renderConfigReader = NULL; +#ifdef OBJ_EDITING_API +#ifdef OBJ_EDITING_EXAMPLE + IVAS_EDITABLE_PARAMETERS editableParameters; +#endif +#endif if ( ( error = IVAS_DEC_is_split_rendering_enabled( hIvasDec, &isSplitRend ) ) != IVAS_ERR_OK ) { @@ -2455,6 +2480,65 @@ static ivas_error decodeG192( } #ifdef OBJ_EDITING_API +#ifdef OBJ_EDITING_EXAMPLE + if ( arg.objEditEnabled ) + { + + /* Do object info editing here */ + /* get object parameters */ + if ( ( error = IVAS_DEC_GetEditableParameters( hIvasDec, &editableParameters ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not get the editable parameters: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + /* edit object parameters...*/ + + /* put the objects equally spaced at the horizontal plane */ + /* and play a little bit with the gains... */ + int16_t obj_idx, non_diegetic_obj_idx; + int16_t num_nondiegetic_objects; + + num_nondiegetic_objects = 0; + for ( obj_idx = 0; obj_idx < editableParameters.num_obj; obj_idx++ ) + { + if ( !editableParameters.ism_metadata[obj_idx].non_diegetic_flag ) + { + num_nondiegetic_objects++; + } + } + if ( num_nondiegetic_objects ) + { + float start_angle, angle_inc; + angle_inc = 360.0f / (float) num_nondiegetic_objects; + start_angle = angle_inc / 2.0f; + for ( obj_idx = 0, non_diegetic_obj_idx = 0; obj_idx < editableParameters.num_obj; obj_idx++ ) + { + if ( !editableParameters.ism_metadata[obj_idx].non_diegetic_flag ) + { + editableParameters.ism_metadata[obj_idx].elevation = 0.0f; + editableParameters.ism_metadata[obj_idx].azimuth = start_angle + (float) non_diegetic_obj_idx * angle_inc; + non_diegetic_obj_idx++; + } + } + } + + /* breakover object gains */ + for ( obj_idx = 0; obj_idx < editableParameters.num_obj; obj_idx++ ) + { + editableParameters.ism_metadata[obj_idx].gain = 0.5f + (float) ( ( frame + obj_idx * 50 ) % 250 ) / 250.0f; + } + + editableParameters.gain_bed = 0.5f; + + /* set new object parameters*/ + if ( ( error = IVAS_DEC_SetEditableParameters( hIvasDec, editableParameters ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not set the editable parameters: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } +#endif /* Do the final preparations needed for rendering */ if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) { diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 09e414867cb14a4dadfde15206cf779b1f7d0029..3456ea29c7d45e8e40860facf570c3db7d523182 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1221,6 +1221,11 @@ enum #define MASA_MAXIMUM_TWO_DIR_BANDS 24 #define NBITS_HR_COH 4 #define OMASA_TDREND_MATCHING_GAIN 0.7943f +#ifdef OMASA_OBJECT_EDITING +#define OMASA_GAIN_EDIT_THR 0.06f /* OMASA gain change threshold */ +#define OMASA_AZI_EDIT_THR 1.0f /* OMASA-DISC azimuth change threshold */ +#define OMASA_ELE_EDIT_THR 2.0f /* OMASA-DISC elevation change threshold */ +#endif #define MASA_JBM_RINGBUFFER_FRAMES 3 diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 656bc60b67abde4ce88c230f833a088381b58705..271720f50cc72214f9095a6a307456918beaf014 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5824,7 +5824,11 @@ void ivas_omasa_dirac_rend_jbm( float *output_f[] /* o : rendered time signal */ ); +#ifdef OMASA_OBJECT_EDITING +void ivas_omasa_preProcessStereoTransportsForEditedObjects( +#else void ivas_omasa_preProcessStereoTransportsForMovedObjects( +#endif Decoder_Struct *st_ivas, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], diff --git a/lib_com/options.h b/lib_com/options.h index b6700bd69ae14d6e64ac880559ae1a9e9b262a20..c640d2b9332933b49de95ecbc30f986bbe2a361d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -203,6 +203,20 @@ #define TMP_FIX_OMASA_SR_BE // temporary fix to keep OMASA split-rendering BE #endif +// objject-editing feature porting +#define OBJ_EDITING_INTERFACE /* Interface for object editing */ +#ifdef OBJ_EDITING_INTERFACE +#define OBJ_EDITING_API /* object editing changes related to the API */ +#ifdef OBJ_EDITING_API +#define FIX_HRTF_LOAD_API // solves API conflicts between HRTF and object-editing features +#define TMP_FIX_SPLIT_REND // temporary fix to split-rendering (it follows the later state of the framework but it is needed now because of current test-conditions) +#define TMP_FIX_OMASA_SR_BE // temporary fix to keep OMASA split-rendering BE +#endif +#define OBJ_EDITING_EXAMPLE /* obj editing example code in decoder.c */ +#endif +#define OMASA_OBJECT_EDITING /* Nokia: object editing interface for OMASA */ +#define OBJ_EDITING_PARAMISM_BIN /* Nokia: object editing for ParamISM to binaural */ + /* #################### End BASOP porting switches ############################ */ /* clang-format on */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index eb1f4fa36d2f60549f9a0f3d59085c253953ff4f..493c38e441b9aae13a05878b85bef0c05244c3f9 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1934,6 +1934,16 @@ void ivas_dirac_dec_render_sf( } } +#ifdef OMASA_OBJECT_EDITING + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { +#ifdef FIX_1319_STACK_SBA_DECODER + ivas_omasa_preProcessStereoTransportsForEditedObjects( st_ivas, Cldfb_RealBuffer_Binaural[0], Cldfb_ImagBuffer_Binaural[0], hSpatParamRendCom->num_freq_bands, subframe_idx ); +#else + ivas_omasa_preProcessStereoTransportsForEditedObjects( st_ivas, Cldfb_RealBuffer_Temp, Cldfb_ImagBuffer_Temp, hSpatParamRendCom->num_freq_bands, subframe_idx ); +#endif + } +#else if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) { #ifdef FIX_1319_STACK_SBA_DECODER @@ -1942,6 +1952,7 @@ void ivas_dirac_dec_render_sf( ivas_omasa_preProcessStereoTransportsForMovedObjects( st_ivas, Cldfb_RealBuffer_Temp, Cldfb_ImagBuffer_Temp, hSpatParamRendCom->num_freq_bands, subframe_idx ); #endif } +#endif } for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index d8df608cf2a13667b679fd2845fc91f081a65e3c..573fff003b1f108b8597c26d04f11ab8f89292bc 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1489,6 +1489,17 @@ ivas_error ivas_init_decoder( if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3; + +#ifdef OBJ_EDITING_PARAMISM_BIN + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + /* reusing OMASA function for allocating and initializing MASA_ISM rendering handle (even though not in OMASA) */ + if ( ( error = ivas_omasa_data_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif } else if ( st_ivas->ism_mode == ISM_MODE_DISC ) { @@ -1787,12 +1798,16 @@ ivas_error ivas_init_decoder( } reset_indices_dec( st_ivas->hSCE[0]->hCoreCoder[0] ); + +#ifndef OMASA_OBJECT_EDITING if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { +#endif if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK ) { return error; } +#ifndef OMASA_OBJECT_EDITING } else { @@ -1801,6 +1816,7 @@ ivas_error ivas_init_decoder( return error; } } +#endif } else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 1967691cdb0be42bddef679ebb48112a620b5ab6..2120f49ba7b19ff89134c9fa6e5ede68692810b1 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -169,6 +169,12 @@ static ivas_error ivas_ism_bitrate_switching_dec( { /* close the parametric binaural renderer */ ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); + +#ifdef OBJ_EDITING_PARAMISM_BIN + /* Close omasa data struct (used for object editing) */ + ivas_omasa_data_close( &st_ivas->hMasaIsmData ); +#endif + /* Open the TD Binaural renderer */ if ( st_ivas->hHrtfTD == NULL || st_ivas->hBinRendererTd == NULL ) { @@ -202,6 +208,11 @@ static ivas_error ivas_ism_bitrate_switching_dec( /* close the parametric binaural renderer */ ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#ifdef OBJ_EDITING_PARAMISM_BIN + /* Close omasa data struct (used for object editing) */ + ivas_omasa_data_close( &st_ivas->hMasaIsmData ); +#endif + /* Open Crend Binaural renderer */ if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hHrtfCrend, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, 0, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) { @@ -234,6 +245,14 @@ static ivas_error ivas_ism_bitrate_switching_dec( return error; } +#ifdef OBJ_EDITING_PARAMISM_BIN + /* Open omasa data struct (used for object editing) */ + if ( ( error = ivas_omasa_data_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + /* Close the TD Binaural renderer */ ivas_td_binaural_close( &st_ivas->hBinRendererTd ); @@ -261,6 +280,14 @@ static ivas_error ivas_ism_bitrate_switching_dec( return error; } +#ifdef OBJ_EDITING_PARAMISM_BIN + /* Open omasa data struct (used for object editing) */ + if ( ( error = ivas_omasa_data_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + /* close the crend binaural renderer */ ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 179e372bdb6efd6bc972859b1af16a4bc4a66c5e..7059174c08214a0308609b8a6fbc0784c4775f85 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -788,7 +788,8 @@ void ivas_ism_dec_digest_tc( { efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP ); #ifdef OBJ_EDITING_API - v_multc( st_ivas->hIsmRendererData->gains[i], st_ivas->hIsmMetaData[i]->edited_gain, st_ivas->hIsmRendererData->gains[i], st_ivas->hEFAPdata->numSpk ); + v_multc( st_ivas->hIsmRendererData->gains[i], + st_ivas->hIsmMetaData[i]->edited_gain, st_ivas->hIsmRendererData->gains[i], st_ivas->hEFAPdata->numSpk ); #endif } } @@ -1436,12 +1437,20 @@ void ivas_param_ism_params_to_masa_param_mapping( int16_t azimuth[2]; int16_t elevation[2]; float power_ratio[2]; +#ifdef OBJ_EDITING_PARAMISM_BIN + MASA_ISM_DATA_HANDLE hMasaIsmData; + int16_t obj; + int16_t obj_idx; +#endif #ifndef OBJ_EDITING_API int32_t ivas_total_brate; #endif hParamIsmDec = st_ivas->hParamIsmDec; hSpatParamRendCom = st_ivas->hSpatParamRendCom; +#ifdef OBJ_EDITING_PARAMISM_BIN + hMasaIsmData = st_ivas->hMasaIsmData; +#endif nBins = hSpatParamRendCom->num_freq_bands; #ifndef OBJ_EDITING_API @@ -1458,99 +1467,117 @@ void ivas_param_ism_params_to_masa_param_mapping( st_ivas->hISMDTX.dtx_flag = 1; } #endif - if ( st_ivas->nchan_ism > 1 ) + + if ( st_ivas->hISMDTX.dtx_flag ) { - if ( st_ivas->hISMDTX.dtx_flag ) - { - float energy_ratio; - energy_ratio = powf( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence, 2.0f ); + float energy_ratio; + energy_ratio = powf( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence, 2.0f ); - hSpatParamRendCom->numSimultaneousDirections = 1; - azimuth[0] = (int16_t) roundf( hParamIsmDec->azimuth_values[0] ); - elevation[0] = (int16_t) roundf( hParamIsmDec->elevation_values[0] ); + hSpatParamRendCom->numSimultaneousDirections = 1; + azimuth[0] = (int16_t) roundf( hParamIsmDec->azimuth_values[0] ); + elevation[0] = (int16_t) roundf( hParamIsmDec->elevation_values[0] ); - for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + for ( bin_idx = 0; bin_idx < nBins; bin_idx++ ) { - for ( bin_idx = 0; bin_idx < nBins; bin_idx++ ) - { - hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0]; - hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0]; + hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0]; + hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0]; - hSpatParamRendCom->energy_ratio1[sf_idx][bin_idx] = energy_ratio; + hSpatParamRendCom->energy_ratio1[sf_idx][bin_idx] = energy_ratio; - hSpatParamRendCom->spreadCoherence[sf_idx][bin_idx] = 0.0f; - hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx] = 0.0; - } + hSpatParamRendCom->spreadCoherence[sf_idx][bin_idx] = 0.0f; + hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx] = 0.0; } } - else + } + else + { + hSpatParamRendCom->numSimultaneousDirections = 2; + for ( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ ) { - hSpatParamRendCom->numSimultaneousDirections = 2; - for ( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ ) - { - brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx]; - brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1]; + brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx]; + brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1]; #ifdef OBJ_EDITING_API - azimuth[0] = (int16_t) roundf( hParamIsmDec->edited_azimuth_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]] ); - elevation[0] = (int16_t) roundf( hParamIsmDec->edited_elevation_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]] ); + azimuth[0] = (int16_t) roundf( hParamIsmDec->edited_azimuth_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]] ); + elevation[0] = (int16_t) roundf( hParamIsmDec->edited_elevation_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]] ); #else - azimuth[0] = (int16_t) roundf( hParamIsmDec->azimuth_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]] ); - elevation[0] = (int16_t) roundf( hParamIsmDec->elevation_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]] ); + azimuth[0] = (int16_t) roundf( hParamIsmDec->azimuth_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]] ); + elevation[0] = (int16_t) roundf( hParamIsmDec->elevation_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]] ); #endif - power_ratio[0] = hParamIsmDec->power_ratios[band_idx][0][0]; + power_ratio[0] = hParamIsmDec->power_ratios[band_idx][0][0]; #ifdef OBJ_EDITING_API - azimuth[1] = (int16_t) roundf( hParamIsmDec->edited_azimuth_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]] ); - elevation[1] = (int16_t) roundf( hParamIsmDec->edited_elevation_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]] ); + azimuth[1] = (int16_t) roundf( hParamIsmDec->edited_azimuth_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]] ); + elevation[1] = (int16_t) roundf( hParamIsmDec->edited_elevation_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]] ); #else - azimuth[1] = (int16_t) roundf( hParamIsmDec->azimuth_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]] ); - elevation[1] = (int16_t) roundf( hParamIsmDec->elevation_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]] ); + azimuth[1] = (int16_t) roundf( hParamIsmDec->azimuth_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]] ); + elevation[1] = (int16_t) roundf( hParamIsmDec->elevation_values[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]] ); #endif - power_ratio[1] = hParamIsmDec->power_ratios[band_idx][0][1]; - - for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) - { - for ( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ ) - { - hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0]; - hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0]; - hSpatParamRendCom->energy_ratio1[sf_idx][bin_idx] = power_ratio[0]; - hSpatParamRendCom->azimuth2[sf_idx][bin_idx] = azimuth[1]; - hSpatParamRendCom->elevation2[sf_idx][bin_idx] = elevation[1]; - hSpatParamRendCom->energy_ratio2[sf_idx][bin_idx] = power_ratio[1]; - } - } - } + power_ratio[1] = hParamIsmDec->power_ratios[band_idx][0][1]; for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) { - for ( bin_idx = 0; bin_idx < nBins; bin_idx++ ) + for ( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ ) { - hSpatParamRendCom->spreadCoherence[sf_idx][bin_idx] = 0.0f; - hSpatParamRendCom->spreadCoherence2[sf_idx][bin_idx] = 0.0f; - hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx] = 0.0; + hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0]; + hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0]; + hSpatParamRendCom->energy_ratio1[sf_idx][bin_idx] = power_ratio[0]; + hSpatParamRendCom->azimuth2[sf_idx][bin_idx] = azimuth[1]; + hSpatParamRendCom->elevation2[sf_idx][bin_idx] = elevation[1]; + hSpatParamRendCom->energy_ratio2[sf_idx][bin_idx] = power_ratio[1]; } } } - } - else - { - hSpatParamRendCom->numSimultaneousDirections = 1; - azimuth[0] = (int16_t) roundf( hParamIsmDec->azimuth_values[0] ); - elevation[0] = (int16_t) roundf( hParamIsmDec->elevation_values[0] ); for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) { for ( bin_idx = 0; bin_idx < nBins; bin_idx++ ) { - hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0]; - hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0]; - hSpatParamRendCom->energy_ratio1[sf_idx][bin_idx] = 1.0f; hSpatParamRendCom->spreadCoherence[sf_idx][bin_idx] = 0.0f; + hSpatParamRendCom->spreadCoherence2[sf_idx][bin_idx] = 0.0f; hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx] = 0.0; } } +#ifdef OBJ_EDITING_PARAMISM_BIN + for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) + { + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + hMasaIsmData->azimuth_ism[obj][sf_idx] = (int16_t) roundf( hParamIsmDec->azimuth_values[obj] ); + hMasaIsmData->elevation_ism[obj][sf_idx] = (int16_t) roundf( hParamIsmDec->elevation_values[obj] ); + } + + hMasaIsmData->azimuth_ism_edited[obj] = (int16_t) roundf( hParamIsmDec->edited_azimuth_values[obj] ); + hMasaIsmData->elevation_ism_edited[obj] = (int16_t) roundf( hParamIsmDec->edited_elevation_values[obj] ); + + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + set_zero( hMasaIsmData->energy_ratio_ism[obj][sf_idx], CLDFB_NO_CHANNELS_MAX ); + } + } + + for ( obj = 0; obj < MAX_PARAM_ISM_WAVE; obj++ ) + { + for ( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ ) + { + brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx]; + brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1]; + + obj_idx = hParamIsmDec->hParamIsm->obj_indices[band_idx][0][obj]; + power_ratio[obj] = hParamIsmDec->power_ratios[band_idx][0][obj]; + + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + for ( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ ) + { + hMasaIsmData->energy_ratio_ism[obj_idx][sf_idx][bin_idx] = power_ratio[obj]; + } + } + } + } +#endif } return; diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 5da61d4f26cce7488e856c9445d34d8352ff8937..81bfa29b9f9063730358ccbafccb08bccfbd7774 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -538,13 +538,39 @@ void ivas_omasa_separate_object_render_jbm( if ( single_separated ) { +#ifdef OMASA_OBJECT_EDITING + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && st_ivas->hMasaIsmData->ism_dir_is_edited[st_ivas->hMasaIsmData->idx_separated_ism] ) + { + azimuth = st_ivas->hMasaIsmData->azimuth_ism_edited[st_ivas->hMasaIsmData->idx_separated_ism]; + elevation = st_ivas->hMasaIsmData->elevation_ism_edited[st_ivas->hMasaIsmData->idx_separated_ism]; + } + else + { + azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[md_idx]; + elevation = st_ivas->hMasaIsmData->elevation_separated_ism[md_idx]; + } +#else azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[md_idx]; elevation = st_ivas->hMasaIsmData->elevation_separated_ism[md_idx]; +#endif } else { +#ifdef OMASA_OBJECT_EDITING + if ( st_ivas->hMasaIsmData->ism_dir_is_edited[obj] ) + { + azimuth = st_ivas->hMasaIsmData->azimuth_ism_edited[obj]; + elevation = st_ivas->hMasaIsmData->elevation_ism_edited[obj]; + } + else + { + azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][md_idx]; + elevation = st_ivas->hMasaIsmData->elevation_ism[obj][md_idx]; + } +#else azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][md_idx]; elevation = st_ivas->hMasaIsmData->elevation_ism[obj][md_idx]; +#endif } if ( st_ivas->hOutSetup.is_planar_setup ) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index b1b9365ccc88cb61cf95fd69fdcfb95b2620eca6..b50829f879077329035e0af906a6bf28302b4221 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -3198,7 +3198,19 @@ void ivas_jbm_dec_prepare_renderer( { if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) { +#ifdef OMASA_OBJECT_EDITING + float gainIsm; + gainIsm = OMASA_TDREND_MATCHING_GAIN; + + if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] ) + { + gainIsm *= st_ivas->hMasaIsmData->gain_ism_edited[n]; + } + + v_multc( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], gainIsm, st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available ); +#else v_multc( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], OMASA_TDREND_MATCHING_GAIN, st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available ); +#endif } #ifndef TMP_FIX_OMASA_SR_BE if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) @@ -3207,6 +3219,21 @@ void ivas_jbm_dec_prepare_renderer( delay_signal( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); } } +#ifdef OMASA_OBJECT_EDITING + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) + { + int16_t tcBufferSize; + tcBufferSize = st_ivas->hSpatParamRendCom->num_slots * st_ivas->hSpatParamRendCom->slot_size; + + if ( st_ivas->hMasaIsmData->masa_gain_is_edited ) + { + for ( int16_t ch = 0; ch < 2; ch++ ) + { + v_multc( st_ivas->hTcBuffer->tc[ch], st_ivas->hMasaIsmData->gain_masa_edited, st_ivas->hTcBuffer->tc[ch], tcBufferSize ); + } + } + } +#endif } } } diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 9a735566a9bfbd2c758dc83bdc9ecb5950055858..6b15e367b7a17c3268372ef53cce99956787c1cd 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -641,7 +641,11 @@ ivas_error ivas_masa_dec_open( ism_total_brate = 0; /* ISM metadata */ +#ifdef OMASA_OBJECT_EDITING + if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hIsmMetaData[0] != NULL ) +#else if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hIsmMetaData[0] != NULL && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) +#endif { /* these are not needed -> clean. EXT metafile writer in OMASA needs only the number of ISMs and writes default null-data */ ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 ); @@ -2448,6 +2452,9 @@ static int16_t ivas_decode_masaism_metadata( for ( obj = 0; obj < nchan_ism; obj++ ) { +#ifdef OMASA_OBJECT_EDITING + hMasaIsmData->bits_ism[obj] = bits_ism[obj]; +#endif index = 0; if ( bits_ism[obj] < 8 ) /* if low resolution, can look to the past */ { diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index ad22f26478b89ae4b010f28322fbf828bc742759..a0b356649a8c39063d877e2dc1cd1469f356894d 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1354,7 +1354,6 @@ void ivas_param_mc_dec_digest_tc( float cx_next_band[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; float cx_imag_next_band[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; float real_part, imag_part; - /* format converter */ int16_t channel_active[MAX_OUTPUT_CHANNELS]; IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 4f53f0634ed2004f7958291c0da16792c246234d..548f1fd61a0da26149f8decf2461084c4542a2a2 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -61,7 +61,11 @@ ivas_error ivas_omasa_data_open( ) { MASA_ISM_DATA_HANDLE hMasaIsmData; +#ifdef OMASA_OBJECT_EDITING + int16_t ch; +#else int16_t ch, bin; +#endif int16_t sf, obj_idx; if ( ( hMasaIsmData = (MASA_ISM_DATA_HANDLE) malloc( sizeof( MASA_ISM_DATA ) ) ) == NULL ) @@ -69,6 +73,23 @@ ivas_error ivas_omasa_data_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM data\n" ) ); } +#ifdef OMASA_OBJECT_EDITING + for ( int16_t band_idx = 0; band_idx < MASA_FREQUENCY_BANDS; band_idx++ ) + { + for ( ch = 0; ch < 2; ch++ ) + { + hMasaIsmData->ismPreprocMatrix[ch][ch][band_idx] = 1.0f; + hMasaIsmData->ismPreprocMatrix[1 - ch][ch][band_idx] = 0.0f; + hMasaIsmData->eneMoveIIR[ch][band_idx] = 0.0f; + hMasaIsmData->enePreserveIIR[ch][band_idx] = 0.0f; + } + hMasaIsmData->eneOrigIIR[band_idx] = 0.0f; + hMasaIsmData->preprocEneTarget[band_idx] = 0.0f; + hMasaIsmData->preprocEneRealized[band_idx] = 0.0f; + } + + hMasaIsmData->objectsEdited = 0; +#else for ( bin = 0; bin < CLDFB_NO_CHANNELS_MAX; bin++ ) { for ( ch = 0; ch < 2; ch++ ) @@ -83,14 +104,24 @@ ivas_error ivas_omasa_data_open( } hMasaIsmData->objectsMoved = 0; +#endif hMasaIsmData->delayBuffer = NULL; for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ ) { +#ifdef OMASA_OBJECT_EDITING + hMasaIsmData->ism_dir_is_edited[ch] = 0; + hMasaIsmData->ism_gain_is_edited[ch] = 0; +#else hMasaIsmData->ism_is_edited[ch] = 0; +#endif hMasaIsmData->q_elevation_old[ch] = 0.0f; hMasaIsmData->q_azimuth_old[ch] = 0.0f; } +#ifdef OMASA_OBJECT_EDITING + hMasaIsmData->masa_gain_is_edited = 0; + hMasaIsmData->idx_separated_ism = -1; +#endif for ( obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ ) { @@ -189,7 +220,11 @@ ivas_error ivas_omasa_dec_config( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { +#ifdef OMASA_OBJECT_EDITING + int16_t k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old; +#else int16_t k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old, n_MD; +#endif int32_t ivas_total_brate, ism_total_brate, cpe_brate; ISM_MODE ism_mode_old; IVAS_FORMAT ivas_format_orig; @@ -281,6 +316,22 @@ ivas_error ivas_omasa_dec_config( if ( ism_mode_old != st_ivas->ism_mode ) { /* ISM MD reconfig. */ +#ifdef OMASA_OBJECT_EDITING + if ( st_ivas->hIsmMetaData[0] == NULL ) + { + if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + for ( k = 0; k < st_ivas->nchan_ism; k++ ) + { + ivas_ism_reset_metadata_handle_dec( st_ivas->hIsmMetaData[k] ); + } + } +#else n_MD = 0; if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -330,6 +381,7 @@ ivas_error ivas_omasa_dec_config( ivas_ism_metadata_close( st_ivas->hIsmMetaData, n_MD ); } +#endif st_ivas->hCPE[0]->element_brate = ivas_total_brate - ism_total_brate; @@ -695,16 +747,45 @@ void ivas_omasa_dirac_rend_jbm( if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { - mvr2r( &output_f[CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[0], *nSamplesRendered ); + +#ifdef OMASA_OBJECT_EDITING + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + /* Gain separated object, if edited */ + for ( n = 0; n < st_ivas->nchan_ism; n++ ) + { + if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] && st_ivas->hMasaIsmData->idx_separated_ism == n ) + { + v_multc( data_separated_objects[0], st_ivas->hMasaIsmData->gain_ism_edited[n], data_separated_objects[0], *nSamplesRendered ); + } + } + } +#endif } else { for ( n = 0; n < st_ivas->nchan_ism; n++ ) { - mvr2r( &output_f[n + CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[n], *nSamplesRendered ); +#ifdef OMASA_OBJECT_EDITING + /* Gain discrete objects, if edited */ + if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] ) + { + v_multc( data_separated_objects[n], st_ivas->hMasaIsmData->gain_ism_edited[n], data_separated_objects[n], *nSamplesRendered ); + } +#endif } +#ifdef OMASA_OBJECT_EDITING + /* Gain MASA part, if edited */ + if ( st_ivas->hMasaIsmData->masa_gain_is_edited ) + { + for ( int16_t ch = 0; ch < 2; ch++ ) + { + v_multc( output_f[ch], st_ivas->hMasaIsmData->gain_masa_edited, output_f[ch], *nSamplesRendered ); + } + } +#endif } } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 5181416cc699808704aa2c6a59a98fb7eedfc63c..94bf01e09f20b121d8bd6f5075d1bb8fd1493987 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -908,12 +908,23 @@ typedef struct ivas_masa_ism_data_structure int16_t azimuth_ism_edited[MAX_NUM_OBJECTS]; int16_t elevation_ism_edited[MAX_NUM_OBJECTS]; +#ifdef OMASA_OBJECT_EDITING + uint8_t ism_dir_is_edited[MAX_NUM_OBJECTS]; +#else uint8_t ism_is_edited[MAX_NUM_OBJECTS]; +#endif #ifdef OBJ_EDITING_API float gain_ism[MAX_NUM_OBJECTS]; float gain_masa; #endif +#ifdef OMASA_OBJECT_EDITING + float gain_ism_edited[MAX_NUM_OBJECTS]; + uint8_t ism_gain_is_edited[MAX_NUM_OBJECTS]; + float gain_masa_edited; + uint8_t masa_gain_is_edited; +#endif + int16_t idx_separated_ism; int16_t azimuth_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; int16_t elevation_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; @@ -921,12 +932,23 @@ typedef struct ivas_masa_ism_data_structure float q_azimuth_old[MAX_NUM_OBJECTS]; float q_elevation_old[MAX_NUM_OBJECTS]; +#ifdef OMASA_OBJECT_EDITING + uint8_t objectsEdited; + float preprocEneTarget[MASA_FREQUENCY_BANDS]; + float preprocEneRealized[MASA_FREQUENCY_BANDS]; + float ismPreprocMatrix[2][2][MASA_FREQUENCY_BANDS]; + float eneMoveIIR[2][MASA_FREQUENCY_BANDS]; + float enePreserveIIR[2][MASA_FREQUENCY_BANDS]; + float eneOrigIIR[MASA_FREQUENCY_BANDS]; + int16_t bits_ism[MAX_NUM_OBJECTS]; +#else float ismPreprocMatrix[2][2][CLDFB_NO_CHANNELS_MAX]; uint8_t objectsMoved; float eneMoveIIR[2][CLDFB_NO_CHANNELS_MAX]; float enePreserveIIR[2][CLDFB_NO_CHANNELS_MAX]; float preprocEneTarget[CLDFB_NO_CHANNELS_MAX]; float preprocEneRealized[CLDFB_NO_CHANNELS_MAX]; +#endif float **delayBuffer; int16_t delayBuffer_size; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index a6d119486bd6f42919467e04376cc12a7d546cff..8f7c9525201518ecf2726c488046176565c05bbb 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -38,6 +38,9 @@ #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "isar_prot.h" +#ifdef OMASA_OBJECT_EDITING +#include "ivas_rom_com.h" +#endif #include "lib_isar_pre_rend.h" #include "prot.h" #include "jbm_jb4sb.h" @@ -1275,7 +1278,11 @@ ivas_error IVAS_DEC_GetSamplesDecoder( { if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT ) { +#ifdef OMASA_OBJECT_EDITING + if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_DISC || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) +#else if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_DISC || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC || hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) +#endif { int16_t obj; ISM_METADATA_HANDLE *hIsmMetaData = hIvasDec->st_ivas->hIsmMetaData; @@ -1329,6 +1336,9 @@ ivas_error IVAS_DEC_GetEditableParameters( int16_t obj; Decoder_Struct *st_ivas; ISM_MODE ism_mode; +#ifdef OMASA_OBJECT_EDITING + int16_t dirac_read_idx; +#endif if ( hIvasEditableParameters == NULL || hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { @@ -1393,6 +1403,55 @@ ivas_error IVAS_DEC_GetEditableParameters( assert( 0 && "This should never happen!" ); } } +#ifdef OMASA_OBJECT_EDITING + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + /* object editing possible only in two highest OMASA modes */ + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + + /* reset the otherwise unused "gain" field for the object */ + st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + } + else + { + /* Handle MONO output */ + if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; + } + else + { + dirac_read_idx = 0; + } + + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; + + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + + /* reset the otherwise unused "gain" field for the object */ + st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + } + } +#endif return IVAS_ERR_OK; } @@ -1411,6 +1470,9 @@ ivas_error IVAS_DEC_SetEditableParameters( int16_t obj; Decoder_Struct *st_ivas; ISM_MODE ism_mode; +#ifdef OMASA_OBJECT_EDITING + int16_t dirac_read_idx; +#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { @@ -1466,13 +1528,162 @@ ivas_error IVAS_DEC_SetEditableParameters( { for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) { +#ifdef OBJ_EDITING_PARAMISM_BIN + st_ivas->hParamIsmDec->edited_azimuth_values[obj] = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hParamIsmDec->edited_elevation_values[obj] = hIvasEditableParameters.ism_metadata[obj].elevation; + st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + + /* Detect direction editing in Param-ISM mode */ + if ( fabsf( st_ivas->hParamIsmDec->azimuth_values[obj] - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( st_ivas->hParamIsmDec->elevation_values[obj] - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } + + /* Detect gain editing in Param-ISM mode */ + if ( fabsf( 1.0f - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; + } +#endif } +#ifdef OBJ_EDITING_PARAMISM_BIN + /* MASA is not present with the ISM format */ + st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; +#endif } else { assert( 0 && "This should never happen!" ); } } +#ifdef OMASA_OBJECT_EDITING + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + int32_t id_th; + float threshold_azi, threshold_ele; + + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + if ( st_ivas->hMasaIsmData != NULL ) + { + /* copy relevant fields also to OMASA structs, but only if the value has been changed. original values are in st_ivas->hIsmMetaData */ + /* first, need to convert float values to ints used internally */ + int16_t new_azi, new_ele; + if ( hIvasEditableParameters.ism_metadata[obj].azimuth > 0.0f ) + { + new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth + 0.5f ); + } + else + { + new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth - 0.5f ); + } + + if ( hIvasEditableParameters.ism_metadata[obj].elevation > 0.0f ) + { + new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation + 0.5f ); + } + else + { + new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation - 0.5f ); + } + + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + /* Handle MONO output */ + if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; + } + else + { + dirac_read_idx = 0; + } + + /* determine thresholds for detecting object metadata edit for direction based on quantization resolution of the spatial direction parameters. + * these depend from the number of bits used to transmit the directions, + * which in turn depends from the object priority and importance: + * importance -> priority -> number of bits -> elevation resolution -> elevation ring index -> azimuth resolution. + * leading to elevation_resolution -> elevation threshold and azimuth resolution -> azimuth threshold */ + id_th = (int) ( fabsf( (float) st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); + threshold_azi = 360.0f / (float) no_phi_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 1][id_th]; + threshold_ele = delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3]; + + if ( ( (float) abs( new_azi - st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx] ) > threshold_azi ) || + ( (float) abs( new_ele - st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) > threshold_ele ) ) + { + /* at least one of the threshold is exceeded, so use new direction value and set editing detection flag */ + st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } + } + else + { + /* detect editing in ISM_MASA_MODE_DISC. optionally, add quantization-resolution -based thresholds */ + if ( fabsf( st_ivas->hIsmMetaData[obj]->azimuth - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( st_ivas->hIsmMetaData[obj]->elevation - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + { + st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } + } + + /* compare pre-edit gain and the edited one to detect editing */ + if ( fabsf( st_ivas->hIsmMetaData[obj]->edited_gain - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + } + else + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; + } + } + + /* Copy edited values to hIsmMetaData struct */ + if ( st_ivas->hIsmMetaData[obj] != NULL ) + { + st_ivas->hIsmMetaData[obj]->azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hIsmMetaData[obj]->elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + st_ivas->hIsmMetaData[obj]->yaw = hIvasEditableParameters.ism_metadata[obj].yaw; + st_ivas->hIsmMetaData[obj]->pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + st_ivas->hIsmMetaData[obj]->radius = hIvasEditableParameters.ism_metadata[obj].radius; + st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; + } + } + + if ( fabsf( hIvasEditableParameters.gain_bed - 1.0f ) > OMASA_GAIN_EDIT_THR ) + { + st_ivas->hMasaIsmData->gain_masa_edited = hIvasEditableParameters.gain_bed; + st_ivas->hMasaIsmData->masa_gain_is_edited = 1u; + } + else + { + st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; + } + } +#endif return IVAS_ERR_OK; } @@ -1809,7 +2020,6 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( return error; } #endif - numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; #ifdef OBJ_EDITING_API @@ -2455,6 +2665,7 @@ ivas_error IVAS_DEC_GetObjectMetadata( metadata->gainFactor = hIsmMeta->edited_gain; metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; } +#ifdef OBJ_EDITING_API else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { metadata->azimuth = st_ivas->hParamIsmDec->edited_azimuth_values[objectIdx]; @@ -2466,6 +2677,7 @@ ivas_error IVAS_DEC_GetObjectMetadata( metadata->gainFactor = 1.f; metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; } +#endif else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { metadata->azimuth = st_ivas->hIsmMetaData[objectIdx]->edited_azimuth; diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 146f5772ac9624bf373794745aa31266d5549f86..28f6b60a51b016a87737eb1e5fe617b036cbb86d 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -736,10 +736,21 @@ static void ivas_dirac_dec_binaural_internal( ivas_sba_prototype_renderer( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe ); } +#ifdef OMASA_OBJECT_EDITING +#ifdef OBJ_EDITING_PARAMISM_BIN + if ( ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) ) ) ) || st_ivas->ivas_format == ISM_FORMAT ) +#else + if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) ) ) ) +#endif + { + ivas_omasa_preProcessStereoTransportsForEditedObjects( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, subframe ); + } +#else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && nchan_transport == 2 && st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) { ivas_omasa_preProcessStereoTransportsForMovedObjects( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, subframe ); } +#endif if ( hCombinedOrientationData ) { @@ -1216,11 +1227,19 @@ static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( uint16_t ismDirIndex; ismDirIndex = dirIndex - hSpatParamRendCom->numParametricDirections; assert( hMasaIsmData != NULL && "hMasaIsmData should not be NULL if we use it" ); +#ifdef OMASA_OBJECT_EDITING + if ( hMasaIsmData->ism_dir_is_edited[ismDirIndex] ) + { + aziDeg = hMasaIsmData->azimuth_ism_edited[ismDirIndex]; + eleDeg = hMasaIsmData->elevation_ism_edited[ismDirIndex]; + } +#else if ( hMasaIsmData->ism_is_edited[ismDirIndex] ) { aziDeg = hMasaIsmData->azimuth_ism_edited[ismDirIndex]; eleDeg = hMasaIsmData->elevation_ism_edited[ismDirIndex]; } +#endif else { aziDeg = hMasaIsmData->azimuth_ism[ismDirIndex][dirac_read_idx]; @@ -1654,13 +1673,39 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( { if ( ism_mode == ISM_MASA_MODE_DISC ) { +#ifdef OMASA_OBJECT_EDITING + if ( hMasaIsmData->ism_dir_is_edited[chB] ) + { + aziDeg = hMasaIsmData->azimuth_ism_edited[chB]; + eleDeg = hMasaIsmData->elevation_ism_edited[chB]; + } + else + { + aziDeg = hMasaIsmData->azimuth_ism[chB][dirac_read_idx]; + eleDeg = hMasaIsmData->elevation_ism[chB][dirac_read_idx]; + } +#else aziDeg = hMasaIsmData->azimuth_ism[chB][dirac_read_idx]; eleDeg = hMasaIsmData->elevation_ism[chB][dirac_read_idx]; +#endif } else { +#ifdef OMASA_OBJECT_EDITING + if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hMasaIsmData->ism_dir_is_edited[hMasaIsmData->idx_separated_ism] ) + { + aziDeg = hMasaIsmData->azimuth_ism_edited[hMasaIsmData->idx_separated_ism]; + eleDeg = hMasaIsmData->elevation_ism_edited[hMasaIsmData->idx_separated_ism]; + } + else + { + aziDeg = hMasaIsmData->azimuth_separated_ism[dirac_read_idx]; + eleDeg = hMasaIsmData->elevation_separated_ism[dirac_read_idx]; + } +#else aziDeg = hMasaIsmData->azimuth_separated_ism[dirac_read_idx]; eleDeg = hMasaIsmData->elevation_separated_ism[dirac_read_idx]; +#endif instantChange = 1; } } @@ -2374,7 +2419,7 @@ static void formulate2x2MixingMatrix( matrixMul( tmpRe, tmpIm, Kxre, Kxim, Are, Aim ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx - For matrix A that is P = A(A'A)^0.5 + For matrix A that is P = A(A'A)^0.5 */ matrixTransp1Mul( Are, Aim, Are, Aim, tmpRe, tmpIm ); @@ -2434,6 +2479,53 @@ static void getDirectPartGains( if ( renderStereoOutputInsteadOfBinaural ) /* In stereo (i.e. non-binaural) rendering mode */ { +#ifdef OMASA_OBJECT_EDITING + *lImagp = 0.0f; + *rImagp = 0.0f; + if ( aziDeg == gainCache->azi && eleDeg == gainCache->ele ) + { + *lRealp = gainCache->shVec[0]; /* Reused memory */ + *rRealp = gainCache->shVec[1]; /* Reused memory */ + } + else + { + /* Convert azi and ele to an azi value of the cone of confusion */ + aziRad = (float) aziDeg * PI_OVER_180; + eleRad = (float) eleDeg * PI_OVER_180; + y = ( sinf( aziRad ) * cosf( eleRad ) ); + mappedX = sqrtf( max( 0.0f, 1.0f - ( y * y ) ) ); + aziRadMapped = atan2f( y, mappedX ); + + /* Determine the real valued amplitude panning gains */ + if ( aziRadMapped >= LsAngleRad ) + { /* Left side */ + *lRealp = 1.0f; + *rRealp = 0.0f; + } + else if ( aziRadMapped <= -LsAngleRad ) + { /* Right side */ + *lRealp = 0.0f; + *rRealp = 1.0f; + } + else /* Tangent panning law */ + { + A = tanf( aziRadMapped ) / tanf( LsAngleRad ); + A2 = ( A - 1.0f ) / max( 0.001f, A + 1.0f ); + A3 = 1.0f / ( A2 * A2 + 1.0f ); + *lRealp = sqrtf( A3 ); + *rRealp = sqrtf( 1.0f - A3 ); + } + /* Scaling to have the same expected gain as for the HRTF rendering */ + *lRealp *= SQRT2; + *rRealp *= SQRT2; + + /* Store to gain cache */ + gainCache->azi = aziDeg; + gainCache->ele = eleDeg; + gainCache->shVec[0] = *lRealp; /* Reuse memory */ + gainCache->shVec[1] = *rRealp; /* Reuse memory */ + } +#else /* Convert azi and ele to an azi value of the cone of confusion */ aziRad = (float) aziDeg * PI_OVER_180; eleRad = (float) eleDeg * PI_OVER_180; @@ -2466,6 +2558,7 @@ static void getDirectPartGains( /* Scaling to have the same expected gain as for the HRTF rendering */ *lRealp *= SQRT2; *rRealp *= SQRT2; +#endif } else /* In regular binaural rendering mode */ { @@ -2619,6 +2712,685 @@ float configure_reqularization_factor( } +#ifdef OMASA_OBJECT_EDITING +/*-------------------------------------------------------------------* + * ivas_omasa_preProcessStereoTransportsForEditedObjects() + * + * + *-------------------------------------------------------------------*/ + +void ivas_omasa_preProcessStereoTransportsForEditedObjects( + Decoder_Struct *st_ivas, + float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + const int16_t nBins, + const int16_t subframe ) +{ + int16_t bin, ch, inCh, outCh, ismDirIndex, slot, band_idx, bin_lo, bin_hi, max_band, n_ism; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + MASA_ISM_DATA_HANDLE hMasaIsmData; +#ifdef OBJ_EDITING_PARAMISM_BIN + PARAM_ISM_DEC_HANDLE hParamIsmDec; +#endif + uint8_t enableCentering; + int16_t dirac_read_idx; + int16_t nSlots; + float panGainsOut[4][2]; + float panGainsIn[4][2]; + float panEnesOut[4][2]; + float panEnesIn[4][2]; + uint8_t ismGainEdited[4]; + uint8_t ismDirEdited[4]; + uint8_t masaGainEdited; +#ifdef OBJ_EDITING_PARAMISM_BIN + uint8_t masaIsmMode; +#endif + + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + hMasaIsmData = st_ivas->hMasaIsmData; +#ifdef OBJ_EDITING_PARAMISM_BIN + hParamIsmDec = st_ivas->hParamIsmDec; + + if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + masaIsmMode = 1u; + } + else + { + masaIsmMode = 0u; + } +#endif + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA3 ) + { + enableCentering = 0; + } + else + { + enableCentering = 1; + } + +#ifdef OBJ_EDITING_PARAMISM_BIN + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ivas_format == ISM_FORMAT ) +#else + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) +#endif + { + n_ism = st_ivas->nchan_ism; + } + else + { + n_ism = hSpatParamRendCom->numIsmDirections; + } + + for ( ismDirIndex = 0; ismDirIndex < n_ism; ismDirIndex++ ) + { + ismGainEdited[ismDirIndex] = hMasaIsmData->ism_gain_is_edited[ismDirIndex]; + ismDirEdited[ismDirIndex] = hMasaIsmData->ism_dir_is_edited[ismDirIndex]; + } + masaGainEdited = hMasaIsmData->masa_gain_is_edited; + + /* Bypass processing until first object is moved or gained */ + if ( hMasaIsmData->objectsEdited == 0 ) + { + for ( ismDirIndex = 0; ismDirIndex < n_ism; ismDirIndex++ ) + { + if ( ismDirEdited[ismDirIndex] ) + { + hMasaIsmData->objectsEdited = 1; + } + + if ( ismGainEdited[ismDirIndex] ) + { + hMasaIsmData->objectsEdited = 1; + } + } + + if ( masaGainEdited ) + { + hMasaIsmData->objectsEdited = 1; + } + + if ( hMasaIsmData->objectsEdited == 0 ) + { + /* No objects have moved so far */ + return; + } + } + + /* OMASA gaining for discrete OMASA mode with stereo_param/bin_room_param renderer */ + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + /* ISM gaining */ + for ( ch = 0; ch < n_ism; ch++ ) + { + if ( st_ivas->hMasaIsmData->ism_gain_is_edited[ch] ) + { + for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) + { + float gain; + gain = st_ivas->hMasaIsmData->gain_ism_edited[ch]; + v_multc( inRe[ch + 2][slot], gain, inRe[ch + 2][slot], nBins ); + v_multc( inIm[ch + 2][slot], gain, inIm[ch + 2][slot], nBins ); + } + } + } + + /* MASA gaining */ + for ( ch = 0; ch < 2; ch++ ) + { + if ( masaGainEdited ) + { + for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) + { + float gain_masa; + gain_masa = st_ivas->hMasaIsmData->gain_masa_edited; + v_multc( inRe[ch][slot], gain_masa, inRe[ch][slot], nBins ); + v_multc( inIm[ch][slot], gain_masa, inIm[ch][slot], nBins ); + } + } + } + } +#ifdef OBJ_EDITING_PARAMISM_BIN + else if ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->hISMDTX.dtx_flag ) /* If dtx on, perform just the smoothing of the processing gains */ + { + float totalTargetEne; + float ismPreprocMtxNew[2][2]; + float ismPreprocMtxIncrement[2][2]; + float nSlotDiv; + float outSlotRe[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float outSlotIm[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float eqVal; + + nSlots = hSpatParamRendCom->subframe_nbslots[subframe]; + nSlotDiv = 1.0f / ( (float) nSlots ); + + /* Use diagonal mixing matrix as the instant mixing matrix, to slowly fade away the editing during dtx */ + for ( ch = 0; ch < 2; ch++ ) + { + ismPreprocMtxNew[ch][ch] = 1.0f; + ismPreprocMtxNew[1 - ch][ch] = 0.0f; + } + + /* Determine the highest band */ + max_band = 0; + while ( max_band < MAX_PARAM_ISM_NBANDS && hParamIsmDec->hParamIsm->band_grouping[max_band] < nBins ) + { + max_band++; + } + + /* Init out array */ + for ( int k = 0; k < nSlots; k++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + set_zero( outSlotRe[ch][k], CLDFB_NO_CHANNELS_MAX ); + set_zero( outSlotIm[ch][k], CLDFB_NO_CHANNELS_MAX ); + } + } + + /* Perform the processing in frequency bands */ + for ( band_idx = 0; band_idx < max_band; band_idx++ ) + { + bin_lo = hParamIsmDec->hParamIsm->band_grouping[band_idx]; + bin_hi = min( hParamIsmDec->hParamIsm->band_grouping[band_idx + 1], nBins ); + + /* Determine transport energies */ + totalTargetEne = 0.0f; + for ( slot = 0; slot < nSlots; slot++ ) + { + for ( ch = 0; ch < 2; ch++ ) + { + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + totalTargetEne += inRe[ch][slot][bin] * inRe[ch][slot][bin]; + totalTargetEne += inIm[ch][slot][bin] * inIm[ch][slot][bin]; + } + } + } + + /* Get increment value for temporal interpolation */ + for ( inCh = 0; inCh < 2; inCh++ ) + { + for ( outCh = 0; outCh < 2; outCh++ ) + { + ismPreprocMtxIncrement[outCh][inCh] = ( ismPreprocMtxNew[outCh][inCh] - hMasaIsmData->ismPreprocMatrix[outCh][inCh][band_idx] ) * nSlotDiv; + } + } + + /* Mix signals */ + hMasaIsmData->preprocEneTarget[band_idx] *= STEREO_PREPROCESS_IIR_FACTOR; + hMasaIsmData->preprocEneRealized[band_idx] *= STEREO_PREPROCESS_IIR_FACTOR; + hMasaIsmData->preprocEneTarget[band_idx] += totalTargetEne; + + for ( outCh = 0; outCh < 2; outCh++ ) + { + for ( slot = 0; slot < nSlots; slot++ ) + { + for ( inCh = 0; inCh < 2; inCh++ ) + { + hMasaIsmData->ismPreprocMatrix[outCh][inCh][band_idx] += ismPreprocMtxIncrement[outCh][inCh]; + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + outSlotRe[outCh][slot][bin] += inRe[inCh][slot][bin] * hMasaIsmData->ismPreprocMatrix[outCh][inCh][band_idx]; + outSlotIm[outCh][slot][bin] += inIm[inCh][slot][bin] * hMasaIsmData->ismPreprocMatrix[outCh][inCh][band_idx]; + } + } + + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + hMasaIsmData->preprocEneRealized[band_idx] += ( outSlotRe[outCh][slot][bin] * outSlotRe[outCh][slot][bin] ) + ( outSlotIm[outCh][slot][bin] * outSlotIm[outCh][slot][bin] ); + } + } + } + + eqVal = fminf( 4.0f, sqrtf( hMasaIsmData->preprocEneTarget[band_idx] / fmaxf( 1e-12f, hMasaIsmData->preprocEneRealized[band_idx] ) ) ); + + for ( ch = 0; ch < 2; ch++ ) + { + for ( slot = 0; slot < nSlots; slot++ ) + { + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + inRe[ch][slot][bin] = outSlotRe[ch][slot][bin] * eqVal; + inIm[ch][slot][bin] = outSlotIm[ch][slot][bin] * eqVal; + } + } + } + } + } +#endif + else /* Other processing modes */ + { + float subframeEne; + float subframeEneCh[2]; + float normEnes[2]; + float ratioAccOrig; + float ratioAccNew; + float ratio; + float ismEneThis; + float ismTargetEneThis; + float ismTargetEneThisCh[2]; + float totalTargetEneCh[2]; + float totalTargetEne; + float masaTargetEneThisCh[2]; + float ismPreprocMtxNew[2][2]; + float ismPreprocMtxIncrement[2][2]; + float eneMove[2]; + float enePreserve[2]; + float ismRatioAcc; + float remainderNormEne; + float centeringFactor; + float eneMoveThis; + float enePreserveThis; + float normVal; + float eqVal; + float outSlotRe[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float outSlotIm[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float newRatios[6]; + float gainIsmThis; + float gainMasaPow2; + float nSlotDiv; + float tempDivisor; + float masaEneThisCh[2]; + float ratioAccNewDivisor; + + + gainMasaPow2 = 1.0f; + if ( masaGainEdited ) + { + gainMasaPow2 = hMasaIsmData->gain_masa_edited; + gainMasaPow2 *= gainMasaPow2; + } + + nSlots = hSpatParamRendCom->subframe_nbslots[subframe]; + dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe]; + nSlotDiv = 1.0f / ( (float) nSlots ); + + /* Determine panning gains and energies for each object */ + for ( ismDirIndex = 0; ismDirIndex < n_ism; ismDirIndex++ ) + { + /* Get input and output panning gains */ + ivas_get_stereo_panning_gains( hMasaIsmData->azimuth_ism[ismDirIndex][dirac_read_idx], + hMasaIsmData->elevation_ism[ismDirIndex][dirac_read_idx], + panGainsIn[ismDirIndex] ); + + if ( ismDirEdited[ismDirIndex] ) + { + ivas_get_stereo_panning_gains( hMasaIsmData->azimuth_ism_edited[ismDirIndex], + hMasaIsmData->elevation_ism_edited[ismDirIndex], + panGainsOut[ismDirIndex] ); + } + else + { + /* When not edited, input and output pan gains are the same */ + for ( ch = 0; ch < 2; ch++ ) + { + panGainsOut[ismDirIndex][ch] = panGainsIn[ismDirIndex][ch]; + } + } + /* Determine pan enes */ + for ( ch = 0; ch < 2; ch++ ) + { + panEnesOut[ismDirIndex][ch] = panGainsOut[ismDirIndex][ch] * panGainsOut[ismDirIndex][ch]; + panEnesIn[ismDirIndex][ch] = panGainsIn[ismDirIndex][ch] * panGainsIn[ismDirIndex][ch]; + } + } + + /* Determine the highest band */ + max_band = 0; +#ifdef OBJ_EDITING_PARAMISM_BIN + if ( masaIsmMode ) + { +#endif + while ( max_band < MASA_FREQUENCY_BANDS && MASA_band_grouping_24[max_band] < nBins ) + { + max_band++; + } +#ifdef OBJ_EDITING_PARAMISM_BIN + } + else + { + while ( max_band < MAX_PARAM_ISM_NBANDS && hParamIsmDec->hParamIsm->band_grouping[max_band] < nBins ) + { + max_band++; + } + } +#endif + + /* Init out array */ + for ( int k = 0; k < nSlots; k++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + set_zero( outSlotRe[ch][k], CLDFB_NO_CHANNELS_MAX ); + set_zero( outSlotIm[ch][k], CLDFB_NO_CHANNELS_MAX ); + } + } + + /* Perform the processing in frequency bands */ + for ( band_idx = 0; band_idx < max_band; band_idx++ ) + { + ratioAccOrig = 0.0f; + ratioAccNew = 0.0f; + ismRatioAcc = 0.0f; + + set_zero( subframeEneCh, 2 ); + set_zero( ismPreprocMtxNew[0], 2 ); + set_zero( ismPreprocMtxNew[1], 2 ); + set_zero( eneMove, 2 ); + set_zero( enePreserve, 2 ); +#ifdef OBJ_EDITING_PARAMISM_BIN + if ( masaIsmMode ) + { +#endif + bin_lo = MASA_band_grouping_24[band_idx]; + bin_hi = min( MASA_band_grouping_24[band_idx + 1], nBins ); +#ifdef OBJ_EDITING_PARAMISM_BIN + } + else + { + bin_lo = hParamIsmDec->hParamIsm->band_grouping[band_idx]; + bin_hi = min( hParamIsmDec->hParamIsm->band_grouping[band_idx + 1], nBins ); + } +#endif + + /* Determine transport normalized energies and subframe energy */ + for ( slot = 0; slot < nSlots; slot++ ) + { + for ( ch = 0; ch < 2; ch++ ) + { + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + subframeEneCh[ch] += inRe[ch][slot][bin] * inRe[ch][slot][bin]; + subframeEneCh[ch] += inIm[ch][slot][bin] * inIm[ch][slot][bin]; + } + } + } + subframeEne = subframeEneCh[0] + subframeEneCh[1]; + totalTargetEneCh[0] = subframeEneCh[0]; + totalTargetEneCh[1] = subframeEneCh[1]; + masaEneThisCh[0] = subframeEneCh[0]; + masaEneThisCh[1] = subframeEneCh[1]; + + /* Gain editing */ + /* For each object, estimate new target energy per channel based on the applied gain */ + for ( ismDirIndex = 0; ismDirIndex < n_ism; ismDirIndex++ ) + { + ratio = hMasaIsmData->energy_ratio_ism[ismDirIndex][dirac_read_idx][bin_lo]; + ratioAccOrig += ratio; + + /* Calculate MASA energy as a residual of original channel energies subtracted with ISM energies */ + for ( ch = 0; ch < 2; ch++ ) + { + masaEneThisCh[ch] -= panEnesIn[ismDirIndex][ch] * ratio * subframeEne; + } + + /* Calculate target energy, gained ratio for accumulation, and transports gains, if ism gain is edited */ + if ( ismGainEdited[ismDirIndex] ) + { + gainIsmThis = hMasaIsmData->gain_ism_edited[ismDirIndex]; + /* ISM original energy */ + ismEneThis = ratio * subframeEne; + + /* ISM target energy */ + ismTargetEneThis = ( gainIsmThis * gainIsmThis ) * ismEneThis; + + ratio *= gainIsmThis * gainIsmThis; + + /* Determine panning energies and channel target energies */ + for ( ch = 0; ch < 2; ch++ ) + { + ismTargetEneThisCh[ch] = panEnesIn[ismDirIndex][ch] * ismTargetEneThis; /* Ism target energy per channel */ + totalTargetEneCh[ch] -= panEnesIn[ismDirIndex][ch] * ismEneThis; /* Reduce original ism energy */ + totalTargetEneCh[ch] += ismTargetEneThisCh[ch]; /* Add ism target energy per channel */ + } + + /* If separated ism edited, apply gain directly to the separated ism */ + if ( ismDirIndex == hMasaIsmData->idx_separated_ism ) + { + /* Separated object gaining is done elsewhere with DIRAC renderer */ + if ( st_ivas->renderer_type != RENDERER_DIRAC ) + { + /* Gain transport channel of separated ism */ + for ( slot = 0; slot < nSlots; slot++ ) + { + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + inRe[2][slot][bin] = gainIsmThis * inRe[2][slot][bin]; + inIm[2][slot][bin] = gainIsmThis * inIm[2][slot][bin]; + } + } + } + } + } + ratioAccNew += ratio; + } + +#ifdef OBJ_EDITING_PARAMISM_BIN + if ( masaIsmMode ) + { +#endif + /* MASA original ratios */ + ratio = hSpatParamRendCom->energy_ratio1[dirac_read_idx][bin_lo] + hSpatParamRendCom->energy_ratio2[dirac_read_idx][bin_lo]; + ratioAccOrig += ratio; + + /* Estimate MASA original energies and determine adjusted target energies and gained ratio for accumulation, if a gain is applied to MASA */ + if ( masaGainEdited ) + { + /* Gained MASA ratio */ + ratio *= gainMasaPow2; + + /* Calculate MASA target energies and add to total target energy estimation */ + for ( ch = 0; ch < 2; ch++ ) + { + masaEneThisCh[ch] = fmaxf( masaEneThisCh[ch], 0.0f ); /* MASA original energy per channel */ + masaTargetEneThisCh[ch] = gainMasaPow2 * masaEneThisCh[ch]; /* MASA target energy per channel */ + totalTargetEneCh[ch] -= masaEneThisCh[ch]; /* Reduce original energy per channel */ + totalTargetEneCh[ch] += masaTargetEneThisCh[ch]; /* Add target energy per channel */ + } + } + + ratioAccNew += ratio; +#ifdef OBJ_EDITING_PARAMISM_BIN + } +#endif + + /* Limit target energies to non-negative values */ + for ( ch = 0; ch < 2; ch++ ) + { + totalTargetEneCh[ch] = max( totalTargetEneCh[ch], 0.0f ); + } + + /* Diffuse ratio accumulation based on gaining */ + if ( masaGainEdited ) + { + ratioAccNew += gainMasaPow2 * ( 1 - ratioAccOrig ); + } + else + { + ratioAccNew += ( 1.0f - ratioAccOrig ); + } + + ratioAccNewDivisor = 1.0f / fmaxf( 1e-12f, ratioAccNew ); /* New target total energy ratio divider */ + + /* Determine and process object energy ratios based on gaining */ + for ( ismDirIndex = 0; ismDirIndex < n_ism; ismDirIndex++ ) + { + newRatios[ismDirIndex + 2] = hMasaIsmData->energy_ratio_ism[ismDirIndex][dirac_read_idx][bin_lo]; /* Determine original object energy ratio */ + if ( ismGainEdited[ismDirIndex] ) + { + gainIsmThis = hMasaIsmData->gain_ism_edited[ismDirIndex]; + newRatios[ismDirIndex + 2] *= ( gainIsmThis * gainIsmThis ); /* Gain original object energy ratio, if edited */ + } + newRatios[ismDirIndex + 2] *= ratioAccNewDivisor; /* Divide with new target total ratio */ + } + + /* Determine and process MASA energy ratios based on gaining */ + newRatios[0] = hSpatParamRendCom->energy_ratio1[dirac_read_idx][bin_lo]; + newRatios[1] = hSpatParamRendCom->energy_ratio2[dirac_read_idx][bin_lo]; + if ( masaGainEdited ) + { + newRatios[0] *= gainMasaPow2; + newRatios[1] *= gainMasaPow2; + } + newRatios[0] *= ratioAccNewDivisor; + newRatios[1] *= ratioAccNewDivisor; + + /* Set adjusted energy ratios */ + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + for ( ismDirIndex = 0; ismDirIndex < n_ism; ismDirIndex++ ) + { + hMasaIsmData->energy_ratio_ism[ismDirIndex][dirac_read_idx][bin] = newRatios[ismDirIndex + 2]; + } + hSpatParamRendCom->energy_ratio1[dirac_read_idx][bin] = newRatios[0]; + hSpatParamRendCom->energy_ratio2[dirac_read_idx][bin] = newRatios[1]; + } + + /* Direction editing */ + /* Determine new energetic values after gaining */ + totalTargetEne = totalTargetEneCh[0] + totalTargetEneCh[1]; + tempDivisor = 1.0f / fmaxf( 1e-12f, totalTargetEne ); + normEnes[0] = totalTargetEneCh[0] * tempDivisor; + normEnes[1] = totalTargetEneCh[1] * tempDivisor; + + /* For each ismDir, determine moved and preserve energy ratio per channel */ + for ( ismDirIndex = 0; ismDirIndex < n_ism; ismDirIndex++ ) + { + ratio = hMasaIsmData->energy_ratio_ism[ismDirIndex][dirac_read_idx][bin_lo]; + + ismRatioAcc += ratio; + + if ( enableCentering ) + { + centeringFactor = fmaxf( 0.0f, 2.0f * fabsf( panEnesIn[ismDirIndex][0] - panEnesOut[ismDirIndex][0] ) - 1.0f ); + for ( ch = 0; ch < 2; ch++ ) + { + panEnesOut[ismDirIndex][ch] *= ( 1.0f - centeringFactor ); + panEnesOut[ismDirIndex][ch] += 0.5f * centeringFactor; + } + } + + for ( ch = 0; ch < 2; ch++ ) + { + eneMoveThis = fmaxf( 0.0f, panEnesIn[ismDirIndex][ch] - panEnesOut[ismDirIndex][ch] ); + enePreserveThis = panEnesIn[ismDirIndex][ch] - eneMoveThis; + + eneMove[ch] += ratio * eneMoveThis; + enePreserve[ch] += ratio * enePreserveThis; + + /* Subtract object parts from normEnes */ + normEnes[ch] -= panEnesIn[ismDirIndex][ch] * ratio; + } + } + + /* Any remaining (non-object) energy is set to be preserved at both channels */ + remainderNormEne = fmaxf( 0.0f, ( 1.0f - ismRatioAcc ) - normEnes[0] - normEnes[1] ); + + /* Normalize */ + for ( ch = 0; ch < 2; ch++ ) + { + enePreserve[ch] += fmaxf( 0.0f, normEnes[ch] + remainderNormEne / 2.0f ); + normVal = 1.0f / fmaxf( EPSILON, eneMove[ch] + enePreserve[ch] ); + normVal *= fminf( 10.0f, totalTargetEneCh[ch] / fmaxf( EPSILON, subframeEneCh[ch] ) ); + eneMove[ch] *= normVal; + enePreserve[ch] *= normVal; + } + + /* Temporally average target energy */ + hMasaIsmData->eneOrigIIR[band_idx] *= STEREO_PREPROCESS_IIR_FACTOR; + hMasaIsmData->eneOrigIIR[band_idx] += totalTargetEne; + + /* Temporally average energy moving and preserving, and generate the transport signal preprocessing matrix for + * gaining objects and moving objects between left and right */ + for ( ch = 0; ch < 2; ch++ ) + { + hMasaIsmData->eneMoveIIR[ch][band_idx] *= STEREO_PREPROCESS_IIR_FACTOR; + hMasaIsmData->eneMoveIIR[ch][band_idx] += eneMove[ch] * totalTargetEne; + hMasaIsmData->enePreserveIIR[ch][band_idx] *= STEREO_PREPROCESS_IIR_FACTOR; + hMasaIsmData->enePreserveIIR[ch][band_idx] += enePreserve[ch] * totalTargetEne; + normVal = 1.0f / fmaxf( EPSILON, hMasaIsmData->eneOrigIIR[band_idx] ); + ismPreprocMtxNew[ch][ch] = fminf( 4.0f, sqrtf( hMasaIsmData->enePreserveIIR[ch][band_idx] * normVal ) ); + ismPreprocMtxNew[1 - ch][ch] = fminf( 4.0f, sqrtf( hMasaIsmData->eneMoveIIR[ch][band_idx] * normVal ) ); + } + + /* Get increment value for temporal interpolation */ + for ( inCh = 0; inCh < 2; inCh++ ) + { + for ( outCh = 0; outCh < 2; outCh++ ) + { + ismPreprocMtxIncrement[outCh][inCh] = ( ismPreprocMtxNew[outCh][inCh] - hMasaIsmData->ismPreprocMatrix[outCh][inCh][band_idx] ) * nSlotDiv; + } + } + + /* Mix signals */ + hMasaIsmData->preprocEneTarget[band_idx] *= STEREO_PREPROCESS_IIR_FACTOR; + hMasaIsmData->preprocEneRealized[band_idx] *= STEREO_PREPROCESS_IIR_FACTOR; + hMasaIsmData->preprocEneTarget[band_idx] += totalTargetEne; + + for ( outCh = 0; outCh < 2; outCh++ ) + { + for ( slot = 0; slot < nSlots; slot++ ) + { + for ( inCh = 0; inCh < 2; inCh++ ) + { + hMasaIsmData->ismPreprocMatrix[outCh][inCh][band_idx] += ismPreprocMtxIncrement[outCh][inCh]; + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + outSlotRe[outCh][slot][bin] += inRe[inCh][slot][bin] * hMasaIsmData->ismPreprocMatrix[outCh][inCh][band_idx]; + outSlotIm[outCh][slot][bin] += inIm[inCh][slot][bin] * hMasaIsmData->ismPreprocMatrix[outCh][inCh][band_idx]; + } + } + + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + hMasaIsmData->preprocEneRealized[band_idx] += ( outSlotRe[outCh][slot][bin] * outSlotRe[outCh][slot][bin] ) + ( outSlotIm[outCh][slot][bin] * outSlotIm[outCh][slot][bin] ); + } + } + } + + eqVal = fminf( 4.0f, sqrtf( hMasaIsmData->preprocEneTarget[band_idx] / fmaxf( 1e-12f, hMasaIsmData->preprocEneRealized[band_idx] ) ) ); + + for ( ch = 0; ch < 2; ch++ ) + { + for ( slot = 0; slot < nSlots; slot++ ) + { + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + inRe[ch][slot][bin] = outSlotRe[ch][slot][bin] * eqVal; + inIm[ch][slot][bin] = outSlotIm[ch][slot][bin] * eqVal; + } + } + } + } + +#ifdef OBJ_EDITING_PARAMISM_BIN + if ( !masaIsmMode ) + { + int16_t obj_idx1, obj_idx2; + + for ( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ ) + { + bin_lo = hParamIsmDec->hParamIsm->band_grouping[band_idx]; + bin_hi = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1]; + + obj_idx1 = hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]; + obj_idx2 = hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]; + + for ( bin = bin_lo; bin < bin_hi; bin++ ) + { + hSpatParamRendCom->energy_ratio1[dirac_read_idx][bin] = hMasaIsmData->energy_ratio_ism[obj_idx1][dirac_read_idx][bin]; + hSpatParamRendCom->energy_ratio2[dirac_read_idx][bin] = hMasaIsmData->energy_ratio_ism[obj_idx2][dirac_read_idx][bin]; + } + } + } +#endif + } + + return; +} +#else /*-------------------------------------------------------------------* * ivas_omasa_preProcessStereoTransportsForMovedObjects() * @@ -2843,6 +3615,7 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects( return; } +#endif static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 34103627ce5fe4502eaafef7adcdc5a9620ecef4..c925bb0e270ad064c8ad29720da341b237cb3073 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1700,10 +1700,17 @@ void ivas_dirac_dec_compute_directional_responses( for ( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ ) { +#ifdef OMASA_OBJECT_EDITING + if ( hMasaIsm->ism_dir_is_edited[dir] ) + { + ivas_dirac_dec_get_response( hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], direct_response_temp, hDirACRend->hOutSetup.ambisonics_order ); + } +#else if ( hMasaIsm->ism_is_edited[dir] ) { ivas_dirac_dec_get_response( hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], direct_response_temp, hDirACRend->hOutSetup.ambisonics_order ); } +#endif else { ivas_dirac_dec_get_response( hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], direct_response_temp, hDirACRend->hOutSetup.ambisonics_order ); @@ -1810,10 +1817,17 @@ void ivas_dirac_dec_compute_directional_responses( for ( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ ) { +#ifdef OMASA_OBJECT_EDITING + if ( hMasaIsm->ism_dir_is_edited[dir] ) + { + vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], 1 ); + } +#else if ( hMasaIsm->ism_is_edited[dir] ) { vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], 1 ); } +#endif else { vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], 1 ); diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index ff978a09ef51419062cb0682237fe3daea9ac5eb..870fa722a3648ffaf6b157584344309021e7d39e 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -571,6 +571,12 @@ ivas_error TDREND_Update_object_positions( return error; } #endif +#ifdef OBJ_EDITING_INTERFACE + if ( ( error = TDREND_MIX_SRC_SetGain( hBinRendererTd, nS, hIsmMetaData[nS]->gain ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif if ( hIsmMetaData[nS]->non_diegetic_flag ) { @@ -806,6 +812,9 @@ ivas_error ivas_td_binaural_renderer_ext( hIsmMetaData[0]->yaw = currentPos->yaw; hIsmMetaData[0]->pitch = currentPos->pitch; hIsmMetaData[0]->radius = currentPos->radius; +#ifdef OBJ_EDITING_INTERFACE + hIsmMetaData[0]->gain = 1.0f; +#endif hIsmMetaData[0]->non_diegetic_flag = currentPos->non_diegetic_flag; } diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index e41088912b56ef50d1f3cc6f2659a58dfe2a8284..f69661ba3b00b42e48aa41713c78dd98b3bc37e4 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -53,6 +53,10 @@ static void TDREND_SRC_SPATIAL_SetDirAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, static void TDREND_SRC_SPATIAL_SetDistAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DistAtten_t *DistAtten_p ); +#ifdef OBJ_EDITING_INTERFACE +static void TDREND_SRC_SPATIAL_SetGain( const TDREND_SRC_t *Src_p, const float Gain ); +#endif + static float TDREND_SRC_SPATIAL_GetDirGain( const TDREND_DirAtten_t *DirAtten_p, const float *Front_p, const float *RelPos_p ); static float TDREND_SRC_SPATIAL_GetDistGain( const TDREND_DistAtten_t *DistAtten_p, const float Dist ); @@ -129,6 +133,26 @@ ivas_error TDREND_MIX_SRC_SetDir( } +#ifdef OBJ_EDITING_INTERFACE +/*-------------------------------------------------------------------* + * TDREND_MIX_SRC_SetSourceGain() + * + * Set source gain + --------------------------------------------------------------------*/ + +ivas_error TDREND_MIX_SRC_SetGain( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const int16_t SrcInd, /* i : Source index */ + const float Gain /* i : Gain */ +) +{ + TDREND_SRC_SPATIAL_SetGain( hBinRendererTd->Sources[SrcInd], Gain ); + + return IVAS_ERR_OK; +} +#endif + + /*-------------------------------------------------------------------* * TDREND_MIX_SRC_SetDirAtten() * @@ -533,6 +557,25 @@ static void TDREND_SRC_SPATIAL_SetDistAtten( return; } + + +#ifdef OBJ_EDITING_INTERFACE +/*-------------------------------------------------------------------* + * TDREND_SRC_SPATIAL_SetGain() + * + * Set the object gain + --------------------------------------------------------------------*/ + +static void TDREND_SRC_SPATIAL_SetGain( + const TDREND_SRC_t *Src_p, /* i : Directional attenuation specification */ + const float Gain /* i : Front-pointing vector */ +) +{ + Src_p->SrcRend_p->SrcGain_p[0] = Gain; +} +#endif + + /*-------------------------------------------------------------------* * TDREND_SRC_SPATIAL_GetDirGain() * diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index eee2360fc5201b935c829d1449dde623b1c51f18..d8517c812cf89d105df3bbfe2c18c39bb1c91b5d 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -728,6 +728,14 @@ ivas_error TDREND_MIX_SRC_SetDir( const float *Vec_p /* i : Direction vector */ ); +#ifdef OBJ_EDITING_INTERFACE +ivas_error TDREND_MIX_SRC_SetGain( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const int16_t SrcInd, /* i : Source index */ + const float Gain /* i : Gain */ +); +#endif + ivas_error TDREND_MIX_SRC_SetDirAtten( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */