diff --git a/lib_com/cnst.h b/lib_com/cnst.h index e1362b0d759ea2fc1762f11aa305f3290c3a8218..a93a2a890ed2d329e8f0a3daa858ec7f5dc0138f 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -2237,11 +2237,13 @@ enum VOIP_RTPDUMP }; +#ifndef JBM_PARAMUPMIX typedef enum _COV_SMOOTHING_TYPE { COV_SMOOTH_SPAR, COV_SMOOTH_MC } COV_SMOOTHING_TYPE; +#endif /* clang-format on */ #endif /* CNST_H */ diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 60807f62cbb847157cf4d56de29a811cc1ad2c71..aa75d3261ed7f0122f2cb3803f060184ee115516 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1332,6 +1332,14 @@ typedef enum #define MC_PARAMUPMIX_NCH 2 /* number of channels to combine into 1 */ #define MC_PARAMUPMIX_MIN_CLDFB 8 +#ifdef JBM_PARAMUPMIX +typedef enum _COV_SMOOTHING_TYPE +{ + COV_SMOOTH_SPAR, + COV_SMOOTH_MC +} COV_SMOOTHING_TYPE; +#endif + typedef struct { const int32_t *value; const uint16_t *length; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 9bc253776da52a8e80ea43224cf48643136b72d4..5ef73792aa5da25651fc53a9c256c82bd5c7bf97 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -837,7 +837,11 @@ TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( /*! r: render granularity */ int16_t ivas_jbm_dec_get_render_granularity( const RENDERER_TYPE rendererType, /* i : renderer type */ - const int32_t output_Fs /* i : sampling rate */ +#ifdef JBM_PARAMUPMIX + const IVAS_FORMAT ivas_format, /* i : ivas format */ + const MC_MODE mc_mode, /* i : MC mode */ +#endif + const int32_t output_Fs /* i : sampling rate */ ); ivas_error ivas_jbm_dec_tc_buffer_open( @@ -3877,6 +3881,23 @@ void ivas_mc_paramupmix_dec_read_BS( int16_t *nb_bits /* o : number of bits written */ ); +#ifdef JBM_PARAMUPMIX +void ivas_mc_paramupmix_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + const int16_t nSamplesForRendering /* i : number of samples provided */ +); + +void ivas_mc_paramupmix_dec_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *input_f[], /* i: core-coder transport channels */ + float *output_f[] /* i/o: synthesized core-coder transport channels */ +); +#endif + void ivas_param_mc_metadata_open( const MC_LS_SETUP mc_ls_setup, /* i : MC ls setup */ const int16_t lfe_index, /* i : channel index of LFE */ @@ -5144,6 +5165,19 @@ void ivas_binRenderer_close( BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: decoder binaural renderer handle */ ); +#ifdef JBM_PARAMUPMIX +void ivas_binaural_cldfb( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +); + +void ivas_binaural_cldfb_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t n_samples_to_render, /* i : output frame length per channel */ + const int16_t slot_size, /* i : JBM slot size */ + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +); +#else #ifdef DEBUGGING void ivas_binaural_cldfb( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -5156,8 +5190,9 @@ void ivas_binaural_cldfb_sf( float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ ); - #endif +#endif + void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ diff --git a/lib_com/options.h b/lib_com/options.h index 1fe1bb999c0a93da0b9acc0a615e6c4efe3f6b4a..38410812e31b18ad198aee5aba80a0376789f6df 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -170,6 +170,7 @@ #define NONBE_FIX_589_JBM_TC_OFFSETS /* FhG: issue 589: wrong offset into the TC buffers is used in some rendering paths in the JBM main rendering function */ #define FIX_MEM_REALLOC_IND_LIST /* VA: issue 601: failure of the automatic memory re-allocation mechanism when ind_list[] buffer is depleted in MASA mode with 2 TC*/ #define FIX_581_CLANG_OFFSET_TO_NULL /* FhG: issue 581: fix CLANG error about applying an offset to a NULL pointer */ +#define JBM_PARAMUPMIX /* Dlb: Issue 471: Integrate the Multichannel Parametric Upmix into the JBM path */ /* ################## End BE DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 5bd09236e0e40471c499b7d55495a096578e0c4f..dd005934e0ae7b0bee83387c5d6c9a7ae1d4dda8 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -942,7 +942,6 @@ void ivas_binaural_add_LFE( } -#ifdef DEBUGGING /*-------------------------------------------------------------------------* * ivas_binaural_cldfb() * @@ -1027,7 +1026,10 @@ void ivas_binaural_cldfb( void ivas_binaural_cldfb_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t n_samples_to_render, /* i : output frame length per channel */ - float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +#ifdef JBM_PARAMUPMIX + const int16_t slot_size, /* i : JBM slot size */ +#endif + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ ) { float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; @@ -1035,12 +1037,18 @@ void ivas_binaural_cldfb_sf( float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch; +#ifdef JBM_PARAMUPMIX + int16_t slots_to_render, first_sf, last_sf; +#else int16_t slot_size, slots_to_render, first_sf, last_sf; +#endif int16_t slot_index_start, slot_index_start_cldfb; /* Implement a 5 msec loops */ maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); +#ifndef JBM_PARAMUPMIX slot_size = st_ivas->hTcBuffer->nb_subframes; +#endif /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, n_samples_to_render / slot_size ); @@ -1110,7 +1118,6 @@ void ivas_binaural_cldfb_sf( return; } -#endif /*------------------------------------------------------------------------- diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 439a90fb2c5cf291ad0206e248c167cd46aa404e..2b88822d06b199f52f56cd64acbcbbe1ac071aa5 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -532,6 +532,10 @@ ivas_error ivas_dec( } /* Rendering */ +#ifdef JBM_PARAMUPMIX + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { +#else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, @@ -539,7 +543,7 @@ ivas_error ivas_dec( { return error; } - +#endif ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); } else if ( st_ivas->renderer_type == RENDERER_MC ) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 22942030530dd939ed9d9fc5d666c1b78fef11e7..3154f19461f693a6d8e112dda155f8b261901890 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1332,13 +1332,39 @@ ivas_error ivas_init_decoder( if ( st_ivas->hDecoderConfig->voip_active ) { +#ifdef JBM_PARAMUPMIX + if ( ( st_ivas->ivas_format == MC_FORMAT ) && ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) + { + granularity = NS2SA( output_Fs, CLDFB_SLOT_NS ); + + n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, MC_PARAMUPMIX_MAX_INPUT_CHANS, MC_PARAMUPMIX_MAX_INPUT_CHANS, granularity ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); + + n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); + n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ) != IVAS_ERR_OK ) { return error; } +#endif } } diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index c031ec8c4bd36f36f7cd001f840f9ebfaeffa7ff..b3c5acc2e4e8808757fdf40be294df119c28769c 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -133,8 +133,11 @@ static ivas_error ivas_ism_bitrate_switching( /* JBM: when granularity goes down (e.g. Discrete ISM with TD Obj Renderer -> ParamISM with binaural fastconv render what still fits in the new granularity */ +#ifdef JBM_PARAMUPMIX + tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs ); +#else tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, st_ivas->hDecoderConfig->output_Fs ); - +#endif if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, MC_MODE_NONE, last_ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index dd06e265b8c3032b944e284939141cbc06b76a27..712a88f114fd9ba2b6201f3bb72933b10fb8c17b 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -362,6 +362,38 @@ ivas_error ivas_jbm_dec_tc( } } } +#ifdef JBM_PARAMUPMIX + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, output_lfe_ch ); + + ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] ); + + if ( ( error = ivas_mct_dec( st_ivas, output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + mvr2r( output_lfe_ch, output[LFE_CHANNEL], output_frame ); + + /* Rendering */ + if ( st_ivas->renderer_type == RENDERER_MC ) + { + if ( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) + { + /* HP filtering */ + for ( n = 0; n < st_ivas->nchan_transport; n++ ) + { + if ( n != LFE_CHANNEL ) + { + hp20( output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + } + ivas_ls_setup_conversion( st_ivas, audioCfg2channels( AUDIO_CONFIG_5_1_2 ), output_frame, p_output, p_output ); + } + } + } +#endif else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) { /* read Parametric MC parameters from the bitstream */ @@ -590,6 +622,12 @@ ivas_error ivas_jbm_dec_feed_tc_to_renderer( { ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); } +#ifdef JBM_PARAMUPMIX + 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 ); + } +#endif 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 ); @@ -769,7 +807,11 @@ ivas_error ivas_jbm_dec_render( #ifdef DEBUGGING else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { +#ifdef JBM_PARAMUPMIX + ivas_binaural_cldfb_sf( st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->nb_subframes, p_output ); +#else ivas_binaural_cldfb_sf( st_ivas, *nSamplesRendered, p_output ); +#endif } #endif } @@ -854,6 +896,49 @@ ivas_error ivas_jbm_dec_render( #endif } } +#ifdef JBM_PARAMUPMIX + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + ivas_mc_paramupmix_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_tc, p_output ); + + /* HP filtering */ + for ( n = 0; n < st_ivas->nchan_transport; n++ ) + { + if ( n != LFE_CHANNEL ) + { + hp20( p_output[n], *nSamplesRendered, st_ivas->mem_hp20_out[n], output_Fs ); + } + } + + if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == AUDIO_CONFIG_FOA || st_ivas->intern_config == AUDIO_CONFIG_HOA2 || st_ivas->intern_config == AUDIO_CONFIG_HOA3 ) ) + { + ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); + } + + /* Rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); + } + else if ( st_ivas->renderer_type == RENDERER_MC ) + { + ivas_ls_setup_conversion( st_ivas, MC_PARAMUPMIX_MAX_INPUT_CHANS, *nSamplesRendered, p_output, p_output ); + } + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { + if ( ( ivas_td_binaural_renderer( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); + } + } +#endif else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) { ivas_param_mc_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); @@ -1411,6 +1496,12 @@ int16_t ivas_jbm_dec_get_num_tc_channels( num_tc = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; } } +#ifdef JBM_PARAMUPMIX + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + num_tc = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS; + } +#endif else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { if ( st_ivas->hOutSetup.separateChannelEnabled ) @@ -1494,7 +1585,36 @@ static void ivas_jbm_dec_copy_tc( * * *--------------------------------------------------------------------------*/ +#ifdef JBM_PARAMUPMIX +/*! r: render granularity */ +int16_t ivas_jbm_dec_get_render_granularity( + const RENDERER_TYPE rendererType, /* i : renderer type */ + const IVAS_FORMAT ivas_format, /* i : ivas format */ + const MC_MODE mc_mode, /* i : MC mode */ + const int32_t output_Fs /* i : sampling rate */ +) +{ + int16_t render_granularity; + if ( rendererType == RENDERER_BINAURAL_OBJECTS_TD || rendererType == RENDERER_BINAURAL_MIXER_CONV || rendererType == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + if ( ( ivas_format == MC_FORMAT ) && ( mc_mode == MC_MODE_PARAMUPMIX ) ) + { + render_granularity = NS2SA( output_Fs, CLDFB_SLOT_NS ); + } + else + { + render_granularity = NS2SA( output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); + } + } + else + { + render_granularity = NS2SA( output_Fs, CLDFB_SLOT_NS ); + } + + return render_granularity; +} +#else /*! r: render granularity */ int16_t ivas_jbm_dec_get_render_granularity( const RENDERER_TYPE rendererType, /* i : renderer type */ @@ -1514,7 +1634,7 @@ int16_t ivas_jbm_dec_get_render_granularity( return render_granularity; } - +#endif /*--------------------------------------------------------------------------* * ivas_jbm_dec_tc_buffer_open() diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index 6447c2f45607a216fb032c61dcc68c50796b8bc7..9ae580ae3a07a06a34721ba4495287088b54e326 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -55,6 +55,14 @@ static void ps_pred_process( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, float qmf_mod_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_mod_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_side_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_side_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t ch ); +#ifdef JBM_PARAMUPMIX +static void ps_pred_process_sf( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, DECODER_TC_BUFFER_HANDLE hTcBuffer, float qmf_mod_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_mod_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float *param_interpol, const int16_t ch, const int16_t slots_rendered ); + +static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, float *output_f[MAX_OUTPUT_CHANNELS] ); + +static void ivas_param_upmix_dec_decorr_subframes( Decoder_Struct *st_ivas, const int16_t nSamplesForRendering ); +#endif + static void paramupmix_td_decorr_process( ivas_td_decorr_state_t *hTdDecorr[], float pcm_in[][L_FRAME48k], float **pp_out_pcm, const int16_t output_frame ); static int huff_read( Decoder_State *st, const int16_t ( *ht )[2] ); @@ -173,7 +181,9 @@ void ivas_mc_paramupmix_dec( float *pPcm_temp[MC_PARAMUPMIX_COMBINATIONS * 2]; /* decorrelated and undecorrelated*/ int16_t noparamupmix_delay; AUDIO_CONFIG output_config; - +#ifdef JBM_PARAMUPMIX + float *p_output[MAX_OUTPUT_CHANNELS]; +#endif hMCParamUpmix = st_ivas->hMCParamUpmix; assert( hMCParamUpmix ); @@ -190,6 +200,19 @@ void ivas_mc_paramupmix_dec( { first_empty_channel = 8; /* Don't upmix */ } +#ifdef JBM_PARAMUPMIX + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + /* Implement binaural rendering */ + first_empty_channel = 4; /* don't erase LFE */ + + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS * 2; ch++ ) + { + p_output[ch] = output_f[ch]; + } + ivas_binaural_cldfb( st_ivas, p_output ); + } +#endif else { first_empty_channel = 12; @@ -292,6 +315,114 @@ void ivas_mc_paramupmix_dec( } +#ifdef JBM_PARAMUPMIX +void ivas_mc_paramupmix_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + const int16_t nSamplesForRendering /* i : number of samples provided */ +) +{ + MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; + hMCParamUpmix = st_ivas->hMCParamUpmix; + assert( hMCParamUpmix ); + + push_wmops( "ivas_mc_paramupmix_dec_digest_tc" ); + + ivas_param_upmix_dec_decorr_subframes( st_ivas, nSamplesForRendering ); + + /* adapt subframes */ + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + + ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hMCParamUpmix->param_interpolator ); + + pop_wmops(); +} + + +void ivas_mc_paramupmix_dec_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *input_f[], /* i: core-coder transport channels */ + float *output_f[] /* i/o: synthesized core-coder transport channels */ +) +{ + int16_t slots_to_render, first_sf, last_sf, subframe_idx; + uint16_t slot_size, ch; + float *output_f_local[MAX_OUTPUT_CHANNELS]; + MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; + + hMCParamUpmix = st_ivas->hMCParamUpmix; + assert( hMCParamUpmix ); + + push_wmops( "ivas_mc_paramupmix_dec_render" ); + + for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + { + output_f_local[ch] = output_f[ch]; + } + + slot_size = st_ivas->hTcBuffer->n_samples_granularity; + + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, nSamplesAsked / slot_size ); + *nSamplesRendered = slots_to_render * slot_size; + first_sf = st_ivas->hTcBuffer->subframes_rendered; + last_sf = first_sf; + + for ( ch = 0; ch < MAX_TRANSPORT_CHANNELS; ch++ ) + { + mvr2r( input_f[ch], output_f_local[ch], *nSamplesRendered ); + } + + while ( slots_to_render > 0 ) + { + slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf]; + last_sf++; + } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif + /* Implement binaural rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + ivas_binaural_cldfb_sf( st_ivas, *nSamplesRendered, slot_size, output_f_local ); + } + else + { + + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) + { + mvr2r( hMCParamUpmix->alpha_prev[ch], hMCParamUpmix->alpha_sf[ch], IVAS_MAX_NUM_BANDS ); + mvr2r( hMCParamUpmix->beta_prev[ch], hMCParamUpmix->beta_sf[ch], IVAS_MAX_NUM_BANDS ); + } + + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + int16_t n_samples_sf = slot_size * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; + + ivas_mc_paramupmix_dec_sf( st_ivas, output_f_local ); + for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + { + output_f_local[ch] += n_samples_sf; + } + } + + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) + { + mvr2r( hMCParamUpmix->alphas[ch], hMCParamUpmix->alpha_prev[ch], IVAS_MAX_NUM_BANDS ); + mvr2r( hMCParamUpmix->betas[ch], hMCParamUpmix->beta_prev[ch], IVAS_MAX_NUM_BANDS ); + } + } + + *nSamplesAvailable = ( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered ) * slot_size; + + pop_wmops(); +} +#endif + + /*------------------------------------------------------------------------- * ivas_mc_paramupmix_dec_open() * @@ -347,15 +478,53 @@ ivas_error ivas_mc_paramupmix_dec_open( ivas_td_decorr_dec_open( &( hMCParamUpmix->hTdDecorr[i] ), output_Fs, 2, 1 ); } +#ifdef JBM_PARAMUPMIX for ( i = 0; i < MC_PARAMUPMIX_MAX_TRANSPORT_CHANS; i++ ) { - if ( ( hMCParamUpmix->pcm_delay[i] = (float *) malloc( 240 * sizeof( float ) ) ) == NULL ) + if ( ( hMCParamUpmix->pcm_delay[i] = (float *) malloc( NS2SA( output_Fs, IVAS_FB_DEC_DELAY_NS ) * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for delay buffer\n" ) ); } - set_zero( hMCParamUpmix->pcm_delay[i], 240 ); + set_zero( hMCParamUpmix->pcm_delay[i], NS2SA( output_Fs, IVAS_FB_DEC_DELAY_NS ) ); } + /* allocate transport channels*/ + hMCParamUpmix->free_param_interpolator = 0; + hMCParamUpmix->param_interpolator = NULL; + if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) + { + int16_t nchan_to_allocate; + int16_t nchan_tc; + TC_BUFFER_MODE buffer_mode; + + buffer_mode = TC_BUFFER_MODE_RENDERER; + nchan_tc = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + nchan_to_allocate = MC_PARAMUPMIX_MAX_INPUT_CHANS; + if ( ( hMCParamUpmix->param_interpolator = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) ); + } + + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO ) + { + buffer_mode = TC_BUFFER_MODE_BUFFER; + nchan_tc = st_ivas->hDecoderConfig->nchan_out; + nchan_to_allocate = nchan_tc; + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + nchan_to_allocate = MC_PARAMUPMIX_MAX_INPUT_CHANS; + } + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + return error; + } + hMCParamUpmix->free_param_interpolator = 1; + + ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, DEFAULT_JBM_CLDFB_TIMESLOTS, hMCParamUpmix->param_interpolator ); + } +#endif + st_ivas->hMCParamUpmix = hMCParamUpmix; return error; @@ -389,13 +558,118 @@ void ivas_mc_paramupmix_dec_close( free( ( *hMCParamUpmix )->pcm_delay[i] ); } } +#ifdef JBM_PARAMUPMIX + if ( ( *hMCParamUpmix )->param_interpolator != NULL ) + { + if ( ( *hMCParamUpmix )->free_param_interpolator == 1 ) + { + free( ( *hMCParamUpmix )->param_interpolator ); + } + } +#endif free( *hMCParamUpmix ); *hMCParamUpmix = NULL; return; } +#ifdef JBM_PARAMUPMIX +/*------------------------------------------------------------------------- + * ivas_param_upmix_dec_decorr_subframes() + * + * + *------------------------------------------------------------------------*/ +static void paramupmix_td_decorr_process_jbm( + ivas_td_decorr_state_t *hTdDecorr[], /* i/o: SPAR Covar. decoder handle */ + float *pcm_in[], /* i : input audio channels */ + float **pp_out_pcm, /* o : output audio channels */ + const int16_t output_frame /* i : output frame length */ +) +{ + int16_t j, k; + int16_t offset; + float in_duck_gain[L_FRAME48k], out_duck_gain[L_FRAME48k]; + + offset = (int16_t) ( output_frame * FRAMES_PER_SEC * IVAS_DECORR_PARM_LOOKAHEAD_TAU ); + + /* Look-ahead delay */ + for ( k = 0; k < MC_PARAMUPMIX_COMBINATIONS; k++ ) + { + mvr2r( pcm_in[k], pp_out_pcm[k], output_frame ); + delay_signal( pp_out_pcm[k], output_frame, hTdDecorr[k]->look_ahead_buf, offset ); + + /* In ducking gains */ + if ( hTdDecorr[k]->ducking_flag ) + { + ivas_td_decorr_get_ducking_gains( hTdDecorr[k]->pTrans_det, pcm_in[k], in_duck_gain, out_duck_gain, output_frame, 0 ); + + for ( j = 0; j < output_frame; j++ ) + { + pp_out_pcm[k][j] = pp_out_pcm[k][j] * in_duck_gain[j]; + } + } + + /* All pass delay section */ + ivas_td_decorr_APD_iir_filter( &hTdDecorr[k]->APD_filt_state[0], pp_out_pcm[k], hTdDecorr[k]->num_apd_sections, output_frame ); + + /* Out ducking gains */ + if ( hTdDecorr[k]->ducking_flag ) + { + for ( j = 0; j < output_frame; j++ ) + { + pp_out_pcm[k][j] = pp_out_pcm[k][j] * out_duck_gain[j]; + } + } + } + + return; +} + +static void ivas_param_upmix_dec_decorr_subframes( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t nSamplesForRendering ) +{ + MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; + float *pPcm_tmp[MC_PARAMUPMIX_COMBINATIONS]; + float *p_tc[MC_PARAMUPMIX_COMBINATIONS]; + int16_t nchan_internal, ch; + int16_t nSamplesLeftForTD, default_frame; + + hMCParamUpmix = st_ivas->hMCParamUpmix; + assert( hMCParamUpmix ); + + push_wmops( "ivas_param_upmix_dec_decorr_subframes" ); + + /* TD decorrelator */ + default_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + nSamplesLeftForTD = nSamplesForRendering; + nchan_internal = MC_PARAMUPMIX_COMBINATIONS; + + for ( ch = 0; ch < nchan_internal; ch++ ) + { + pPcm_tmp[ch] = st_ivas->hTcBuffer->tc[ch + 8]; + p_tc[ch] = st_ivas->hTcBuffer->tc[ch + 4]; + } + + while ( nSamplesLeftForTD ) + { + int16_t nSamplesToDecorr = min( nSamplesLeftForTD, default_frame ); + + paramupmix_td_decorr_process_jbm( hMCParamUpmix->hTdDecorr, p_tc, pPcm_tmp, nSamplesToDecorr ); + for ( ch = 0; ch < nchan_internal; ch++ ) + { + p_tc[ch] += nSamplesToDecorr; + } + + nSamplesLeftForTD -= nSamplesToDecorr; + } + + pop_wmops(); + + return; +} +#endif /*****************************************************************************************/ /* local functions */ @@ -464,6 +738,204 @@ static void ps_pred_process( return; } +#ifdef JBM_PARAMUPMIX +static void ps_pred_process_sf( + MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, + DECODER_TC_BUFFER_HANDLE hTcBuffer, + float qmf_mod_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* in/out */ + float qmf_mod_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float qmf_side_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* in/out */ + float qmf_side_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float *param_interpol, + const int16_t ch, + const int16_t slots_rendered ) +{ + float vmre, vmim, vsre, vsim; + int16_t iqmf, ipar, ismp, iismp; + float alpha_smp, beta_smp; + float *alpha1, *alpha2; + float *beta1, *beta2; + float *alpha_prev = hMCParamUpmix->alpha_prev[ch]; + float *beta_prev = hMCParamUpmix->beta_prev[ch]; + float *alpha_sf = hMCParamUpmix->alpha_sf[ch]; + float *beta_sf = hMCParamUpmix->beta_sf[ch]; + float dalpha, dbeta, ifac; + float alpha_start[IVAS_MAX_NUM_BANDS], beta_start[IVAS_MAX_NUM_BANDS]; + + const int16_t qmf_to_par_band[] = { + 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 + }; + + mvr2r( alpha_sf, alpha_start, IVAS_MAX_NUM_BANDS ); + mvr2r( beta_sf, beta_start, IVAS_MAX_NUM_BANDS ); + for ( iqmf = 0; iqmf < CLDFB_NO_CHANNELS_MAX; iqmf++ ) + { + ipar = qmf_to_par_band[iqmf]; + alpha1 = alpha_prev; + beta1 = beta_prev; + + ismp = 0; + alpha2 = hMCParamUpmix->alphas[ch]; + beta2 = hMCParamUpmix->betas[ch]; + alpha_smp = alpha_start[ipar]; + beta_smp = beta_start[ipar]; + + for ( iismp = 0; iismp < hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered]; iismp++ ) + { + if ( ( slots_rendered == 0 ) && ( iismp == 0 ) ) + { + ifac = param_interpol[iismp]; + } + else + { + ifac = param_interpol[iismp] - param_interpol[iismp - 1]; + } + dalpha = ( alpha2[ipar] - alpha1[ipar] ) * ifac; + dbeta = ( beta2[ipar] - beta1[ipar] ) * ifac; + + alpha_smp += dalpha; + beta_smp += dbeta; + + vmre = qmf_mod_re[ismp][iqmf]; + vmim = qmf_mod_im[ismp][iqmf]; + vsre = qmf_side_re[ismp][iqmf]; + vsim = qmf_side_im[ismp][iqmf]; + + qmf_side_re[ismp][iqmf] = alpha_smp * vmre + beta_smp * vsre; + qmf_side_im[ismp][iqmf] = alpha_smp * vmim + beta_smp * vsim; + + ismp++; + } + alpha_sf[ipar] = alpha_smp; + beta_sf[ipar] = beta_smp; + } + + return; +} + + +static void ivas_mc_paramupmix_dec_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float *output_f[MAX_OUTPUT_CHANNELS] /* i/o: synthesized core-coder transport channels */ +) +{ + int16_t i, ch, slot_idx, k; + float *pPcm_temp[MC_PARAMUPMIX_COMBINATIONS * 2]; /* decorrelated and undecorrelated*/ + /*CLDFB*/ + float Cldfb_RealBuffer[MC_PARAMUPMIX_MAX_TRANSPORT_CHANS][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MC_PARAMUPMIX_MAX_TRANSPORT_CHANS][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + int16_t noparamupmix_delay, n_samples_rendered; + MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; + hMCParamUpmix = st_ivas->hMCParamUpmix; + assert( hMCParamUpmix ); + + push_wmops( "ivas_mc_paramupmix_dec_sf" ); + + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + pPcm_temp[2 * i] = output_f[i + 4]; /* un-decorrelated */ + pPcm_temp[2 * i + 1] = output_f[i + 8]; /* decorrelated */ + } + + /* CLDFB Analysis*/ + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS * 2; ch++ ) + { + /* slot loop for gathering the input data */ + for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ ) + { + cldfbAnalysis_ts( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), Cldfb_RealBuffer[ch][slot_idx], Cldfb_ImagBuffer[ch][slot_idx], hMCParamUpmix->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + } + } + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) + { + ps_pred_process_sf( hMCParamUpmix, + st_ivas->hTcBuffer, + Cldfb_RealBuffer[2 * ch], /* in/out */ + Cldfb_ImagBuffer[2 * ch], + Cldfb_RealBuffer[2 * ch + 1], /* in/out decorr */ + Cldfb_ImagBuffer[2 * ch + 1], + &hMCParamUpmix->param_interpolator[st_ivas->hTcBuffer->slots_rendered], + ch, + st_ivas->hTcBuffer->slots_rendered ); + + /*-- m, s -> l, r ----------------------------*/ + for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ ) + { + for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + float qlre = Cldfb_RealBuffer[2 * ch][slot_idx][k]; + float qlim = Cldfb_ImagBuffer[2 * ch][slot_idx][k]; + float qrre = Cldfb_RealBuffer[2 * ch + 1][slot_idx][k]; + float qrim = Cldfb_ImagBuffer[2 * ch + 1][slot_idx][k]; + + Cldfb_RealBuffer[2 * ch][slot_idx][k] = qlre + qrre; + Cldfb_ImagBuffer[2 * ch][slot_idx][k] = qlim + qrim; + Cldfb_RealBuffer[2 * ch + 1][slot_idx][k] = qlre - qrre; + Cldfb_ImagBuffer[2 * ch + 1][slot_idx][k] = qlim - qrim; + } + } + } + /* boxes = { 0 1 2 3 [4 6] [5 7] [8 10] [9 11] }; */ + pPcm_temp[0] = output_f[4]; + pPcm_temp[1] = output_f[6]; + pPcm_temp[2] = output_f[5]; + pPcm_temp[3] = output_f[7]; + pPcm_temp[4] = output_f[8]; + pPcm_temp[5] = output_f[10]; + pPcm_temp[6] = output_f[9]; + pPcm_temp[7] = output_f[11]; + + /* CLDFB synthesis */ + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS * 2; ch++ ) + { + for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ ) + { + float *ptr_im[1], *ptr_re[1]; + ptr_re[0] = Cldfb_RealBuffer[ch][slot_idx]; + ptr_im[0] = Cldfb_ImagBuffer[ch][slot_idx]; + + cldfbSynthesis( ptr_re, ptr_im, &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), + hMCParamUpmix->num_freq_bands, st_ivas->cldfbSynDec[ch] ); + } + } + /* adjust delay of other channels */ + noparamupmix_delay = NS2SA( st_ivas->hDecoderConfig->output_Fs, IVAS_FB_DEC_DELAY_NS ); + n_samples_rendered = st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered] * hMCParamUpmix->num_freq_bands; + if ( n_samples_rendered > noparamupmix_delay ) + { + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) + { + float tmp_buf[L_SUBFRAME5MS_48k]; + mvr2r( &output_f[ch][n_samples_rendered - noparamupmix_delay], tmp_buf, noparamupmix_delay ); + mvr2r( output_f[ch], &output_f[ch][noparamupmix_delay], n_samples_rendered - noparamupmix_delay ); + mvr2r( hMCParamUpmix->pcm_delay[ch], output_f[ch], noparamupmix_delay ); + mvr2r( tmp_buf, hMCParamUpmix->pcm_delay[ch], noparamupmix_delay ); + } + } + else + { + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) + { + float tmp_buf[L_SUBFRAME5MS_48k]; + mvr2r( &output_f[ch][0], tmp_buf, n_samples_rendered ); + mvr2r( hMCParamUpmix->pcm_delay[ch], output_f[ch], n_samples_rendered ); + mvr2r( &hMCParamUpmix->pcm_delay[ch][n_samples_rendered], &hMCParamUpmix->pcm_delay[ch][0], noparamupmix_delay - n_samples_rendered ); + mvr2r( tmp_buf, &hMCParamUpmix->pcm_delay[ch][noparamupmix_delay - n_samples_rendered], n_samples_rendered ); + } + } + + st_ivas->hTcBuffer->slots_rendered += st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; + st_ivas->hTcBuffer->subframes_rendered++; + + pop_wmops(); +} +#endif + static void paramupmix_td_decorr_process( ivas_td_decorr_state_t *hTdDecorr[], /* i/o: SPAR Covar. decoder handle */ diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 7742656899b573b0cc86254b5cf43ebc76661131..a9a0442c8a37290a9cf488c03d590f49372fa4c9 100755 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -748,7 +748,11 @@ static ivas_error ivas_mc_dec_reconfig( /* JBM: when granularity goes down (e.g. MCT with CREND -> ParamMC with binaural fastconv render what still fits in the new granularity */ +#ifdef JBM_PARAMUPMIX + tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs ); +#else tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, st_ivas->hDecoderConfig->output_Fs ); +#endif if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, last_mc_mode, ISM_MODE_NONE, nSamplesRendered, data ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index 16787b63cdd383b24bb8b3c93fe50513e1bca5d3..a068e97b792c19623d1a1e2919a493ed76f2aaf9 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -199,7 +199,11 @@ void ivas_renderer_select( } else { +#ifdef JBM_PARAMUPMIX + if ( st_ivas->mc_mode == MC_MODE_MCT ) +#else if ( ( st_ivas->mc_mode == MC_MODE_MCT ) || ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) +#endif { *renderer_type = RENDERER_BINAURAL_MIXER_CONV; } @@ -223,11 +227,21 @@ void ivas_renderer_select( /* force HOA3 domain for rotation*/ *internal_config = AUDIO_CONFIG_HOA3; } +#ifdef JBM_PARAMUPMIX + if ( ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && ( *renderer_type == RENDERER_BINAURAL_FASTCONV ) ) + { + *internal_config = AUDIO_CONFIG_5_1_2; + } +#endif } } else { +#ifdef JBM_PARAMUPMIX + if ( st_ivas->mc_mode == MC_MODE_MCT ) +#else if ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) +#endif { *renderer_type = RENDERER_BINAURAL_MIXER_CONV_ROOM; } @@ -244,6 +258,12 @@ void ivas_renderer_select( { *renderer_type = RENDERER_BINAURAL_FASTCONV_ROOM; } +#endif +#ifdef JBM_PARAMUPMIX + if ( ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && ( *renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + *internal_config = AUDIO_CONFIG_5_1_2; + } #endif } } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 315cfbad668d813f787933ea38d810ec8daed60d..e13be187937ca0c12f3efad5fa9fdeec3df1c9c8 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -802,6 +802,12 @@ typedef struct ivas_mc_paramupmix_dec_data_structure int32_t beta_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; int16_t first_frame; float *pcm_delay[MC_PARAMUPMIX_MAX_TRANSPORT_CHANS]; +#ifdef JBM_PARAMUPMIX + float *param_interpolator; + float alpha_sf[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + float beta_sf[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + int16_t free_param_interpolator; +#endif } MC_PARAMUPMIX_DEC_DATA, *MC_PARAMUPMIX_DEC_HANDLE; diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index b2b488749952f4a748bd0cab3d294e4849f31bb6..6d536bd6254069d7f2052f99e10bdaa462fc3e88 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1514,8 +1514,9 @@ ivas_error ivas_rend_crendProcessSubframe( slots_to_render = min( hTcBuffer->num_slots - hTcBuffer->slots_rendered, n_samples_to_render / slot_size ); first_sf = hTcBuffer->subframes_rendered; last_sf = first_sf; +#ifndef JBM_PARAMUPMIX hTcBuffer->slots_rendered += slots_to_render; - +#endif while ( slots_to_render > 0 ) { slots_to_render -= hTcBuffer->subframe_nbslots[last_sf]; @@ -1569,6 +1570,9 @@ ivas_error ivas_rend_crendProcessSubframe( { p_pcm_tmp[ch] += subframe_len; } +#ifdef JBM_PARAMUPMIX + hTcBuffer->slots_rendered += hTcBuffer->subframe_nbslots[subframe_idx]; +#endif } else {