From 8c3578cb266c31c4bf4f41c3899f4f64e16af7c0 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 2 Oct 2025 21:02:09 +0200 Subject: [PATCH 01/14] port OBJ_EDITING_API + introduce FIX_HRTF_LOAD_API --- apps/decoder.c | 112 +++- lib_com/common_api_types.h | 12 + lib_com/ivas_ism_com.c | 11 + lib_com/ivas_prot.h | 29 + lib_com/ivas_stat_com.h | 12 + lib_com/options.h | 5 + lib_dec/ivas_dirac_dec.c | 3 + lib_dec/ivas_ism_param_dec.c | 190 ++++++ lib_dec/ivas_ism_renderer.c | 11 + lib_dec/ivas_jbm_dec.c | 253 ++++++- lib_dec/ivas_mc_param_dec.c | 198 +++++- lib_dec/ivas_objectRenderer_internal.c | 26 +- lib_dec/ivas_sba_dec.c | 19 + lib_dec/ivas_stat_dec.h | 12 + lib_dec/lib_dec.c | 882 ++++++++++++++++++++++++- lib_dec/lib_dec.h | 41 +- lib_rend/ivas_objectRenderer.c | 3 + lib_rend/ivas_objectRenderer_sources.c | 4 + lib_rend/ivas_prot_rend.h | 8 + 19 files changed, 1789 insertions(+), 42 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 6c1622381..1272e03fa 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 @@ -2259,6 +2263,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 ) { @@ -2597,6 +2606,82 @@ static ivas_error decodeG192( } } #endif + +#ifdef FIX_HRTF_LOAD_API + /* decode transport channels, do TSM and feed to renderer */ + if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, isSplitRend, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } + +#endif +#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 ) + { + fprintf( stderr, "\nError: could not prepare the renderer: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } +#endif } if ( isSplitRend ) @@ -3153,6 +3238,9 @@ static ivas_error decodeVoIP( int16_t nOutSamples = 0; #ifdef FIX_CREND_SIMPLIFY_CODE bool bitstreamReadDone = false; +#ifdef OBJ_EDITING_API + bool parameterAvailableForEditing = false; +#endif uint16_t nSamplesRendered; #endif @@ -3444,13 +3532,21 @@ static ivas_error decodeVoIP( #endif #ifdef SUPPORT_JBM_TRACEFILE #ifdef FIX_CREND_SIMPLIFY_CODE - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, &nSamplesRendered ) ) != IVAS_ERR_OK ) +#ifdef OBJ_EDITING_API + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, &nSamplesRendered, ¶meterAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, &nSamplesRendered, systemTime_ms ) ) != IVAS_ERR_OK ) +#endif #else - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, writeJbmTraceFileFrameWrapper, jbmTraceWriter, systemTime_ms ) ) != IVAS_ERR_OK ) #endif #else #ifdef FIX_CREND_SIMPLIFY_CODE - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, &bitstreamReadDone ) ) != IVAS_ERR_OK ) +#ifdef OBJ_EDITING_API + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &bitstreamReadDone, ¶meterAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &bitstreamReadDone, systemTime_ms ) ) != IVAS_ERR_OK ) +#endif #else if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) #endif @@ -3485,8 +3581,14 @@ static ivas_error decodeVoIP( } } #endif +#ifdef OBJ_EDITING_API + if ( parameterAvailableForEditing == true ) + { + /* do the object editing here */ + } +#endif #ifdef FIX_HRTF_LOAD - } + } /* while ( nSamplesRendered < nOutSamples ) */ #endif /* write JBM Offset file entry */ diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 0d269d103..e3aa7344b 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -128,9 +128,21 @@ typedef struct _IVAS_ISM_METADATA float yaw; float pitch; int16_t non_diegetic_flag; +#ifdef OBJ_EDITING_API + float gain; +#endif } IVAS_ISM_METADATA; +#ifdef OBJ_EDITING_API +typedef struct _IVAS_EDITABLE_PARAMETERS +{ + int16_t num_obj; + IVAS_ISM_METADATA ism_metadata[IVAS_MAX_NUM_OBJECTS]; + float gain_bed; +} IVAS_EDITABLE_PARAMETERS; +#endif + typedef struct { float w, x, y, z; diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com.c index 146d9b3a4..11e184e1c 100644 --- a/lib_com/ivas_ism_com.c +++ b/lib_com/ivas_ism_com.c @@ -418,6 +418,17 @@ void ivas_ism_reset_metadata( hIsmMeta->ism_metadata_flag = 0; hIsmMeta->non_diegetic_flag = 0; +#ifdef OBJ_EDITING_API + hIsmMeta->edited_gain = 1.0f; + hIsmMeta->edited_azimuth = 0.0f; + hIsmMeta->edited_elevation = 0.0f; + hIsmMeta->edited_pitch = 0.0f; + hIsmMeta->edited_yaw = 0.0f; + hIsmMeta->edited_radius = 1.0f; + hIsmMeta->gain = 1.0f; + hIsmMeta->non_diegetic_flag = 0; +#endif + return; } diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 91ca864ad..39b6233c5 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -864,6 +864,12 @@ void ivas_jbm_dec_feed_tc_to_renderer( float *data /* i/o: transport channels/output synthesis signal */ ); +#ifdef OBJ_EDITING_API +void ivas_jbm_dec_prepare_renderer( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); +#endif + ivas_error ivas_jbm_dec_set_discard_samples( Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */ ); @@ -1073,6 +1079,11 @@ ivas_error ivas_ism_metadata_dec( DEC_CORE_HANDLE st0 /* i : core-coder handle */ ); +#ifdef OBJ_EDITING_API +void ivas_ism_renderer_update_md( + Decoder_Struct *st_ivas /* i/o: main IVAS decoder handle */ +); +#endif /*----------------------------------------------------------------------------------* * Parametric ISM prototypes @@ -1150,6 +1161,17 @@ void ivas_param_ism_dec_digest_tc( float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ ); +#ifdef OBJ_EDITING_API +void ivas_param_ism_dec_dequant_md( + Decoder_Struct *st_ivas +); + +void ivas_param_ism_dec_prepare_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +); +#endif + void ivas_ism_param_dec_tc_gain_ajust( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamples, /* i : number of samples to be compensate */ @@ -3911,6 +3933,13 @@ void ivas_param_mc_dec_digest_tc( float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output*/ ); +#ifdef OBJ_EDITING_API +void ivas_param_mc_dec_prepare_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +); +#endif + void ivas_param_mc_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 2e849a1f2..cb5b00699 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -65,6 +65,18 @@ typedef struct float yaw; /* yaw value read from the input metadata file */ float pitch; /* pitch value read from the input metadata file */ +#ifdef OBJ_EDITING_API + float gain; + + float edited_azimuth; + float edited_elevation; + float edited_radius; + + float edited_yaw; + float edited_pitch; + float edited_gain; +#endif + int16_t non_diegetic_flag; /* Non-diegetic (non-headtracked) object flag */ ISM_METADATA_ANGLE position_angle; /* Angle structs for azimuth and elevation */ diff --git a/lib_com/options.h b/lib_com/options.h index b72019e28..63d9a3b96 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -189,6 +189,11 @@ #define ADJUST_MCT_CHANNELS_MAX /* FhG: set correct max mct channels constant*/ #define FIX_1053_REVERB_RECONFIGURATION +#define OBJ_EDITING_API /* object editing changes related to the API */ +#ifdef OBJ_EDITING_API +#define FIX_HRTF_LOAD_API +#endif + /* #################### End BASOP porting switches ############################ */ /* clang-format on */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index e0119b903..eb1f4fa36 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2356,6 +2356,9 @@ void ivas_dirac_dec_render_sf( if ( st_ivas->hEFAPdata != NULL ) { efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], az1, el1, 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], nchan_out_woLFE ); +#endif } } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 4845004dc..c2e4a05ce 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -740,13 +740,23 @@ void ivas_ism_dec_digest_tc( if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_STEREO ) { +#ifdef OBJ_EDITING_API + ivas_ism_get_stereo_gains( st_ivas->hIsmMetaData[i]->edited_azimuth, st_ivas->hIsmMetaData[i]->edited_elevation, &st_ivas->hIsmRendererData->gains[i][0], &st_ivas->hIsmRendererData->gains[i][1] ); + v_multc( st_ivas->hIsmRendererData->gains[i], st_ivas->hIsmMetaData[i]->edited_gain, st_ivas->hIsmRendererData->gains[i], CPE_CHANNELS ); +#else ivas_ism_get_stereo_gains( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &st_ivas->hIsmRendererData->gains[i][0], &st_ivas->hIsmRendererData->gains[i][1] ); +#endif } else { // TODO tmu review when #215 is resolved +#ifdef OBJ_EDITING_API + azimuth = (int16_t) floorf( st_ivas->hIsmMetaData[i]->edited_azimuth + 0.5f ); + elevation = (int16_t) floorf( st_ivas->hIsmMetaData[i]->edited_elevation + 0.5f ); +#else azimuth = (int16_t) floorf( st_ivas->hIsmMetaData[i]->azimuth + 0.5f ); elevation = (int16_t) floorf( st_ivas->hIsmMetaData[i]->elevation + 0.5f ); +#endif if ( ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_OSBA_LS || @@ -762,6 +772,9 @@ void ivas_ism_dec_digest_tc( if ( st_ivas->hEFAPdata != NULL ) { 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 ); +#endif } } else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || @@ -770,6 +783,9 @@ void ivas_ism_dec_digest_tc( { /*get HOA gets for direction (ACN/SN3D)*/ ivas_dirac_dec_get_response( azimuth, elevation, st_ivas->hIsmRendererData->gains[i], st_ivas->hIntSetup.ambisonics_order ); +#ifdef OBJ_EDITING_API + v_multc( st_ivas->hIsmRendererData->gains[i], st_ivas->hIsmMetaData[i]->edited_gain, st_ivas->hIsmRendererData->gains[i], ivas_sba_get_nchan( st_ivas->hIntSetup.ambisonics_order, 0 ) ); +#endif } } } @@ -791,14 +807,21 @@ void ivas_param_ism_dec_digest_tc( float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ ) { +#ifndef OBJ_EDITING_API int16_t ch, nchan_transport, nchan_out, nchan_out_woLFE, i; int16_t slot_idx, bin_idx; int32_t ivas_total_brate; +#else + int16_t ch, nchan_transport; + int16_t slot_idx; +#endif int16_t output_frame; +#ifndef OBJ_EDITING_API float ref_power[CLDFB_NO_CHANNELS_MAX]; float cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; /* Direct Response/EFAP Gains */ float direct_response[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN]; +#endif PARAM_ISM_DEC_HANDLE hParamIsmDec; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; int16_t fade_len; @@ -812,6 +835,8 @@ void ivas_param_ism_dec_digest_tc( fade_len = output_frame / 2; nchan_transport = st_ivas->nchan_transport; + +#ifndef OBJ_EDITING_API ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) @@ -825,9 +850,11 @@ void ivas_param_ism_dec_digest_tc( nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; } +#endif push_wmops( "ivas_param_ism_dec_digest_tc" ); +#ifndef OBJ_EDITING_API /* general setup */ ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hParamIsmDec->hParamIsmRendering->interpolator ); @@ -902,6 +929,7 @@ void ivas_param_ism_dec_digest_tc( } } } +#endif if ( st_ivas->hDecoderConfig->Opt_tsm ) { @@ -924,7 +952,168 @@ void ivas_param_ism_dec_digest_tc( mvr2r( RealBuffer, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands ); mvr2r( ImagBuffer, &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands ); } +#ifndef OBJ_EDITING_API + ivas_param_ism_collect_slot( hParamIsmDec, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], ch, ref_power, cx_diag ); +#endif + } + } + +#ifndef OBJ_EDITING_API + /* Obtain Mixing Matrix on a frame-level */ + for ( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ ) + { + set_f( hParamIsmDec->hParamIsmRendering->mixing_matrix_lin[bin_idx], 0.0f, nchan_transport * nchan_out_woLFE ); + } + + /* Compute mixing matrix */ + ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response, nchan_transport, nchan_out_woLFE, cx_diag, ref_power, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin ); +#endif + + pop_wmops(); + + return; +} + + +#ifdef OBJ_EDITING_API +/*-------------------------------------------------------------------------* + * ivas_param_ism_dec_prepare_renderer() + * + * + *-------------------------------------------------------------------------*/ + +void ivas_param_ism_dec_dequant_md( + Decoder_Struct *st_ivas ) +{ + /* De-quantization */ + if ( !( st_ivas->hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 || st_ivas->hDecoderConfig->ivas_total_brate == FRAME_NO_DATA ) ) + { + ivas_param_ism_dec_dequant_DOA( st_ivas->hParamIsmDec, st_ivas->nchan_ism ); + ivas_param_ism_dec_dequant_powrat( st_ivas->hParamIsmDec ); + st_ivas->hISMDTX.dtx_flag = 0; + } + else + { + st_ivas->hISMDTX.dtx_flag = 1; + } + + return; +} + + +/*-------------------------------------------------------------------------* + * ivas_param_ism_dec_prepare_renderer() + * + * + *-------------------------------------------------------------------------*/ +void ivas_param_ism_dec_prepare_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +) +{ + int16_t ch, nchan_transport, nchan_out, nchan_out_woLFE, i; + int16_t slot_idx, bin_idx; + float ref_power[CLDFB_NO_CHANNELS_MAX]; + float cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + /* Direct Response/EFAP Gains */ + float direct_response[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN]; + PARAM_ISM_DEC_HANDLE hParamIsmDec; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + + /* Initialization */ + hParamIsmDec = st_ivas->hParamIsmDec; + assert( hParamIsmDec ); + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + assert( hSpatParamRendCom ); + + nchan_transport = st_ivas->nchan_transport; + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + nchan_out = st_ivas->nchan_ism; + nchan_out_woLFE = nchan_out; + st_ivas->hDecoderConfig->nchan_out = nchan_out; + } + else + { + nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; + nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; + } + + push_wmops( "ivas_param_ism_dec_digest_tc" ); + + /* general setup */ + ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hParamIsmDec->hParamIsmRendering->interpolator ); + + ivas_dirac_dec_set_md_map( st_ivas, nCldfbSlots ); + + /* set buffers to zero */ + for ( bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++ ) + { + set_zero( cx_diag[bin_idx], PARAM_ISM_MAX_DMX ); + } + set_zero( ref_power, CLDFB_NO_CHANNELS_MAX ); + + /* obtain the direct response using EFAP */ + if ( !( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) ) + { + for ( i = 0; i < st_ivas->nchan_ism; i++ ) + { +#ifdef OBJ_EDITING_API + efap_determine_gains( st_ivas->hEFAPdata, direct_response[i], hParamIsmDec->edited_azimuth_values[i], hParamIsmDec->edited_elevation_values[i], EFAP_MODE_EFAP ); +#else + efap_determine_gains( st_ivas->hEFAPdata, direct_response[i], hParamIsmDec->azimuth_values[i], hParamIsmDec->elevation_values[i], EFAP_MODE_EFAP ); +#endif + } + } + else + { + int16_t j; + + for ( i = 0; i < st_ivas->nchan_ism; i++ ) + { + for ( j = 0; j < nchan_out_woLFE; j++ ) + { + if ( i == j ) + { + direct_response[i][j] = 1.0f; + } + else + { + direct_response[i][j] = 0.0f; + } + } + } + + for ( j = 0; j < nchan_out_woLFE; j++ ) + { + if ( hParamIsmDec->azimuth_values[j] > 0.0f ) + { + hParamIsmDec->hParamIsmRendering->proto_matrix[j] = 1.0f; + hParamIsmDec->hParamIsmRendering->proto_matrix[nchan_out_woLFE + j] = 0.0f; + } + else + { + if ( hParamIsmDec->azimuth_values[j] < 0.0f ) + { + hParamIsmDec->hParamIsmRendering->proto_matrix[j] = 0.0f; + hParamIsmDec->hParamIsmRendering->proto_matrix[nchan_out_woLFE + j] = 1.0f; + } + else /* == 0.0f */ + { + hParamIsmDec->hParamIsmRendering->proto_matrix[j] = 0.5f; + hParamIsmDec->hParamIsmRendering->proto_matrix[nchan_out_woLFE + j] = 0.5f; + } + } + } + } + + for ( ch = 0; ch < nchan_transport; ch++ ) + { + /* CLDFB Analysis */ + for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { ivas_param_ism_collect_slot( hParamIsmDec, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], ch, ref_power, cx_diag ); } } @@ -942,6 +1131,7 @@ void ivas_param_ism_dec_digest_tc( return; } +#endif /*-------------------------------------------------------------------------* diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 95bdd1d7c..5da61d4f2 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -234,15 +234,26 @@ void ivas_ism_render_sf( { if ( subframe_idx >= ism_md_subframe_update_jbm ) { +#ifdef OBJ_EDITING_API + rotateAziEle( st_ivas->hIsmMetaData[i]->edited_azimuth, st_ivas->hIsmMetaData[i]->edited_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); +#else rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); +#endif } else { +#ifdef OBJ_EDITING_API + rotateAziEle( st_ivas->hIsmMetaData[i]->edited_azimuth, st_ivas->hIsmMetaData[i]->edited_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); +#else rotateAziEle( st_ivas->hIsmMetaData[i]->last_azimuth, st_ivas->hIsmMetaData[i]->last_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); +#endif } if ( st_ivas->hEFAPdata != NULL ) { 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], nchan_out_woLFE ); +#endif } } diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index d6729e8fc..2ca5f5419 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -150,6 +150,9 @@ ivas_error ivas_jbm_dec_tc( } ivas_ism_dtx_limit_noise_energy_for_near_silence( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport ); +#ifdef OBJ_EDITING_API + ivas_param_ism_dec_dequant_md( st_ivas ); +#endif } else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { @@ -157,6 +160,9 @@ ivas_error ivas_jbm_dec_tc( { return error; } +#ifdef OBJ_EDITING_API + ivas_param_ism_dec_dequant_md( st_ivas ); +#endif } else /* ISM_MODE_DISC */ { @@ -808,6 +814,7 @@ void ivas_jbm_dec_feed_tc_to_renderer( } n_render_timeslots = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; +#ifndef OBJ_EDITING_API if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) { ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); @@ -821,27 +828,35 @@ void ivas_jbm_dec_feed_tc_to_renderer( { ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); } - else if ( st_ivas->ivas_format == ISM_FORMAT ) + else +#endif + if ( st_ivas->ivas_format == ISM_FORMAT ) { /* Rendering */ if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { +#ifndef OBJ_EDITING_API if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { ivas_dirac_dec_set_md_map( st_ivas, n_render_timeslots ); ivas_param_ism_params_to_masa_param_mapping( st_ivas ); } - else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + else +#endif + if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { ivas_param_ism_dec_digest_tc( st_ivas, n_render_timeslots, p_data_f ); } } +#ifndef OBJ_EDITING_API else /* ISM_MODE_DISC */ { ivas_ism_dec_digest_tc( st_ivas ); } +#endif } +#ifndef OBJ_EDITING_API else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) { ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); @@ -955,6 +970,15 @@ void ivas_jbm_dec_feed_tc_to_renderer( ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); } } +#else + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + if ( st_ivas->mc_mode == MC_MODE_PARAMMC && st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_RENDERER ) + { + ivas_param_mc_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, p_data_f ); + } + } +#endif pop_wmops(); return; @@ -1215,7 +1239,34 @@ ivas_error ivas_jbm_dec_render( ivas_ism_render_sf( st_ivas, st_ivas->renderer_type, p_output, *nSamplesRendered ); /* add already rendered SBA part */ - ivas_osba_stereo_add_channels( p_tc, p_output, 1.0f, nchan_out, st_ivas->nchan_ism, *nSamplesRendered ); +#ifdef OBJ_EDITING_API + if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + float gain = st_ivas->hSbaIsmData->gain_bed; + if ( gain != 1.0f && gain >= 0.0f ) + { + int16_t i; + for ( n = 0; n < nchan_out; n++ ) + { + for ( i = 0; i < *nSamplesRendered; i++ ) + { + p_output[n][i] += p_tc[n + st_ivas->nchan_ism][i] * gain; + } + } + } + else + { + for ( n = 0; n < nchan_out; n++ ) + { + v_add( p_output[n], p_tc[n + st_ivas->nchan_ism], p_output[n], *nSamplesRendered ); + } + } + } + else +#endif + { + ivas_osba_stereo_add_channels( p_tc, p_output, 1.0f, nchan_out, st_ivas->nchan_ism, *nSamplesRendered ); + } } else if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { @@ -2974,3 +3025,199 @@ void ivas_jbm_masa_sf_to_sf_map( return; } + +#ifdef OBJ_EDITING_API +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_prepare_renderer() + * + * prepare IVAS JBM renderer routine + *--------------------------------------------------------------------------*/ + +void ivas_jbm_dec_prepare_renderer( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +) +{ + int16_t n, n_render_timeslots; + + push_wmops( "ivas_jbm_dec_feed_tc_to_rendererer" ); + + n_render_timeslots = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; + + if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + + if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL && st_ivas->hDecoderConfig->Opt_tsm ) + { + ivas_jbm_masa_sf_to_slot_map( st_ivas, n_render_timeslots ); + } + } + else if ( st_ivas->ivas_format == STEREO_FORMAT ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + } + else if ( st_ivas->ivas_format == ISM_FORMAT ) + { + /* Rendering */ + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + ivas_dirac_dec_set_md_map( st_ivas, n_render_timeslots ); + ivas_param_ism_params_to_masa_param_mapping( st_ivas ); + } + else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_param_ism_dec_prepare_renderer( st_ivas, n_render_timeslots ); + } + } + else /* ISM_MODE_DISC */ + { + ivas_ism_dec_digest_tc( st_ivas ); + } + } + else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) + { + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + ivas_ism_dec_digest_tc( st_ivas ); + + /* delay the objects here for all renderers where it is needed */ + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) && + ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + for ( n = 0; n < st_ivas->nchan_ism; n++ ) + { + delay_signal( st_ivas->hTcBuffer->tc[n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); + } + } + + if ( !st_ivas->sba_dirac_stereo_flag ) + { + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + n_render_timeslots *= ( st_ivas->hTcBuffer->n_samples_granularity / st_ivas->hSpatParamRendCom->slot_size ); + } + + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + } + else + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + if ( st_ivas->renderer_type == RENDERER_OMASA_MIX_EXT || st_ivas->renderer_type == RENDERER_OMASA_OBJECT_EXT ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + + if ( st_ivas->hDecoderConfig->Opt_tsm ) + { + ivas_jbm_masa_sf_to_slot_map( st_ivas, n_render_timeslots ); + } + } + else + { + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + n_render_timeslots *= ( st_ivas->hTcBuffer->n_samples_granularity / st_ivas->hSpatParamRendCom->slot_size ); + } + + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + ivas_ism_dec_digest_tc( st_ivas ); + } + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_DIRAC ) + { + int16_t num_objects; + /* Delay the signal to match CLDFB delay. Delay the whole buffer. */ + num_objects = 0; + if ( ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC ) + { + num_objects = 1; + } + else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + num_objects = st_ivas->nchan_ism; + } + for ( n = 0; n < num_objects; n++ ) + { + 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 + } + if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + 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 + } + } + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + if ( st_ivas->mc_mode == MC_MODE_MCT ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + } + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + ivas_mc_paramupmix_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) + { + ivas_param_mc_dec_prepare_renderer( st_ivas, (uint8_t) n_render_timeslots ); + } + else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) + { + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + } + + pop_wmops(); + return; +} +#endif diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 68da9856b..d43f4d594 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1327,11 +1327,17 @@ void ivas_param_mc_dec_digest_tc( ) { PARAM_MC_DEC_HANDLE hParamMC; +#ifdef OBJ_EDITING_API + int16_t ch, slot_idx; + int16_t nchan_transport; +#else int16_t i, ch; int16_t is_next_band, skip_next_band; int16_t slot_idx, param_band_idx; int16_t nchan_transport, nchan_out_transport, nchan_out_cldfb; int16_t nchan_out_cov; +#endif +#ifndef OBJ_EDITING_API /*CLDFB*/ float *pCx, *pCx_imag; float cx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; @@ -1339,18 +1345,21 @@ 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; +#endif hParamMC = st_ivas->hParamMC; assert( hParamMC ); push_wmops( "param_mc_dec_digest_tc" ); +#ifndef OBJ_EDITING_API set_s( channel_active, 0, MAX_CICP_CHANNELS ); +#endif nchan_transport = st_ivas->nchan_transport; +#ifndef OBJ_EDITING_API nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) @@ -1407,14 +1416,17 @@ void ivas_param_mc_dec_digest_tc( set_zero( cx_imag, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); set_zero( cx_next_band, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); set_zero( cx_imag_next_band, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); +#endif /* slot loop for gathering the input data */ for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { if ( st_ivas->hDecoderConfig->Opt_tsm ) { +#ifndef OBJ_EDITING_API if ( param_band_idx == 0 ) /* only run cldfbAna once */ { +#endif float RealBuffer[CLDFB_NO_CHANNELS_MAX]; float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; @@ -1426,9 +1438,12 @@ void ivas_param_mc_dec_digest_tc( mvr2r( RealBuffer, &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); mvr2r( ImagBuffer, &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); } +#ifndef OBJ_EDITING_API } +#endif } +#ifndef OBJ_EDITING_API if ( slot_idx >= 2 * hParamMC->hMetadataPMC->attackIndex ) { for ( is_next_band = 0; is_next_band < 2; is_next_band++ ) @@ -1447,8 +1462,10 @@ void ivas_param_mc_dec_digest_tc( nchan_transport ); } } +#endif } +#ifndef OBJ_EDITING_API /* map from complex input covariance to real values */ for ( is_next_band = 0; is_next_band < 2; is_next_band++ ) { @@ -1485,6 +1502,184 @@ void ivas_param_mc_dec_digest_tc( } + for ( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + if ( is_next_band && skip_next_band ) + { + continue; + } + + /* generate mixing matrices */ + ivas_param_mc_get_mixing_matrices( hParamMC, + hSynthesisOutputSetup, + is_next_band ? cx_next_band : cx, + param_band_idx + is_next_band, + hParamMC->h_output_synthesis_cov_state.mixing_matrix, + hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, + nchan_out_transport, + hParamMC->synthesis_conf, + nchan_transport, + nchan_out_cov ); + } + } +#endif + pop_wmops(); + + return; +} + + +#ifdef OBJ_EDITING_API +/*------------------------------------------------------------------------- + * ivas_param_mc_dec_prepare_renderer() + * + * + *------------------------------------------------------------------------*/ + +void ivas_param_mc_dec_prepare_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +) +{ + PARAM_MC_DEC_HANDLE hParamMC; + int16_t i; + int16_t is_next_band, skip_next_band; + int16_t slot_idx, param_band_idx; + int16_t nchan_transport, nchan_out_transport, nchan_out_cldfb; + int16_t nchan_out_cov; + /*CLDFB*/ + float *pCx, *pCx_imag; + float cx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + float cx_imag[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + 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; + + hParamMC = st_ivas->hParamMC; + assert( hParamMC ); + + push_wmops( "param_mc_dec_digest_tc" ); + + set_s( channel_active, 0, MAX_CICP_CHANNELS ); + nchan_transport = st_ivas->nchan_transport; + nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + nchan_out_cldfb = BINAURAL_CHANNELS; + set_s( channel_active, 1, nchan_out_cldfb ); + nchan_out_cov = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB ) + { + nchan_out_cov = nchan_out_transport; + nchan_out_cldfb = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) + { + nchan_out_cov = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; + nchan_out_cldfb = nchan_out_cov; + set_s( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hOutSetup; + } + else + { + nchan_out_cov = nchan_out_transport; + nchan_out_cldfb = nchan_out_transport; + set_s( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + + /* adapt transient position */ + if ( hParamMC->hMetadataPMC->bAttackPresent ) + { + hParamMC->hMetadataPMC->attackIndex = (int16_t) max( 0, hParamMC->hMetadataPMC->attackIndex + ( ( nCldfbSlots - DEFAULT_JBM_CLDFB_TIMESLOTS ) / 2 ) ); + } + /* adapt subframes */ + hParamMC->num_slots = nCldfbSlots; + hParamMC->slots_rendered = 0; + hParamMC->subframes_rendered = 0; + ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); + st_ivas->hTcBuffer->nb_subframes = hParamMC->nb_subframes; + mvs2s( hParamMC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hParamMC->nb_subframes ); + + ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); + + /* loop over two bands at a time */ + for ( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx += 2 ) + { + /* don't process next band if it exceeds the limit */ + skip_next_band = ( ( param_band_idx + 1 ) == hParamMC->num_param_bands_synth ) ? 1 : 0; + + set_zero( cx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero( cx_imag, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero( cx_next_band, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero( cx_imag_next_band, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + + /* slot loop for gathering the input data */ + for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { + if ( slot_idx >= 2 * hParamMC->hMetadataPMC->attackIndex ) + { + for ( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + if ( is_next_band && skip_next_band ) + { + continue; + } + + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], + &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], + is_next_band ? cx_next_band : cx, + is_next_band ? cx_imag_next_band : cx_imag, + param_band_idx + is_next_band, + hParamMC, + nchan_transport ); + } + } + } + + /* map from complex input covariance to real values */ + for ( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + if ( is_next_band && skip_next_band ) + { + continue; + } + + /* Cx for transport channels */ + pCx = is_next_band ? &cx_next_band[0] : &cx[0]; + pCx_imag = is_next_band ? &cx_imag_next_band[0] : &cx_imag[0]; + + for ( i = 0; i < nchan_transport * nchan_transport; i++ ) + { + real_part = pCx[i]; + imag_part = pCx_imag[i]; + + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + if ( param_band_idx < hParamMC->max_param_band_abs_cov ) + { + pCx[i] = sqrtf( real_part * real_part + imag_part * imag_part ); + } + else + { + pCx[i] = real_part; + } + } + } + + /* we have to do it similar to the encoder in case of attacks (i.e. accumulate two bands) to ensure correct DMX of the target covariance*/ + if ( hParamMC->hMetadataPMC->bAttackPresent && ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) ) + { + v_add( cx, cx_next_band, cx, nchan_transport * nchan_transport ); + mvr2r( cx, cx_next_band, nchan_transport * nchan_transport ); + } + for ( is_next_band = 0; is_next_band < 2; is_next_band++ ) { if ( is_next_band && skip_next_band ) @@ -1510,6 +1705,7 @@ void ivas_param_mc_dec_digest_tc( return; } +#endif /*------------------------------------------------------------------------- diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 366d42074..653205365 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -182,7 +182,31 @@ ivas_error ivas_td_binaural_renderer_sf( } if ( subframe_idx == ism_md_subframe_update_jbm ) { - if ( ( error = TDREND_Update_object_positions( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, st_ivas->hIsmMetaData ) ) != IVAS_ERR_OK ) +#ifdef OBJ_EDITING_API + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + ISM_METADATA_FRAME ismMetaData[MAX_NUM_OBJECTS]; + ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS]; + for ( nS = 0; nS < nchan_ism; nS++ ) + { + ismMetaData[nS].azimuth = st_ivas->hIsmMetaData[nS]->edited_azimuth; + ismMetaData[nS].elevation = st_ivas->hIsmMetaData[nS]->edited_elevation; + ismMetaData[nS].radius = st_ivas->hIsmMetaData[nS]->edited_radius; + ismMetaData[nS].yaw = st_ivas->hIsmMetaData[nS]->edited_yaw; + ismMetaData[nS].pitch = st_ivas->hIsmMetaData[nS]->edited_pitch; + ismMetaData[nS].non_diegetic_flag = st_ivas->hIsmMetaData[nS]->non_diegetic_flag; + ismMetaData[nS].gain = st_ivas->hIsmMetaData[nS]->edited_gain; + hIsmMetaData[nS] = &ismMetaData[nS]; + } + + if ( ( error = TDREND_Update_object_positions( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, hIsmMetaData ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else +#endif + if ( ( error = TDREND_Update_object_positions( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, st_ivas->hIsmMetaData ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 5a149f224..360a3aac3 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -804,6 +804,25 @@ ivas_error ivas_sba_dec_render( int16_t n_samples_sf = slot_size * hSpar->subframe_nbslots[subframe_idx]; ivas_spar_dec_upmixer_sf( st_ivas, output_f_local, nchan_internal ); + +#ifdef OBJ_EDITING_API + if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + float gain = st_ivas->hSbaIsmData->gain_bed; + if ( gain != 1.0f && gain >= 0.0f ) + { + for ( ch = 0; ch < nchan_out; ch++ ) + { + int16_t i; + for ( i = 0; i < n_samples_sf; i++ ) + { + output_f_local[ch][i] *= gain; + } + } + } + } +#endif + for ( ch = 0; ch < nchan_out; ch++ ) { output_f_local[ch] += n_samples_sf; diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index e3253069a..04d23b6d1 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -422,6 +422,11 @@ typedef struct ivas_param_ism_dec_data_structure float elevation_values[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS]; float power_ratios[MAX_PARAM_ISM_NBANDS][MAX_PARAM_ISM_NBLOCKS][MAX_PARAM_ISM_WAVE]; +#ifdef OBJ_EDITING_API + float edited_azimuth_values[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS]; + float edited_elevation_values[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS]; +#endif + /*sub-modules*/ PARAM_ISM_CONFIG_HANDLE hParamIsm; /* Parametric ISM common handle */ PARAM_ISM_RENDERING_HANDLE hParamIsmRendering; /* ParamISM rendering handle */ @@ -674,6 +679,9 @@ typedef struct ivas_osba_data float **delayBuffer; int16_t delayBuffer_size; int16_t delayBuffer_nchan; +#ifdef OBJ_EDITING_API + float gain_bed; +#endif } SBA_ISM_DATA, *SBA_ISM_DATA_HANDLE; @@ -901,6 +909,10 @@ typedef struct ivas_masa_ism_data_structure int16_t azimuth_ism_edited[MAX_NUM_OBJECTS]; int16_t elevation_ism_edited[MAX_NUM_OBJECTS]; uint8_t ism_is_edited[MAX_NUM_OBJECTS]; +#ifdef OBJ_EDITING_API + float gain_ism[MAX_NUM_OBJECTS]; + float gain_masa; +#endif int16_t idx_separated_ism; int16_t azimuth_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 81545fc6b..17ea7e859 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -98,8 +98,12 @@ struct IVAS_DEC #ifdef FIX_HRTF_LOAD uint16_t nSamplesFlushed; - int16_t flushbuffer[20 * 960 / 4]; // temp. hack + int16_t *flushbuffer; IVAS_DEC_PCM_TYPE pcmType; +#ifdef OBJ_EDITING_API + bool hasEditableParameters; + bool enableParameterEditing; +#endif bool hasBeenPreparedRendering; #endif }; @@ -184,10 +188,14 @@ ivas_error IVAS_DEC_Open( hIvasDec->isInitialized = false; hIvasDec->updateOrientation = false; #ifdef FIX_HRTF_LOAD - // hIvasDec->flushbuffer = NULL; + hIvasDec->flushbuffer = NULL; // VE: TODO hIvasDec->pcmType = IVAS_DEC_PCM_INVALID; hIvasDec->pcmType = IVAS_DEC_PCM_INT16; // temp. hack hIvasDec->nSamplesFlushed = 0; +#ifdef OBJ_EDITING_API + hIvasDec->hasEditableParameters = false; + hIvasDec->enableParameterEditing = false; +#endif hIvasDec->hasBeenPreparedRendering = false; #endif @@ -367,6 +375,12 @@ void IVAS_DEC_Close( { free( ( *phIvasDec )->apaExecBuffer ); } +#ifdef OBJ_EDITING_API + if ( ( *phIvasDec )->flushbuffer != NULL ) + { + free( ( *phIvasDec )->flushbuffer ); + } +#endif free( *phIvasDec ); *phIvasDec = NULL; phIvasDec = NULL; @@ -532,6 +546,16 @@ ivas_error IVAS_DEC_Configure( hIvasDec->tsm_max_scaling = 0; hIvasDec->tsm_quality = 1.0f; +#ifdef OBJ_EDITING_API + /* init flush buffer if necessary (only needed for binaural)*/ + if ( tsmEnabled && ( outputConfig == IVAS_AUDIO_CONFIG_BINAURAL || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + { + hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); + hIvasDec->pcmType = IVAS_DEC_PCM_INT16; + set_s( (int16_t *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); + } +#endif + return IVAS_ERR_OK; } @@ -784,6 +808,16 @@ ivas_error IVAS_DEC_EnableVoIP( return IVAS_ERR_FAILED_ALLOC; } +#ifdef OBJ_EDITING_API + /* init flush buffer if necessary (only needed for binaural)*/ + if ( hIvasDec->flushbuffer == NULL && ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + { + hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); + hIvasDec->pcmType = IVAS_DEC_PCM_INT16; + set_s( (int16_t *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); + } +#endif + return IVAS_ERR_OK; } @@ -876,8 +910,139 @@ ivas_error IVAS_DEC_FeedFrame_Serial( hIvasDec->nSamplesRendered = 0; hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; +#ifndef FIX_HRTF_LOAD_API +#ifdef OBJ_EDITING_API + int16_t isSplitRend = 0; // VE: TODO + ISAR_SPLIT_REND_BITS_DATA *splitRendBits = NULL; // VE: TODO + + /* decode TCs, do TSM and feed to renderer */ + /* setup */ + if ( hIvasDec->hasBeenFedFirstGoodFrame ) + { + uint16_t l_ts, nTimeScalerOutSamples; + uint8_t nTransportChannels; + int16_t nResidualSamples, nSamplesTcsScaled, nOutSamplesElse; + + if ( isSplitRend ) + { + if ( ( error = isar_set_split_rend_setup( hIvasDec->st_ivas->hSplitBinRend, &hIvasDec->st_ivas->hRenderConfig->split_rend_config, hIvasDec->st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } + } + +#ifdef FIX_HRTF_LOAD + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &hIvasDec->nSamplesFlushed, hIvasDec->pcmType, hIvasDec->flushbuffer ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && nTransportChannels != hIvasDec->nTransportChannelsOld ) + { + if ( ( error = IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* IVAS TC decoder */ + if ( ( error = IVAS_DEC_GetTcSamples( hIvasDec, hIvasDec->apaExecBuffer, &nOutSamplesElse ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* JBM */ + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + { + if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + + if ( apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + + assert( nTimeScalerOutSamples <= APA_BUF ); + nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; + hIvasDec->timeScalingDone = 1; + } + else + { + nSamplesTcsScaled = hIvasDec->nSamplesFrame; + } + + /* Feed decoded transport channels samples to the renderer */ + if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + { + /* feed residual samples to TSM for the next call */ + if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + } + hIvasDec->hasBeenPreparedRendering = false; + + if ( hIvasDec->st_ivas->hIsmMetaData[0] ) + { + 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; + for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) + { + hIsmMetaData[obj]->edited_azimuth = hIsmMetaData[obj]->azimuth; + hIsmMetaData[obj]->edited_elevation = hIsmMetaData[obj]->elevation; + hIsmMetaData[obj]->edited_yaw = hIsmMetaData[obj]->yaw; + hIsmMetaData[obj]->edited_pitch = hIsmMetaData[obj]->pitch; + hIsmMetaData[obj]->edited_radius = hIsmMetaData[obj]->radius; + hIsmMetaData[obj]->edited_gain = 1.0f; + } + + if ( hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + hIvasDec->st_ivas->hSbaIsmData->gain_bed = 1.0f; + } + } + } + } + + if ( hIvasDec->st_ivas->hParamIsmDec != NULL ) + { + if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_PARAM ) + { + int16_t obj = 0; + PARAM_ISM_DEC_HANDLE hParamIsmDec = hIvasDec->st_ivas->hParamIsmDec; + for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) + { + hParamIsmDec->edited_azimuth_values[obj] = hParamIsmDec->azimuth_values[obj]; + hParamIsmDec->edited_elevation_values[obj] = hParamIsmDec->elevation_values[obj]; + } + } + } +#endif +#endif + return IVAS_ERR_OK; } + + #ifdef FIX_CREND_SIMPLIFY_CODE /*---------------------------------------------------------------------* * renderer_type_to_mode() @@ -1069,7 +1234,539 @@ ivas_error IVAS_DEC_ReadFormat( return IVAS_ERR_OK; } + +#ifdef FIX_HRTF_LOAD_API +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSamplesDecoder( ) + * + * Main function to decode transport channels, do TSM and feed to renderer. + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetSamplesDecoder( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t isSplitRend, /* i : split rendering enabled flag */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + ivas_error error; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* If TSM is generally enabled, we have to wait for the first good frame. + Otherwise, we directly decode the first frame in any case. */ +#ifdef FIX_HRTF_LOAD + if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) +#else + if ( ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && hIvasDec->hasBeenFedFirstGoodFrame ) || !hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) +#endif + { + uint16_t l_ts, nTimeScalerOutSamples; +#ifdef FIX_HRTF_LOAD + uint8_t nTransportChannels; +#else + uint8_t nTransportChannels, nOutChannels; +#endif + int16_t nResidualSamples, nSamplesTcsScaled, nOutSamplesElse; + + if ( isSplitRend ) + { + if ( ( error = isar_set_split_rend_setup( hIvasDec->st_ivas->hSplitBinRend, &hIvasDec->st_ivas->hRenderConfig->split_rend_config, hIvasDec->st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } + } + +#ifdef FIX_HRTF_LOAD + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &hIvasDec->nSamplesFlushed, hIvasDec->pcmType, hIvasDec->flushbuffer ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && nTransportChannels != hIvasDec->nTransportChannelsOld ) + { + if ( ( error = IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* IVAS TC decoder */ + if ( ( error = IVAS_DEC_GetTcSamples( hIvasDec, hIvasDec->apaExecBuffer, &nOutSamplesElse ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* JBM */ + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + { + if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + + if ( apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + + assert( nTimeScalerOutSamples <= APA_BUF ); + nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; + hIvasDec->timeScalingDone = 1; + } + else + { + nSamplesTcsScaled = hIvasDec->nSamplesFrame; + } + + /* Feed decoded transport channels samples to the renderer */ + if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + { + /* feed residual samples to TSM for the next call */ + if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + hIvasDec->hasBeenFedFrame = false; + } + hIvasDec->hasBeenPreparedRendering = false; + + if ( hIvasDec->st_ivas->hIsmMetaData[0] ) + { + 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; + for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) + { + hIsmMetaData[obj]->edited_azimuth = hIsmMetaData[obj]->azimuth; + hIsmMetaData[obj]->edited_elevation = hIsmMetaData[obj]->elevation; + hIsmMetaData[obj]->edited_yaw = hIsmMetaData[obj]->yaw; + hIsmMetaData[obj]->edited_pitch = hIsmMetaData[obj]->pitch; + hIsmMetaData[obj]->edited_radius = hIsmMetaData[obj]->radius; + hIsmMetaData[obj]->edited_gain = 1.0f; + } + + if ( hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + hIvasDec->st_ivas->hSbaIsmData->gain_bed = 1.0f; + } + } + } + } + + if ( hIvasDec->st_ivas->hParamIsmDec != NULL ) + { + if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_PARAM ) + { + int16_t obj = 0; + PARAM_ISM_DEC_HANDLE hParamIsmDec = hIvasDec->st_ivas->hParamIsmDec; + for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) + { + hParamIsmDec->edited_azimuth_values[obj] = hParamIsmDec->azimuth_values[obj]; + hParamIsmDec->edited_elevation_values[obj] = hParamIsmDec->elevation_values[obj]; + } + } + } + + return IVAS_ERR_OK; +} +#endif #endif + + +#ifdef OBJ_EDITING_API +/*---------------------------------------------------------------------* + * IVAS_DEC_GetEditableParameters( ) + * + * + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, + IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters ) +{ + ivas_error error; +#ifdef OMASA_OBJECT_EDITING + int16_t dirac_read_idx; +#endif + if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || + ( hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT && hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) || + ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Object editing no supported in this operation mode." ); + } + + if ( hIvasEditableParameters == NULL || hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hIvasEditableParameters->gain_bed = 1.0f; + hIvasEditableParameters->num_obj = hIvasDec->st_ivas->nchan_ism; + if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_DISC || hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + int16_t obj; + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = hIvasDec->st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = hIvasDec->st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = hIvasDec->st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = hIvasDec->st_ivas->hIsmMetaData[obj]->radius; + hIvasEditableParameters->ism_metadata[obj].gain = hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + if ( hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + hIvasEditableParameters->gain_bed = 1.0f; + } + } + else if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_PARAM ) + { + int16_t obj; + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hParamIsmDec->azimuth_values[obj]; + hIvasEditableParameters->ism_metadata[obj].elevation = hIvasDec->st_ivas->hParamIsmDec->elevation_values[obj]; + hIvasEditableParameters->ism_metadata[obj].yaw = 0.0f; + hIvasEditableParameters->ism_metadata[obj].pitch = 0.0f; + hIvasEditableParameters->ism_metadata[obj].radius = 0.0f; + hIvasEditableParameters->ism_metadata[obj].gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = 0; + } + } + else + { + assert( 0 && "This should never happen!" ); + } + } +#ifdef OMASA_OBJECT_EDITING + else if ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + /* object editing possible only in two highest OMASA modes */ + int16_t obj; + + if ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = hIvasDec->st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = hIvasDec->st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = hIvasDec->st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = hIvasDec->st_ivas->hIsmMetaData[obj]->radius; + + /* reset the otherwise unused "gain" field for the object */ + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + } + else + { + /* Handle MONO output */ + if ( hIvasDec->st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + dirac_read_idx = hIvasDec->st_ivas->hSpatParamRendCom->render_to_md_map[hIvasDec->st_ivas->hSpatParamRendCom->subframes_rendered]; + } + else + { + dirac_read_idx = 0; + } + + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; + hIvasEditableParameters->ism_metadata[obj].elevation = hIvasDec->st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; + + hIvasEditableParameters->ism_metadata[obj].yaw = hIvasDec->st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = hIvasDec->st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = hIvasDec->st_ivas->hIsmMetaData[obj]->radius; + + /* reset the otherwise unused "gain" field for the object */ + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + } + } +#endif + + error = IVAS_ERR_OK; + + return error; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_SetEditableParameters( ) + * + * Main function to decode to PCM data + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_SetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, + IVAS_EDITABLE_PARAMETERS hIvasEditableParameters ) +{ + ivas_error error; +#ifdef OMASA_OBJECT_EDITING + int16_t dirac_read_idx; +#endif + + if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || + ( hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT && hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) || + ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) ) || + hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Object editing no supported in this operation mode." ); + } + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + error = IVAS_ERR_OK; + +#ifdef DEBUGGING + assert( hIvasEditableParameters.num_obj == hIvasDec->st_ivas->nchan_ism ); +#endif + + if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_DISC || hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + int16_t obj; + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; + + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + + hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; + } + + if ( hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + hIvasDec->st_ivas->hSbaIsmData->gain_bed = hIvasEditableParameters.gain_bed; + } + } + else if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_PARAM ) + { + int16_t obj; + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { +#ifdef OBJ_EDITING_PARAMISM_BIN + hIvasDec->st_ivas->hParamIsmDec->edited_azimuth_values[obj] = hIvasEditableParameters.ism_metadata[obj].azimuth; + hIvasDec->st_ivas->hParamIsmDec->edited_elevation_values[obj] = hIvasEditableParameters.ism_metadata[obj].elevation; + hIvasDec->st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + + /* Detect direction editing in Param-ISM mode */ + if ( fabsf( hIvasDec->st_ivas->hParamIsmDec->azimuth_values[obj] - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( hIvasDec->st_ivas->hParamIsmDec->elevation_values[obj] - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + { + hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + hIvasDec->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 ) + { + hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + } + else + { + hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; + } +#endif + } +#ifdef OBJ_EDITING_PARAMISM_BIN + /* MASA is not present with the ISM format */ + hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; +#endif + } + else + { + assert( 0 && "This should never happen!" ); + } + } +#ifdef OMASA_OBJECT_EDITING + else if ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + int16_t obj; + int32_t id_th; + float threshold_azi, threshold_ele; + + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + if ( hIvasDec->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 ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + /* Handle MONO output */ + if ( hIvasDec->st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + dirac_read_idx = hIvasDec->st_ivas->hSpatParamRendCom->render_to_md_map[hIvasDec->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) hIvasDec->st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); + threshold_azi = 360.0f / (float) no_phi_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 1][id_th]; + threshold_ele = delta_theta_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 3]; + + if ( ( (float) abs( new_azi - hIvasDec->st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx] ) > threshold_azi ) || + ( (float) abs( new_ele - hIvasDec->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 */ + hIvasDec->st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + hIvasDec->st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + hIvasDec->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( hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( hIvasDec->st_ivas->hIsmMetaData[obj]->elevation - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + { + hIvasDec->st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + hIvasDec->st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } + } + + /* compare pre-edit gain and the edited one to detect editing */ + if ( fabsf( hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) + { + hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + hIvasDec->st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + } + else + { + hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; + } + } + + /* Copy edited values to hIsmMetaData struct */ + if ( hIvasDec->st_ivas->hIsmMetaData[obj] != NULL ) + { + hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; + hIvasDec->st_ivas->hIsmMetaData[obj]->elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + hIvasDec->st_ivas->hIsmMetaData[obj]->yaw = hIvasEditableParameters.ism_metadata[obj].yaw; + hIvasDec->st_ivas->hIsmMetaData[obj]->pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + hIvasDec->st_ivas->hIsmMetaData[obj]->radius = hIvasEditableParameters.ism_metadata[obj].radius; + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + hIvasDec->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 ) + { + hIvasDec->st_ivas->hMasaIsmData->gain_masa_edited = hIvasEditableParameters.gain_bed; + hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 1u; + } + else + { + hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; + } + } +#endif + + return error; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_PrepareRenderer( ) + * + * Main function to decode to PCM data + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_PrepareRenderer( + IVAS_DEC_HANDLE hIvasDec ) +{ + ivas_error error; + + error = IVAS_ERR_OK; + + if ( hIvasDec == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + ivas_jbm_dec_prepare_renderer( hIvasDec->st_ivas ); + hIvasDec->hasBeenPreparedRendering = true; + return error; +} +#endif + /*---------------------------------------------------------------------* * IVAS_DEC_GetSamples( ) * @@ -1087,21 +1784,37 @@ ivas_error IVAS_DEC_GetSamples( ) { ivas_error error; +#ifdef OBJ_EDITING_API + int16_t nSamplesToRender; + uint16_t nSamplesRendered, nSamplesRendered_loop; + uint8_t nOutChannels; +#else int16_t nOutSamplesElse, nSamplesToRender; uint16_t nSamplesRendered, nSamplesRendered_loop, l_ts, nTimeScalerOutSamples; uint8_t nTransportChannels, nOutChannels; +#endif nSamplesRendered = 0; nOutChannels = 0; nSamplesRendered_loop = 0; +#ifndef OBJ_EDITING_API l_ts = 0; nTransportChannels = 0; +#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef OBJ_EDITING_API + /* the rendering needs to be prepared at this point */ + if ( hIvasDec->hasBeenPreparedRendering == false ) + { + return IVAS_ERR_UNKNOWN; + } +#endif + if ( hIvasDec->updateOrientation ) { /*----------------------------------------------------------------* @@ -1150,6 +1863,7 @@ ivas_error IVAS_DEC_GetSamples( } else { +#ifndef OBJ_EDITING_API /* check if we need to run the setup function */ if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) { @@ -1163,8 +1877,10 @@ ivas_error IVAS_DEC_GetSamples( return error; } } +#endif { /* check if we need to run the setup function, tc decoding and feeding the renderer */ +#ifndef OBJ_EDITING_API if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) { int16_t nResidualSamples, nSamplesTcsScaled; @@ -1228,6 +1944,35 @@ ivas_error IVAS_DEC_GetSamples( } hIvasDec->hasBeenFedFrame = false; } +#else + nOutChannels = (uint8_t) hIvasDec->st_ivas->hDecoderConfig->nchan_out; + hIvasDec->hasBeenFedFrame = false; + /* check for possible flushed samples from a rate switch */ + if ( hIvasDec->nSamplesFlushed > 0 ) + { + void *pPcmBuffer; +#ifdef DEBUGGING + assert( hIvasDec->pcmType == pcmType ); +#endif + pPcmBuffer = pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ); + if ( pcmType == IVAS_DEC_PCM_INT16 ) + { + mvs2s( (int16_t *) hIvasDec->flushbuffer, pPcmBuffer, hIvasDec->nSamplesFlushed * nOutChannels ); + } + else if ( pcmType == IVAS_DEC_PCM_FLOAT ) + { + mvr2r( (float *) hIvasDec->flushbuffer, pPcmBuffer, hIvasDec->nSamplesFlushed * nOutChannels ); + } +#ifdef DEBUGGING + else + { + assert( 0 & "wrong PCM type for the flush buffer!" ); + } +#endif + nSamplesRendered += hIvasDec->nSamplesFlushed; + hIvasDec->nSamplesFlushed = 0; + } +#endif /* render IVAS frames directly to the output buffer */ nSamplesToRender = nSamplesAsked - nSamplesRendered; @@ -1304,13 +2049,24 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( *needNewFrame = false; hSplitBinRend = st_ivas->hSplitBinRend; +#ifndef OBJ_EDITING_API if ( ( error = isar_set_split_rend_setup( hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) { return error; } - +#endif numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; +#ifdef OBJ_EDITING_API + /* init flush buffer for rate switch if not already initizalized */ + if ( hIvasDec->flushbuffer == NULL ) + { + hIvasDec->flushbuffer = (void *) malloc( numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float ) ); + hIvasDec->pcmType = IVAS_DEC_PCM_FLOAT; + set_zero( (float *) hIvasDec->flushbuffer, numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); + } +#endif + if ( st_ivas->hDecoderConfig->render_framesize != IVAS_RENDER_FRAMESIZE_20MS && ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) @@ -1950,14 +2706,56 @@ ivas_error IVAS_DEC_GetObjectMetadata( } else { - metadata->azimuth = hIsmMeta->azimuth; - metadata->elevation = hIsmMeta->elevation; - metadata->radius = hIsmMeta->radius; - metadata->yaw = hIsmMeta->yaw; - metadata->pitch = hIsmMeta->pitch; - metadata->spread = 0.f; - metadata->gainFactor = 1.f; - metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; +#ifdef OBJ_EDITING_API + if ( st_ivas->ism_mode == ISM_MODE_DISC ) + { + metadata->azimuth = hIsmMeta->edited_azimuth; + metadata->elevation = hIsmMeta->edited_elevation; + metadata->radius = hIsmMeta->edited_radius; + + metadata->yaw = hIsmMeta->edited_yaw; + metadata->pitch = hIsmMeta->edited_pitch; + metadata->spread = 0.f; + + 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]; + metadata->elevation = st_ivas->hParamIsmDec->edited_elevation_values[objectIdx]; + metadata->radius = hIsmMeta->radius; + metadata->yaw = hIsmMeta->yaw; + metadata->pitch = hIsmMeta->pitch; + metadata->spread = 0.f; + 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; + metadata->elevation = st_ivas->hIsmMetaData[objectIdx]->edited_elevation; + metadata->radius = st_ivas->hIsmMetaData[objectIdx]->edited_radius; + metadata->yaw = st_ivas->hIsmMetaData[objectIdx]->edited_yaw; + metadata->pitch = st_ivas->hIsmMetaData[objectIdx]->edited_pitch; + metadata->spread = 0.f; + metadata->gainFactor = st_ivas->hIsmMetaData[objectIdx]->edited_gain; + metadata->non_diegetic_flag = st_ivas->hIsmMetaData[objectIdx]->non_diegetic_flag; + } + else +#endif + { + metadata->azimuth = hIsmMeta->azimuth; + metadata->elevation = hIsmMeta->elevation; + metadata->radius = hIsmMeta->radius; + metadata->yaw = hIsmMeta->yaw; + metadata->pitch = hIsmMeta->pitch; + metadata->spread = 0.f; + metadata->gainFactor = 1.f; + metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + } } return IVAS_ERR_OK; @@ -2991,22 +3789,18 @@ ivas_error IVAS_DEC_VoIP_GetSamples( uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf, - const uint32_t systemTimestamp_ms /* i : current system timestamp */ -#ifdef FIX_CREND_SIMPLIFY_CODE #ifdef SUPPORT_JBM_TRACEFILE - , JbmTraceFileWriterFn jbmWriterFn, - void *jbmWriter + void *jbmWriter, #endif - , - bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ - uint16_t *nSamplesRendered /* o : number of samples rendered */ -#else -#ifdef SUPPORT_JBM_TRACEFILE - JbmTraceFileWriterFn jbmWriterFn, - void *jbmWriter +#ifdef FIX_CREND_SIMPLIFY_CODE + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ #endif +#ifdef OBJ_EDITING_API + bool *parametersAvailableForEditing, #endif + const uint32_t systemTimestamp_ms /* i : current system timestamp */ ) { Decoder_Struct *st_ivas; @@ -3034,6 +3828,9 @@ ivas_error IVAS_DEC_VoIP_GetSamples( #ifndef FIX_CREND_SIMPLIFY_CODE nSamplesRendered = 0; #endif +#ifdef OBJ_EDITING_API + *parametersAvailableForEditing = false; +#endif if ( nSamplesPerChannel == 0 ) { @@ -3169,6 +3966,15 @@ ivas_error IVAS_DEC_VoIP_GetSamples( hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; hIvasDec->nSamplesRendered = 0; } +#ifdef OBJ_EDITING_API + + /* :TODO: only return here if we really have editing initialized */ + if ( hIvasDec->hasBeenFedFirstGoodFrame && hIvasDec->hasEditableParameters == true && hIvasDec->enableParameterEditing == true ) + { + *parametersAvailableForEditing = true; + return IVAS_ERR_OK; + } +#endif } /* decode */ @@ -3192,12 +3998,44 @@ ivas_error IVAS_DEC_VoIP_GetSamples( { int16_t nSamplesToRender, nSamplesRendered_loop; bool tmp; + +#ifdef FIX_HRTF_LOAD_API + if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) + { + if ( hIvasDec->nSamplesAvailableNext == 0 || hIvasDec->nSamplesAvailableNext == hIvasDec->nSamplesFrame ) + { + uint16_t nSamplesFlushed_ref = hIvasDec->nSamplesFlushed; + + if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, 0, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + hIvasDec->nSamplesFlushed = nSamplesFlushed_ref; + + *bitstreamReadDone = false; + } + } +#endif + #ifdef FIX_CREND_SIMPLIFY_CODE nSamplesToRender = nSamplesPerChannel - *nSamplesRendered; #else nSamplesToRender = nSamplesPerChannel - nSamplesRendered; #endif +#ifdef OBJ_EDITING_API + /* check if we still need to prepare the renderer */ + if ( hIvasDec->hasBeenPreparedRendering == false ) + { + + if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + /* render IVAS frames directly to the output buffer */ #ifdef FIX_CREND_SIMPLIFY_CODE if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 80ecf18fe..ef9f03995 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -158,6 +158,14 @@ ivas_error IVAS_DEC_ReadFormat( IVAS_BIN_RENDERER_TYPE *binaural_renderer_sec,/* o: secondary binaural renderer type */ IVAS_AUDIO_CONFIG *hrtf_set_audio_cfg /* o : HRTF set audio config. */ ); + +#ifdef FIX_HRTF_LOAD_API +ivas_error IVAS_DEC_GetSamplesDecoder( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t isSplitRend, /* i : split rendering enabled flag */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +); +#endif #endif /*! r: decoder error code */ @@ -170,6 +178,22 @@ ivas_error IVAS_DEC_GetSamples( bool *needNewFrame /* o : indication that the decoder needs a new frame */ ); +#ifdef OBJ_EDITING_API +ivas_error IVAS_DEC_GetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, + IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters +); + +ivas_error IVAS_DEC_SetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, + IVAS_EDITABLE_PARAMETERS hIvasEditableParameters +); + +ivas_error IVAS_DEC_PrepareRenderer( + IVAS_DEC_HANDLE hIvasDec +); +#endif + ivas_error IVAS_DEC_GetSplitBinauralBitstream( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ @@ -283,21 +307,18 @@ ivas_error IVAS_DEC_VoIP_GetSamples( uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf, - const uint32_t systemTimestamp_ms /* i : current system timestamp */ -#ifdef FIX_CREND_SIMPLIFY_CODE #ifdef SUPPORT_JBM_TRACEFILE - , JbmTraceFileWriterFn jbmWriterFn, - void* jbmWriter + JbmTraceFileWriterFn jbmWriterFn, + void* jbmWriter, #endif - , +#ifdef FIX_CREND_SIMPLIFY_CODE bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ - uint16_t *nSamplesRendered /* o : number of samples rendered */ -#else -#ifdef SUPPORT_JBM_TRACEFILE - JbmTraceFileWriterFn jbmWriterFn, - void* jbmWriter + uint16_t *nSamplesRendered, /* o : number of samples rendered */ #endif +#ifdef OBJ_EDITING_API + bool *parametersAvailableForEditing, #endif + const uint32_t systemTimestamp_ms /* i : current system timestamp */ ); ivas_error IVAS_DEC_Flush( diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 879aa5e90..5248c5d09 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -499,6 +499,9 @@ static void TDREND_Clear_Update_flags( for ( i = 0; i < hBinRendererTd->NumOfSrcs; i++ ) { hBinRendererTd->Sources[i]->SrcSpatial_p->Updated = FALSE; +#ifdef OBJ_EDITING_API + hBinRendererTd->Sources[i]->SrcRend_p->SrcGainUpdated = FALSE; +#endif } return; diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 91be83ab7..e41088912 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -251,7 +251,11 @@ static void TDREND_SRC_REND_Init( { SrcRend_p->SrcGainMin_p[nC] = 0.0f; SrcRend_p->SrcGain_p[nC] = 1.0f; +#ifdef OBJ_EDITING_API + SrcRend_p->SrcGainMax_p[nC] = 2.0f; +#else SrcRend_p->SrcGainMax_p[nC] = 1.0f; +#endif } SrcRend_p->SrcGainUpdated = FALSE; diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 7f96b5647..1a86ba3bb 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -759,6 +759,14 @@ ivas_error TDREND_MIX_SRC_SetPlayState( const TDREND_PlayStatus_t PlayStatus /* i : Play state */ ); +#ifdef OBJ_EDITING_API +ivas_error TDREND_MIX_SRC_SetSrcGain( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const int16_t SrcInd, /* i : Source index */ + const float SrcGain_p /* i : Source gain */ +); +#endif + void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_SRC_REND_t *SrcRend_p, /* i/o: Source object */ -- GitLab From 0ae069f0da55db3112dd77d953f68113371b4681 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 2 Oct 2025 22:01:08 +0200 Subject: [PATCH 02/14] fix --- lib_dec/ivas_binRenderer_internal.c | 2 ++ lib_dec/lib_dec.c | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index b865b77a6..25e680f4d 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1699,6 +1699,7 @@ void ivas_binaural_add_LFE( return; } +#ifndef FIX_HRTF_LOAD_API #ifdef FIX_CREND_SIMPLIFY_CODE #ifdef DEBUGGING /*-------------------------------------------------------------------------* @@ -1986,6 +1987,7 @@ void ivas_binaural_cldfb_sf( } #endif #endif +#endif /*------------------------------------------------------------------------- * ivas_binRenderer() diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 17ea7e859..339954f5e 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -188,9 +188,15 @@ ivas_error IVAS_DEC_Open( hIvasDec->isInitialized = false; hIvasDec->updateOrientation = false; #ifdef FIX_HRTF_LOAD - hIvasDec->flushbuffer = NULL; // VE: TODO +#ifdef OBJ_EDITING_API + hIvasDec->flushbuffer = NULL; +#else + int16_t flushbuffer[20 * 960 / 4]; // temp. hack +#endif hIvasDec->pcmType = IVAS_DEC_PCM_INVALID; +#ifndef FIX_HRTF_LOAD_API hIvasDec->pcmType = IVAS_DEC_PCM_INT16; // temp. hack +#endif hIvasDec->nSamplesFlushed = 0; #ifdef OBJ_EDITING_API hIvasDec->hasEditableParameters = false; @@ -1966,7 +1972,7 @@ ivas_error IVAS_DEC_GetSamples( #ifdef DEBUGGING else { - assert( 0 & "wrong PCM type for the flush buffer!" ); + assert( 0 && "wrong PCM type for the flush buffer!" ); } #endif nSamplesRendered += hIvasDec->nSamplesFlushed; @@ -4046,9 +4052,11 @@ ivas_error IVAS_DEC_VoIP_GetSamples( return error; } +#ifndef FIX_HRTF_LOAD_API #ifdef FIX_HRTF_LOAD *bitstreamReadDone = false; // temp hack until JBM API is reworked #endif +#endif #ifdef FIX_CREND_SIMPLIFY_CODE *nSamplesRendered += nSamplesRendered_loop; #else -- GitLab From 52631efbc322b3083ea048d09450678de72c1aea Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 3 Oct 2025 11:55:47 +0200 Subject: [PATCH 03/14] introduce TMP_FIX_SPLIT_REND --- lib_com/options.h | 3 ++- lib_dec/lib_dec.c | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 253d0bb6b..9b565a5b7 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -195,7 +195,8 @@ #define OBJ_EDITING_API /* object editing changes related to the API */ #ifdef OBJ_EDITING_API -#define FIX_HRTF_LOAD_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) #endif /* #################### End BASOP porting switches ############################ */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 339954f5e..caf37f7b2 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -299,11 +299,12 @@ static ivas_error isar_set_split_rend_setup( splitRendBits->isar_frame_size_ms = 0; splitRendBits->lc3plus_highres = 0; +#ifndef TMP_FIX_SPLIT_REND if ( ( hSplitBinRend->hMultiBinCldfbData = (ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); } - +#endif ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); if ( hCombinedOrientationData != NULL ) @@ -2207,8 +2208,9 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( ivas_syn_output( pOutput, numSamplesPerChannelToDecode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); } +#ifndef TMP_FIX_SPLIT_REND free( st_ivas->hSplitBinRend->hMultiBinCldfbData ); - +#endif return error; } @@ -5198,6 +5200,11 @@ static void ivas_destroy_handle_isar( { if ( *hSplitBinRend != NULL ) { +#ifdef TMP_FIX_SPLIT_REND + free( ( *hSplitBinRend )->hMultiBinCldfbData ); + ( *hSplitBinRend )->hMultiBinCldfbData = NULL; + +#endif ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL ); if ( ( *hSplitBinRend )->hCldfbDataOut != NULL ) @@ -5395,6 +5402,14 @@ static ivas_error ivas_dec_init_split_rend( cldfb_in_flag = 1; } +#ifdef TMP_FIX_SPLIT_REND + /* note: this is intra-frame heap memory */ + if ( ( st_ivas->hSplitBinRend->hMultiBinCldfbData = (ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); + } +#endif + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) -- GitLab From 313a1cae8953571f197bffa1c5299e1fcde135dd Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 3 Oct 2025 14:44:39 +0200 Subject: [PATCH 04/14] - introduce TMP_FIX_OMASA_SR_BE - port OMASA_OBJECT_EDITING (not verified) --- apps/decoder.c | 3 + lib_com/ivas_cnst.h | 5 + lib_com/ivas_prot.h | 4 + lib_com/options.h | 6 +- lib_dec/ivas_dirac_dec.c | 11 + lib_dec/ivas_init_dec.c | 5 + lib_dec/ivas_ism_renderer.c | 26 + lib_dec/ivas_jbm_dec.c | 2 + lib_dec/ivas_masa_dec.c | 7 + lib_dec/ivas_omasa_dec.c | 85 +- lib_dec/ivas_stat_dec.h | 22 + lib_dec/lib_dec.c | 3 + lib_rend/ivas_dirac_dec_binaural_functions.c | 824 ++++++++++++++++++- lib_rend/ivas_dirac_output_synthesis_dec.c | 14 + 14 files changed, 988 insertions(+), 29 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 1272e03fa..13125aaf3 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1887,6 +1887,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" ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index a06746fbf..a364b1156 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1218,6 +1218,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 39b6233c5..dd3cf60b6 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5862,7 +5862,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 9b565a5b7..48cf937c9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -195,8 +195,10 @@ #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 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 +//#define OMASA_OBJECT_EDITING // not really verified #endif /* #################### End BASOP porting switches ############################ */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index eb1f4fa36..493c38e44 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 d821e0a95..ea78d14f3 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1850,12 +1850,16 @@ ivas_error ivas_init_decoder( } reset_indices_dec( st_ivas->hSCE[0]->hCoreCoder[0] ); + +#ifndef OMASA_OBJECT_EDITING if ( hDecoderConfig->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 { @@ -1864,6 +1868,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_renderer.c b/lib_dec/ivas_ism_renderer.c index 5da61d4f2..81bfa29b9 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 2ca5f5419..627507749 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -3174,7 +3174,9 @@ void ivas_jbm_dec_prepare_renderer( 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 ) +#endif { 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 ); } diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index dd4e52527..6ab2a6ec5 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -649,7 +649,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 ); @@ -2460,6 +2464,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_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 56c2fd5c3..73c0c8499 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++ ) { @@ -195,7 +226,11 @@ ivas_error ivas_omasa_dec_config( #endif ) { +#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; @@ -291,6 +326,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 ) { @@ -340,6 +391,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; @@ -705,16 +757,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 04d23b6d1..842d617b2 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 caf37f7b2..c795520ce 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" diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 2afb92986..a69201a27 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -728,10 +728,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 ) { @@ -1208,11 +1219,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]; @@ -1646,13 +1665,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; } } @@ -1766,9 +1811,9 @@ static void ivas_dirac_dec_binaural_process_output( if ( chB < BINAURAL_CHANNELS ) { /* Decorrelator signal for TD decorrelation is stored in two input channels above the two normal inputs. - * It should be noted that TD decorrelation is used only in cases where numInChannels is 2. If this - * changes, additional adjustments are required. When using CLDFB decorrelator, we simply assign the - * pointers to buffers. */ + * It should be noted that TD decorrelation is used only in cases where numInChannels is 2. If this + * changes, additional adjustments are required. When using CLDFB decorrelator, we simply assign the + * pointers to buffers. */ if ( hDiracDecBin->useTdDecorr ) { decSlotRePointer = inRe[chB + 2][slot]; @@ -1861,7 +1906,7 @@ static void adaptTransportSignalsHeadtracked( int16_t band_idx, bin_lo, bin_hi; /* Determine head-orientation-based mono factor. - Rmat[1][1] entry informs how close the ears are aligned according to transport signals. */ + Rmat[1][1] entry informs how close the ears are aligned according to transport signals. */ y_val = 1.0f - fabsf( Rmat[1][1] ); mono_factor_rotation = ( y_val - ADAPT_HTPROTO_ROT_LIM_0 ) / ( ADAPT_HTPROTO_ROT_LIM_1 - ADAPT_HTPROTO_ROT_LIM_0 ); mono_factor_rotation = fmaxf( 0.0f, fminf( 1.0f, mono_factor_rotation ) ); @@ -2291,14 +2336,14 @@ static void formulate2x2MixingMatrix( const float regularizationFactor ) { /* - This function implements a 2x2 solution for an optimized spatial audio rendering algorithm - Vilkamo, J., Bäckström, T. and Kuntz, A., 2013. - "Optimized covariance domain framework for time–frequency processing of spatial audio." - Journal of the Audio Engineering Society, 61(6), pp.403-411. - - The result of the formulas below are the same as those in the publication, however, some - derivation details differ for as simple as possible 2x2 formulattion - */ + This function implements a 2x2 solution for an optimized spatial audio rendering algorithm + Vilkamo, J., Bäckström, T. and Kuntz, A., 2013. + "Optimized covariance domain framework for time–frequency processing of spatial audio." + Journal of the Audio Engineering Society, 61(6), pp.403-411. + + The result of the formulas below are the same as those in the publication, however, some + derivation details differ for as simple as possible 2x2 formulattion + */ int16_t chA, chB; float maxEne, maxEneDiv; float KyRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], KyIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; @@ -2366,8 +2411,8 @@ 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 ); eig2x2( tmpRe[0][0], tmpRe[1][1], tmpRe[1][0], tmpIm[1][0], Ure, Uim, D ); @@ -2426,6 +2471,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; @@ -2458,6 +2550,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 */ { @@ -2542,11 +2635,11 @@ static void hrtfShGetHrtf( /*------------------------------------------------------------------------- - * configure_reqularization_factor() - * - * Configure regularization factor for the mixing matrix generation of the - * parametric binauralizer using IVAS codec format and current bitrate. - *------------------------------------------------------------------------*/ + * configure_reqularization_factor() + * + * Configure regularization factor for the mixing matrix generation of the + * parametric binauralizer using IVAS codec format and current bitrate. + *------------------------------------------------------------------------*/ /*! r: Configured reqularization factor value */ float configure_reqularization_factor( @@ -2611,11 +2704,690 @@ float configure_reqularization_factor( } +#ifdef OMASA_OBJECT_EDITING /*-------------------------------------------------------------------* - * ivas_omasa_preProcessStereoTransportsForMovedObjects() - * - * - *-------------------------------------------------------------------*/ + * 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() + * + * + *-------------------------------------------------------------------*/ void ivas_omasa_preProcessStereoTransportsForMovedObjects( Decoder_Struct *st_ivas, @@ -2699,7 +3471,7 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects( normEnes[1] /= fmaxf( 1e-12f, subframeEne ); /* For each ismDir, formulate a mix-matrix that moves object audio signals between - * left and right channels when needed. Make a combined matrix by a ratio-weighted sum */ + * left and right channels when needed. Make a combined matrix by a ratio-weighted sum */ for ( ismDirIndex = 0; ismDirIndex < hSpatParamRendCom->numIsmDirections; ismDirIndex++ ) { float panGainsOut[2]; @@ -2835,6 +3607,8 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects( return; } +#endif + static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, @@ -2919,7 +3693,7 @@ static void ivas_masa_ext_rend_parambin_internal( else /* when nchan_transport == 1 and ch == 1 */ { /* At mono input duplicate the channel to dual-mono, and apply gain - correction to ensure same overall level as in stereo mode */ + correction to ensure same overall level as in stereo mode */ v_multc( Cldfb_RealBuffer_in[0][slot], INV_SQRT_2, Cldfb_RealBuffer_in[0][slot], nBins ); v_multc( Cldfb_ImagBuffer_in[0][slot], INV_SQRT_2, Cldfb_ImagBuffer_in[0][slot], nBins ); diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 34103627c..c925bb0e2 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 ); -- GitLab From 3c40b8131bc7e61bfbea6d64a83a9751eb19168b Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 3 Oct 2025 15:01:47 +0200 Subject: [PATCH 05/14] clang-format --- lib_rend/ivas_dirac_dec_binaural_functions.c | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index a69201a27..039127645 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -1811,9 +1811,9 @@ static void ivas_dirac_dec_binaural_process_output( if ( chB < BINAURAL_CHANNELS ) { /* Decorrelator signal for TD decorrelation is stored in two input channels above the two normal inputs. - * It should be noted that TD decorrelation is used only in cases where numInChannels is 2. If this - * changes, additional adjustments are required. When using CLDFB decorrelator, we simply assign the - * pointers to buffers. */ + * It should be noted that TD decorrelation is used only in cases where numInChannels is 2. If this + * changes, additional adjustments are required. When using CLDFB decorrelator, we simply assign the + * pointers to buffers. */ if ( hDiracDecBin->useTdDecorr ) { decSlotRePointer = inRe[chB + 2][slot]; @@ -2635,11 +2635,11 @@ static void hrtfShGetHrtf( /*------------------------------------------------------------------------- - * configure_reqularization_factor() - * - * Configure regularization factor for the mixing matrix generation of the - * parametric binauralizer using IVAS codec format and current bitrate. - *------------------------------------------------------------------------*/ + * configure_reqularization_factor() + * + * Configure regularization factor for the mixing matrix generation of the + * parametric binauralizer using IVAS codec format and current bitrate. + *------------------------------------------------------------------------*/ /*! r: Configured reqularization factor value */ float configure_reqularization_factor( @@ -2706,10 +2706,10 @@ float configure_reqularization_factor( #ifdef OMASA_OBJECT_EDITING /*-------------------------------------------------------------------* - * ivas_omasa_preProcessStereoTransportsForEditedObjects() - * - * - *-------------------------------------------------------------------*/ + * ivas_omasa_preProcessStereoTransportsForEditedObjects() + * + * + *-------------------------------------------------------------------*/ void ivas_omasa_preProcessStereoTransportsForEditedObjects( Decoder_Struct *st_ivas, @@ -3295,7 +3295,7 @@ void ivas_omasa_preProcessStereoTransportsForEditedObjects( 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 */ + * gaining objects and moving objects between left and right */ for ( ch = 0; ch < 2; ch++ ) { hMasaIsmData->eneMoveIIR[ch][band_idx] *= STEREO_PREPROCESS_IIR_FACTOR; @@ -3384,10 +3384,10 @@ void ivas_omasa_preProcessStereoTransportsForEditedObjects( } #else /*-------------------------------------------------------------------* - * ivas_omasa_preProcessStereoTransportsForMovedObjects() - * - * - *-------------------------------------------------------------------*/ + * ivas_omasa_preProcessStereoTransportsForMovedObjects() + * + * + *-------------------------------------------------------------------*/ void ivas_omasa_preProcessStereoTransportsForMovedObjects( Decoder_Struct *st_ivas, @@ -3471,7 +3471,7 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects( normEnes[1] /= fmaxf( 1e-12f, subframeEne ); /* For each ismDir, formulate a mix-matrix that moves object audio signals between - * left and right channels when needed. Make a combined matrix by a ratio-weighted sum */ + * left and right channels when needed. Make a combined matrix by a ratio-weighted sum */ for ( ismDirIndex = 0; ismDirIndex < hSpatParamRendCom->numIsmDirections; ismDirIndex++ ) { float panGainsOut[2]; -- GitLab From 57c1ed8d4dd93c6911c0eb8eca9cfd53c7951a12 Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 6 Oct 2025 18:56:27 +0200 Subject: [PATCH 06/14] port and activate other object-editing switches --- apps/decoder.c | 13 +++++ lib_com/options.h | 9 +++- lib_dec/ivas_init_dec.c | 11 ++++ lib_dec/ivas_ism_dec.c | 27 ++++++++++ lib_dec/ivas_ism_param_dec.c | 74 +++++++++++++++++++++++++- lib_rend/ivas_objectRenderer.c | 9 ++++ lib_rend/ivas_objectRenderer_sources.c | 43 +++++++++++++++ lib_rend/ivas_prot_rend.h | 8 +++ 8 files changed, 192 insertions(+), 2 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 13125aaf3..e4c516ea0 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -157,6 +157,9 @@ typedef struct AcousticEnvironmentSequence aeSequence; bool dpidEnabled; uint16_t directivityPatternId[IVAS_MAX_NUM_OBJECTS]; +#ifdef OBJ_EDITING_EXAMPLE + bool objEditEnabled; +#endif } DecArguments; @@ -1163,6 +1166,9 @@ static bool parseCmdlIVAS_dec( { arg->directivityPatternId[i] = 65535; } +#ifdef OBJ_EDITING_EXAMPLE + arg->objEditEnabled = false; +#endif /*-----------------------------------------------------------------* * Initialization @@ -1676,6 +1682,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 diff --git a/lib_com/options.h b/lib_com/options.h index 48cf937c9..da2a46d20 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -193,13 +193,20 @@ #define ADJUST_MCT_CHANNELS_MAX /* FhG: set correct max mct channels constant*/ #define FIX_1053_REVERB_RECONFIGURATION +// 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 -//#define OMASA_OBJECT_EDITING // not really verified #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 ############################ */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index ea78d14f3..6e2621ab1 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1552,6 +1552,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 ) { diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index bd051a922..3cc183023 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -189,6 +189,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 ) { @@ -222,6 +228,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 */ #ifdef FIX_CREND_SIMPLIFY_CODE 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 ) @@ -258,6 +269,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 ); @@ -285,6 +304,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 */ #ifdef FIX_CREND_SIMPLIFY_CODE 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 c2e4a05ce..8e7b61fc1 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1372,6 +1372,17 @@ void ivas_param_ism_dec_render( /* store MetaData parameters */ for ( ch = 0; ch < st_ivas->nchan_ism; ch++ ) { +#ifdef OBJ_EDITING_API + if ( st_ivas->hParamIsmDec->azimuth_values[ch] > 180.0f ) + { + st_ivas->hIsmMetaData[ch]->azimuth = st_ivas->hParamIsmDec->edited_azimuth_values[ch] - 360.0f; + } + else + { + st_ivas->hIsmMetaData[ch]->azimuth = st_ivas->hParamIsmDec->edited_azimuth_values[ch]; + } + st_ivas->hIsmMetaData[ch]->elevation = st_ivas->hParamIsmDec->edited_elevation_values[ch]; +#else if ( st_ivas->hParamIsmDec->azimuth_values[ch] > 180.0f ) { st_ivas->hIsmMetaData[ch]->azimuth = st_ivas->hParamIsmDec->azimuth_values[ch] - 360.0f; @@ -1382,6 +1393,7 @@ void ivas_param_ism_dec_render( } st_ivas->hIsmMetaData[ch]->elevation = st_ivas->hParamIsmDec->elevation_values[ch]; +#endif } } @@ -1409,12 +1421,23 @@ 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 ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; if ( !( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) @@ -1427,7 +1450,7 @@ 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 ) @@ -1461,12 +1484,22 @@ void ivas_param_ism_params_to_masa_param_mapping( 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]] ); +#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]] ); +#endif 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]] ); +#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]] ); +#endif power_ratio[1] = hParamIsmDec->power_ratios[band_idx][0][1]; for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) @@ -1492,6 +1525,45 @@ void ivas_param_ism_params_to_masa_param_mapping( 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 } } else diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 5248c5d09..30fcd08d8 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -553,6 +553,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 ) { @@ -788,6 +794,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 e41088912..f69661ba3 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 1a86ba3bb..a8f61edb0 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -743,6 +743,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 */ -- GitLab From 3b704fc8185a0271c6db4bf72e315100f48863b4 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 7 Oct 2025 14:00:53 +0200 Subject: [PATCH 07/14] remove OBJ_EDITING_INTERFACE, OBJ_EDITING_PARAMISM_BIN, and OMASA_OBJECT_EDITING --- apps/decoder.c | 3 - lib_com/ivas_cnst.h | 5 - lib_com/ivas_prot.h | 4 - lib_com/options.h | 7 +- lib_dec/ivas_dirac_dec.c | 11 - lib_dec/ivas_init_dec.c | 15 - lib_dec/ivas_ism_dec.c | 26 - lib_dec/ivas_ism_param_dec.c | 47 -- lib_dec/ivas_ism_renderer.c | 26 - lib_dec/ivas_jbm_dec.c | 27 - lib_dec/ivas_masa_dec.c | 7 - lib_dec/ivas_omasa_dec.c | 83 -- lib_dec/ivas_stat_dec.h | 22 - lib_dec/lib_dec.c | 219 +----- lib_rend/ivas_dirac_dec_binaural_functions.c | 773 ------------------- lib_rend/ivas_dirac_output_synthesis_dec.c | 14 - lib_rend/ivas_objectRenderer.c | 10 - lib_rend/ivas_objectRenderer_sources.c | 41 - lib_rend/ivas_prot_rend.h | 8 - 19 files changed, 2 insertions(+), 1346 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index e4c516ea0..a3a1a9968 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1900,9 +1900,6 @@ 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" ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index a364b1156..a06746fbf 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1218,11 +1218,6 @@ 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 dd3cf60b6..39b6233c5 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5862,11 +5862,7 @@ 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 056ac7234..c833c86ea 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -204,9 +204,7 @@ #define FIX_1385_INIT_IGF_STOP_FREQ /* FhG: Initialize infoIGFStopFreq in init_igf_dec() */ #define FIX_1387_INIT_PRM_SQQ /* FhG: initialize pointer prm_sqQ, which might be uninitialized in case of bfi == 1 */ -// objject-editing feature porting -#define OBJ_EDITING_INTERFACE /* Interface for object editing */ -#ifdef OBJ_EDITING_INTERFACE +// object-editing feature porting #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 @@ -214,10 +212,7 @@ #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 ############################ */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 493c38e44..eb1f4fa36 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1934,16 +1934,6 @@ 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 @@ -1952,7 +1942,6 @@ 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 6e2621ab1..f7887f15a 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1552,17 +1552,6 @@ 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 ) { @@ -1862,15 +1851,12 @@ ivas_error ivas_init_decoder( reset_indices_dec( st_ivas->hSCE[0]->hCoreCoder[0] ); -#ifndef OMASA_OBJECT_EDITING if ( hDecoderConfig->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 { @@ -1879,7 +1865,6 @@ 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 3cc183023..0eeeeae8d 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -190,11 +190,6 @@ 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 ) { @@ -228,11 +223,6 @@ 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 */ #ifdef FIX_CREND_SIMPLIFY_CODE 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 ) @@ -269,14 +259,6 @@ 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 ); @@ -304,14 +286,6 @@ 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 */ #ifdef FIX_CREND_SIMPLIFY_CODE 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 8e7b61fc1..adbf555bc 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1421,20 +1421,12 @@ 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 @@ -1525,45 +1517,6 @@ void ivas_param_ism_params_to_masa_param_mapping( 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 } } else diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 81bfa29b9..5da61d4f2 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -538,39 +538,13 @@ 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 627507749..6ce2d8d3a 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -3160,19 +3160,7 @@ 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 ) @@ -3181,21 +3169,6 @@ 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 6ab2a6ec5..dd4e52527 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -649,11 +649,7 @@ 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 ); @@ -2464,9 +2460,6 @@ 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_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 73c0c8499..8e1eb441a 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -61,11 +61,7 @@ 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 ) @@ -73,23 +69,6 @@ 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++ ) @@ -104,24 +83,14 @@ 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++ ) { @@ -226,11 +195,7 @@ ivas_error ivas_omasa_dec_config( #endif ) { -#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; @@ -326,22 +291,6 @@ 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 ) { @@ -391,7 +340,6 @@ 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; @@ -758,44 +706,13 @@ 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 842d617b2..04d23b6d1 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -908,23 +908,12 @@ 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]; @@ -932,23 +921,12 @@ 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 1073a1788..c11969bae 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -38,9 +38,6 @@ #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" @@ -1014,11 +1011,7 @@ ivas_error IVAS_DEC_FeedFrame_Serial( { 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; @@ -1363,11 +1356,7 @@ 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; @@ -1421,9 +1410,7 @@ ivas_error IVAS_DEC_GetEditableParameters( IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters ) { ivas_error error; -#ifdef OMASA_OBJECT_EDITING - int16_t dirac_read_idx; -#endif + if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || ( hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT && hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) || ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) ) ) @@ -1477,57 +1464,6 @@ ivas_error IVAS_DEC_GetEditableParameters( assert( 0 && "This should never happen!" ); } } -#ifdef OMASA_OBJECT_EDITING - else if ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) - { - /* object editing possible only in two highest OMASA modes */ - int16_t obj; - - if ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) - { - for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) - { - hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth; - hIvasEditableParameters->ism_metadata[obj].elevation = hIvasDec->st_ivas->hIsmMetaData[obj]->elevation; - hIvasEditableParameters->ism_metadata[obj].yaw = hIvasDec->st_ivas->hIsmMetaData[obj]->yaw; - hIvasEditableParameters->ism_metadata[obj].pitch = hIvasDec->st_ivas->hIsmMetaData[obj]->pitch; - hIvasEditableParameters->ism_metadata[obj].radius = hIvasDec->st_ivas->hIsmMetaData[obj]->radius; - - /* reset the otherwise unused "gain" field for the object */ - hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; - hIvasEditableParameters->ism_metadata[obj].gain = hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain; - hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag; - } - } - else - { - /* Handle MONO output */ - if ( hIvasDec->st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) - { - dirac_read_idx = hIvasDec->st_ivas->hSpatParamRendCom->render_to_md_map[hIvasDec->st_ivas->hSpatParamRendCom->subframes_rendered]; - } - else - { - dirac_read_idx = 0; - } - - for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) - { - hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; - hIvasEditableParameters->ism_metadata[obj].elevation = hIvasDec->st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; - - hIvasEditableParameters->ism_metadata[obj].yaw = hIvasDec->st_ivas->hIsmMetaData[obj]->yaw; - hIvasEditableParameters->ism_metadata[obj].pitch = hIvasDec->st_ivas->hIsmMetaData[obj]->pitch; - hIvasEditableParameters->ism_metadata[obj].radius = hIvasDec->st_ivas->hIsmMetaData[obj]->radius; - - /* reset the otherwise unused "gain" field for the object */ - hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; - hIvasEditableParameters->ism_metadata[obj].gain = hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain; - hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag; - } - } - } -#endif error = IVAS_ERR_OK; @@ -1546,9 +1482,6 @@ ivas_error IVAS_DEC_SetEditableParameters( IVAS_EDITABLE_PARAMETERS hIvasEditableParameters ) { ivas_error error; -#ifdef OMASA_OBJECT_EDITING - int16_t dirac_read_idx; -#endif if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || ( hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT && hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) || @@ -1598,163 +1531,13 @@ ivas_error IVAS_DEC_SetEditableParameters( int16_t obj; for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) { -#ifdef OBJ_EDITING_PARAMISM_BIN - hIvasDec->st_ivas->hParamIsmDec->edited_azimuth_values[obj] = hIvasEditableParameters.ism_metadata[obj].azimuth; - hIvasDec->st_ivas->hParamIsmDec->edited_elevation_values[obj] = hIvasEditableParameters.ism_metadata[obj].elevation; - hIvasDec->st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; - - /* Detect direction editing in Param-ISM mode */ - if ( fabsf( hIvasDec->st_ivas->hParamIsmDec->azimuth_values[obj] - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || - fabsf( hIvasDec->st_ivas->hParamIsmDec->elevation_values[obj] - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) - { - hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; - } - else - { - hIvasDec->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 ) - { - hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; - } - else - { - hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; - } -#endif } -#ifdef OBJ_EDITING_PARAMISM_BIN - /* MASA is not present with the ISM format */ - hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; -#endif } else { assert( 0 && "This should never happen!" ); } } -#ifdef OMASA_OBJECT_EDITING - else if ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) - { - int16_t obj; - int32_t id_th; - float threshold_azi, threshold_ele; - - for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) - { - if ( hIvasDec->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 ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) - { - /* Handle MONO output */ - if ( hIvasDec->st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) - { - dirac_read_idx = hIvasDec->st_ivas->hSpatParamRendCom->render_to_md_map[hIvasDec->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) hIvasDec->st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); - threshold_azi = 360.0f / (float) no_phi_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 1][id_th]; - threshold_ele = delta_theta_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 3]; - - if ( ( (float) abs( new_azi - hIvasDec->st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx] ) > threshold_azi ) || - ( (float) abs( new_ele - hIvasDec->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 */ - hIvasDec->st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; - hIvasDec->st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; - - hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; - } - else - { - hIvasDec->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( hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || - fabsf( hIvasDec->st_ivas->hIsmMetaData[obj]->elevation - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) - { - hIvasDec->st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; - hIvasDec->st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; - - hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; - } - else - { - hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; - } - } - - /* compare pre-edit gain and the edited one to detect editing */ - if ( fabsf( hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) - { - hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; - hIvasDec->st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; - } - else - { - hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; - } - } - - /* Copy edited values to hIsmMetaData struct */ - if ( hIvasDec->st_ivas->hIsmMetaData[obj] != NULL ) - { - hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; - hIvasDec->st_ivas->hIsmMetaData[obj]->elevation = hIvasEditableParameters.ism_metadata[obj].elevation; - hIvasDec->st_ivas->hIsmMetaData[obj]->yaw = hIvasEditableParameters.ism_metadata[obj].yaw; - hIvasDec->st_ivas->hIsmMetaData[obj]->pitch = hIvasEditableParameters.ism_metadata[obj].pitch; - hIvasDec->st_ivas->hIsmMetaData[obj]->radius = hIvasEditableParameters.ism_metadata[obj].radius; - hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; - hIvasDec->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 ) - { - hIvasDec->st_ivas->hMasaIsmData->gain_masa_edited = hIvasEditableParameters.gain_bed; - hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 1u; - } - else - { - hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; - } - } -#endif return error; } diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 039127645..1f4335c99 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -728,21 +728,10 @@ 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 ) { @@ -1219,19 +1208,11 @@ 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]; @@ -1665,39 +1646,13 @@ 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; } } @@ -2471,53 +2426,6 @@ 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; @@ -2550,7 +2458,6 @@ 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 */ { @@ -2704,685 +2611,6 @@ 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() * @@ -3607,7 +2835,6 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects( return; } -#endif static void ivas_masa_ext_rend_parambin_internal( diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index c925bb0e2..34103627c 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1700,17 +1700,10 @@ 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 ); @@ -1817,17 +1810,10 @@ 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 30fcd08d8..90c490bd6 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -553,13 +553,6 @@ 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 ) { Pos[0] = 0; @@ -794,9 +787,6 @@ 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 f69661ba3..f3cf77fce 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -53,10 +53,6 @@ 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 ); @@ -133,26 +129,6 @@ 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() * @@ -559,23 +535,6 @@ static void TDREND_SRC_SPATIAL_SetDistAtten( } -#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 a8f61edb0..1a86ba3bb 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -743,14 +743,6 @@ 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 */ -- GitLab From 82fc93e3abcd0abc8b5890d2cdb1b4a5fddb2c33 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 7 Oct 2025 14:08:46 +0200 Subject: [PATCH 08/14] fix diff --- lib_dec/lib_dec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index c11969bae..1eedebb1f 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -98,7 +98,11 @@ struct IVAS_DEC #ifdef FIX_HRTF_LOAD uint16_t nSamplesFlushed; +#ifdef FIX_HRTF_LOAD_API int16_t *flushbuffer; +#else + int16_t flushbuffer[20 * 960 / 4]; // temp. hack +#endif IVAS_DEC_PCM_TYPE pcmType; #ifdef OBJ_EDITING_API bool hasEditableParameters; @@ -191,7 +195,7 @@ ivas_error IVAS_DEC_Open( #ifdef OBJ_EDITING_API hIvasDec->flushbuffer = NULL; #else - int16_t flushbuffer[20 * 960 / 4]; // temp. hack + // hIvasDec->flushbuffer = NULL; #endif hIvasDec->pcmType = IVAS_DEC_PCM_INVALID; #ifndef FIX_HRTF_LOAD_API -- GitLab From aebf574ff86440e9101cf396e0f3340b754e5360 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 7 Oct 2025 14:25:34 +0200 Subject: [PATCH 09/14] revert formatting diffs --- lib_com/options.h | 10 ++++---- lib_dec/ivas_init_dec.c | 1 - lib_dec/ivas_ism_dec.c | 1 - lib_rend/ivas_dirac_dec_binaural_functions.c | 25 ++++++++++---------- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index c833c86ea..75b7cc35f 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -205,13 +205,13 @@ #define FIX_1387_INIT_PRM_SQQ /* FhG: initialize pointer prm_sqQ, which might be uninitialized in case of bfi == 1 */ // object-editing feature porting -#define OBJ_EDITING_API /* object editing changes related to the API */ +#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 +#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 */ +#define OBJ_EDITING_EXAMPLE /* obj editing example code in decoder.c */ /* #################### End BASOP porting switches ############################ */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index f7887f15a..d821e0a95 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1850,7 +1850,6 @@ ivas_error ivas_init_decoder( } reset_indices_dec( st_ivas->hSCE[0]->hCoreCoder[0] ); - if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 0eeeeae8d..bd051a922 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -189,7 +189,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( { /* close the parametric binaural renderer */ ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); - /* Open the TD Binaural renderer */ if ( st_ivas->hHrtfTD == NULL || st_ivas->hBinRendererTd == NULL ) { diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 1f4335c99..7a3a6c0d9 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -1861,7 +1861,7 @@ static void adaptTransportSignalsHeadtracked( int16_t band_idx, bin_lo, bin_hi; /* Determine head-orientation-based mono factor. - Rmat[1][1] entry informs how close the ears are aligned according to transport signals. */ + Rmat[1][1] entry informs how close the ears are aligned according to transport signals. */ y_val = 1.0f - fabsf( Rmat[1][1] ); mono_factor_rotation = ( y_val - ADAPT_HTPROTO_ROT_LIM_0 ) / ( ADAPT_HTPROTO_ROT_LIM_1 - ADAPT_HTPROTO_ROT_LIM_0 ); mono_factor_rotation = fmaxf( 0.0f, fminf( 1.0f, mono_factor_rotation ) ); @@ -2291,14 +2291,14 @@ static void formulate2x2MixingMatrix( const float regularizationFactor ) { /* - This function implements a 2x2 solution for an optimized spatial audio rendering algorithm - Vilkamo, J., Bäckström, T. and Kuntz, A., 2013. - "Optimized covariance domain framework for time–frequency processing of spatial audio." - Journal of the Audio Engineering Society, 61(6), pp.403-411. - - The result of the formulas below are the same as those in the publication, however, some - derivation details differ for as simple as possible 2x2 formulattion - */ + This function implements a 2x2 solution for an optimized spatial audio rendering algorithm + Vilkamo, J., Bäckström, T. and Kuntz, A., 2013. + "Optimized covariance domain framework for time–frequency processing of spatial audio." + Journal of the Audio Engineering Society, 61(6), pp.403-411. + + The result of the formulas below are the same as those in the publication, however, some + derivation details differ for as simple as possible 2x2 formulattion + */ int16_t chA, chB; float maxEne, maxEneDiv; float KyRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], KyIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; @@ -2366,8 +2366,8 @@ 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 ); eig2x2( tmpRe[0][0], tmpRe[1][1], tmpRe[1][0], tmpIm[1][0], Ure, Uim, D ); @@ -2836,7 +2836,6 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects( return; } - static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, @@ -2920,7 +2919,7 @@ static void ivas_masa_ext_rend_parambin_internal( else /* when nchan_transport == 1 and ch == 1 */ { /* At mono input duplicate the channel to dual-mono, and apply gain - correction to ensure same overall level as in stereo mode */ + correction to ensure same overall level as in stereo mode */ v_multc( Cldfb_RealBuffer_in[0][slot], INV_SQRT_2, Cldfb_RealBuffer_in[0][slot], nBins ); v_multc( Cldfb_ImagBuffer_in[0][slot], INV_SQRT_2, Cldfb_ImagBuffer_in[0][slot], nBins ); -- GitLab From 16cd48600d1ccf680d89cb0ea10d0c4f4174139a Mon Sep 17 00:00:00 2001 From: Eleni Fotopoulou Date: Wed, 8 Oct 2025 14:35:40 +0200 Subject: [PATCH 10/14] Revert "remove OBJ_EDITING_INTERFACE, OBJ_EDITING_PARAMISM_BIN, and OMASA_OBJECT_EDITING" This reverts commit 3b704fc8185a0271c6db4bf72e315100f48863b4. --- apps/decoder.c | 3 + lib_com/ivas_cnst.h | 5 + lib_com/ivas_prot.h | 4 + lib_com/options.h | 10 +- lib_dec/ivas_dirac_dec.c | 11 + lib_dec/ivas_init_dec.c | 16 + lib_dec/ivas_ism_dec.c | 27 + lib_dec/ivas_ism_param_dec.c | 47 ++ lib_dec/ivas_ism_renderer.c | 26 + lib_dec/ivas_jbm_dec.c | 27 + lib_dec/ivas_masa_dec.c | 7 + lib_dec/ivas_omasa_dec.c | 83 ++ lib_dec/ivas_stat_dec.h | 22 + lib_dec/lib_dec.c | 219 +++++- lib_rend/ivas_dirac_dec_binaural_functions.c | 773 +++++++++++++++++++ lib_rend/ivas_dirac_output_synthesis_dec.c | 14 + lib_rend/ivas_objectRenderer.c | 10 + lib_rend/ivas_objectRenderer_sources.c | 41 + lib_rend/ivas_prot_rend.h | 8 + 19 files changed, 1349 insertions(+), 4 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index a3a1a9968..e4c516ea0 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1900,6 +1900,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" ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index a06746fbf..a364b1156 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1218,6 +1218,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 39b6233c5..dd3cf60b6 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5862,7 +5862,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 75b7cc35f..f9b15a7a6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -204,15 +204,19 @@ #define FIX_1385_INIT_IGF_STOP_FREQ /* FhG: Initialize infoIGFStopFreq in init_igf_dec() */ #define FIX_1387_INIT_PRM_SQQ /* FhG: initialize pointer prm_sqQ, which might be uninitialized in case of bfi == 1 */ -// object-editing feature porting +// 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 */ - +#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 ############################ */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index eb1f4fa36..493c38e44 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 d821e0a95..6e2621ab1 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1552,6 +1552,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 ) { @@ -1850,12 +1861,16 @@ ivas_error ivas_init_decoder( } reset_indices_dec( st_ivas->hSCE[0]->hCoreCoder[0] ); + +#ifndef OMASA_OBJECT_EDITING if ( hDecoderConfig->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 { @@ -1864,6 +1879,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 bd051a922..3cc183023 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -189,6 +189,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 ) { @@ -222,6 +228,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 */ #ifdef FIX_CREND_SIMPLIFY_CODE 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 ) @@ -258,6 +269,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 ); @@ -285,6 +304,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 */ #ifdef FIX_CREND_SIMPLIFY_CODE 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 adbf555bc..8e7b61fc1 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1421,12 +1421,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 @@ -1517,6 +1525,45 @@ void ivas_param_ism_params_to_masa_param_mapping( 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 } } else diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 5da61d4f2..81bfa29b9 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 6ce2d8d3a..627507749 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -3160,7 +3160,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 ) @@ -3169,6 +3181,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 dd4e52527..6ab2a6ec5 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -649,7 +649,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 ); @@ -2460,6 +2464,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_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 8e1eb441a..73c0c8499 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++ ) { @@ -195,7 +226,11 @@ ivas_error ivas_omasa_dec_config( #endif ) { +#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; @@ -291,6 +326,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 ) { @@ -340,6 +391,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; @@ -706,13 +758,44 @@ 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 04d23b6d1..842d617b2 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 1eedebb1f..10781b1e7 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" @@ -1015,7 +1018,11 @@ ivas_error IVAS_DEC_FeedFrame_Serial( { 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; @@ -1360,7 +1367,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; @@ -1414,7 +1425,9 @@ ivas_error IVAS_DEC_GetEditableParameters( IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters ) { ivas_error error; - +#ifdef OMASA_OBJECT_EDITING + int16_t dirac_read_idx; +#endif if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || ( hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT && hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) || ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) ) ) @@ -1468,6 +1481,57 @@ ivas_error IVAS_DEC_GetEditableParameters( assert( 0 && "This should never happen!" ); } } +#ifdef OMASA_OBJECT_EDITING + else if ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + /* object editing possible only in two highest OMASA modes */ + int16_t obj; + + if ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = hIvasDec->st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = hIvasDec->st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = hIvasDec->st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = hIvasDec->st_ivas->hIsmMetaData[obj]->radius; + + /* reset the otherwise unused "gain" field for the object */ + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + } + else + { + /* Handle MONO output */ + if ( hIvasDec->st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + dirac_read_idx = hIvasDec->st_ivas->hSpatParamRendCom->render_to_md_map[hIvasDec->st_ivas->hSpatParamRendCom->subframes_rendered]; + } + else + { + dirac_read_idx = 0; + } + + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; + hIvasEditableParameters->ism_metadata[obj].elevation = hIvasDec->st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; + + hIvasEditableParameters->ism_metadata[obj].yaw = hIvasDec->st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = hIvasDec->st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = hIvasDec->st_ivas->hIsmMetaData[obj]->radius; + + /* reset the otherwise unused "gain" field for the object */ + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + } + } +#endif error = IVAS_ERR_OK; @@ -1486,6 +1550,9 @@ ivas_error IVAS_DEC_SetEditableParameters( IVAS_EDITABLE_PARAMETERS hIvasEditableParameters ) { ivas_error error; +#ifdef OMASA_OBJECT_EDITING + int16_t dirac_read_idx; +#endif if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || ( hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT && hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) || @@ -1535,13 +1602,163 @@ ivas_error IVAS_DEC_SetEditableParameters( int16_t obj; for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) { +#ifdef OBJ_EDITING_PARAMISM_BIN + hIvasDec->st_ivas->hParamIsmDec->edited_azimuth_values[obj] = hIvasEditableParameters.ism_metadata[obj].azimuth; + hIvasDec->st_ivas->hParamIsmDec->edited_elevation_values[obj] = hIvasEditableParameters.ism_metadata[obj].elevation; + hIvasDec->st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + + /* Detect direction editing in Param-ISM mode */ + if ( fabsf( hIvasDec->st_ivas->hParamIsmDec->azimuth_values[obj] - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( hIvasDec->st_ivas->hParamIsmDec->elevation_values[obj] - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + { + hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + hIvasDec->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 ) + { + hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + } + else + { + hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; + } +#endif } +#ifdef OBJ_EDITING_PARAMISM_BIN + /* MASA is not present with the ISM format */ + hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; +#endif } else { assert( 0 && "This should never happen!" ); } } +#ifdef OMASA_OBJECT_EDITING + else if ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT && ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + int16_t obj; + int32_t id_th; + float threshold_azi, threshold_ele; + + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + if ( hIvasDec->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 ( hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + /* Handle MONO output */ + if ( hIvasDec->st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + dirac_read_idx = hIvasDec->st_ivas->hSpatParamRendCom->render_to_md_map[hIvasDec->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) hIvasDec->st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); + threshold_azi = 360.0f / (float) no_phi_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 1][id_th]; + threshold_ele = delta_theta_masa[hIvasDec->st_ivas->hMasaIsmData->bits_ism[obj] - 3]; + + if ( ( (float) abs( new_azi - hIvasDec->st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx] ) > threshold_azi ) || + ( (float) abs( new_ele - hIvasDec->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 */ + hIvasDec->st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + hIvasDec->st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + hIvasDec->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( hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( hIvasDec->st_ivas->hIsmMetaData[obj]->elevation - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + { + hIvasDec->st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + hIvasDec->st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + hIvasDec->st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } + } + + /* compare pre-edit gain and the edited one to detect editing */ + if ( fabsf( hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) + { + hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + hIvasDec->st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + } + else + { + hIvasDec->st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; + } + } + + /* Copy edited values to hIsmMetaData struct */ + if ( hIvasDec->st_ivas->hIsmMetaData[obj] != NULL ) + { + hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; + hIvasDec->st_ivas->hIsmMetaData[obj]->elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + hIvasDec->st_ivas->hIsmMetaData[obj]->yaw = hIvasEditableParameters.ism_metadata[obj].yaw; + hIvasDec->st_ivas->hIsmMetaData[obj]->pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + hIvasDec->st_ivas->hIsmMetaData[obj]->radius = hIvasEditableParameters.ism_metadata[obj].radius; + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + hIvasDec->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 ) + { + hIvasDec->st_ivas->hMasaIsmData->gain_masa_edited = hIvasEditableParameters.gain_bed; + hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 1u; + } + else + { + hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; + } + } +#endif return error; } diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 7a3a6c0d9..3d7beab78 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -728,10 +728,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 ) { @@ -1208,11 +1219,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]; @@ -1646,13 +1665,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; } } @@ -2426,6 +2471,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; @@ -2458,6 +2550,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 */ { @@ -2611,6 +2704,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() * @@ -2835,6 +3607,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 34103627c..c925bb0e2 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 90c490bd6..30fcd08d8 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -553,6 +553,13 @@ 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 ) { Pos[0] = 0; @@ -787,6 +794,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 f3cf77fce..f69661ba3 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() * @@ -535,6 +559,23 @@ static void TDREND_SRC_SPATIAL_SetDistAtten( } +#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 1a86ba3bb..a8f61edb0 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -743,6 +743,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 */ -- GitLab From 146421e7487891c0f20d0535763e1f056123da12 Mon Sep 17 00:00:00 2001 From: Eleni Fotopoulou Date: Wed, 8 Oct 2025 17:04:57 +0200 Subject: [PATCH 11/14] remove if condition that is remaining by mistake from porting !1437 --- lib_dec/ivas_ism_param_dec.c | 170 ++++++++++++++++------------------- 1 file changed, 75 insertions(+), 95 deletions(-) diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 8e7b61fc1..43d88609c 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -773,7 +773,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 } } @@ -1451,138 +1452,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]; } } + } + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + for ( bin_idx = 0; bin_idx < nBins; 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; + } + } #ifdef OBJ_EDITING_PARAMISM_BIN - for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) + for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) + { + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) { - 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[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] ); + 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 ( 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 ( obj = 0; obj < MAX_PARAM_ISM_WAVE; obj++ ) + { + for ( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ ) { - 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]; - obj_idx = hParamIsmDec->hParamIsm->obj_indices[band_idx][0][obj]; - power_ratio[obj] = hParamIsmDec->power_ratios[band_idx][0][obj]; + 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 ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + for ( bin_idx = brange[0]; bin_idx < brange[1]; bin_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]; - } + hMasaIsmData->energy_ratio_ism[obj_idx][sf_idx][bin_idx] = power_ratio[obj]; } } } -#endif - } - } - 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->surroundingCoherence[sf_idx][bin_idx] = 0.0; - } } +#endif } return; -- GitLab From e9f27d3ac5129b156b8143d3a539af7417f11cc4 Mon Sep 17 00:00:00 2001 From: Eleni Fotopoulou Date: Thu, 9 Oct 2025 13:50:36 +0200 Subject: [PATCH 12/14] formatiing --- lib_com/ivas_cnst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index a364b1156..de5e52bab 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1218,7 +1218,7 @@ enum #define MASA_MAXIMUM_TWO_DIR_BANDS 24 #define NBITS_HR_COH 4 #define OMASA_TDREND_MATCHING_GAIN 0.7943f - #ifdef OMASA_OBJECT_EDITING +#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 */ -- GitLab From acf73a130dadde0189766a1377fd9f1d13382539 Mon Sep 17 00:00:00 2001 From: Eleni Fotopoulou Date: Thu, 16 Oct 2025 11:26:43 +0200 Subject: [PATCH 13/14] Fix windows build --- lib_dec/lib_dec.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 3ee9c2889..089bd3947 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1398,8 +1398,6 @@ ivas_error IVAS_DEC_GetEditableParameters( 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 */ - int16_t obj; - if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) -- GitLab From 94d5b80b076cb22b271aa95adcc544c8b3d28628 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 16 Oct 2025 09:47:10 +0200 Subject: [PATCH 14/14] port float MR 2075 --- lib_com/options.h | 5 ----- lib_dec/FEC_HQ_phase_ecu.c | 32 +++++++++--------------------- lib_dec/ivas_jbm_dec.c | 17 +--------------- lib_dec/ivas_sba_dec.c | 4 ---- lib_dec/jbm_jb4sb.c | 7 ------- lib_dec/lib_dec.c | 5 ----- lib_rend/ivas_objectRenderer_sfx.c | 3 --- 7 files changed, 10 insertions(+), 63 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 8d8a1533e..cfb24acf3 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -180,21 +180,16 @@ #define FIX_1113_EXTREND_ISAR /* FhG: issue 1113: fix external renderer asserts for FOA/HOA2 and CLDFB config */ #define FIX_1166_TDREND_DIV0 /* FhG,Eri: issue 1166: potential divide by zero in TD Renderer */ #define NONBE_1203_MDCT2DFT_SWITCHING /* VA: issue 1203: fix severe artifacts during MDCT to DFT stereo switching when MDCT ITD is not used */ -#define NONBE_1122_JBM_FIX_PLAYOUT_DELAY_IN_DTX /* FhG: Avoid JBM ignoring safety margin and setting playout delay to 0 during DTX */ #define NONBE_1122_KEEP_EVS_MODE_UNCHANGED /* FhG: Disables fix for issue 1122 in EVS mode to keep BE tests green. This switch should be removed once the 1122 fix is added to EVS via a CR. */ #define FIX_938_COMPILER_WARNING /* FhG: Fix compiler warning in ivas_mdct_core_reconstruct() */ #define FIX_1376_MISSING_ISM_METADATA /* FhG: IVAS_rend: throw error if there exists an ISM input without a corresponding metadata file path */ #define FIX_1385_INIT_IGF_STOP_FREQ /* FhG: Initialize infoIGFStopFreq in init_igf_dec() */ #define FIX_1387_INIT_PRM_SQQ /* FhG: initialize pointer prm_sqQ, which might be uninitialized in case of bfi == 1 */ -#define NONBE_1296_TDREND_ITD_OUT_OF_BOUNDS_ACCESS /* Eri: issue 1296: ITD resampling can occasionally read out of bounds, especially when the requested subframes are short (1.25 ms). Seen for headtracking+JBM. */ #define FIX_1349_TNS_CRASH /* FhG: Fix crash in TNS entropy coding, in case order of joint TNS coding is reduced to 0 */ -#define NONBE_FIX_1180_HQMDCT_PHECU_LT_MUTING /* Ericsson: issue 1180, corrected long term mute loop attnuation after 200ms in PhECU-PLC */ #define NONBE_1199_OMASA_JBM_BRATE_SW_FLUSH /* VA: issue 1199: fix bug in renderer flush in OMASA JBM bitrate switching */ #define NONBE_1200_ISM_JBM_BRATE_SW_FLUSH /* VA: issue 1200: fix bug in renderer flush in ISM JBM bitrate switching */ #define NONBE_1293_CRASH_FIRST_FRAME_LOST /* VA: issue 1293: fix G.192 decoder crash when first frame is lost */ #define FIX_1384_MSAN_stereo_tcx_core_enc /* VA: issue 1384: fix use-of-uninitialized value in stereo_tcx_core_enc() */ -#define NONBE_FIX_1297_SPAR_JBM_MEM_SAN /* Dolby: issue 1297, SPAR + JBM + BR switch memory sanitizer */ -#define NONBE_1303_GRANULARITY_OSBA_REND /* VA: issue 1303: Correctly set the granularity in OSBA, Disc mode, and BINAURAL_ROOM_REVERB output */ #define NONBE_1303_REND_GRANULARITY /* VA: issue 1303: Renderer granularity revision */ // object-editing feature porting diff --git a/lib_dec/FEC_HQ_phase_ecu.c b/lib_dec/FEC_HQ_phase_ecu.c index da65786dc..4470b677c 100644 --- a/lib_dec/FEC_HQ_phase_ecu.c +++ b/lib_dec/FEC_HQ_phase_ecu.c @@ -263,13 +263,11 @@ static void trans_ana( const int16_t time_offs, /* i : Time offset */ const float est_mus_content, /* i : 0.0=speech_like ... 1.0=Music (==st->env_stab ) */ const int16_t last_fec, /* i : signal that previous frame was concealed with fec_alg*/ -#ifdef NONBE_FIX_1180_HQMDCT_PHECU_LT_MUTING - const int16_t element_mode, /* i : element_mode req to handle EVS_MONO specific BE path */ -#endif - float *alpha, /* o : Magnitude modification factors for fade to average */ - float *beta, /* o : Magnitude modification factors for fade to average */ - float *beta_mute, /* o : Factor for long-term mute */ - float Xavg[LGW_MAX] /* o : Frequency group average gain to fade to */ + const int16_t element_mode, /* i : element_mode req to handle EVS_MONO specific BE path */ + float *alpha, /* o : Magnitude modification factors for fade to average */ + float *beta, /* o : Magnitude modification factors for fade to average */ + float *beta_mute, /* o : Factor for long-term mute */ + float Xavg[LGW_MAX] /* o : Frequency group average gain to fade to */ ) { const float *w_hamm; @@ -420,7 +418,6 @@ static void trans_ana( mag_chg[k] = 0; } -#ifdef NONBE_FIX_1180_HQMDCT_PHECU_LT_MUTING if ( element_mode != EVS_MONO ) { if ( k == 0 && burst_len > BETA_MUTE_THR ) /* beta_mute final long term attenuation adjusted only once per frame in the first sub-band, Ref Eq(184) in 26.447 */ @@ -435,12 +432,7 @@ static void trans_ana( *beta_mute *= BETA_MUTE_FAC; } } -#else - if ( burst_len > BETA_MUTE_THR ) - { - *beta_mute *= BETA_MUTE_FAC; - } -#endif + alpha[k] = mag_chg[k]; beta[k] = (float) ( sqrt( 1.0f - SQR( alpha[k] ) ) * *beta_mute ); if ( k >= LGW32k - 1 ) @@ -2125,11 +2117,9 @@ static void hq_phase_ecu( *time_offs = 0; } #endif -#ifdef NONBE_FIX_1180_HQMDCT_PHECU_LT_MUTING + trans_ana( prevsynth + 2 * output_frame - Lprot - *time_offs + ph_ecu_lookahead, mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, *last_fec, element_mode, alpha, beta, beta_mute, Xavg ); -#else - trans_ana( prevsynth + 2 * output_frame - Lprot - *time_offs + ph_ecu_lookahead, mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, *last_fec, alpha, beta, beta_mute, Xavg ); -#endif + spec_ana( prevsynth + 2 * output_frame - Lprot - *time_offs + ph_ecu_lookahead, plocs, plocsi, num_p, X_sav, output_frame, bwidth, element_mode, &noise_fac, pcorr ); if ( prev_bfi && *last_fec ) @@ -2166,15 +2156,11 @@ static void hq_phase_ecu( #ifdef FIX_1179_USAN_PHASEECU *time_offs = (int16_t) INT16_MAX; /* high value --> continued muting will ensure that the now saturated seed is not creating tones */ #else - *time_offs = MAX16B; /* continued muting will ensure that the now fixed seeds are not creating tones */ + *time_offs = MAX16B; /* continued muting will ensure that the now fixed seeds are not creating tones */ #endif } -#ifdef NONBE_FIX_1180_HQMDCT_PHECU_LT_MUTING trans_ana( prevsynth + 2 * output_frame - Lprot, mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, 0, element_mode, alpha, beta, beta_mute, Xavg ); /* 1.0 stable-music, 0.0 speech-like */ -#else - trans_ana( prevsynth + 2 * output_frame - Lprot, mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, 0, alpha, beta, beta_mute, Xavg ); /* 1.0 stable-music, 0.0 speech-like */ -#endif } mvr2r( X_sav, X, Lprot ); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index e3a084664..b50829f87 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -1749,15 +1749,12 @@ ivas_error ivas_jbm_dec_flush_renderer( } else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { -#ifdef NONBE_FIX_1297_SPAR_JBM_MEM_SAN if ( ism_mode_old == ISM_SBA_MODE_DISC ) { -#endif float *tc_local[MAX_TRANSPORT_CHANNELS]; int16_t last_spar_md_idx; int16_t last_dirac_md_idx; uint16_t nSamplesAvailableNext; -#ifdef NONBE_FIX_1297_SPAR_JBM_MEM_SAN ISM_MODE ism_mode_orig; RENDERER_TYPE renderer_type_orig; int32_t ivas_total_brate; @@ -1767,27 +1764,16 @@ ivas_error ivas_jbm_dec_flush_renderer( st_ivas->ism_mode = ism_mode_old; st_ivas->renderer_type = renderer_type_old; st_ivas->hDecoderConfig->ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; -#endif last_spar_md_idx = st_ivas->hSpar->render_to_md_map[st_ivas->hSpar->slots_rendered - 1]; last_dirac_md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->slots_rendered - 1]; -#ifdef NONBE_FIX_1297_SPAR_JBM_MEM_SAN #ifdef DEBUGGING assert( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ); -#endif -#else -#ifdef DEBUGGING - assert( ism_mode_old == ISM_SBA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ); -#endif #endif /* copy from ISM delay buffer to the correct place in tcs */ for ( ch_idx = 0; ch_idx < st_ivas->nchan_ism; ch_idx++ ) { -#ifdef NONBE_FIX_1297_SPAR_JBM_MEM_SAN tc_local[ch_idx] = &st_ivas->hTcBuffer->tc[ch_idx][hTcBuffer->n_samples_rendered]; -#else - tc_local[ch_idx] = &st_ivas->hTcBuffer->tc[ch_idx + 2][hTcBuffer->n_samples_rendered]; -#endif mvr2r( st_ivas->hSbaIsmData->delayBuffer[ch_idx], tc_local[ch_idx], st_ivas->hSbaIsmData->delayBuffer_size ); } @@ -1812,12 +1798,11 @@ ivas_error ivas_jbm_dec_flush_renderer( { return error; } -#ifdef NONBE_FIX_1297_SPAR_JBM_MEM_SAN + st_ivas->ism_mode = ism_mode_orig; st_ivas->renderer_type = renderer_type_orig; st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate; } -#endif } else { diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 398032da9..2f96d59a4 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -184,11 +184,7 @@ ivas_error ivas_sba_dec_reconfigure( } else { -#ifdef NONBE_1303_GRANULARITY_OSBA_REND if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#endif { renderer_type_new = RENDERER_BINAURAL_FASTCONV; } diff --git a/lib_dec/jbm_jb4sb.c b/lib_dec/jbm_jb4sb.c index ad3ba459a..6f6844f3a 100644 --- a/lib_dec/jbm_jb4sb.c +++ b/lib_dec/jbm_jb4sb.c @@ -683,7 +683,6 @@ static void JB4_targetPlayoutDelay( *targetStartUp = ( *targetMin + *targetMax ) / 2; } -#ifdef NONBE_1122_JBM_FIX_PLAYOUT_DELAY_IN_DTX #ifdef NONBE_1122_KEEP_EVS_MODE_UNCHANGED if ( !h->evsMode ) { @@ -693,12 +692,6 @@ static void JB4_targetPlayoutDelay( } #endif *targetStartUp = JB4_MAX( *targetStartUp, (uint32_t) h->safetyMargin ); -#else - if ( *targetStartUp < 60 ) - { - *targetStartUp = 60; - } -#endif return; } diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 089bd3947..43fbfdc33 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1117,15 +1117,10 @@ ivas_error IVAS_DEC_ReadFormat( } } #else -#ifdef NONBE_FIX_1297_SPAR_JBM_MEM_SAN if ( ( renderer_type_old != st_ivas->renderer_type && renderer_type_old != RENDERER_DISABLE ) || ( st_ivas->ini_active_frame > 0 && ( ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ism_mode != ISM_MASA_MODE_DISC ) || ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ism_mode != ISM_SBA_MODE_DISC ) ) ) ) -#else - if ( ( renderer_type_old != st_ivas->renderer_type && renderer_type_old != RENDERER_DISABLE ) || - ( st_ivas->ini_active_frame > 0 && ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ism_mode != ISM_MASA_MODE_DISC ) ) -#endif { /* JBM: when granularity goes down (e.g. Discrete ISM with TD Obj Renderer -> ParamISM with binaural fastconv render what still fits in the new granularity */ diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 713a0b790..1f774bb0f 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -216,9 +216,6 @@ static void sincResample( p_forward++; p_backward--; } -#ifndef NONBE_1296_TDREND_ITD_OUT_OF_BOUNDS_ACCESS - tmp += ( *p_forward ) * ( *p_sinc_forward ); /* Integer index always rounded down --> 4 steps backward, 5 steps forward */ -#endif output[i] = tmp; /* Advance fractional time */ -- GitLab