diff --git a/apps/decoder.c b/apps/decoder.c index de0dd8bca9161e73bf2e5f856a5de51884ac6c89..87db265e44e3fd51f0ca94b14ef536b838c631e2 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -55,6 +55,11 @@ #include "debug.h" #endif #include "wmc_auto.h" +#ifdef OBJ_EDITING_API +#ifdef OBJ_EDITING_EXAMPLE +#include +#endif +#endif #define WMC_TOOL_SKIP @@ -159,7 +164,11 @@ typedef struct #endif int16_t Opt_dpid_on; uint16_t directivityPatternId[IVAS_MAX_NUM_OBJECTS]; - +#ifdef OBJ_EDITING_API +#ifdef OBJ_EDITING_EXAMPLE + bool objEditEnabled; +#endif +#endif } DecArguments; @@ -1151,6 +1160,13 @@ static bool parseCmdlIVAS_dec( arg->directivityPatternId[i] = 65535; } +#ifdef OBJ_EDITING_API +#ifdef OBJ_EDITING_EXAMPLE + arg->objEditEnabled = false; +#endif +#endif + + /*-----------------------------------------------------------------* * Initialization *-----------------------------------------------------------------*/ @@ -1655,6 +1671,15 @@ static bool parseCmdlIVAS_dec( i += tmp; } +#ifdef OBJ_EDITING_API +#ifdef OBJ_EDITING_EXAMPLE + else if ( strcmp( argv_to_upper, "-OBJ_EDIT" ) == 0 ) + { + arg->objEditEnabled = true; + i++; + } +#endif +#endif /*-----------------------------------------------------------------* * Option not recognized @@ -2232,6 +2257,9 @@ static ivas_error decodeG192( #ifdef SPLIT_REND_WITH_HEAD_ROT SplitFileReadWrite *splitRendWriter = NULL; #endif +#ifdef OBJ_EDITING_API + IVAS_EDITABLE_PARAMETERS editableParameters; +#endif #ifdef FIX_1053_REVERB_RECONFIGURATION IVAS_RENDER_CONFIG_DATA renderConfig; @@ -2550,6 +2578,77 @@ static ivas_error decodeG192( fprintf( stderr, "\nError: could not feed frame to decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } +#ifdef OBJ_EDITING_API +#ifdef OBJ_EDITING_EXAMPLE + if ( arg.objEditEnabled ) + { + + /* Do object info editing here */ + /* get object parameters */ + if ( ( error = IVAS_DEC_GetEditableParameters( hIvasDec, &editableParameters ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not get the editable parameters: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + /* edit object parameters...*/ + + /* put the objects equally spaced at the horizontal plane */ + /* and play a little bit with the gains... */ + int16_t obj_idx, non_diegetic_obj_idx; + int16_t num_nondiegetic_objects; + float gain_mean; + float gain_amplitude; + float gain_freq; + float gain_freq_offset; + + num_nondiegetic_objects = 0; + for ( obj_idx = 0; obj_idx < editableParameters.num_obj; obj_idx++ ) + { + if ( !editableParameters.ism_metadata[obj_idx].non_diegetic_flag ) + { + num_nondiegetic_objects++; + } + } + if ( num_nondiegetic_objects ) + { + float start_angle, angle_inc; + angle_inc = 360.0f / (float) num_nondiegetic_objects; + start_angle = angle_inc / 2.0f; + for ( obj_idx = 0, non_diegetic_obj_idx = 0; obj_idx < editableParameters.num_obj; obj_idx++ ) + { + if ( !editableParameters.ism_metadata[obj_idx].non_diegetic_flag ) + { + editableParameters.ism_metadata[obj_idx].elevation = 0.0f; + editableParameters.ism_metadata[obj_idx].azimuth = start_angle + (float) non_diegetic_obj_idx * angle_inc; + non_diegetic_obj_idx++; + } + } + } + /* 2 second AM of the object gains. */ + gain_mean = 1.0f; + gain_amplitude = 0.7f; + gain_freq = ( 2.0f * 3.1415f ) / 100.0f; + gain_freq_offset = 2.0f * 3.1415f / (float) ( editableParameters.num_obj + 1 ); + for ( obj_idx = 0; obj_idx < editableParameters.num_obj; obj_idx++ ) + { + editableParameters.ism_metadata[obj_idx].gain = gain_mean + gain_amplitude * sinf( (float) frame * gain_freq + gain_freq_offset * (float) obj_idx ); + } + /* set new object parameters*/ + if ( ( error = IVAS_DEC_SetEditableParameters( hIvasDec, editableParameters ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not set the editable parameters: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } +#endif + /* Do the final preparations needed for rendering */ + if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not prepare the renderer: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } +#endif } #ifdef SPLIT_REND_WITH_HEAD_ROT @@ -3132,6 +3231,11 @@ static ivas_error decodeVoIP( int16_t vec_pos_update, vec_pos_len; int16_t nOutSamples = 0; +#ifdef OBJ_EDITING_API + bool parameterAvailableForEditing = false; + uint16_t nSamplesRendered = 0; +#endif + vec_pos_update = 0; if ( ( error = IVAS_DEC_GetRenderFramesizeMs( hIvasDec, &systemTimeInc_ms ) ) != IVAS_ERR_OK ) { @@ -3248,7 +3352,9 @@ static ivas_error decodeVoIP( while ( 1 ) { - +#ifdef OBJ_EDITING_API + nSamplesRendered = 0; +#endif /* reference vector */ if ( arg.enableReferenceVectorTracking && vec_pos_update == 0 ) { @@ -3419,7 +3525,25 @@ static ivas_error decodeVoIP( /* decode and get samples */ - +#ifdef OBJ_EDITING_API + while ( nSamplesRendered < nOutSamples ) + { +#endif +#ifdef OBJ_EDITING_API +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef SUPPORT_JBM_TRACEFILE + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &nSamplesRendered, ¶meterAvailableForEditing ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, &nSamplesRendered, ¶meterAvailableForEditing ) ) != IVAS_ERR_OK ) +#endif +#else +#ifdef SUPPORT_JBM_TRACEFILE + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &nSamplesRendered, ¶meterAvailableForEditing ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms, &nSamplesRendered, ¶meterAvailableForEditing ) ) != IVAS_ERR_OK ) +#endif +#endif +#else #ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SUPPORT_JBM_TRACEFILE if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) @@ -3433,10 +3557,18 @@ static ivas_error decodeVoIP( if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) #endif #endif - { - fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } +#endif + { + fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } +#ifdef OBJ_EDITING_API + if ( parameterAvailableForEditing == true ) + { + /* do the object editing here */ + } + } /* while ( nSamplesRendered < nOutSamples ) */ +#endif /* write JBM Offset file entry */ if ( jbmOffsetWriter != NULL ) diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 1d4cde968052f087cd94d8e37f9d8269de822d2d..01c96df4fdc07a23e97c9cd47770534a7f48188c 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -128,9 +128,21 @@ typedef struct _IVAS_ISM_METADATA float yaw; float pitch; int16_t non_diegetic_flag; +#ifdef OBJ_EDITING_API + float gain; +#endif } IVAS_ISM_METADATA; +#ifdef OBJ_EDITING_API +typedef struct _IVAS_EDITABLE_PARAMETERS +{ + int16_t num_obj; + IVAS_ISM_METADATA ism_metadata[IVAS_MAX_NUM_OBJECTS]; + float gain_bed; +} IVAS_EDITABLE_PARAMETERS; +#endif + typedef struct { float w, x, y, z; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 202ccf3dd9237dc534cf3a0aceda5901f6e9e738..893543b3ead2b71d35d9ae4036bef4d439b04182 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -823,6 +823,12 @@ void ivas_jbm_dec_feed_tc_to_renderer( float *data /* i/o: transport channels/output synthesis signal */ ); +#ifdef OBJ_EDITING_API +void ivas_jbm_dec_prepare_renderer( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); +#endif + ivas_error ivas_jbm_dec_set_discard_samples( Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */ ); @@ -1110,6 +1116,13 @@ void ivas_param_ism_dec_digest_tc( float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ ); +#ifdef OBJ_EDITING_API +void ivas_param_ism_dec_prepare_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +); +#endif + void ivas_ism_param_dec_tc_gain_ajust( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamples, /* i : number of samples to be compensate */ @@ -3859,6 +3872,13 @@ void ivas_param_mc_dec_digest_tc( float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output*/ ); +#ifdef OBJ_EDITING_API +void ivas_param_mc_dec_prepare_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +); +#endif + void ivas_param_mc_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 23645a77dc88154235066ef245a229ee81eeebb9..bc146b73e0d32ea5c7eab4ddd1c1c36db81e965a 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -87,6 +87,7 @@ typedef struct float q_azimuth_old; float q_elevation_old; + } ISM_METADATA_FRAME, *ISM_METADATA_HANDLE; diff --git a/lib_com/options.h b/lib_com/options.h index 43cb02520ede8f5b965f04b2be7cd46f3c0afd4d..e5f15d4dd68467bd985980a9df4d49e8d15ed860 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -150,6 +150,12 @@ /* ################## Start DEVELOPMENT switches ######################### */ +#define OBJ_EDITING_INTERFACE /* Interface for object editing */ +#ifdef OBJ_EDITING_INTERFACE +#define OBJ_EDITING_API /* object editing changes related to the API */ +#define OBJ_EDITING_EXAMPLE /* obj editing example code in decoder.c */ +#endif + /* ################### Start BE switches ################################# */ /* only BE switches wrt selection floating point code */ diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 2e3720c9493acc638d2a74fa3dddd735eaf2e003..48e76d2889fa177971c12b0b5f8c9258b0eb005c 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -803,14 +803,20 @@ void ivas_param_ism_dec_digest_tc( float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ ) { - int16_t ch, nchan_transport, nchan_out, nchan_out_woLFE, i; - int16_t slot_idx, bin_idx; + int16_t ch, nchan_transport; + int16_t slot_idx; +#ifndef OBJ_EDITING_API + int16_t nchan_out, nchan_out_woLFE, i; + int16_t bin_idx; int32_t ivas_total_brate; +#endif int16_t output_frame; +#ifndef OBJ_EDITING_API float ref_power[CLDFB_NO_CHANNELS_MAX]; float cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; /* Direct Response/EFAP Gains */ float direct_response[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN]; +#endif PARAM_ISM_DEC_HANDLE hParamIsmDec; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; int16_t fade_len; @@ -824,6 +830,8 @@ void ivas_param_ism_dec_digest_tc( fade_len = output_frame / 2; nchan_transport = st_ivas->nchan_transport; + +#ifndef OBJ_EDITING_API ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) @@ -837,9 +845,10 @@ void ivas_param_ism_dec_digest_tc( nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; } - +#endif push_wmops( "ivas_param_ism_dec_digest_tc" ); +#ifndef OBJ_EDITING_API /* general setup */ ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hParamIsmDec->hParamIsmRendering->interpolator ); @@ -914,7 +923,7 @@ void ivas_param_ism_dec_digest_tc( } } } - +#endif if ( st_ivas->hDecoderConfig->Opt_tsm ) { /*TODO : FhG to check*/ @@ -936,11 +945,13 @@ void ivas_param_ism_dec_digest_tc( mvr2r( RealBuffer, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands ); mvr2r( ImagBuffer, &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands ); } - +#ifndef OBJ_EDITING_API ivas_param_ism_collect_slot( hParamIsmDec, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], ch, ref_power, cx_diag ); +#endif } } +#ifndef OBJ_EDITING_API /* Obtain Mixing Matrix on a frame-level */ for ( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ ) { @@ -949,6 +960,7 @@ void ivas_param_ism_dec_digest_tc( /* Compute mixing matrix */ ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response, nchan_transport, nchan_out_woLFE, cx_diag, ref_power, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin ); +#endif pop_wmops(); @@ -956,6 +968,150 @@ void ivas_param_ism_dec_digest_tc( } +#ifdef OBJ_EDITING_API +/*-------------------------------------------------------------------------* + * ivas_param_ism_dec_prepare_renderer() + * + * + *-------------------------------------------------------------------------*/ + +void ivas_param_ism_dec_prepare_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +) +{ + int16_t ch, nchan_transport, nchan_out, nchan_out_woLFE, i; + int16_t slot_idx, bin_idx; + int32_t ivas_total_brate; + float ref_power[CLDFB_NO_CHANNELS_MAX]; + float cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + /* Direct Response/EFAP Gains */ + float direct_response[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN]; + PARAM_ISM_DEC_HANDLE hParamIsmDec; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + + /* Initialization */ + hParamIsmDec = st_ivas->hParamIsmDec; + assert( hParamIsmDec ); + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + assert( hSpatParamRendCom ); + + nchan_transport = st_ivas->nchan_transport; + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + nchan_out = st_ivas->nchan_ism; + nchan_out_woLFE = nchan_out; + st_ivas->hDecoderConfig->nchan_out = nchan_out; + } + else + { + nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; + nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; + } + + push_wmops( "ivas_param_ism_dec_digest_tc" ); + + /* general setup */ + ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hParamIsmDec->hParamIsmRendering->interpolator ); + + ivas_dirac_dec_set_md_map( st_ivas, nCldfbSlots ); + + /* set buffers to zero */ + for ( bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++ ) + { + set_zero( cx_diag[bin_idx], PARAM_ISM_MAX_DMX ); + } + set_zero( ref_power, CLDFB_NO_CHANNELS_MAX ); + + /* Frame-level Processing */ + /* De-quantization */ + if ( !( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) + { + ivas_param_ism_dec_dequant_DOA( hParamIsmDec, st_ivas->nchan_ism ); + ivas_param_ism_dec_dequant_powrat( hParamIsmDec ); + st_ivas->hISMDTX.dtx_flag = 0; + } + else + { + st_ivas->hISMDTX.dtx_flag = 1; + } + + /* obtain the direct response using EFAP */ + if ( !( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) ) + { + for ( i = 0; i < st_ivas->nchan_ism; i++ ) + { + efap_determine_gains( st_ivas->hEFAPdata, direct_response[i], hParamIsmDec->azimuth_values[i], hParamIsmDec->elevation_values[i], EFAP_MODE_EFAP ); + } + } + else + { + int16_t j; + + for ( i = 0; i < st_ivas->nchan_ism; i++ ) + { + for ( j = 0; j < nchan_out_woLFE; j++ ) + { + if ( i == j ) + { + direct_response[i][j] = 1.0f; + } + else + { + direct_response[i][j] = 0.0f; + } + } + } + + for ( j = 0; j < nchan_out_woLFE; j++ ) + { + if ( hParamIsmDec->azimuth_values[j] > 0.0f ) + { + hParamIsmDec->hParamIsmRendering->proto_matrix[j] = 1.0f; + hParamIsmDec->hParamIsmRendering->proto_matrix[nchan_out_woLFE + j] = 0.0f; + } + else + { + if ( hParamIsmDec->azimuth_values[j] < 0.0f ) + { + hParamIsmDec->hParamIsmRendering->proto_matrix[j] = 0.0f; + hParamIsmDec->hParamIsmRendering->proto_matrix[nchan_out_woLFE + j] = 1.0f; + } + else /* == 0.0f */ + { + hParamIsmDec->hParamIsmRendering->proto_matrix[j] = 0.5f; + hParamIsmDec->hParamIsmRendering->proto_matrix[nchan_out_woLFE + j] = 0.5f; + } + } + } + } + + for ( ch = 0; ch < nchan_transport; ch++ ) + { + /* CLDFB Analysis */ + for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { + ivas_param_ism_collect_slot( hParamIsmDec, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], ch, ref_power, cx_diag ); + } + } + + /* Obtain Mixing Matrix on a frame-level */ + for ( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ ) + { + set_f( hParamIsmDec->hParamIsmRendering->mixing_matrix_lin[bin_idx], 0.0f, nchan_transport * nchan_out_woLFE ); + } + + /* Compute mixing matrix */ + ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response, nchan_transport, nchan_out_woLFE, cx_diag, ref_power, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin ); + + pop_wmops(); + + return; +} +#endif + /*-------------------------------------------------------------------------* * ivas_ism_param_dec_tc_gain_ajust() * diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index db2b95c0bf68ab3eb862341b9c3275b11862a883..402b3adacd211f23c12cf63663e1cbc8aba3da10 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -146,6 +146,7 @@ ivas_error ivas_jbm_dec_tc( } else if ( st_ivas->ivas_format == ISM_FORMAT ) { + /* Metadata decoding and configuration */ if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) { @@ -189,6 +190,7 @@ ivas_error ivas_jbm_dec_tc( hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); } + if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) { ivas_ism_mono_dmx( st_ivas, p_output, output_frame ); @@ -811,6 +813,195 @@ void ivas_jbm_dec_feed_tc_to_renderer( } n_render_timeslots = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; +#ifndef OBJ_EDITING_API + if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + + if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + ivas_jbm_masa_sf_to_slot_map( st_ivas, n_render_timeslots ); + } + } + else if ( st_ivas->ivas_format == STEREO_FORMAT ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + } + else +#endif + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + /* Rendering */ + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { +#ifndef OBJ_EDITING_API + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + ivas_dirac_dec_set_md_map( st_ivas, n_render_timeslots ); + + ivas_param_ism_params_to_masa_param_mapping( st_ivas ); + } + else +#endif + if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_param_ism_dec_digest_tc( st_ivas, n_render_timeslots, p_data_f ); + } + } +#ifndef OBJ_EDITING_API + else /* ISM_MODE_DISC */ + { + ivas_ism_dec_digest_tc( st_ivas ); + } +#endif + } +#ifndef OBJ_EDITING_API + else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) + { + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + ivas_ism_dec_digest_tc( st_ivas ); + + /* delay the objects here for all renderers where it is needed */ + if ( +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( +#endif + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL +#ifdef SPLIT_REND_WITH_HEAD_ROT + ) && + ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#endif + ) + { + for ( n = 0; n < st_ivas->nchan_ism; n++ ) + { + delay_signal( st_ivas->hTcBuffer->tc[n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); + } + } + + if ( !st_ivas->sba_dirac_stereo_flag ) + { + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + n_render_timeslots *= ( st_ivas->hTcBuffer->n_samples_granularity / st_ivas->hSpatParamRendCom->slot_size ); + } + + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + } + else + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + if ( st_ivas->renderer_type == RENDERER_OMASA_MIX_EXT || st_ivas->renderer_type == RENDERER_OMASA_OBJECT_EXT ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + ivas_jbm_masa_sf_to_slot_map( st_ivas, n_render_timeslots ); + } + else + { + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + n_render_timeslots *= ( st_ivas->hTcBuffer->n_samples_granularity / st_ivas->hSpatParamRendCom->slot_size ); + } + + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + ivas_ism_dec_digest_tc( st_ivas ); + } + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_DIRAC ) + { + int16_t num_objects; + /* Delay the signal to match CLDFB delay. Delay the whole buffer. */ + num_objects = 0; + if ( ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC ) + { + num_objects = 1; + } + else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + num_objects = st_ivas->nchan_ism; + } + for ( n = 0; n < num_objects; n++ ) + { + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) + { + v_multc( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], OMASA_TDREND_MATCHING_GAIN, st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available ); + } + delay_signal( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); + } + } + } + } +#endif + else if ( st_ivas->ivas_format == MC_FORMAT ) + { +#ifndef OBJ_EDITING_API + if ( st_ivas->mc_mode == MC_MODE_MCT ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + } + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + ivas_mc_paramupmix_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } + else +#endif + if ( st_ivas->mc_mode == MC_MODE_PARAMMC +#ifdef OBJ_EDITING_API + && st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_RENDERER +#endif + ) + { + ivas_param_mc_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, p_data_f ); + } +#ifndef OBJ_EDITING_API + else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) + { + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + } +#endif + } + + pop_wmops(); + return; +} + +#ifdef OBJ_EDITING_API +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_prepare_renderer() + * + * prepare IVAS JBM renderer routine + *--------------------------------------------------------------------------*/ + +void ivas_jbm_dec_prepare_renderer( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +) +{ + int16_t n, n_render_timeslots; + + push_wmops( "ivas_jbm_dec_feed_tc_to_rendererer" ); + + n_render_timeslots = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; + if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) { ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); @@ -837,7 +1028,7 @@ void ivas_jbm_dec_feed_tc_to_renderer( } else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { - ivas_param_ism_dec_digest_tc( st_ivas, n_render_timeslots, p_data_f ); + ivas_param_ism_dec_prepare_renderer( st_ivas, n_render_timeslots ); } } else /* ISM_MODE_DISC */ @@ -963,7 +1154,7 @@ void ivas_jbm_dec_feed_tc_to_renderer( } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) { - ivas_param_mc_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, p_data_f ); + ivas_param_mc_dec_prepare_renderer( st_ivas, (uint8_t) n_render_timeslots ); } else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { @@ -974,7 +1165,7 @@ void ivas_jbm_dec_feed_tc_to_renderer( pop_wmops(); return; } - +#endif /*--------------------------------------------------------------------------* * ivas_dec_render() diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 4e709162129b182f9db51afe4e8aa26758016e30..11fb97c9cfb2a7bb7a051d6819c951e91ff6a2bf 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1327,9 +1327,11 @@ void ivas_param_mc_dec_digest_tc( ) { PARAM_MC_DEC_HANDLE hParamMC; - int16_t i, ch; - int16_t slot_idx, param_band_idx; - int16_t nchan_transport, nchan_out_transport, nchan_out_cldfb; + int16_t ch; + int16_t slot_idx; + int16_t nchan_transport; +#ifndef OBJ_EDITING_API + int16_t nchan_out_transport, nchan_out_cldfb, i, param_band_idx; int16_t nchan_out_cov; /*CLDFB*/ float cx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; @@ -1338,14 +1340,17 @@ void ivas_param_mc_dec_digest_tc( /* format converter */ int16_t channel_active[MAX_OUTPUT_CHANNELS]; IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; - +#endif hParamMC = st_ivas->hParamMC; assert( hParamMC ); push_wmops( "param_mc_dec_digest_tc" ); - +#ifndef OBJ_EDITING_API set_s( channel_active, 0, MAX_CICP_CHANNELS ); +#endif nchan_transport = st_ivas->nchan_transport; + +#ifndef OBJ_EDITING_API nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) @@ -1396,7 +1401,7 @@ void ivas_param_mc_dec_digest_tc( set_zero( cx[param_band_idx], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); set_zero( cx_imag[param_band_idx], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); } - +#endif /* slot loop for gathering the input data */ for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { @@ -1414,6 +1419,151 @@ void ivas_param_mc_dec_digest_tc( mvr2r( ImagBuffer, &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); } } +#ifndef OBJ_EDITING_API + if ( slot_idx >= 2 * hParamMC->hMetadataPMC->attackIndex ) + { + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], cx, cx_imag, hParamMC, nchan_transport ); + } +#endif + } +#ifndef OBJ_EDITING_API + /* map from complex input covariance to real values */ + for ( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx++ ) + { + /* Cx for transport channels */ + for ( i = 0; i < nchan_transport * nchan_transport; i++ ) + { + real_part = cx[param_band_idx][i]; + imag_part = cx_imag[param_band_idx][i]; + + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + if ( param_band_idx < hParamMC->max_param_band_abs_cov ) + { + cx[param_band_idx][i] = sqrtf( real_part * real_part + imag_part * imag_part ); + } + else + { + cx[param_band_idx][i] = real_part; + } + } + } + + /* we have to do it similar to the encoder in case of attacks (i.e. accumulate two bands) to ensure correct DMX of the target covariance*/ + if ( hParamMC->hMetadataPMC->bAttackPresent && ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) ) + { + for ( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx += 2 ) + { + v_add( cx[param_band_idx], cx[param_band_idx + 1], cx[param_band_idx], nchan_transport * nchan_transport ); + mvr2r( cx[param_band_idx], cx[param_band_idx + 1], nchan_transport * nchan_transport ); + } + } + + +#ifndef FIX_1024_REMOVE_PARAMMC_MIXING_MAT + if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) + { + ivas_param_mc_get_mono_stereo_mixing_matrices( hParamMC, cx, hParamMC->h_output_synthesis_cov_state.mixing_matrix, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, nchan_out_transport, nchan_transport, nchan_out_cov ); + } + else + { +#endif + /* generate mixing matrices */ + ivas_param_mc_get_mixing_matrices( hParamMC, hSynthesisOutputSetup, cx, hParamMC->h_output_synthesis_cov_state.mixing_matrix, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); +#ifndef FIX_1024_REMOVE_PARAMMC_MIXING_MAT + } +#endif +#endif + pop_wmops(); + + return; +} + +#ifdef OBJ_EDITING_API +/*------------------------------------------------------------------------- + * ivas_param_mc_dec_prepare_renderer() + * + * + *------------------------------------------------------------------------*/ + +void ivas_param_mc_dec_prepare_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots /* i : number of CLFBS slots in the transport channels */ +) +{ + PARAM_MC_DEC_HANDLE hParamMC; + int16_t i; + int16_t slot_idx, param_band_idx; + int16_t nchan_transport, nchan_out_transport, nchan_out_cldfb; + int16_t nchan_out_cov; + /*CLDFB*/ + float cx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + float cx_imag[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + float real_part, imag_part; + /* format converter */ + int16_t channel_active[MAX_OUTPUT_CHANNELS]; + IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; + + hParamMC = st_ivas->hParamMC; + assert( hParamMC ); + + push_wmops( "param_mc_dec_digest_tc" ); + + set_s( channel_active, 0, MAX_CICP_CHANNELS ); + nchan_transport = st_ivas->nchan_transport; + nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + nchan_out_cldfb = BINAURAL_CHANNELS; + set_s( channel_active, 1, nchan_out_cldfb ); + nchan_out_cov = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB ) + { + nchan_out_cov = nchan_out_transport; + nchan_out_cldfb = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) + { + nchan_out_cov = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; + nchan_out_cldfb = nchan_out_cov; + set_s( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hOutSetup; + } + else + { + nchan_out_cov = nchan_out_transport; + nchan_out_cldfb = nchan_out_transport; + set_s( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + + /* adapt transient position */ + if ( hParamMC->hMetadataPMC->bAttackPresent ) + { + hParamMC->hMetadataPMC->attackIndex = (int16_t) max( 0, hParamMC->hMetadataPMC->attackIndex + ( ( nCldfbSlots - DEFAULT_JBM_CLDFB_TIMESLOTS ) / 2 ) ); + } + /* adapt subframes */ + hParamMC->num_slots = nCldfbSlots; + hParamMC->slots_rendered = 0; + hParamMC->subframes_rendered = 0; + ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); + st_ivas->hTcBuffer->nb_subframes = hParamMC->nb_subframes; + mvs2s( hParamMC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hParamMC->nb_subframes ); + + ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); + + for ( param_band_idx = 0; param_band_idx < PARAM_MC_MAX_PARAMETER_BANDS; param_band_idx++ ) + { + set_zero( cx[param_band_idx], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero( cx_imag[param_band_idx], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + } + + /* slot loop for gathering the input data */ + for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { if ( slot_idx >= 2 * hParamMC->hMetadataPMC->attackIndex ) { ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], cx, cx_imag, hParamMC, nchan_transport ); @@ -1459,7 +1609,7 @@ void ivas_param_mc_dec_digest_tc( return; } - +#endif /*------------------------------------------------------------------------- * ivas_param_mc_dec_render() diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 71f89ea508d9baf17ccb9aa12ed166c08d0a94a2..0153363b9657345740c1616a07327d89a7541965 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -95,6 +95,19 @@ struct IVAS_DEC int16_t sdp_hf_only; /* RTP payload format parameter: only Header-Full format without zero padding for size collision avoidance */ int16_t prev_ft_speech; /* RXDTX handler: previous frametype flag for G.192 format AMRWB SID_FIRST detection */ int16_t CNG; /* RXDTX handler: CNG=1, nonCNG=0 */ + +#ifdef OBJ_EDITING_API + uint16_t nSamplesFlushed; +#ifdef SPLIT_REND_WITH_HEAD_ROT + void *flushbuffer; + IVAS_DEC_PCM_TYPE pcmType; +#else + int16_t *flushbuffer; +#endif + bool hasEditableParameters; + bool enableParameterEditing; + bool hasBeenPreparedRendering; +#endif }; @@ -178,6 +191,16 @@ ivas_error IVAS_DEC_Open( hIvasDec->hasDecodedFirstGoodFrame = false; hIvasDec->isInitialized = false; hIvasDec->updateOrientation = false; +#ifdef OBJ_EDITING_API + hIvasDec->flushbuffer = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasDec->pcmType = IVAS_DEC_PCM_INVALID; +#endif + hIvasDec->nSamplesFlushed = 0; + hIvasDec->hasEditableParameters = false; + hIvasDec->enableParameterEditing = false; + hIvasDec->hasBeenPreparedRendering = false; +#endif hIvasDec->mode = mode; @@ -355,6 +378,12 @@ void IVAS_DEC_Close( { free( ( *phIvasDec )->apaExecBuffer ); } +#ifdef OBJ_EDITING_API + if ( ( *phIvasDec )->flushbuffer != NULL ) + { + free( ( *phIvasDec )->flushbuffer ); + } +#endif free( *phIvasDec ); *phIvasDec = NULL; phIvasDec = NULL; @@ -519,6 +548,21 @@ ivas_error IVAS_DEC_Configure( hIvasDec->tsm_max_scaling = 0; hIvasDec->tsm_quality = 1.0f; +#ifdef OBJ_EDITING_API + /* init flush buffer if necessary (only needed for binaural)*/ + if ( tsmEnabled && ( outputConfig == IVAS_AUDIO_CONFIG_BINAURAL || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); + hIvasDec->pcmType = IVAS_DEC_PCM_INT16; + set_s( (int16_t *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); +#else + hIvasDec->flushbuffer = (int16_t *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); + set_s( hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); +#endif + } +#endif + return error; } @@ -783,6 +827,21 @@ ivas_error IVAS_DEC_EnableVoIP( return IVAS_ERR_FAILED_ALLOC; } +#ifdef OBJ_EDITING_API + /* init flush buffer if necessary (only needed for binaural)*/ + if ( hIvasDec->flushbuffer == NULL && ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); + hIvasDec->pcmType = IVAS_DEC_PCM_INT16; + set_s( (int16_t *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); +#else + hIvasDec->flushbuffer = (int16_t *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); + set_s( hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); +#endif + } +#endif + return error; } @@ -875,10 +934,196 @@ ivas_error IVAS_DEC_FeedFrame_Serial( hIvasDec->nSamplesRendered = 0; hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; +#ifdef OBJ_EDITING_API + /* decode TCs, do TSM and feed to renderer */ + /* setup */ + /* special case for EVS and JBM needed here */ + if ( !( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && !hIvasDec->hasBeenFedFirstGoodFrame && hIvasDec->mode == IVAS_DEC_MODE_EVS ) ) + { + uint16_t l_ts, nTimeScalerOutSamples; + uint8_t nTransportChannels, nOutChannels; + int16_t nResidualSamples, nSamplesTcsScaled, nOutSamplesElse; + + l_ts = 0; + nTransportChannels = 0; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &hIvasDec->nSamplesFlushed, hIvasDec->pcmType, hIvasDec->flushbuffer ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &hIvasDec->nSamplesFlushed, hIvasDec->flushbuffer ) ) != IVAS_ERR_OK ) +#endif + + { + return error; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* :TODO: change nSamplesAsked also if we are in 5ms 0dof split rendering... */ +#endif + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && nTransportChannels != hIvasDec->nTransportChannelsOld ) + { + if ( ( error = IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* IVAS TC decoder */ + if ( ( error = IVAS_DEC_GetTcSamples( hIvasDec, hIvasDec->apaExecBuffer, &nOutSamplesElse ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* JBM */ + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + { + if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + + if ( apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + + assert( nTimeScalerOutSamples <= APA_BUF ); + nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; + } + else + { + nSamplesTcsScaled = hIvasDec->nSamplesFrame; + } + + /* Feed decoded transport channels samples to the renderer */ + if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + { + /* feed residual samples to TSM for the next call */ + if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + } + hIvasDec->hasBeenPreparedRendering = false; +#endif + return IVAS_ERR_OK; } +#ifdef OBJ_EDITING_API +/*---------------------------------------------------------------------* + * IVAS_DEC_GetEditableParameters( ) + * + * Main function to decode to PCM data + *---------------------------------------------------------------------*/ +ivas_error IVAS_DEC_GetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, + IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters ) +{ + ivas_error error; + + if ( hIvasEditableParameters == NULL || hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hIvasEditableParameters->num_obj = hIvasDec->st_ivas->nchan_ism; + if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + int16_t obj; + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = hIvasDec->st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = hIvasDec->st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = hIvasDec->st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = hIvasDec->st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = hIvasDec->st_ivas->hIsmMetaData[obj]->radius; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = hIvasDec->st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + } + else if ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + } + else + { + } + + + 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; + + error = IVAS_ERR_OK; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + +#ifdef DEBUGGING + assert( hIvasEditableParameters.num_obj == hIvasDec->st_ivas->nchan_ism ); +#endif + /* transfer edited values to the decoder */ + if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + int16_t obj; + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + } + } + else if ( hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + } + else + { + } + + return error; +} + +/*---------------------------------------------------------------------* + * IVAS_DEC_PrepareRenderer( ) + * + * Main function to decode to PCM data + *---------------------------------------------------------------------*/ +ivas_error IVAS_DEC_PrepareRenderer( + IVAS_DEC_HANDLE hIvasDec ) +{ + ivas_error error; + + error = IVAS_ERR_OK; + + if ( hIvasDec == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + ivas_jbm_dec_prepare_renderer( hIvasDec->st_ivas ); + hIvasDec->hasBeenPreparedRendering = true; + return error; +} + + +#endif + /*---------------------------------------------------------------------* * IVAS_DEC_GetSamples( ) * @@ -900,21 +1145,36 @@ ivas_error IVAS_DEC_GetSamples( ) { ivas_error error; - int16_t nOutSamplesElse, nSamplesToRender; - uint16_t nSamplesRendered, nSamplesRendered_loop, l_ts, nTimeScalerOutSamples; - uint8_t nTransportChannels, nOutChannels; - + int16_t nSamplesToRender; + uint16_t nSamplesRendered, nSamplesRendered_loop; + uint8_t nOutChannels; +#ifndef OBJ_EDITING_API + uint8_t nTransportChannels; + int16_t nOutSamplesElse; + uint16_t nTimeScalerOutSamples, l_ts; +#endif nSamplesRendered = 0; nOutChannels = 0; nSamplesRendered_loop = 0; +#ifndef OBJ_EDITING_API l_ts = 0; nTransportChannels = 0; +#endif + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef OBJ_EDITING_API + /* the rendering needs to be prepared at this point */ + if ( hIvasDec->hasBeenPreparedRendering == false ) + { + return IVAS_ERR_UNKNOWN; + } +#endif + if ( hIvasDec->updateOrientation ) { /*----------------------------------------------------------------* @@ -965,6 +1225,7 @@ ivas_error IVAS_DEC_GetSamples( } else { +#ifndef OBJ_EDITING_API /* check if we need to run the setup function */ if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) { @@ -980,8 +1241,10 @@ ivas_error IVAS_DEC_GetSamples( return error; } } +#endif { /* check if we need to run the setup function, tc decoding and feeding the renderer */ +#ifndef OBJ_EDITING_API if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) { int16_t nResidualSamples, nSamplesTcsScaled; @@ -1043,6 +1306,39 @@ ivas_error IVAS_DEC_GetSamples( } hIvasDec->hasBeenFedFrame = false; } +#else + nOutChannels = (uint8_t) hIvasDec->st_ivas->hDecoderConfig->nchan_out; + hIvasDec->hasBeenFedFrame = false; + /* check for possible flushed samples from a rate switch */ + if ( hIvasDec->nSamplesFlushed > 0 ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + void *pPcmBuffer; +#ifdef DEBUGGING + assert( hIvasDec->pcmType == pcmType ); +#endif + pPcmBuffer = pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ); + if ( pcmType == IVAS_DEC_PCM_INT16 ) + { + mvs2s( (int16_t *) hIvasDec->flushbuffer, pPcmBuffer, hIvasDec->nSamplesFlushed * nOutChannels ); + } + else if ( pcmType == IVAS_DEC_PCM_FLOAT ) + { + mvr2r( (float *) hIvasDec->flushbuffer, pPcmBuffer, hIvasDec->nSamplesFlushed * nOutChannels ); + } +#ifdef DEBUGGING + else + { + assert( 0 & "wrong PCM type for the flush buffer!" ); + } +#endif +#else + mvs2s( hIvasDec->flushbuffer, pcmBuf + nSamplesRendered * nOutChannels, hIvasDec->nSamplesFlushed * nOutChannels ); +#endif + nSamplesRendered += hIvasDec->nSamplesFlushed; + hIvasDec->nSamplesFlushed = 0; + } +#endif /* render IVAS frames directly to the output buffer */ nSamplesToRender = nSamplesAsked - nSamplesRendered; @@ -1126,6 +1422,16 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; +#ifdef OBJ_EDITING_API + /* init flush buffer for rate switch if not already initizalized */ + if ( hIvasDec->flushbuffer == NULL ) + { + hIvasDec->flushbuffer = (void *) malloc( numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float ) ); + hIvasDec->pcmType = IVAS_DEC_PCM_FLOAT; + set_zero( (float *) hIvasDec->flushbuffer, numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); + } +#endif + if ( st_ivas->hDecoderConfig->render_framesize != IVAS_RENDER_FRAMESIZE_20MS && ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) @@ -2631,6 +2937,11 @@ ivas_error IVAS_DEC_VoIP_GetSamples( JbmTraceFileWriterFn jbmWriterFn, void *jbmWriter #endif +#ifdef OBJ_EDITING_API + , + uint16_t *nSamplesRendered, + bool *parametersAvailableForEditing +#endif ) { Decoder_Struct *st_ivas; @@ -2641,14 +2952,21 @@ ivas_error IVAS_DEC_VoIP_GetSamples( uint16_t extBufferedSamples; int16_t result; ivas_error error; +#ifndef OBJ_EDITING_API int16_t nSamplesRendered; +#endif uint8_t nOutChannels; st_ivas = hIvasDec->st_ivas; hDecoderConfig = st_ivas->hDecoderConfig; hVoIP = hIvasDec->hVoIP; nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; +#ifndef OBJ_EDITING_API nSamplesRendered = 0; +#endif +#ifdef OBJ_EDITING_API + *parametersAvailableForEditing = false; +#endif if ( nSamplesPerChannel == 0 ) { @@ -2656,7 +2974,11 @@ ivas_error IVAS_DEC_VoIP_GetSamples( } /* make sure that the FIFO after decoder/scaler contains at least one sound card frame (i.e. 20ms) */ +#ifdef OBJ_EDITING_API + while ( *nSamplesRendered < nSamplesPerChannel ) +#else while ( nSamplesRendered < nSamplesPerChannel ) +#endif { if ( hIvasDec->nSamplesAvailableNext == 0 ) { @@ -2769,6 +3091,14 @@ ivas_error IVAS_DEC_VoIP_GetSamples( hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; hIvasDec->nSamplesRendered = 0; } +#ifdef OBJ_EDITING_API + /* :TODO: only return here if we really have editing initialized */ + if ( hIvasDec->hasBeenFedFirstGoodFrame && hIvasDec->hasEditableParameters == true && hIvasDec->enableParameterEditing == true ) + { + *parametersAvailableForEditing = true; + return IVAS_ERR_OK; + } +#endif } /* decode */ @@ -2777,12 +3107,21 @@ ivas_error IVAS_DEC_VoIP_GetSamples( /* codec mode to use not known yet - simply output silence */ /* directly set output zero */ int16_t nSamplesToZero = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); +#ifdef OBJ_EDITING_API +#ifdef SPLIT_REND_WITH_HEAD_ROT + set_pcm_buffer_to_zero( pcm_buffer_offset( pcmBuf, pcmType, ( *nSamplesRendered ) * nOutChannels ), pcmType, nSamplesToZero * nOutChannels ); +#else + set_s( pcmBuf + ( *nSamplesRendered ) * nOutChannels, 0, nSamplesToZero * nOutChannels ); +#endif + *nSamplesRendered += nSamplesToZero; +#else #ifdef SPLIT_REND_WITH_HEAD_ROT set_pcm_buffer_to_zero( pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ), pcmType, nSamplesToZero * nOutChannels ); #else set_s( pcmBuf + nSamplesRendered * nOutChannels, 0, nSamplesToZero * nOutChannels ); #endif nSamplesRendered += nSamplesToZero; +#endif hIvasDec->nSamplesRendered += nSamplesToZero; hIvasDec->nSamplesAvailableNext -= nSamplesToZero; update_voip_rendered20ms( hIvasDec, nSamplesToZero ); @@ -2791,9 +3130,37 @@ ivas_error IVAS_DEC_VoIP_GetSamples( { int16_t nSamplesToRender, nSamplesRendered_loop; bool tmp; +#ifdef OBJ_EDITING_API + nSamplesToRender = nSamplesPerChannel - *nSamplesRendered; +#else nSamplesToRender = nSamplesPerChannel - nSamplesRendered; +#endif + +#ifdef OBJ_EDITING_API + /* check if we still need to prepare the renderer */ + if ( hIvasDec->hasBeenPreparedRendering == false ) + { + + if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif /* render IVAS frames directly to the output buffer */ +#ifdef OBJ_EDITING_API +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + *nSamplesRendered * nOutChannels, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + + *nSamplesRendered += nSamplesRendered_loop; +#else #ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) #else @@ -2804,6 +3171,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( } nSamplesRendered += nSamplesRendered_loop; +#endif update_voip_rendered20ms( hIvasDec, nSamplesRendered_loop ); } } diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 9a2b6d4b16929457cabad7a37dada51439003002..4d3bc50ec1b571fff7b5c57e197b2344ff87fa82 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -154,6 +154,22 @@ ivas_error IVAS_DEC_FeedFrame_Serial( int16_t bfi /* i : bad frame indicator flag */ ); +#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 + /*! r: decoder error code */ ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ @@ -291,6 +307,11 @@ ivas_error IVAS_DEC_VoIP_GetSamples( , JbmTraceFileWriterFn jbmWriterFn, void* jbmWriter #endif +#ifdef OBJ_EDITING_API + , + uint16_t *nSamplesRendered, + bool *parametersAvailableForEditing +#endif ); ivas_error IVAS_DEC_Flush( diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 0434031c8140a90e385605716e72eacf7fc25584..179b150e81d714ce4d660b85d1c1509beca30fe4 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -729,6 +729,7 @@ ivas_error TDREND_MIX_SRC_SetPlayState( const TDREND_PlayStatus_t PlayStatus /* i : Play state */ ); + void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_SRC_REND_t *SrcRend_p, /* i/o: Source object */ diff --git a/tests/codec_be_on_mr_nonselection/test_param_file.py b/tests/codec_be_on_mr_nonselection/test_param_file.py index 12e9208da89f6d57edf4e4cc486ffcdadea4ae5b..5fff131ec0ab9478dbc1149987f7283e3b356587 100644 --- a/tests/codec_be_on_mr_nonselection/test_param_file.py +++ b/tests/codec_be_on_mr_nonselection/test_param_file.py @@ -202,6 +202,19 @@ def test_param_file_tests( enc_split, update_ref, ) + else: + print_encoder_commandline( + dut_encoder_frontend, + ref_encoder_frontend, + reference_path, + dut_base_path, + bitrate, + sampling_rate, + testv_file, + bitstream_file, + enc_split, + update_ref, + ) if sba_br_switching_dtx == 1 and not keep_files: is_exist = os.path.exists(cut_file) if is_exist: @@ -445,6 +458,47 @@ def encode( add_option_list=enc_opts_list, ) +def print_encoder_commandline( + dut_encoder_frontend, + ref_encoder_frontend, + reference_path, + dut_base_path, + bitrate, + sampling_rate, + testv_file, + bitstream_file, + enc_opts_list, + update_ref, +): + """ + Call REF and/or DUT encoder. + """ + # directories + dut_out_dir = f"{dut_base_path}/param_file/enc" + ref_out_dir = f"{reference_path}/param_file/enc" + + ref_out_file = f"{ref_out_dir}/{bitstream_file}" + dut_out_file = f"{dut_out_dir}/{bitstream_file}" + + if update_ref == 1 or update_ref == 2: + # call REF encoder + ref_encoder_frontend.print_cmdline( + bitrate, + sampling_rate, + testv_file, + ref_out_file, + add_option_list=enc_opts_list, + ) + + if update_ref in [0, 2]: + # call DUT encoder + dut_encoder_frontend.print_cmdline( + bitrate, + sampling_rate, + testv_file, + dut_out_file, + add_option_list=enc_opts_list, + ) def pre_proc_input(testv_file, fs): cut_from = "0.0" diff --git a/tests/conftest.py b/tests/conftest.py index c975e409c01ed4a2401e146d6946cdaba37bb7ba..1ce3f899f31992d9ebd51f75bb19e3bc574e0086 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -300,6 +300,50 @@ class EncoderFrontend: self.stderr = None self.timeout = timeout + def print_cmdline(self, + bitrate: int, + input_sampling_rate: int, + input_path: Path, + output_bitstream_path: Path, + sba_order: Optional[str] = None, + dtx_mode: Optional[bool] = False, + max_band: Optional[str] = None, + pca: Optional[bool] = None, + quiet_mode: Optional[bool] = True, + add_option_list: Optional[list] = None, + ) -> None: + command = [self._path] + + # add optional parameters + if sba_order is not None: + command.extend(["-sba", sba_order]) + + if dtx_mode: + command.extend(["-dtx"]) + + if max_band is not None: + command.extend(["-max_band", max_band]) + + if pca: + command.extend(["-pca"]) + + if quiet_mode: + command.extend(["-q"]) + + if add_option_list is not None: + command.extend(add_option_list) + + # add mandatory parameters + command += [ + str(bitrate), + str(input_sampling_rate), + str(input_path), + str(output_bitstream_path), + ] + + cmd_str = textwrap.indent(" ".join(command), prefix="\t") + log_dbg_msg(f"{self._type} encoder command:\n{cmd_str}") + def run( self, bitrate: int,