diff --git a/apps/decoder.c b/apps/decoder.c index 6c16223810c798a6d2f4f1af510c9472fdd84f15..686c6ae0a9f046516b1d74535b32658bd7c99a5d 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -2597,6 +2597,23 @@ 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 + /* 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 +3170,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 +3464,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 +3513,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 0d269d103fdd4b1d3d32e632291a7bd0f3b4f779..e3aa7344bdf64458321046b3d8807e47a912f0be 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 146d9b3a446e524e21d2c0090e14f0483795306a..11e184e1ce0f608978125c7455373bcf1ed2dbba 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 91ca864ad745bd3ab1fe7d63789e218df974956b..39b6233c5ac16aebc8f1ff81314502d0f9b563cc 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 2e849a1f2f2c120fd60fe621d21c4ab3f5aeecaf..cb5b006994dba4a081ed4766bdd621bb76c97dfd 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 4e7cfd796f2a91a0ae35151672cd4c28b3ae8145..795fde1d6982ecfcc8e8cfc8c7d7b94b38626cf8 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -207,6 +207,14 @@ #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 */ +// 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 +#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 + /* #################### End BASOP porting switches ############################ */ /* clang-format on */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index b865b77a6e3d507cda7ac858fa15e7defdfae593..25e680f4d43ce403401adfe669f63a95b0532eeb 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/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index e0119b9033390999e364c555e88344485580a059..eb1f4fa36d2f60549f9a0f3d59085c253953ff4f 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 4845004dc80dc31bd1678ad26c2682bfbe5785fb..adbf555bcd165934d9d57361aec34d231b485245 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 /*-------------------------------------------------------------------------* @@ -1182,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; @@ -1192,6 +1393,7 @@ void ivas_param_ism_dec_render( } st_ivas->hIsmMetaData[ch]->elevation = st_ivas->hParamIsmDec->elevation_values[ch]; +#endif } } @@ -1219,12 +1421,15 @@ void ivas_param_ism_params_to_masa_param_mapping( int16_t azimuth[2]; int16_t elevation[2]; float power_ratio[2]; +#ifndef OBJ_EDITING_API int32_t ivas_total_brate; +#endif hParamIsmDec = st_ivas->hParamIsmDec; hSpatParamRendCom = st_ivas->hSpatParamRendCom; 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 ) ) @@ -1237,7 +1442,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 ) @@ -1271,12 +1476,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++ ) diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 95bdd1d7c29d72f320360e8f29fb0df9d89f3ade..5da61d4f26cce7488e856c9445d34d8352ff8937 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 d6729e8fcebdd1ba63d7c2a910773401b19ae078..6ce2d8d3af517120e0f8c3163f4da0da0c9606ad 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,174 @@ 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 ) + { + 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 ); + } +#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 ); + } + } + } + } + } + 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 68da9856be0f5fefc4aa18e7983bdc86b40216d8..299fa549c58e5477f3595a4f63fe27e86a66eaef 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]; @@ -1343,14 +1349,18 @@ void ivas_param_mc_dec_digest_tc( /* 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 +1417,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 +1439,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 +1463,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 +1503,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 +1706,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 366d42074e8179e67866f8439cca9b63cfbec807..6532053658d711dbdeae841dbc3f98f95526e43f 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 5a149f2247edc985311f577a4dd36b06b2dbd619..360a3aac3aaaa39c4c319e06532f5a1570424d1a 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 e3253069ace9b7be6a5ab4567512b4eb5611b9ad..04d23b6d1e1b03684e835727d238dde154e109d6 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 6de11f8048f53f4b9042db3a18b2861bbd881661..f1f183463e06c4a9d2dedde149244391f8426fcc 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -98,8 +98,16 @@ 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; + bool enableParameterEditing; +#endif bool hasBeenPreparedRendering; #endif }; @@ -184,10 +192,20 @@ ivas_error IVAS_DEC_Open( hIvasDec->isInitialized = false; hIvasDec->updateOrientation = false; #ifdef FIX_HRTF_LOAD - // hIvasDec->flushbuffer = NULL; +#ifdef OBJ_EDITING_API + hIvasDec->flushbuffer = NULL; +#else + // hIvasDec->flushbuffer = NULL; +#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; + hIvasDec->enableParameterEditing = false; +#endif hIvasDec->hasBeenPreparedRendering = false; #endif @@ -285,11 +303,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 ) @@ -367,6 +386,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 +557,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; } @@ -791,6 +826,16 @@ ivas_error IVAS_DEC_EnableVoIP( } #endif +#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; } @@ -883,6 +928,131 @@ 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 ) + { + 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 ) + { + 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 @@ -1076,7 +1246,329 @@ 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 ) + { + 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 ) + { + 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; + + 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!" ); + } + } + + 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; + + 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++ ) + { + } + } + else + { + assert( 0 && "This should never happen!" ); + } + } + + 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( ) * @@ -1094,21 +1586,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 ) { /*----------------------------------------------------------------* @@ -1157,6 +1665,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 ) { @@ -1170,8 +1679,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; @@ -1235,6 +1746,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; @@ -1311,13 +1851,25 @@ 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 ) ) @@ -1452,8 +2004,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; } @@ -1957,14 +2510,54 @@ 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; + } + 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; + } + 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; @@ -2999,22 +3592,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; @@ -3042,6 +3631,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 ) { @@ -3185,6 +3777,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 */ @@ -3208,12 +3809,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 ) @@ -3224,9 +3857,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 @@ -4368,6 +5003,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 ) @@ -4565,6 +5205,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 ) ) diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 80ecf18fe51b6b7c91c9d5ddfe60f2806d83bdeb..ef9f03995cc60e8519e4a11f65ec2e0c124064f4 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 879aa5e90fcf6dc2903ba71382346ddd38659bbc..5248c5d092dd3469c93a0ab8b0d38bb52a0df6fe 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 91be83ab737c488db3b909e356335c389c16b75c..e41088912b56ef50d1f3cc6f2659a58dfe2a8284 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 7f96b5647562ff883646f9391a89de2418a9a00e..1a86ba3bbe01fbaf401a5eb4dc104f1a7f3100b3 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 */