diff --git a/apps/decoder.c b/apps/decoder.c index deb97aeff98579f557d6c16571ef0b04752fa444..36ed7a94a92b9bbc77e66edc6d6a323d9a111f86 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -2265,6 +2265,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 ) @@ -2714,6 +2731,9 @@ static ivas_error decodeVoIP( int16_t nOutSamples = 0; #ifdef FIX_CREND_SIMPLIFY_CODE bool bitstreamReadDone = false; +#ifdef OBJ_EDITING_API + bool parametersAvailableForEditing = false; +#endif uint16_t nSamplesRendered; #endif @@ -3005,13 +3025,21 @@ static ivas_error decodeVoIP( #endif #ifdef SUPPORT_JBM_TRACEFILE #ifdef FIX_CREND_SIMPLIFY_CODE +#ifdef OBJ_EDITING_API + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, &nSamplesRendered, ¶metersAvailableForEditing ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, &nSamplesRendered ) ) != IVAS_ERR_OK ) +#endif #else if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) #endif #else #ifdef FIX_CREND_SIMPLIFY_CODE +#ifdef OBJ_EDITING_API + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, (void *) pcmBuf, systemTime_ms, &bitstreamReadDone, ¶metersAvailableForEditing ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, (void *) pcmBuf, systemTime_ms, &bitstreamReadDone ) ) != IVAS_ERR_OK ) +#endif #else if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) #endif @@ -3046,8 +3074,14 @@ static ivas_error decodeVoIP( } } #endif +#ifdef OBJ_EDITING_API + if ( parametersAvailableForEditing == 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 112d826079cd4f80204a821ac10370c21da53fb4..d8ccd49d97dadd7c535501dd5871fafb91757f07 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -137,9 +137,21 @@ typedef struct _IVAS_ISM_METADATA float yaw; float pitch; Word16 non_diegetic_flag; +#ifdef OBJ_EDITING_API + Word32 gain_fx; +#endif } IVAS_ISM_METADATA; +#ifdef OBJ_EDITING_API +typedef struct _IVAS_EDITABLE_PARAMETERS +{ + Word16 num_obj; + IVAS_ISM_METADATA ism_metadata[IVAS_MAX_NUM_OBJECTS]; + Word32 gain_bed_fx; +} IVAS_EDITABLE_PARAMETERS; +#endif + typedef struct { // float w, x, y, z; diff --git a/lib_com/ivas_ism_com_fx.c b/lib_com/ivas_ism_com_fx.c index 7e9ab34ccc534546ff3b89731a683864dc3867bf..30cd2f29e095ddb08699ac2b5a0e5ca2de9fccbc 100644 --- a/lib_com/ivas_ism_com_fx.c +++ b/lib_com/ivas_ism_com_fx.c @@ -470,6 +470,17 @@ void ivas_ism_reset_metadata( hIsmMeta->non_diegetic_flag = 0; move16(); +#ifdef OBJ_EDITING_API + hIsmMeta->edited_gain_fx = ONE_IN_Q31; + hIsmMeta->edited_azimuth_fx = 0; + hIsmMeta->edited_elevation_fx = 0; + hIsmMeta->edited_pitch_fx = 0; + hIsmMeta->edited_yaw_fx = 0; + hIsmMeta->edited_radius_fx = ONE_IN_Q9; + hIsmMeta->gain_fx = ONE_IN_Q31; + hIsmMeta->non_diegetic_flag = 0; +#endif + return; } diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 7c3354dbadb992eb3b15044aac801ac5316882be..f226e5d95f6be98e4bb9bdb429f6d3c1c1cc8200 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -777,6 +777,12 @@ ivas_error ivas_ism_metadata_dec_fx( 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 + void ivas_get_ism_sid_quan_bitbudget_fx( const Word16 nchan_ism, /* i : number of objects */ Word16 *nBits_azimuth, /* o : number of Q bits for azimuth */ @@ -4225,6 +4231,12 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( Word32 *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 + void ivas_jbm_dec_get_adapted_subframes( const Word16 nCldfbTs, /* i : number of time slots in the current frame */ Word16 *subframe_nbslots, /* i/o: subframe grid */ @@ -4320,6 +4332,18 @@ void ivas_param_ism_dec_digest_tc_fx( Word32 *transport_channels[], /* i : synthesized core-coder transport channels/DirAC output */ Word16 q_tc_in ); + +#ifdef OBJ_EDITING_API +void ivas_param_ism_dec_dequant_md_fx( + Decoder_Struct *st_ivas +); + +void ivas_param_ism_dec_prepare_renderer_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const Word16 nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +); +#endif + void ivas_param_ism_dec_render_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ @@ -5163,6 +5187,13 @@ void ivas_param_mc_dec_digest_tc_fx( Word32 *transport_channels_f_fx[], Word16 transport_f_e ); +#ifdef OBJ_EDITING_API +void ivas_param_mc_dec_prepare_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord8 nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +); +#endif + void ivas_param_mc_dec_render_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 847442c35ec12dfcc6ef295995e71a5fde700668..1f7ea778d06534d594480c2be3ad04c0278fed6d 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -65,6 +65,18 @@ typedef struct Word32 yaw_fx; /* yaw value read from the input metadata file */ /* Q22 */ Word32 pitch_fx; /* pitch value read from the input metadata file */ /* Q22 */ +#ifdef OBJ_EDITING_API + Word32 gain_fx; /* Q31 */ + + Word32 edited_azimuth_fx; /* Q22 */ + Word32 edited_elevation_fx; /* Q22 */ + Word16 edited_radius_fx; /* Q9 */ + + Word32 edited_yaw_fx; /* Q22 */ + Word32 edited_pitch_fx; /* Q22 */ + Word32 edited_gain_fx; /* Q31 */ +#endif + Word16 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 d1d569cfba8cfee0638a9668438f39be87fda40b..9891ef397d965df02dc3c817dbf3c5d603f1258b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -154,6 +154,14 @@ #define NONBE_FIX_1180_HQMDCT_PHECU_LT_MUTING /* Ericsson: issue 1180, corrected long term mute loop attnuation after 200ms in PhECU-PLC */ #define FIX_1179_USAN_PHASEECU /* Eri: issue 1179: better handling of 16 bit wrap around for very long(>200ms) FER-bursts */ +// 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 ############################ */ #endif diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index a2b3096a97bf6dcec56ef561a7a906f2252f086e..6d36b342903b909194a52f873911e86a8ebbcc85 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -3837,6 +3837,10 @@ void ivas_dirac_dec_render_sf_fx( const Word32 azi_fx = L_shl( az1_32, Q22 - Q16 ); // Q16 -> Q22 const Word32 ele_fx = L_shl( el1_32, Q22 - Q16 ); // Q16 -> Q22 efap_determine_gains_fx( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains_fx[i], azi_fx, ele_fx, EFAP_MODE_EFAP ); +#ifdef OBJ_EDITING_API + // TODO: Enable gain editing feature + // v_multc_fixed( st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIsmMetaData[i]->edited_gain_fx, st_ivas->hIsmRendererData->gains_fx[i], nchan_out_woLFE ); // Q30, Q30 --> Q30 +#endif } } diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 53c25b4d5ae288b7821cacc3ae2a9b37856725dc..973d726b0b8a8f54d4236c3cec4d7842d0269f24 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -979,18 +979,34 @@ void ivas_ism_dec_digest_tc_fx( IF( EQ_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_STEREO ) ) { +#ifdef OBJ_EDITING_API Word16 gains_fx[2]; ivas_ism_get_stereo_gains_fx( (Word16) L_shr( st_ivas->hIsmMetaData[i]->azimuth_fx, 22 ), (Word16) L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, 22 ), &gains_fx[0], &gains_fx[1] ); st_ivas->hIsmRendererData->gains_fx[i][0] = L_shr( L_deposit_h( gains_fx[0] ), 1 ); // Q31 -> Q30 move32(); st_ivas->hIsmRendererData->gains_fx[i][1] = L_shr( L_deposit_h( gains_fx[1] ), 1 ); // Q31 -> Q30 move32(); + // TODO: Enable gain editing feature + // v_multc_fixed( st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIsmMetaData[i]->edited_gain_fx, st_ivas->hIsmRendererData->gains_fx[i], CPE_CHANNELS ); // Q30, Q30 --> Q30 +#else + Word16 gains_fx[2]; + ivas_ism_get_stereo_gains_fx( (Word16) L_shr( st_ivas->hIsmMetaData[i]->azimuth_fx, 22 ), (Word16) L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, 22 ), &gains_fx[0], &gains_fx[1] ); + st_ivas->hIsmRendererData->gains_fx[i][0] = L_shr( L_deposit_h( gains_fx[0] ), 1 ); // Q31 -> Q30 + move32(); + st_ivas->hIsmRendererData->gains_fx[i][1] = L_shr( L_deposit_h( gains_fx[1] ), 1 ); // Q31 -> Q30 + move32(); +#endif } ELSE { // TODO tmu review when #215 is resolved +#ifdef OBJ_EDITING_API + azimuth_fx = L_shr( L_add( st_ivas->hIsmMetaData[i]->edited_azimuth_fx, 2097152 ), Q22 ); // Q0 ,2097152 = .5f in Q22 + elevation_fx = L_shr( L_add( st_ivas->hIsmMetaData[i]->edited_elevation_fx, 2097152 ), Q22 ); // Q0 ,2097152 = .5f in Q22 +#else azimuth_fx = L_shr( L_add( st_ivas->hIsmMetaData[i]->azimuth_fx, 2097152 ), Q22 ); // Q0 ,2097152 = .5f in Q22 elevation_fx = L_shr( L_add( st_ivas->hIsmMetaData[i]->elevation_fx, 2097152 ), Q22 ); // Q0 ,2097152 = .5f in Q22 +#endif test(); test(); @@ -1018,6 +1034,10 @@ void ivas_ism_dec_digest_tc_fx( azimuth_fx = L_shl( azimuth_fx, Q22 ); // Q22 elevation_fx = L_shl( elevation_fx, Q22 ); // Q22 efap_determine_gains_fx( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains_fx[i], azimuth_fx, elevation_fx, EFAP_MODE_EFAP ); +#ifdef OBJ_EDITING_API + // TODO: Enable gain editing feature + // v_multc_fixed( st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIsmMetaData[i]->edited_gain_fx, st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hEFAPdata->numSpk ); +#endif } } ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) || @@ -1028,6 +1048,10 @@ void ivas_ism_dec_digest_tc_fx( Word16 azi = shr( extract_h( st_ivas->hIsmMetaData[i]->azimuth_fx ), 22 - 16 ); // Q0 Word16 ele = shr( extract_h( st_ivas->hIsmMetaData[i]->elevation_fx ), 22 - 16 ); // Q0 ivas_dirac_dec_get_response_fx( azi, ele, st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIntSetup.ambisonics_order, Q30 ); +#ifdef OBJ_EDITING_API + // TODO: Enable gain editing feature + // v_multc_fixed( st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIsmMetaData[i]->edited_gain_fx, st_ivas->hIsmRendererData->gains_fx[i], ivas_sba_get_nchan_fx( st_ivas->hIntSetup.ambisonics_order, 0 ) ); // Q30, Q30 --> Q30 +#endif } } } @@ -1047,28 +1071,40 @@ void ivas_param_ism_dec_digest_tc_fx( Word32 *transport_channels[], /* i : synthesized core-coder transport channels/DirAC output q_tc_in*/ Word16 q_tc_in ) { - Word16 exp_real_tmp = 0, exp_imag_tmp = 0; move16(); move16(); move16(); move16(); +#ifndef OBJ_EDITING_API Word32 cx_diag_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; Word16 exp_cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + Word16 exp_real_tmp = 0, exp_imag_tmp = 0; +#endif Word16 q_tc = q_tc_in; move16(); +#ifndef OBJ_EDITING_API Word16 ch, nchan_transport, nchan_out, nchan_out_woLFE, i; Word16 slot_idx, bin_idx; Word32 ivas_total_brate; +#else + Word16 ch, nchan_transport, i; + Word16 slot_idx; +#endif + Word16 output_frame; +#ifndef OBJ_EDITING_API /* Direct Response/EFAP Gains */ Word32 direct_response_fx[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN]; +#endif PARAM_ISM_DEC_HANDLE hParamIsmDec; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; Word16 fade_len; /* Initialization */ +#ifndef OBJ_EDITING_API set32_fx( &direct_response_fx[0][0], 0, MAX_NUM_OBJECTS * PARAM_ISM_MAX_CHAN ); +#endif hParamIsmDec = st_ivas->hParamIsmDec; assert( hParamIsmDec ); hSpatParamRendCom = st_ivas->hSpatParamRendCom; @@ -1078,6 +1114,7 @@ void ivas_param_ism_dec_digest_tc_fx( nchan_transport = st_ivas->nchan_transport; move16(); +#ifndef OBJ_EDITING_API ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; move32(); @@ -1100,9 +1137,11 @@ void ivas_param_ism_dec_digest_tc_fx( nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; move16(); } +#endif push_wmops( "ivas_param_ism_dec" ); +#ifndef OBJ_EDITING_API /* general setup */ ivas_jbm_dec_get_adapted_linear_interpolator_fx( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hParamIsmDec->hParamIsmRendering->interpolator_fx ); @@ -1185,6 +1224,7 @@ void ivas_param_ism_dec_digest_tc_fx( } } } +#endif IF( st_ivas->hDecoderConfig->Opt_tsm ) { @@ -1220,6 +1260,8 @@ void ivas_param_ism_dec_digest_tc_fx( hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp = sub( 31, q_tc ); move16(); } + +#ifndef OBJ_EDITING_API Word16 scale_factor_real, scale_factor_imag; Word16 current_idx; exp_real_tmp = hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp; @@ -1245,8 +1287,11 @@ void ivas_param_ism_dec_digest_tc_fx( exp_imag_tmp = add( exp_imag_tmp, scale_factor_imag ); scale_sig32( &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands, -scale_factor_real ); // Q(31-(exp_real_tmp)) scale_sig32( &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands, -scale_factor_imag ); // Q(31-(exp_imag_tmp)) +#endif } } + +#ifndef OBJ_EDITING_API /* Obtain Mixing Matrix on a frame-level */ FOR( bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++ ) { @@ -1257,12 +1302,231 @@ void ivas_param_ism_dec_digest_tc_fx( ivas_param_ism_compute_mixing_matrix_fx( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response_fx, nchan_transport, nchan_out_woLFE, cx_diag_fx, exp_cx_diag, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx ); +#endif pop_wmops(); return; } +#ifdef OBJ_EDITING_API + + +/*-------------------------------------------------------------------------* + * ivas_param_ism_dec_prepare_renderer_fx() + * + * + *-------------------------------------------------------------------------*/ + +void ivas_param_ism_dec_dequant_md_fx( + Decoder_Struct *st_ivas ) +{ + /* De-quantization */ + IF( !( EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, FRAME_NO_DATA ) ) ) + { + ivas_param_ism_dec_dequant_DOA_fx( st_ivas->hParamIsmDec, st_ivas->nchan_ism ); + ivas_param_ism_dec_dequant_powrat_fx( st_ivas->hParamIsmDec ); + st_ivas->hISMDTX.dtx_flag = 0; + move16(); + } + ELSE + { + st_ivas->hISMDTX.dtx_flag = 1; + move16(); + } + + return; +} + +/*-------------------------------------------------------------------------* + * ivas_param_ism_dec_prepare_renderer_fx() + * + * + *-------------------------------------------------------------------------*/ + +void ivas_param_ism_dec_prepare_renderer_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const Word16 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; + Word32 cx_diag_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + Word16 exp_cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + Word16 exp_real_tmp = 0, exp_imag_tmp = 0; + Word32 ivas_total_brate; + /* Direct Response/EFAP Gains */ + Word32 direct_response_fx[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN]; + PARAM_ISM_DEC_HANDLE hParamIsmDec; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + + /* Initialization */ + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + assert( hSpatParamRendCom ); + move32(); + hParamIsmDec = st_ivas->hParamIsmDec; + assert( hParamIsmDec ); + move32(); + nchan_transport = st_ivas->nchan_transport; + move16(); + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + + /* Initialization */ + + hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp = 25; + move16(); + hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp = 25; + move16(); + IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) + { + nchan_out = st_ivas->nchan_ism; + move16(); + nchan_out_woLFE = nchan_out; + move16(); + st_ivas->hDecoderConfig->nchan_out = nchan_out; + move16(); + } + ELSE + { + nchan_out = add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe ); + nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; + move16(); + } + push_wmops( "ivas_param_ism_dec_digest_tc" ); + + /* general setup */ + ivas_jbm_dec_get_adapted_linear_interpolator_fx( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hParamIsmDec->hParamIsmRendering->interpolator_fx ); + + ivas_dirac_dec_set_md_map_fx( st_ivas, nCldfbSlots ); + /* set buffers to zero */ + + set_zero_fx( &cx_diag_fx[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX ); + set16_zero_fx( &exp_cx_diag[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX ); + + /* Frame-level Processing */ + /* De-quantization */ + test(); + IF( !( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) ) + { + ivas_param_ism_dec_dequant_DOA_fx( hParamIsmDec, st_ivas->nchan_ism ); + ivas_param_ism_dec_dequant_powrat_fx( hParamIsmDec ); + st_ivas->hISMDTX.dtx_flag = 0; + move16(); + } + ELSE + { + st_ivas->hISMDTX.dtx_flag = 1; + move16(); + } + + /* obtain the direct response using EFAP */ + IF( !( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) ) + { + FOR( i = 0; i < st_ivas->nchan_ism; i++ ) + { + efap_determine_gains_fx( st_ivas->hEFAPdata, direct_response_fx[i], hParamIsmDec->azimuth_values_fx[i], hParamIsmDec->elevation_values_fx[i], EFAP_MODE_EFAP ); + } + } + ELSE + { + Word16 j; + + FOR( i = 0; i < st_ivas->nchan_ism; i++ ) + { + FOR( j = 0; j < nchan_out_woLFE; j++ ) + { + IF( EQ_16( i, j ) ) + { + direct_response_fx[i][j] = ONE_IN_Q30; + move32(); + } + ELSE + { + direct_response_fx[i][j] = 0; + move32(); + } + } + } + + FOR( j = 0; j < nchan_out_woLFE; j++ ) + { + IF( hParamIsmDec->azimuth_values_fx[j] > 0 ) + { + hParamIsmDec->hParamIsmRendering->proto_matrix_fx[j] = 32767; // (1.0f in Q15) - 1 + move16(); + hParamIsmDec->hParamIsmRendering->proto_matrix_fx[nchan_out_woLFE + j] = 0; + move16(); + } + ELSE + { + IF( hParamIsmDec->azimuth_values_fx[j] < 0 ) + { + hParamIsmDec->hParamIsmRendering->proto_matrix_fx[j] = 0; + move16(); + hParamIsmDec->hParamIsmRendering->proto_matrix_fx[nchan_out_woLFE + j] = 32767; // (1.0f in Q15) - 1 + move16(); + } + ELSE /* == 0.0f */ + { + hParamIsmDec->hParamIsmRendering->proto_matrix_fx[j] = ONE_IN_Q14; // Q15 + move16(); + hParamIsmDec->hParamIsmRendering->proto_matrix_fx[nchan_out_woLFE + j] = ONE_IN_Q14; // Q15 + move16(); + } + } + } + } + + FOR( ch = 0; ch < nchan_transport; ch++ ) + { + /* CLDFB Analysis */ + FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { + Word16 scale_factor_real, scale_factor_imag; + Word16 current_idx; + exp_real_tmp = hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp; + move16(); + exp_imag_tmp = hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp; + move16(); + current_idx = add( imult1616( imult1616( slot_idx, hSpatParamRendCom->num_freq_bands ), nchan_transport ), imult1616( ch, hSpatParamRendCom->num_freq_bands ) ); + scale_factor_real = getScaleFactor32( &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands ); + scale_factor_imag = getScaleFactor32( &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands ); + scale_sig32( &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands, scale_factor_real ); // Q(31-(exp_real_tmp-scale_factor_real)) + scale_sig32( &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands, scale_factor_imag ); // Q(31-(exp_imag_tmp-scale_factor_imag)) + exp_real_tmp = sub( exp_real_tmp, scale_factor_real ); + exp_imag_tmp = sub( exp_imag_tmp, scale_factor_imag ); + ivas_param_ism_collect_slot_fx( hParamIsmDec, + &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[current_idx], + exp_real_tmp, + &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], + exp_imag_tmp, + ch, + cx_diag_fx, exp_cx_diag ); + + exp_real_tmp = add( exp_real_tmp, scale_factor_real ); + exp_imag_tmp = add( exp_imag_tmp, scale_factor_imag ); + scale_sig32( &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands, -scale_factor_real ); // Q(31-(exp_real_tmp)) + scale_sig32( &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands, -scale_factor_imag ); // Q(31-(exp_imag_tmp)) + } + } + + /* Obtain Mixing Matrix on a frame-level */ + FOR( bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++ ) + { + set32_fx( hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx[bin_idx], 0, PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX ); + } + + /* Compute mixing matrix */ + ivas_param_ism_compute_mixing_matrix_fx( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response_fx, nchan_transport, nchan_out_woLFE, cx_diag_fx, exp_cx_diag, + hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx ); + + + pop_wmops(); + + return; +} +#endif + /*-------------------------------------------------------------------------* * ivas_ism_param_dec_tc_gain_ajust() * @@ -1666,6 +1930,20 @@ void ivas_param_ism_dec_render_fx( /* store MetaData parameters */ FOR( ch = 0; ch < st_ivas->nchan_ism; ch++ ) { +#ifdef OBJ_EDITING_API + IF( GT_32( st_ivas->hParamIsmDec->azimuth_values_fx[ch], 754974720 ) /*180.f in Q22*/ ) + { + st_ivas->hIsmMetaData[ch]->azimuth_fx = L_sub( st_ivas->hParamIsmDec->edited_azimuth_values_fx[ch], 1509949440 ) /*360.0F in Q22*/; + move32(); + } + ELSE + { + st_ivas->hIsmMetaData[ch]->azimuth_fx = st_ivas->hParamIsmDec->edited_azimuth_values_fx[ch]; + move32(); + } + st_ivas->hIsmMetaData[ch]->elevation_fx = st_ivas->hParamIsmDec->edited_elevation_values_fx[ch]; + move32(); +#else IF( GT_32( st_ivas->hParamIsmDec->azimuth_values_fx[ch], 754974720 ) /*180.f in Q22*/ ) { st_ivas->hIsmMetaData[ch]->azimuth_fx = L_sub( st_ivas->hParamIsmDec->azimuth_values_fx[ch], 1509949440 ) /*360.0F in Q22*/; @@ -1676,6 +1954,7 @@ void ivas_param_ism_dec_render_fx( st_ivas->hIsmMetaData[ch]->azimuth_fx = st_ivas->hParamIsmDec->azimuth_values_fx[ch]; move32(); } +#endif st_ivas->hIsmMetaData[ch]->elevation_fx = st_ivas->hParamIsmDec->elevation_values_fx[ch]; move32(); @@ -1705,12 +1984,16 @@ void ivas_param_ism_params_to_masa_param_mapping_fx( Word16 azimuth[2]; Word16 elevation[2]; Word16 power_ratio_fx[2]; /* Q15 */ +#ifndef OBJ_EDITING_API Word32 ivas_total_brate; +#endif + hParamIsmDec = st_ivas->hParamIsmDec; hSpatParamRendCom = st_ivas->hSpatParamRendCom; nBins = hSpatParamRendCom->num_freq_bands; move16(); +#ifndef OBJ_EDITING_API ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; move32(); @@ -1727,6 +2010,7 @@ void ivas_param_ism_params_to_masa_param_mapping_fx( st_ivas->hISMDTX.dtx_flag = 1; move16(); } +#endif IF( GT_16( st_ivas->nchan_ism, 1 ) ) { @@ -1767,6 +2051,15 @@ void ivas_param_ism_params_to_masa_param_mapping_fx( { brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx]; move16(); +#ifdef OBJ_EDITING_API + brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1]; + move16(); + + azimuth[0] = extract_l( L_shr( L_add( hParamIsmDec->edited_azimuth_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]], ( 1 << 21 ) ), 22 ) ); // Q0 + move16(); + elevation[0] = extract_l( L_shr( L_add( hParamIsmDec->edited_elevation_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]], ( 1 << 21 ) ), 22 ) ); // Q0 + move16(); +#else brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1]; move16(); @@ -1774,12 +2067,21 @@ void ivas_param_ism_params_to_masa_param_mapping_fx( move16(); elevation[0] = extract_l( L_shr( L_add( hParamIsmDec->elevation_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]], ( 1 << 21 ) ), 22 ) ); // Q0 move16(); +#endif power_ratio_fx[0] = hParamIsmDec->power_ratios_fx[band_idx][0][0]; move16(); + +#ifdef OBJ_EDITING_API + azimuth[1] = extract_l( L_shr( L_add( hParamIsmDec->edited_azimuth_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]], ( 1 << 21 ) ), 22 ) ); // Q0 + move16(); + elevation[1] = extract_l( L_shr( L_add( hParamIsmDec->edited_elevation_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]], ( 1 << 21 ) ), 22 ) ); // Q0 + move16(); +#else azimuth[1] = extract_l( L_shr( L_add( hParamIsmDec->azimuth_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]], ( 1 << 21 ) ), 22 ) ); // Q0 move16(); elevation[1] = extract_l( L_shr( L_add( hParamIsmDec->elevation_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]], ( 1 << 21 ) ), 22 ) ); // Q0 move16(); +#endif power_ratio_fx[1] = hParamIsmDec->power_ratios_fx[band_idx][0][1]; move16(); diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index 11a06abd496fb5e39b958facbbad0700779a5c30..36234bf4713f711712cbb3f3b63a4b3a0c6b42b3 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -259,16 +259,28 @@ void ivas_ism_render_sf_fx( { if ( GE_16( subframe_idx, ism_md_subframe_update_jbm ) ) { +#ifdef OBJ_EDITING_API + rotateAziEle_fx( extract_l( L_shr( st_ivas->hIsmMetaData[i]->edited_azimuth_fx, 22 ) ), extract_l( L_shr( st_ivas->hIsmMetaData[i]->edited_elevation_fx, 22 ) ), &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat_fx[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); +#else rotateAziEle_fx( extract_l( L_shr( st_ivas->hIsmMetaData[i]->azimuth_fx, 22 ) ), extract_l( L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, 22 ) ), &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat_fx[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); +#endif } else { +#ifdef OBJ_EDITING_API + rotateAziEle_fx( extract_l( L_shr( st_ivas->hIsmMetaData[i]->edited_azimuth_fx, 22 ) ), extract_l( L_shr( st_ivas->hIsmMetaData[i]->edited_elevation_fx, 22 ) ), &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat_fx[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); +#else rotateAziEle_fx( extract_l( L_shr( st_ivas->hIsmMetaData[i]->last_azimuth_fx, 22 ) ), extract_l( L_shr( st_ivas->hIsmMetaData[i]->last_elevation_fx, 22 ) ), &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat_fx[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup ); +#endif } IF( st_ivas->hEFAPdata != NULL ) { efap_determine_gains_fx( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains_fx[i], L_shl( azimuth, 22 ), L_shl( elevation, 22 ), EFAP_MODE_EFAP ); +#ifdef OBJ_EDITING_API + // TODO: Enable gain editing feature + // v_multc_fixed( st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIsmMetaData[i]->edited_gain_fx, st_ivas->hIsmRendererData->gains_fx[i], nchan_out_woLFE ); // Q30, Q30 --> Q30 +#endif } } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index fa1f9b39dc144cdeb90d480adcf6a5ecf900bfb9..767979d8aaf16d1430a786c3ff53a1156a9416e8 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -198,6 +198,9 @@ ivas_error ivas_jbm_dec_tc_fx( } } ivas_ism_dtx_limit_noise_energy_for_near_silence_fx( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport, Q_cngNoiseLevel ); +#ifdef OBJ_EDITING_API + ivas_param_ism_dec_dequant_md_fx( st_ivas ); +#endif } ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) { @@ -205,6 +208,9 @@ ivas_error ivas_jbm_dec_tc_fx( { return error; } +#ifdef OBJ_EDITING_API + ivas_param_ism_dec_dequant_md_fx( st_ivas ); +#endif } ELSE /* ISM_MODE_DISC */ { @@ -1617,6 +1623,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( } n_render_timeslots = idiv1616( st_ivas->hTcBuffer->n_samples_available, st_ivas->hTcBuffer->n_samples_granularity ); +#ifndef OBJ_EDITING_API test(); IF( EQ_16( st_ivas->hTcBuffer->tc_buffer_mode, TC_BUFFER_MODE_BUFFER ) ) { @@ -1634,12 +1641,15 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( { ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); } - ELSE IF( EQ_16( st_ivas->ivas_format, ISM_FORMAT ) ) + ELSE +#endif + IF( EQ_16( st_ivas->ivas_format, ISM_FORMAT ) ) { /* Rendering */ IF( EQ_16( st_ivas->ism_mode, ISM_MODE_PARAM ) ) { test(); +#ifndef OBJ_EDITING_API test(); test(); IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_16( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) ) @@ -1648,17 +1658,22 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( ivas_param_ism_params_to_masa_param_mapping_fx( st_ivas ); } - ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_PARAM_ISM ) || EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + ELSE +#endif + IF( EQ_16( st_ivas->renderer_type, RENDERER_PARAM_ISM ) || EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) { ivas_param_ism_dec_digest_tc_fx( st_ivas, n_render_timeslots, p_data_f_fx, Q11 ); } } +#ifndef OBJ_EDITING_API ELSE /* ISM_MODE_DISC */ { ivas_ism_dec_digest_tc_fx( st_ivas ); } +#endif } +#ifndef OBJ_EDITING_API ELSE IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, MASA_FORMAT ) ) { IF( st_ivas->hSCE[0] ) @@ -1885,6 +1900,16 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( ivas_sba_dec_digest_tc_fx( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); } } +#else + ELSE IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) ) + { + test(); + IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMMC ) && EQ_16( st_ivas->hTcBuffer->tc_buffer_mode, TC_BUFFER_MODE_RENDERER ) ) + { + ivas_param_mc_dec_digest_tc_fx( st_ivas, (UWord8) n_render_timeslots, (Word32 **) p_data_f_fx, Q11 ); + } + } +#endif pop_wmops(); return; @@ -2231,7 +2256,44 @@ ivas_error ivas_jbm_dec_render_fx( ivas_ism_render_sf_fx( st_ivas, st_ivas->renderer_type, p_output_fx, *nSamplesRendered ); /* add already rendered SBA part */ - ivas_osba_stereo_add_channels_fx( p_tc_fx, p_output_fx, ONE_IN_Q11, nchan_out, st_ivas->nchan_ism, *nSamplesRendered ); +#ifdef OBJ_EDITING_API + test(); + IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_16( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) + { + Word32 gain = st_ivas->hSbaIsmData->gain_bed_fx; + test(); + // TODO: Enable gain editing feature (NE_32 ( gain, ONE_IN_Q_gain ) ) + IF( NE_32( gain, ONE_IN_Q31 ) && GT_32( gain, 0 ) ) + { + FOR( n = 0; n < nchan_out; n++ ) + { + FOR( i = 0; i < *nSamplesRendered; i++ ) + { + Word32 tmp1 = Mpy_32_32( p_tc_fx[n + st_ivas->nchan_ism][i], gain ); // Q11 + Q30 - 32 = Q9 + tmp1 = L_shl( tmp1, 2 ); // Q9 --> Q11 + p_output_fx[n][i] = L_add_sat( p_output_fx[n][i], tmp1 ); // Q11 + } + } + } + ELSE + { + FOR( n = 0; n < nchan_out; n++ ) + { + FOR( n = 0; n < nchan_out; n++ ) + { + FOR( i = 0; i < *nSamplesRendered; i++ ) + { + p_output_fx[n][i] = L_add_sat( p_output_fx[n][i], p_tc_fx[n + st_ivas->nchan_ism][i] ); // Q11 + } + } + } + } + } + ELSE +#endif + { + ivas_osba_stereo_add_channels_fx( p_tc_fx, p_output_fx, ONE_IN_Q11, nchan_out, st_ivas->nchan_ism, *nSamplesRendered ); + } } ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) || EQ_32( st_ivas->renderer_type, RENDERER_OSBA_LS ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) { @@ -4387,3 +4449,293 @@ 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 */ +) +{ + Word16 n, n_render_timeslots, tmp, exp; + + push_wmops( "ivas_jbm_dec_feed_tc_to_rendererer" ); + + /* n_render_timeslots = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; */ + tmp = BASOP_Util_Divide1616_Scale( st_ivas->hTcBuffer->n_samples_available, st_ivas->hTcBuffer->n_samples_granularity, &exp ); + n_render_timeslots = shr( tmp, sub( 15, exp ) ); // Q0 + + + IF( EQ_16( st_ivas->hTcBuffer->tc_buffer_mode, TC_BUFFER_MODE_BUFFER ) ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + + test(); + test(); + test(); + IF( ( EQ_16( st_ivas->ivas_format, MASA_FORMAT ) || EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) && EQ_16( 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( EQ_16( st_ivas->ivas_format, STEREO_FORMAT ) ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + } + ELSE IF( EQ_16( st_ivas->ivas_format, ISM_FORMAT ) ) + { + /* Rendering */ + IF( EQ_16( st_ivas->ism_mode, ISM_MODE_PARAM ) ) + { + test(); + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_16( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) ) + { + ivas_dirac_dec_set_md_map_fx( st_ivas, n_render_timeslots ); + + ivas_param_ism_params_to_masa_param_mapping_fx( st_ivas ); + } + ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_PARAM_ISM ) || EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + { + ivas_param_ism_dec_prepare_renderer_fx( st_ivas, n_render_timeslots ); + } + } + ELSE /* ISM_MODE_DISC */ + { + ivas_ism_dec_digest_tc_fx( st_ivas ); + } + } + ELSE IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, MASA_FORMAT ) ) + { + IF( st_ivas->hSCE[0] ) + { + Word16 shift = getScaleFactor32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); + IF( LT_16( sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) + { + shift = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, 4 ); + } + scale_sig32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); // Q(31-cngNoiseLevelExp+shift) + st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ); + } + ivas_sba_dec_digest_tc_fx( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + ELSE IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) + { + + IF( EQ_16( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) + { + ivas_ism_dec_digest_tc_fx( st_ivas ); + + test(); + test(); + test(); + test(); + /* delay the objects here for all renderers where it is needed */ + IF( + ( + EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || + EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || + EQ_16( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) || + EQ_16( st_ivas->renderer_type, RENDERER_OSBA_LS ) || + EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) && + ( NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) ) + { + FOR( n = 0; n < st_ivas->nchan_ism; n++ ) + { + delay_signal32_fx( st_ivas->hTcBuffer->tc_fx[n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hSbaIsmData->delayBuffer_fx[n], st_ivas->hSbaIsmData->delayBuffer_size ); + } + } + + IF( !st_ivas->sba_dirac_stereo_flag ) + { + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ) + { + Word16 temp, temp_e; + temp = BASOP_Util_Divide1616_Scale( st_ivas->hTcBuffer->n_samples_granularity, st_ivas->hSpatParamRendCom->slot_size, &temp_e ); + n_render_timeslots = extract_l( L_shr( L_mult0( n_render_timeslots, temp ), sub( 15, temp_e ) ) ); + } + + IF( st_ivas->hSCE[0] ) + { + Word16 shift = getScaleFactor32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); + if ( LT_16( sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) + { + shift = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, 4 ); + } + scale_sig32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); // Q(31-cngNoiseLevelExp+shift) + st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ); + } + ivas_sba_dec_digest_tc_fx( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + } + ELSE + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + + IF( st_ivas->hSCE[0] ) + { + Word16 shift = getScaleFactor32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); + if ( LT_16( sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) + { + shift = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, 4 ); + } + scale_sig32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); // Q(31-cngNoiseLevelExp+shift) + st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ); + } + ivas_sba_dec_digest_tc_fx( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + } + ELSE IF( EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) + { + test(); + IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_MIX_EXT ) || EQ_32( 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 + { + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + n_render_timeslots = i_mult( n_render_timeslots, idiv1616( st_ivas->hTcBuffer->n_samples_granularity, st_ivas->hSpatParamRendCom->slot_size ) ); + } + + IF( st_ivas->hSCE[0] ) + { + Word16 shift = getScaleFactor32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); + if ( LT_16( sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) + { + shift = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, 4 ); + } + scale_sig32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); // Q(31- (st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp - shift) + st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ); + move16(); + } + ivas_sba_dec_digest_tc_fx( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + + IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + ivas_ism_dec_digest_tc_fx( st_ivas ); + } + } + + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_16( st_ivas->renderer_type, RENDERER_DIRAC ) ) + { + Word16 num_objects; + + /* Delay the signal to match CLDFB delay. Delay the whole buffer. */ + num_objects = 0; + move16(); + + test(); + test(); + IF( ( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ) + { + num_objects = 1; + move16(); + } + ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + num_objects = st_ivas->nchan_ism; + move16(); + } + FOR( n = 0; n < num_objects; n++ ) + { + test(); + IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ) + { + v_multc_fixed_16( st_ivas->hTcBuffer->tc_fx[CPE_CHANNELS + n], OMASA_TDREND_MATCHING_GAIN_FX, st_ivas->hTcBuffer->tc_fx[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available ); + } + delay_signal32_fx( st_ivas->hTcBuffer->tc_fx[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hMasaIsmData->delayBuffer_fx[n], st_ivas->hMasaIsmData->delayBuffer_size ); + } + } + } + ELSE IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) ) + { + IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCT ) ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + } + ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) + { + ivas_mc_paramupmix_dec_digest_tc( st_ivas, (UWord8) n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMMC ) ) + { + Word16 nchan_transport = st_ivas->nchan_transport; + move16(); + Word16 nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + Word16 nchan_out_cov; + test(); + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + } + ELSE IF( EQ_16( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) + { + nchan_out_cov = nchan_out_transport; + move16(); + } + ELSE IF( EQ_16( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + } + ELSE + { + nchan_out_cov = nchan_out_transport; + move16(); + } + + scale_sig32( st_ivas->hParamMC->proto_matrix_int_fx, st_ivas->hParamMC->proto_matrix_int_len, -1 ); // Q(31-1) + st_ivas->hParamMC->proto_matrix_int_e = 1; + move16(); + + ivas_param_mc_dec_prepare_renderer( st_ivas, (UWord8) n_render_timeslots ); + + scale_sig32( st_ivas->hParamMC->proto_matrix_int_fx, st_ivas->hParamMC->proto_matrix_int_len, 1 ); // Q(31-1+1) + + Word16 shift; + FOR( Word16 param_band_idx = 0; param_band_idx < st_ivas->hParamMC->num_param_bands_synth; param_band_idx++ ) + { + shift = getScaleFactor32( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx], s_min( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_len, nchan_transport * nchan_transport ) ); + scale_sig32( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx], s_min( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_len, i_mult( nchan_transport, nchan_transport ) ), shift ); // Q(31-cx_old_e+shift) + st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = sub( st_ivas->hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx], shift ); + move16(); + + shift = getScaleFactor32( st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx], nchan_out_cov * nchan_out_cov ); + scale_sig32( st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx], i_mult( nchan_out_cov, nchan_out_cov ), shift ); // Q(31-cy_old_e+shift) + st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = sub( st_ivas->hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx], shift ); + move16(); + } + } + ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) ) + { + IF( st_ivas->hSCE[0] ) + { + Word16 shift = getScaleFactor32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); + if ( LT_16( sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) + { + shift = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, 4 ); + } + scale_sig32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); // Q(31-cngNoiseLevelExp+shift) + st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ); + move16(); + } + ivas_sba_dec_digest_tc_fx( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + } + + pop_wmops(); + return; +} +#endif diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 243377a498dbcba545268605ebfa8bb7ada48930..250b37675be3e1d0c4432fa5bc2863ddc064b91b 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -1519,40 +1519,53 @@ void ivas_param_mc_dec_digest_tc_fx( Word16 transport_f_e ) { PARAM_MC_DEC_HANDLE hParamMC; +#ifdef OBJ_EDITING_API + Word16 ch, slot_idx; + Word16 nchan_transport; +#else Word16 i, ch; Word16 is_next_band, skip_next_band; Word16 slot_idx, param_band_idx; Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; Word16 nchan_out_cov; +#endif /*CLDFB*/ - /* format converter */ - Word16 channel_active[MAX_OUTPUT_CHANNELS]; - IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; hParamMC = st_ivas->hParamMC; assert( hParamMC ); + +#ifndef OBJ_EDITING_API Word32 *pCx, *pCx_imag; Word32 cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_e) Word32 cx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_e) Word32 cx_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_next_band_e) Word32 cx_imag_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_next_band_e) + Word32 real_part_fx, imag_part_fx, L_tmp1, L_tmp2; Word16 cx_buff_e[2][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; Word16 cx_e; Word16 cx_imag_e, tmp_e; Word16 cx_imag_next_band_e, cx_next_band_e; + + Word16 max_e; + + /* format converter */ + Word16 channel_active[MAX_OUTPUT_CHANNELS]; + IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; +#endif Word16 qout = 0; move16(); - Word32 real_part_fx, imag_part_fx, L_tmp1, L_tmp2; - - Word16 max_e; push_wmops( "param_mc_dec_digest_tc" ); +#ifndef OBJ_EDITING_API set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); +#endif nchan_transport = st_ivas->nchan_transport; move16(); + +#ifndef OBJ_EDITING_API nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); test(); @@ -1629,13 +1642,17 @@ void ivas_param_mc_dec_digest_tc_fx( move16(); cx_imag_next_band_e = 0; move16(); +#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 Word32 RealBuffer_fx[CLDFB_NO_CHANNELS_MAX]; Word32 ImagBuffer_fx[CLDFB_NO_CHANNELS_MAX]; @@ -1652,8 +1669,12 @@ void ivas_param_mc_dec_digest_tc_fx( hParamMC->Cldfb_ImagBuffer_tc_e = qout; move16(); +#ifndef OBJ_EDITING_API } +#endif } + +#ifndef OBJ_EDITING_API IF( GE_16( slot_idx, shl( hParamMC->hMetadataPMC->attackIndex, 1 ) ) ) { FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) @@ -1693,8 +1714,10 @@ void ivas_param_mc_dec_digest_tc_fx( } } } +#endif } +#ifndef OBJ_EDITING_API Word16 tmp_cx_e, tmp_cx_imag_e; /* map from complex input covariance to real values */ FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) @@ -1826,12 +1849,312 @@ void ivas_param_mc_dec_digest_tc_fx( } } } +#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 UWord8 nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +) +{ + Word16 i; + Word16 is_next_band, skip_next_band; + Word16 slot_idx, param_band_idx; + Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; + Word16 nchan_out_cov; + PARAM_MC_DEC_HANDLE hParamMC; + + Word32 *pCx, *pCx_imag; + Word32 cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_e) + Word32 cx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_e) + Word32 cx_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_next_band_e) + Word32 cx_imag_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_next_band_e) + Word32 real_part_fx, imag_part_fx, L_tmp1, L_tmp2; + + Word16 cx_buff_e[2][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word16 cx_e; + Word16 cx_imag_e, tmp_e; + Word16 cx_imag_next_band_e, cx_next_band_e; + + Word16 max_e; + + /* format converter */ + Word16 channel_active[MAX_OUTPUT_CHANNELS]; + IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; + + hParamMC = st_ivas->hParamMC; + assert( hParamMC ); + + set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); + + nchan_transport = st_ivas->nchan_transport; + move16(); + + nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + + test(); + test(); + IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + nchan_out_cldfb = BINAURAL_CHANNELS; + move16(); + set16_fx( channel_active, 1, nchan_out_cldfb ); + nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + ELSE IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) + { + nchan_out_cov = nchan_out_transport; + move16(); + nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + ELSE IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + nchan_out_cldfb = nchan_out_cov; + move16(); + set16_fx( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hOutSetup; + } + ELSE + { + nchan_out_cov = nchan_out_transport; + move16(); + nchan_out_cldfb = nchan_out_transport; + move16(); + set16_fx( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + + /* adapt transient position */ + IF( hParamMC->hMetadataPMC->bAttackPresent ) + { + hParamMC->hMetadataPMC->attackIndex = s_max( 0, add( hParamMC->hMetadataPMC->attackIndex, shr( sub( nCldfbSlots, DEFAULT_JBM_CLDFB_TIMESLOTS ), 1 ) ) ); + move16(); + } + /* adapt subframes */ + hParamMC->num_slots = nCldfbSlots; + move16(); + hParamMC->slots_rendered = 0; + move16(); + hParamMC->subframes_rendered = 0; + move16(); + ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); + st_ivas->hTcBuffer->nb_subframes = hParamMC->nb_subframes; + move16(); + Copy( hParamMC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hParamMC->nb_subframes ); + + ivas_param_mc_dec_compute_interpolator_fx( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator_fx ); + + /* 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_fx( cx_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( cx_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( cx_next_band_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( cx_imag_next_band_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + + cx_e = 0; + move16(); + cx_imag_e = 0; + move16(); + cx_next_band_e = 0; + move16(); + cx_imag_next_band_e = 0; + move16(); + + /* slot loop for gathering the input data */ + FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { + IF( GE_16( slot_idx, shl( hParamMC->hMetadataPMC->attackIndex, 1 ) ) ) + { + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + test(); + IF( is_next_band && skip_next_band ) + { + CONTINUE; + } + IF( is_next_band ) + { + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, + &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, + cx_next_band_fx, + &cx_next_band_e, + cx_imag_next_band_fx, + &cx_imag_next_band_e, + hParamMC, + add( param_band_idx, is_next_band ), + nchan_transport ); + } + ELSE + { + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, + &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, + cx_fx, + &cx_e, + cx_imag_fx, + &cx_imag_e, + hParamMC, + add( param_band_idx, is_next_band ), + nchan_transport ); + } + } + } + } + Word16 tmp_cx_e, tmp_cx_imag_e; + /* map from complex input covariance to real values */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + test(); + IF( is_next_band && skip_next_band ) + { + CONTINUE; + } + /* Cx for transport channels */ + IF( is_next_band ) + { + pCx = &cx_next_band_fx[0]; + pCx_imag = &cx_imag_next_band_fx[0]; + tmp_cx_e = cx_next_band_e; + tmp_cx_imag_e = cx_imag_next_band_e; + } + ELSE + { + pCx = &cx_fx[0]; + pCx_imag = &cx_imag_fx[0]; + tmp_cx_e = cx_e; + tmp_cx_imag_e = cx_imag_e; + } + + FOR( i = 0; i < nchan_transport * nchan_transport; i++ ) + { + real_part_fx = pCx[i]; // Q(31 - cx_buff_e) + imag_part_fx = pCx_imag[i]; + move32(); + move32(); + cx_buff_e[is_next_band][i] = tmp_cx_e; + move16(); + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + IF( LT_16( param_band_idx, hParamMC->max_param_band_abs_cov ) ) + { + L_tmp1 = Mpy_32_32( real_part_fx, real_part_fx ); + L_tmp2 = Mpy_32_32( imag_part_fx, imag_part_fx ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, add( tmp_cx_e, tmp_cx_e ), L_tmp2, add( tmp_cx_imag_e, tmp_cx_imag_e ), &tmp_e ); + pCx[i] = Sqrt32( L_tmp1, &tmp_e ); + move32(); + cx_buff_e[is_next_band][i] = tmp_e; + move16(); + } + ELSE + { + pCx[i] = real_part_fx; + move32(); + cx_buff_e[is_next_band][i] = tmp_cx_e; + move16(); + } + } + } + + max_e = cx_buff_e[0][0]; + move16(); + + /* Cx for transport channels */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) + { + + IF( LT_16( max_e, cx_buff_e[is_next_band][i] ) ) + { + max_e = cx_buff_e[is_next_band][i]; + } + } + } + /* Cx for transport channels */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) + { + if ( is_next_band == 0 ) + { + cx_fx[i] = L_shr( cx_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); + } + else + { + cx_next_band_fx[i] = L_shr( cx_next_band_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); + } + move32(); + } + } + cx_e = max_e; + move16(); + + + /* 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*/ + + test(); + test(); + IF( hParamMC->hMetadataPMC->bAttackPresent && ( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) ) + { + Word16 len = imult1616( nchan_transport, nchan_transport ); + Word16 sc = s_min( getScaleFactor32( cx_fx, len ), getScaleFactor32( cx_next_band_fx, len ) ); + IF( EQ_16( sc, 0 ) ) + { + Scale_sig32( cx_fx, len, -Q1 ); // add one bit head room + Scale_sig32( cx_next_band_fx, len, -Q1 ); // add one bit head room + cx_e = add( cx_e, Q1 ); + cx_next_band_e = add( cx_e, Q1 ); + } + v_add_fx( cx_fx, cx_next_band_fx, cx_fx, len ); + Copy32( cx_fx, cx_next_band_fx, len ); + } + + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + test(); + IF( is_next_band && skip_next_band ) + { + CONTINUE; + } + + IF( NE_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + IF( is_next_band ) + { + + ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_next_band_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); + } + ELSE + { + + ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); + } + } + } + } +} +#endif + /*------------------------------------------------------------------------- * ivas_param_mc_dec() * diff --git a/lib_dec/ivas_objectRenderer_internal_fx.c b/lib_dec/ivas_objectRenderer_internal_fx.c index 5e898d236581592d3e4595f9b3e25dec01e9c4d8..a97567c198c8f2f9348370572adeb9081d996c4e 100644 --- a/lib_dec/ivas_objectRenderer_internal_fx.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -210,9 +210,43 @@ ivas_error ivas_td_binaural_renderer_sf_fx( IF( EQ_16( subframe_idx, ism_md_subframe_update_jbm ) ) { - IF( ( error = TDREND_Update_object_positions_fx( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, st_ivas->hIsmMetaData ) ) != IVAS_ERR_OK ) +#ifdef OBJ_EDITING_API + test(); + IF( EQ_16( st_ivas->ivas_format, ISM_FORMAT ) || EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) { - return error; + ISM_METADATA_FRAME ismMetaData[MAX_NUM_OBJECTS]; + ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS]; + FOR( nS = 0; nS < nchan_ism; nS++ ) + { + ismMetaData[nS].azimuth_fx = st_ivas->hIsmMetaData[nS]->edited_azimuth_fx; + move32(); + ismMetaData[nS].elevation_fx = st_ivas->hIsmMetaData[nS]->edited_elevation_fx; + move32(); + ismMetaData[nS].radius_fx = st_ivas->hIsmMetaData[nS]->edited_radius_fx; + move16(); + ismMetaData[nS].yaw_fx = st_ivas->hIsmMetaData[nS]->edited_yaw_fx; + move32(); + ismMetaData[nS].pitch_fx = st_ivas->hIsmMetaData[nS]->edited_pitch_fx; + move32(); + ismMetaData[nS].non_diegetic_flag = st_ivas->hIsmMetaData[nS]->non_diegetic_flag; + move16(); + ismMetaData[nS].gain_fx = st_ivas->hIsmMetaData[nS]->edited_gain_fx; + move32(); + hIsmMetaData[nS] = &ismMetaData[nS]; + } + + IF( NE_16( ( error = TDREND_Update_object_positions_fx( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, hIsmMetaData ) ), IVAS_ERR_OK ) ) + { + return error; + } + } + else +#endif + { + IF( NE_16( error = TDREND_Update_object_positions_fx( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, st_ivas->hIsmMetaData ), IVAS_ERR_OK ) ) + { + return error; + } } } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index a4d03c644244da92f86ebf0715db44c0958a4139..edf9729cedb15a3b209b976647ac2e468033fb1f 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -463,6 +463,11 @@ typedef struct ivas_param_ism_dec_data_structure Word32 elevation_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS]; /* Q22 */ Word16 power_ratios_fx[MAX_PARAM_ISM_NBANDS][MAX_PARAM_ISM_NBLOCKS][MAX_PARAM_ISM_WAVE]; /* Q15 */ +#ifdef OBJ_EDITING_API + Word32 edited_azimuth_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS]; + Word32 edited_elevation_values_fx[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 */ @@ -715,6 +720,10 @@ typedef struct ivas_osba_data Word16 delayBuffer_size; Word16 delayBuffer_nchan; +#ifdef OBJ_EDITING_API + Word32 gain_bed_fx; +#endif + } SBA_ISM_DATA, *SBA_ISM_DATA_HANDLE; @@ -954,6 +963,10 @@ typedef struct ivas_masa_ism_data_structure Word16 azimuth_ism_edited[MAX_NUM_OBJECTS]; Word16 elevation_ism_edited[MAX_NUM_OBJECTS]; UWord8 ism_is_edited[MAX_NUM_OBJECTS]; +#ifdef OBJ_EDITING_API + Word32 gain_ism[MAX_NUM_OBJECTS]; + Word32 gain_masa; +#endif Word16 idx_separated_ism; Word16 azimuth_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index c87b4292c2582e7a4f7093557c8803bb9a4cf1ac..dc95fe00e9aac3e958d53d16508693f2c79debe5 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -150,6 +150,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 */ @@ -161,6 +169,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 */ Word16 *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ @@ -287,6 +311,10 @@ ivas_error IVAS_DEC_VoIP_GetSamples( void* jbmWriter #endif #endif +#ifdef OBJ_EDITING_API + , + bool *parametersAvailableForEditing +#endif ); ivas_error IVAS_DEC_Flush( diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 4a929f97edf910e4d2c5b864021a54fbd7d648e3..051876ff9e4d5342fa596c5cb2e12b7bc86c3095 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -99,7 +99,15 @@ struct IVAS_DEC #ifdef FIX_HRTF_LOAD UWord16 nSamplesFlushed; +#ifdef FIX_HRTF_LOAD_API + Word16 *flushbuffer; +#else Word16 flushbuffer[20 * 960 / 4]; // temp. hack +#endif +#ifdef OBJ_EDITING_API + bool hasEditableParameters; + bool enableParameterEditing; +#endif bool hasBeenPreparedRendering; #endif }; @@ -195,7 +203,16 @@ ivas_error IVAS_DEC_Open( move16(); move16(); #ifdef FIX_HRTF_LOAD +#ifdef OBJ_EDITING_API + hIvasDec->flushbuffer = NULL; +#else + // hIvasDec->flushbuffer = NULL; +#endif hIvasDec->nSamplesFlushed = 0; +#ifdef OBJ_EDITING_API + hIvasDec->hasEditableParameters = false; + hIvasDec->enableParameterEditing = false; +#endif hIvasDec->hasBeenPreparedRendering = false; #endif @@ -320,10 +337,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 ); @@ -418,6 +437,12 @@ void IVAS_DEC_Close( { free( ( *phIvasDec )->apaExecBuffer_fx ); } +#ifdef OBJ_EDITING_API + IF( ( *phIvasDec )->flushbuffer != NULL ) + { + free( ( *phIvasDec )->flushbuffer ); + } +#endif free( *phIvasDec ); *phIvasDec = NULL; phIvasDec = NULL; @@ -621,6 +646,20 @@ ivas_error IVAS_DEC_Configure( move16(); move16(); +#ifdef OBJ_EDITING_API + /* init flush buffer if necessary (only needed for binaural)*/ + test(); + test(); + test(); + test(); + test(); + IF( tsmEnabled && ( EQ_32( outputConfig, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) || EQ_32( outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) + { + hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 ) ); + set16_fx( (Word16 *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); + } +#endif + return IVAS_ERR_OK; } @@ -949,6 +988,14 @@ ivas_error IVAS_DEC_EnableVoIP( } #endif +#ifdef OBJ_EDITING_API + IF( hIvasDec->flushbuffer == NULL && ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) + { + hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 ) ); + set16_fx( (Word16 *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); + } +#endif + return IVAS_ERR_OK; } @@ -1092,17 +1139,26 @@ ivas_error IVAS_DEC_GetSamples( ) { ivas_error error; +#ifdef OBJ_EDITING_API + Word16 nSamplesToRender; + UWord16 nSamplesRendered, nSamplesRendered_loop; + UWord16 nOutChannels; +#else Word16 nOutSamplesElse, nSamplesToRender; UWord16 nSamplesRendered, nSamplesRendered_loop, l_ts, nTimeScalerOutSamples; UWord8 nTransportChannels, nOutChannels; +#endif nSamplesRendered = 0; nOutChannels = 0; nSamplesRendered_loop = 0; +#ifndef OBJ_EDITING_API l_ts = 0; nTransportChannels = 0; move16(); move16(); +#endif + move16(); move16(); move16(); @@ -1112,6 +1168,13 @@ ivas_error IVAS_DEC_GetSamples( { 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 ) { @@ -1176,138 +1239,157 @@ ivas_error IVAS_DEC_GetSamples( } ELSE { +#ifndef OBJ_EDITING_API /* check if we need to run the setup function */ test(); - IF( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ){ - /* setup */ + IF( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) + { + /* setup */ #ifdef FIX_HRTF_LOAD IF( NE_32( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels ) ), IVAS_ERR_OK ) ) #else IF( NE_32( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &nSamplesRendered_loop, pcmBuf + imult3216( nSamplesRendered, nOutChannels ) ) ), IVAS_ERR_OK ) ) #endif - { - return error; - } -} -{ - /* check if we need to run the setup function, tc decoding and feeding the renderer */ - test(); - IF( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) - { - Word16 nResidualSamples, nSamplesTcsScaled; - nSamplesRendered = add( nSamplesRendered, nSamplesRendered_loop ); - - test(); - IF( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && NE_16( (Word16) nTransportChannels, hIvasDec->nTransportChannelsOld ) ) - { - IF( NE_32( ( error = IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ) ), IVAS_ERR_OK ) ) { return error; } } - - /* IVAS decoder */ - IF( NE_32( ( error = IVAS_DEC_GetTcSamples( hIvasDec, hIvasDec->apaExecBuffer_fx, &nOutSamplesElse ) ), IVAS_ERR_OK ) ) - { - return error; - } - - /* JBM */ - IF( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) +#endif { - IF( apa_set_scale_fx( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) +#ifndef OBJ_EDITING_API + /* check if we need to run the setup function, tc decoding and feeding the renderer */ + test(); + IF( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) { - return IVAS_ERR_UNKNOWN; - } + Word16 nResidualSamples, nSamplesTcsScaled; + nSamplesRendered = add( nSamplesRendered, nSamplesRendered_loop ); - // tmp apaExecBuffer - IF( EQ_16( (Word16) hIvasDec->mode, IVAS_DEC_MODE_EVS ) ) - { - Word16 tmp_apaExecBuffer[APA_BUF]; - FOR( Word32 i = 0; i < APA_BUF_PER_CHANNEL * nTransportChannels; ++i ) + test(); + IF( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && NE_16( (Word16) nTransportChannels, hIvasDec->nTransportChannelsOld ) ) { - tmp_apaExecBuffer[i] = extract_l( L_shr( hIvasDec->apaExecBuffer_fx[i], Q11 ) ); // Q0 + IF( NE_32( ( error = IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ) ), IVAS_ERR_OK ) ) + { + return error; + } } - IF( apa_exec_fx( hIvasDec->hTimeScaler, tmp_apaExecBuffer, (UWord16) imult3216( hIvasDec->nSamplesFrame, nTransportChannels ), (UWord16) hIvasDec->tsm_max_scaling, tmp_apaExecBuffer, &nTimeScalerOutSamples ) != 0 ) + + /* IVAS decoder */ + IF( NE_32( ( error = IVAS_DEC_GetTcSamples( hIvasDec, hIvasDec->apaExecBuffer_fx, &nOutSamplesElse ) ), IVAS_ERR_OK ) ) { - return IVAS_ERR_UNKNOWN; + return error; } - FOR( Word32 i = 0; i < APA_BUF_PER_CHANNEL * nTransportChannels; ++i ) + + /* JBM */ + IF( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) { - hIvasDec->apaExecBuffer_fx[i] = L_shl( tmp_apaExecBuffer[i], Q11 ); // Q11 + IF( apa_set_scale_fx( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + + // tmp apaExecBuffer + IF( EQ_16( (Word16) hIvasDec->mode, IVAS_DEC_MODE_EVS ) ) + { + Word16 tmp_apaExecBuffer[APA_BUF]; + FOR( Word32 i = 0; i < APA_BUF_PER_CHANNEL * nTransportChannels; ++i ) + { + tmp_apaExecBuffer[i] = extract_l( L_shr( hIvasDec->apaExecBuffer_fx[i], Q11 ) ); // Q0 + } + IF( apa_exec_fx( hIvasDec->hTimeScaler, tmp_apaExecBuffer, (UWord16) imult3216( hIvasDec->nSamplesFrame, nTransportChannels ), (UWord16) hIvasDec->tsm_max_scaling, tmp_apaExecBuffer, &nTimeScalerOutSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + FOR( Word32 i = 0; i < APA_BUF_PER_CHANNEL * nTransportChannels; ++i ) + { + hIvasDec->apaExecBuffer_fx[i] = L_shl( tmp_apaExecBuffer[i], Q11 ); // Q11 + } + } + ELSE + { + IF( apa_exec_ivas_fx( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer_fx, (UWord16) imult3216( hIvasDec->nSamplesFrame, nTransportChannels ), (UWord16) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer_fx, &nTimeScalerOutSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + assert( LE_32( (Word32) nTimeScalerOutSamples, APA_BUF ) ); + nSamplesTcsScaled = idiv1616U( extract_l( nTimeScalerOutSamples ), nTransportChannels ); + hIvasDec->timeScalingDone = 1; + move16(); } - } - ELSE - { - IF( apa_exec_ivas_fx( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer_fx, (UWord16) imult3216( hIvasDec->nSamplesFrame, nTransportChannels ), (UWord16) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer_fx, &nTimeScalerOutSamples ) != 0 ) + ELSE { - return IVAS_ERR_UNKNOWN; + nSamplesTcsScaled = hIvasDec->nSamplesFrame; + move16(); } - } - assert( LE_32( (Word32) nTimeScalerOutSamples, APA_BUF ) ); - nSamplesTcsScaled = idiv1616U( extract_l( nTimeScalerOutSamples ), nTransportChannels ); - hIvasDec->timeScalingDone = 1; - move16(); - } - ELSE - { - nSamplesTcsScaled = hIvasDec->nSamplesFrame; - move16(); - } #ifdef DEBUG_MODE_JBM - dbgwrite( &nTimeScalerOutSamples, sizeof( uint16_t ), 1, 1, "./res/JBM_nTimeScaleOutSamples.dat" ); + dbgwrite( &nTimeScalerOutSamples, sizeof( uint16_t ), 1, 1, "./res/JBM_nTimeScaleOutSamples.dat" ); #endif - /* Feed decoded transport channels samples to the renderer */ - IF( NE_32( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer_fx ) ), IVAS_ERR_OK ) ) - { - return error; - } + /* Feed decoded transport channels samples to the renderer */ + IF( NE_32( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer_fx ) ), IVAS_ERR_OK ) ) + { + return error; + } #ifdef DEBUG_MODE_JBM - dbgwrite( &nResidualSamples, sizeof( int16_t ), 1, 1, "./res/JBM_nResidualSamples.dat" ); + dbgwrite( &nResidualSamples, sizeof( int16_t ), 1, 1, "./res/JBM_nResidualSamples.dat" ); #endif - IF( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) - { - /* feed residual samples to TSM for the next call */ - IF( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (UWord16) nResidualSamples ) != 0 ) + IF( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + { + /* feed residual samples to TSM for the next call */ + IF( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (UWord16) nResidualSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + hIvasDec->hasBeenFedFrame = false; + move16(); + } +#else + nOutChannels = (UWord8) hIvasDec->st_ivas->hDecoderConfig->nchan_out; + hIvasDec->hasBeenFedFrame = false; + /* check for possible flushed samples from a rate switch */ + IF( GE_16( hIvasDec->nSamplesFlushed, 0 ) ) { - return IVAS_ERR_UNKNOWN; + /* note: offset (rendered samples) is always 0 */ + Copy( hIvasDec->flushbuffer, pcmBuf, imult1616( hIvasDec->nSamplesFlushed, nOutChannels ) ); + + nSamplesRendered = add( nSamplesRendered, hIvasDec->nSamplesFlushed ); + hIvasDec->nSamplesFlushed = 0; + move16(); + move16(); } - } - hIvasDec->hasBeenFedFrame = false; - move16(); - } +#endif - /* render IVAS frames directly to the output buffer */ - nSamplesToRender = sub( nSamplesAsked, nSamplesRendered ); - IF( NE_32( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcmBuf + imult3216( nSamplesRendered, nOutChannels ) ) ), IVAS_ERR_OK ) ) - { - return error; - } + /* render IVAS frames directly to the output buffer */ + nSamplesToRender = sub( nSamplesAsked, nSamplesRendered ); + IF( NE_32( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcmBuf + imult3216( nSamplesRendered, nOutChannels ) ) ), IVAS_ERR_OK ) ) + { + return error; + } - nSamplesRendered = add( nSamplesRendered, nSamplesRendered_loop ); - nSamplesToRender = sub( nSamplesToRender, nSamplesRendered_loop ); - IF( hIvasDec->nSamplesAvailableNext == 0 ) - { - *needNewFrame = true; - hIvasDec->needNewFrame = true; - move16(); - move16(); - } - ELSE - { - *needNewFrame = false; - move16(); + nSamplesRendered = add( nSamplesRendered, nSamplesRendered_loop ); + nSamplesToRender = sub( nSamplesToRender, nSamplesRendered_loop ); + IF( hIvasDec->nSamplesAvailableNext == 0 ) + { + *needNewFrame = true; + hIvasDec->needNewFrame = true; + move16(); + move16(); + } + ELSE + { + *needNewFrame = false; + move16(); + } + } } -} -} -*nOutSamples = nSamplesRendered; -move16(); + *nOutSamples = nSamplesRendered; + move16(); -return IVAS_ERR_OK; + return IVAS_ERR_OK; } @@ -1357,10 +1439,12 @@ 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 FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) { @@ -1388,6 +1472,15 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; move16(); +#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 ) ); + set16_fx( (Word16 *) hIvasDec->flushbuffer, 0, numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); + } +#endif + IF( NE_32( st_ivas->hDecoderConfig->render_framesize, IVAS_RENDER_FRAMESIZE_20MS ) && ( EQ_32( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) || EQ_16( hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof, 0 ) ) ) @@ -1568,7 +1661,9 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( ivas_syn_output_fx( pOutput, Q11, numSamplesPerChannelToDecode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); } +#ifndef TMP_FIX_SPLIT_REND free( st_ivas->hSplitBinRend->hMultiBinCldfbData ); +#endif return IVAS_ERR_OK; } @@ -2197,14 +2292,54 @@ ivas_error IVAS_DEC_GetObjectMetadata( } ELSE { - metadata->azimuth_fx = hIsmMeta->azimuth_fx; // Q22 - metadata->elevation_fx = hIsmMeta->elevation_fx; // Q22 - metadata->radius_fx = hIsmMeta->radius_fx; // Q9 - metadata->yaw_fx = hIsmMeta->yaw_fx; // Q22 - metadata->pitch_fx = hIsmMeta->pitch_fx; // Q22 - metadata->spread_fx = 0; // Q22 - metadata->gainFactor_fx = ONE_IN_Q31; - metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; +#ifdef OBJ_EDITING_API + IF( EQ_32( st_ivas->ism_mode, ISM_MODE_DISC ) ) + { + metadata->azimuth_fx = hIsmMeta->edited_azimuth_fx; + metadata->elevation_fx = hIsmMeta->edited_elevation_fx; + metadata->radius_fx = hIsmMeta->edited_radius_fx; + + metadata->yaw_fx = hIsmMeta->edited_yaw_fx; + metadata->pitch_fx = hIsmMeta->edited_pitch_fx; + metadata->spread_fx = 0; + + metadata->gainFactor_fx = hIsmMeta->edited_gain_fx; + metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + } + ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) + { + metadata->azimuth_fx = st_ivas->hParamIsmDec->edited_azimuth_values_fx[objectIdx]; + metadata->elevation_fx = st_ivas->hParamIsmDec->edited_elevation_values_fx[objectIdx]; + metadata->radius_fx = hIsmMeta->radius_fx; + metadata->yaw_fx = hIsmMeta->yaw_fx; + metadata->pitch_fx = hIsmMeta->pitch_fx; + metadata->spread_fx = 0; + metadata->gainFactor_fx = ONE_IN_Q31; + metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + } + ELSE IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + metadata->azimuth_fx = st_ivas->hIsmMetaData[objectIdx]->edited_azimuth_fx; + metadata->elevation_fx = st_ivas->hIsmMetaData[objectIdx]->edited_elevation_fx; + metadata->radius_fx = st_ivas->hIsmMetaData[objectIdx]->edited_radius_fx; + metadata->yaw_fx = st_ivas->hIsmMetaData[objectIdx]->edited_yaw_fx; + metadata->pitch_fx = st_ivas->hIsmMetaData[objectIdx]->edited_pitch_fx; + metadata->spread_fx = 0; + metadata->gainFactor_fx = st_ivas->hIsmMetaData[objectIdx]->edited_gain_fx; + metadata->non_diegetic_flag = st_ivas->hIsmMetaData[objectIdx]->non_diegetic_flag; + } + ELSE +#endif + { + metadata->azimuth_fx = hIsmMeta->azimuth_fx; // Q22 + metadata->elevation_fx = hIsmMeta->elevation_fx; // Q22 + metadata->radius_fx = hIsmMeta->radius_fx; // Q9 + metadata->yaw_fx = hIsmMeta->yaw_fx; // Q22 + metadata->pitch_fx = hIsmMeta->pitch_fx; // Q22 + metadata->spread_fx = 0; // Q22 + metadata->gainFactor_fx = ONE_IN_Q31; + metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + } } move32(); @@ -3622,6 +3757,374 @@ ivas_error IVAS_DEC_ReadFormat( } #endif +#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 + { + + UWord16 l_ts, nTimeScalerOutSamples; +#ifdef FIX_HRTF_LOAD + UWord8 nTransportChannels; +#else + UWord8 nTransportChannels, nOutChannels; +#endif + Word16 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_fx, &nOutSamplesElse ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* JBM */ + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + { + IF( apa_set_scale_fx( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + + // tmp apaExecBuffer + IF( EQ_16( (Word16) hIvasDec->mode, IVAS_DEC_MODE_EVS ) ) + { + Word16 tmp_apaExecBuffer[APA_BUF]; + FOR( Word32 i = 0; i < APA_BUF_PER_CHANNEL * nTransportChannels; ++i ) + { + tmp_apaExecBuffer[i] = extract_l( L_shr( hIvasDec->apaExecBuffer_fx[i], Q11 ) ); // Q0 + } + IF( apa_exec_fx( hIvasDec->hTimeScaler, tmp_apaExecBuffer, (UWord16) imult3216( hIvasDec->nSamplesFrame, nTransportChannels ), (UWord16) hIvasDec->tsm_max_scaling, tmp_apaExecBuffer, &nTimeScalerOutSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + FOR( Word32 i = 0; i < APA_BUF_PER_CHANNEL * nTransportChannels; ++i ) + { + hIvasDec->apaExecBuffer_fx[i] = L_shl( tmp_apaExecBuffer[i], Q11 ); // Q11 + } + } + ELSE + { + IF( apa_exec_ivas_fx( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer_fx, (UWord16) imult3216( hIvasDec->nSamplesFrame, nTransportChannels ), (UWord16) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer_fx, &nTimeScalerOutSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + assert( LE_32( (Word32) nTimeScalerOutSamples, APA_BUF ) ); + nSamplesTcsScaled = idiv1616U( extract_l( nTimeScalerOutSamples ), nTransportChannels ); + hIvasDec->timeScalingDone = 1; + move16(); + } + else + { + nSamplesTcsScaled = hIvasDec->nSamplesFrame; + } + + /* Feed decoded transport channels samples to the renderer */ + if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer_fx ) ) != 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 ) + { + Word16 obj; + ISM_METADATA_HANDLE *hIsmMetaData = hIvasDec->st_ivas->hIsmMetaData; + FOR( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) + { + hIsmMetaData[obj]->edited_azimuth_fx = hIsmMetaData[obj]->azimuth_fx; + hIsmMetaData[obj]->edited_elevation_fx = hIsmMetaData[obj]->elevation_fx; + hIsmMetaData[obj]->edited_yaw_fx = hIsmMetaData[obj]->yaw_fx; + hIsmMetaData[obj]->edited_pitch_fx = hIsmMetaData[obj]->pitch_fx; + hIsmMetaData[obj]->edited_radius_fx = hIsmMetaData[obj]->radius_fx; + hIsmMetaData[obj]->edited_gain_fx = ONE_IN_Q31; + } + + IF( hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + hIvasDec->st_ivas->hSbaIsmData->gain_bed_fx = ONE_IN_Q31; + } + } + } + } + + IF( hIvasDec->st_ivas->hParamIsmDec != NULL ) + { + IF( hIvasDec->st_ivas->ism_mode == ISM_MODE_PARAM ) + { + Word16 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_fx[obj] = hParamIsmDec->azimuth_values_fx[obj]; + hParamIsmDec->edited_elevation_values_fx[obj] = hParamIsmDec->elevation_values_fx[obj]; + } + } + } + + return IVAS_ERR_OK; +} +#endif + +#ifdef OBJ_EDITING_API +/*---------------------------------------------------------------------* + * IVAS_DEC_GetEditableParameters( ) + * + * + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, + IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters ) +{ + ivas_error error; + + test(); + test(); + test(); + test(); + test(); + 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." ); + } + + test(); + test(); + if ( hIvasEditableParameters == NULL || hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hIvasEditableParameters->gain_bed_fx = ONE_IN_Q30; + move32(); + hIvasEditableParameters->num_obj = hIvasDec->st_ivas->nchan_ism; + move16(); + test(); + test(); + 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 ) + { + Word16 obj; + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth_fx = hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth_fx; + move32(); + hIvasEditableParameters->ism_metadata[obj].elevation_fx = hIvasDec->st_ivas->hIsmMetaData[obj]->elevation_fx; + move32(); + hIvasEditableParameters->ism_metadata[obj].yaw_fx = hIvasDec->st_ivas->hIsmMetaData[obj]->yaw_fx; + move32(); + hIvasEditableParameters->ism_metadata[obj].pitch_fx = hIvasDec->st_ivas->hIsmMetaData[obj]->pitch_fx; + move32(); + hIvasEditableParameters->ism_metadata[obj].radius_fx = hIvasDec->st_ivas->hIsmMetaData[obj]->radius_fx; + move16(); + hIvasEditableParameters->ism_metadata[obj].gain_fx = hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain_fx; + move32(); + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + move16(); + } + if ( hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + hIvasEditableParameters->gain_bed_fx = ONE_IN_Q30; + move32(); + } + } + else if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_PARAM ) + { + Word16 obj; + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth_fx = hIvasDec->st_ivas->hParamIsmDec->azimuth_values_fx[obj]; + move32(); + hIvasEditableParameters->ism_metadata[obj].elevation_fx = hIvasDec->st_ivas->hParamIsmDec->elevation_values_fx[obj]; + move32(); + hIvasEditableParameters->ism_metadata[obj].yaw_fx = 0; + move32(); + hIvasEditableParameters->ism_metadata[obj].pitch_fx = 0; + move32(); + hIvasEditableParameters->ism_metadata[obj].radius_fx = 0; + move16(); + hIvasEditableParameters->ism_metadata[obj].gain_fx = ONE_IN_Q31; + move32(); + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = 0; + move16(); + } + } + 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_fx = hIvasEditableParameters.ism_metadata[obj].azimuth_fx; + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_elevation_fx = hIvasEditableParameters.ism_metadata[obj].elevation_fx; + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_radius_fx = hIvasEditableParameters.ism_metadata[obj].radius_fx; + + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain_fx = hIvasEditableParameters.ism_metadata[obj].gain_fx; + + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_yaw_fx = hIvasEditableParameters.ism_metadata[obj].yaw_fx; + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_pitch_fx = hIvasEditableParameters.ism_metadata[obj].pitch_fx; + + 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_fx = hIvasEditableParameters.gain_bed_fx; + } + } + 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_VoIP_GetSamples( ) @@ -3647,6 +4150,10 @@ ivas_error IVAS_DEC_VoIP_GetSamples( void *jbmWriter #endif #endif +#ifdef OBJ_EDITING_API + , + bool *parametersAvailableForEditing +#endif ) { Decoder_Struct *st_ivas; @@ -3660,6 +4167,10 @@ ivas_error IVAS_DEC_VoIP_GetSamples( #ifndef FIX_CREND_SIMPLIFY_CODE Word16 nSamplesRendered; #endif +#ifdef OBJ_EDITING_API + *parametersAvailableForEditing = false; +#endif + UWord8 nOutChannels; test(); @@ -3844,6 +4355,15 @@ ivas_error IVAS_DEC_VoIP_GetSamples( move16(); move16(); } + +#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 */ @@ -3869,12 +4389,44 @@ ivas_error IVAS_DEC_VoIP_GetSamples( { Word16 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 = sub( nSamplesPerChannel, *nSamplesRendered ); #else nSamplesToRender = sub( nSamplesPerChannel, nSamplesRendered ); #endif +#ifdef OBJ_EDITING_API + /* check if we still need to prepare the renderer */ + IF( hIvasDec->hasBeenPreparedRendering == false ) + { + + IF( NE_32( ( 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( NE_32( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + imult1616( *nSamplesRendered, nOutChannels ), &nSamplesRendered_loop, &tmp ) ), IVAS_ERR_OK ) ) @@ -3885,9 +4437,12 @@ 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 = add( *nSamplesRendered, nSamplesRendered_loop ); #else @@ -4804,6 +5359,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 ) @@ -5014,6 +5574,14 @@ static ivas_error ivas_dec_init_split_rend( cldfb_in_flag = 0; move16(); +#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 + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index 024f5b6ac77f17657204e35ecba8272f76cac3f7..463c0315872826c42cc368498a3b7e080e00be3a 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -586,6 +586,10 @@ static void TDREND_Clear_Update_flags_fx( { hBinRendererTd->Sources[i]->SrcSpatial_p->Updated = FALSE; move16(); +#ifdef OBJ_EDITING_API + hBinRendererTd->Sources[i]->SrcRend_p->SrcGainUpdated = FALSE; + move16(); +#endif } return; diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index 5b18e8a43642e1e7e0e906996b628ff85ed06ee7..90ac586ee23437e9861127afa0d90b014bedf041 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -254,7 +254,11 @@ static void TDREND_SRC_REND_Init_fx( move16(); SrcRend_p->SrcGain_p_fx[nC] = ONE_IN_Q14; // Q14 move16(); +#ifdef OBJ_EDITING_API + SrcRend_p->SrcGainMax_p_fx[nC] = 32767; // TODO: make it 2, this is one in Q15, i thinki, need to change Q for that +#else SrcRend_p->SrcGainMax_p_fx[nC] = 32767; /* Q15 */ +#endif move16(); } SrcRend_p->SrcGainUpdated = FALSE;