From 6f627602f034ae93377ced5290e633f405f79dae Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 5 May 2025 16:00:44 +0200 Subject: [PATCH 1/6] issue 1322: Correct the number of float buffers (channels) at the decoder; under FIX_NCHAN_BUFFERS --- lib_com/options.h | 1 + lib_dec/ivas_dirac_dec.c | 24 +++++- lib_dec/ivas_init_dec.c | 7 +- lib_dec/ivas_jbm_dec.c | 18 +++++ lib_dec/ivas_masa_dec.c | 30 +++++++ lib_dec/ivas_mct_dec.c | 12 +++ lib_dec/ivas_sba_dec.c | 14 ++++ lib_rend/ivas_crend.c | 28 ++++++- lib_rend/ivas_dirac_dec_binaural_functions.c | 24 ++++++ lib_rend/ivas_output_init.c | 84 +++++++++++++++++++- 10 files changed, 238 insertions(+), 4 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 904e462921..96168a1b4c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -161,6 +161,7 @@ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ #define TMP_FIX_1119_SPLIT_RENDERING_VOIP /* FhG: Add error check for unsupported config: split rendering with VoIP mode */ #define UNIFIED_DECODING_PATHS_LEFTOVERS /* VA: issue 880: remove leftovers after NONBE_UNIFIED_DECODING_PATHS */ +#define FIX_NCHAN_BUFFERS /* VA: issue 1322: Correct the number of float buffers (channels) at the decoder */ /* #################### End BE switches ################################## */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index cfc4b0bc30..ade39c535b 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1554,7 +1554,12 @@ void ivas_dirac_dec_render( uint16_t slot_size, n_samples_sf, ch, nchan_intern; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; +#ifdef FIX_NCHAN_BUFFERS + float *p_output_f[MAX_OUTPUT_CHANNELS]; + float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; +#else float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; +#endif hSpatParamRendCom = st_ivas->hSpatParamRendCom; @@ -1565,7 +1570,11 @@ void ivas_dirac_dec_render( for ( ch = 0; ch < nchan_intern; ch++ ) { output_f_local[ch] = output_f_local_buff[ch]; +#ifdef FIX_NCHAN_BUFFERS + p_output_f[ch] = output_f[ch]; +#else set_zero( output_f_local_buff[ch], nSamplesAsked ); +#endif } slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); @@ -1587,16 +1596,29 @@ void ivas_dirac_dec_render( for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL ); + n_samples_sf = hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->slot_size; + for ( ch = 0; ch < nchan_intern; ch++ ) { +#ifdef FIX_NCHAN_BUFFERS + /* move to output */ + if ( !( ( st_ivas->hDirACRend->hOutSetup.separateChannelEnabled ) && ( st_ivas->hDirACRend->hOutSetup.separateChannelIndex == ch || st_ivas->hDirACRend->hOutSetup.separateChannelIndex + 1 == ch ) ) ) + { + mvr2r( output_f_local_buff[ch], p_output_f[ch], n_samples_sf ); + } + + p_output_f[ch] += n_samples_sf; +#else output_f_local[ch] += n_samples_sf; +#endif } /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } +#ifndef FIX_NCHAN_BUFFERS for ( ch = 0; ch < nchan_intern; ch++ ) { if ( !( ( st_ivas->hDirACRend->hOutSetup.separateChannelEnabled ) && ( st_ivas->hDirACRend->hOutSetup.separateChannelIndex == ch || st_ivas->hDirACRend->hOutSetup.separateChannelIndex + 1 == ch ) ) ) @@ -1604,7 +1626,7 @@ void ivas_dirac_dec_render( mvr2r( output_f_local_buff[ch], output_f[ch], *nSamplesRendered ); } } - +#endif if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots ) { if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 0d3610065b..f59064bbb8 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -487,7 +487,7 @@ ivas_error ivas_dec_setup( } /*-------------------------------------------------------------------* - * Read other signling (ISM/MC mode, number of channels, etc.) + * Read other signaling (ISM/MC mode, number of channels, etc.) *-------------------------------------------------------------------*/ if ( is_DTXrate( ivas_total_brate ) == 0 ) @@ -2378,7 +2378,12 @@ ivas_error ivas_init_decoder( * Allocate floating-point output audio buffers *-----------------------------------------------------------------*/ +#ifdef FIX_NCHAN_BUFFERS + k = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); + for ( n = 0; n < k; n++ ) +#else for ( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ ) +#endif { /* note: these are intra-frame heap memories */ if ( ( st_ivas->p_output_f[n] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 68e9099896..596a9edd74 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -849,7 +849,12 @@ void ivas_jbm_dec_feed_tc_to_renderer( p_data_f[n] = &st_ivas->p_output_f[n][0]; } +#ifdef FIX_NCHAN_BUFFERS + ch = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); + for ( n = 0; n < ch; n++ ) +#else for ( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ ) +#endif { hTcBuffer->tc[n] = st_ivas->p_output_f[n]; /* note: buffers needed in the TD decorellator */ } @@ -2379,11 +2384,20 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( { int16_t nsamp_to_allocate, n_samp_full, n_samp_residual, offset, nchan_residual; int16_t ch_idx; +#ifdef FIX_NCHAN_BUFFERS + float tc_buffer_mem[CPE_CHANNELS * MAX_JBM_L_FRAME48k]; + int16_t num_tc_buffer_mem; +#endif DECODER_TC_BUFFER_HANDLE hTcBuffer; hTcBuffer = st_ivas->hTcBuffer; +#ifdef FIX_NCHAN_BUFFERS + /* 2 channels of the TC buffer for smooth transition in bitrate swithing within 1 CPE and TD decorr. on and off */ + num_tc_buffer_mem = min( hTcBuffer->nchan_buffer_full, CPE_CHANNELS ); + mvr2r( hTcBuffer->tc_buffer, tc_buffer_mem, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); +#endif /* if granularity changes, adapt subframe_nb_slots */ if ( n_samples_granularity != hTcBuffer->n_samples_granularity ) { @@ -2488,6 +2502,10 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( } } +#ifdef FIX_NCHAN_BUFFERS + mvr2r( tc_buffer_mem, hTcBuffer->tc_buffer, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); + +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 34d528b0e3..560cb474b4 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -1320,6 +1320,9 @@ ivas_error ivas_masa_dec_reconfigure( Decoder_State **sts; int32_t ivas_total_brate, last_ivas_total_brate; int16_t numCldfbAnalyses_old, numCldfbSyntheses_old; +#ifdef FIX_NCHAN_BUFFERS + int16_t nchan_out_buff_old, nchan_out_buff; +#endif ivas_error error; int16_t pos_idx; int32_t ism_total_brate; @@ -1327,6 +1330,10 @@ ivas_error ivas_masa_dec_reconfigure( ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; +#ifdef FIX_NCHAN_BUFFERS + nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); + +#endif /* Copy state to TC buffer if granularity matches and we are not in OMASA EXT rendering mode */ if ( st_ivas->hSpatParamRendCom != NULL && st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -1490,7 +1497,15 @@ ivas_error ivas_masa_dec_reconfigure( } else { +#ifdef FIX_NCHAN_BUFFERS + tc_nchan_to_allocate = BINAURAL_CHANNELS; + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) + { + tc_nchan_to_allocate = 2 * BINAURAL_CHANNELS; + } +#else tc_nchan_to_allocate = 2 * BINAURAL_CHANNELS; +#endif } } else if ( st_ivas->nchan_transport == 1 && ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) ) @@ -1530,6 +1545,21 @@ ivas_error ivas_masa_dec_reconfigure( } } +#ifdef FIX_NCHAN_BUFFERS + /*-----------------------------------------------------------------* + * floating-point output audio buffers + *-----------------------------------------------------------------*/ + + if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->last_ivas_format == MASA_FORMAT ) /* note: switching with OMASA is addressed in ivas_omasa_dec_config() */ + { + nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); + if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) + { + return error; + } + } + +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 3300eb7965..4097c4d71d 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -1279,7 +1279,19 @@ static ivas_error ivas_mc_dec_reconfig( if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { +#ifdef FIX_NCHAN_BUFFERS + tc_nchan_allocate_new = BINAURAL_CHANNELS; + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) + { + tc_nchan_allocate_new = 2 * BINAURAL_CHANNELS; + } + else if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + tc_nchan_allocate_new++; + } +#else tc_nchan_allocate_new = 2 * BINAURAL_CHANNELS; +#endif tc_nchan_full_new = tc_nchan_allocate_new; } diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index ade8e11b02..de0e9444c6 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -704,6 +704,20 @@ ivas_error ivas_sba_dec_render( nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; +#ifdef FIX_NCHAN_BUFFERS + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + nchan_out = max( nchan_internal, st_ivas->hDecoderConfig->nchan_out ); + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + nchan_out = max( nchan_internal, st_ivas->hDecoderConfig->nchan_out - st_ivas->nchan_ism ); + } + } + + nchan_out = min( nchan_out, ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) ); + +#endif #ifdef DEBUGGING assert( hSpar ); #endif diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index fde8148951..b0c9631bdc 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1501,8 +1501,13 @@ static ivas_error ivas_rend_crendConvolver( const float *pFreq_filt_re, *pFreq_filt_im; float *pFreq_buf_re = NULL, *pFreq_buf_im = NULL; float *pFreq_buf2_re = NULL, *pFreq_buf2_im = NULL; +#ifdef FIX_NCHAN_BUFFERS + float pOut[2 /*Re,Im*/ * L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + float tmp_out_re[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES], tmp_out_im[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; +#else float pOut[L_FRAME48k * 2]; float tmp_out_re[L_FRAME48k], tmp_out_im[L_FRAME48k]; +#endif CREND_HANDLE hCrend; ivas_error error; @@ -1708,7 +1713,12 @@ ivas_error ivas_rend_crendProcessSubframe( int16_t subframe_idx, subframe_len; int16_t nchan_out, nchan_in, ch, first_sf, last_sf, slot_size, slots_to_render; float *tc_local[MAX_OUTPUT_CHANNELS]; +#ifdef FIX_NCHAN_BUFFERS + float *p_output[BINAURAL_CHANNELS]; + float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; +#else float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; +#endif float *p_pcm_tmp[BINAURAL_CHANNELS]; IVAS_REND_AudioConfigType inConfigType; ivas_error error; @@ -1747,6 +1757,9 @@ ivas_error ivas_rend_crendProcessSubframe( for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { p_pcm_tmp[ch] = pcm_tmp[ch]; +#ifdef FIX_NCHAN_BUFFERS + p_output[ch] = output[ch]; +#endif } if ( hTcBuffer != NULL ) @@ -1827,10 +1840,12 @@ ivas_error ivas_rend_crendProcessSubframe( { tc_local[ch] += subframe_len; } +#ifndef FIX_NCHAN_BUFFERS for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { p_pcm_tmp[ch] += subframe_len; } +#endif if ( hTcBuffer != NULL ) { @@ -1842,16 +1857,27 @@ ivas_error ivas_rend_crendProcessSubframe( return IVAS_ERR_INVALID_INPUT_FORMAT; } +#ifdef FIX_NCHAN_BUFFERS + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + /* move to output */ + mvr2r( pcm_tmp[ch], p_output[ch], subframe_len ); + + p_output[ch] += subframe_len; + } + +#endif /* update combined orientation access index */ ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_len ); } +#ifndef FIX_NCHAN_BUFFERS /* move to output */ for ( ch = 0; ch < nchan_out; ch++ ) { mvr2r( pcm_tmp[ch], output[ch], n_samples_to_render ); } - +#endif if ( hTcBuffer != NULL ) { hTcBuffer->subframes_rendered = last_sf; diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index cc1bccb131..8aa7b94d58 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -318,7 +318,19 @@ ivas_error ivas_dirac_dec_init_binaural_data( int16_t nchan_to_allocate; int16_t n_samples_granularity; +#ifdef FIX_NCHAN_BUFFERS + nchan_to_allocate = BINAURAL_CHANNELS; + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) + { + nchan_to_allocate = 2 * BINAURAL_CHANNELS; + } + else if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + nchan_to_allocate++; + } +#else nchan_to_allocate = 2 * BINAURAL_CHANNELS; +#endif if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) { nchan_to_allocate = BINAURAL_CHANNELS + st_ivas->nchan_ism; @@ -444,8 +456,10 @@ void ivas_dirac_dec_binaural_render( uint16_t nchan_out; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; +#ifndef FIX_NCHAN_BUFFERS float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; int16_t output_length; +#endif hSpatParamRendCom = st_ivas->hSpatParamRendCom; nchan_out = BINAURAL_CHANNELS; @@ -454,7 +468,11 @@ void ivas_dirac_dec_binaural_render( #endif for ( ch = 0; ch < nchan_out; ch++ ) { +#ifdef FIX_NCHAN_BUFFERS + output_f_local[ch] = output_f[ch]; +#else output_f_local[ch] = output_f_local_buff[ch]; +#endif } slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); @@ -473,7 +491,9 @@ void ivas_dirac_dec_binaural_render( #ifdef DEBUGGING assert( slots_to_render == 0 ); #endif +#ifndef FIX_NCHAN_BUFFERS output_length = 0; +#endif for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { int16_t n_samples_sf = slot_size * hSpatParamRendCom->subframe_nbslots[subframe_idx]; @@ -484,17 +504,21 @@ void ivas_dirac_dec_binaural_render( output_f_local[ch] += n_samples_sf; } +#ifndef FIX_NCHAN_BUFFERS output_length += n_samples_sf; +#endif /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } +#ifndef FIX_NCHAN_BUFFERS for ( ch = 0; ch < nchan_out; ch++ ) { mvr2r( output_f_local_buff[ch], output_f[ch], output_length ); } +#endif if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots ) { hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length; diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 1487181715..4458e9ea84 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -271,7 +271,11 @@ int16_t ivas_get_nchan_buffers_dec( output_config = st_ivas->hDecoderConfig->output_config; +#ifdef FIX_NCHAN_BUFFERS + nchan_out_buff = st_ivas->nchan_transport; +#else nchan_out_buff = MAX_OUTPUT_CHANNELS; +#endif if ( st_ivas->ivas_format == MONO_FORMAT ) { @@ -283,6 +287,14 @@ int16_t ivas_get_nchan_buffers_dec( } else if ( st_ivas->ivas_format == ISM_FORMAT ) { +#ifdef FIX_NCHAN_BUFFERS + nchan_out_buff = max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_ism ); + + if ( st_ivas->ism_mode == ISM_MODE_PARAM || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) + { + nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); + } +#else nchan_out_buff = st_ivas->nchan_ism; if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) @@ -294,9 +306,16 @@ int16_t ivas_get_nchan_buffers_dec( nchan_out_buff = max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) ); nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); } +#endif } else if ( st_ivas->ivas_format == SBA_FORMAT ) { +#ifdef FIX_NCHAN_BUFFERS + int16_t nchan_internal; + nchan_internal = ivas_sba_get_nchan_metadata( sba_analysis_order, ivas_total_brate ); + + nchan_out_buff = max( nchan_internal, st_ivas->hDecoderConfig->nchan_out ); +#else int16_t nchan_internal; nchan_internal = ivas_sba_get_nchan_metadata( sba_analysis_order, ivas_total_brate ); nchan_out_buff = st_ivas->hDecoderConfig->nchan_out; @@ -311,9 +330,18 @@ int16_t ivas_get_nchan_buffers_dec( nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); } nchan_out_buff = max( nchan_out_buff, nchan_internal ); +#endif } else if ( st_ivas->ivas_format == MASA_FORMAT ) { +#ifdef FIX_NCHAN_BUFFERS + nchan_out_buff = max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); + + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) + { + nchan_out_buff = 2 * BINAURAL_CHANNELS; + } +#else nchan_out_buff = CPE_CHANNELS; if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) @@ -334,9 +362,13 @@ int16_t ivas_get_nchan_buffers_dec( { nchan_out_buff = st_ivas->nchan_ism + CPE_CHANNELS; } +#endif } else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) { +#ifdef FIX_NCHAN_BUFFERS + nchan_out_buff = max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport + st_ivas->nchan_ism ); +#else nchan_out_buff = st_ivas->nchan_ism + CPE_CHANNELS; if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) @@ -352,9 +384,32 @@ int16_t ivas_get_nchan_buffers_dec( nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); } +#endif } else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { +#ifdef FIX_NCHAN_BUFFERS + int16_t nchan_internal; + + nchan_internal = ivas_sba_get_nchan_metadata( sba_analysis_order, ivas_total_brate ); + + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + nchan_internal += st_ivas->nchan_ism; + } + + if ( st_ivas->hMCT != NULL ) + { + nchan_internal = ( ( nchan_internal + 1 ) >> 1 ) << 1; /* ensure odd number of channels in MCT */ + } + + nchan_out_buff = max( nchan_internal, st_ivas->hDecoderConfig->nchan_out ); + + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) + { + nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); + } +#else int16_t nchan_internal; nchan_internal = ivas_sba_get_nchan_metadata( sba_analysis_order, ivas_total_brate ); nchan_out_buff = st_ivas->nchan_ism + st_ivas->nchan_transport; @@ -392,9 +447,27 @@ int16_t ivas_get_nchan_buffers_dec( nchan_out_buff = max( nchan_out_buff, nchan_internal + st_ivas->nchan_ism ); } nchan_out_buff = min( nchan_out_buff, MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ); +#endif } else if ( st_ivas->ivas_format == MC_FORMAT ) { +#ifdef FIX_NCHAN_BUFFERS + nchan_out_buff = max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); + + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + nchan_out_buff = max( nchan_out_buff, st_ivas->nchan_transport + 1 ); + } + + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) + { + nchan_out_buff = 2 * BINAURAL_CHANNELS; + } + else + { + nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); + } +#else nchan_out_buff = st_ivas->hDecoderConfig->nchan_out; if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) @@ -406,6 +479,7 @@ int16_t ivas_get_nchan_buffers_dec( nchan_out_buff = max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) ); nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); } +#endif } if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) @@ -435,8 +509,16 @@ ivas_error ivas_output_buff_dec( { for ( ch = nchan_out_buff_old; ch < nchan_out_buff; ch++ ) { +#ifdef FIX_NCHAN_BUFFERS +#ifdef DEBUGGING + if ( p_output_f[ch] != NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Memory for floating-point output audio buffer is already allocated!\n" ) ); + } +#endif +#endif /* note: these are intra-frame heap memories */ - if ( ( p_output_f[ch] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) /* note: 32000 == max internal sampling rate */ + if ( ( p_output_f[ch] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); } -- GitLab From d817b428cd68b85254ff06b115d0ae0c221780e8 Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 5 May 2025 16:47:29 +0200 Subject: [PATCH 2/6] fix non-JBM BR switching crash --- lib_dec/ivas_jbm_dec.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 596a9edd74..6a02f16c8d 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -2395,7 +2395,10 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( #ifdef FIX_NCHAN_BUFFERS /* 2 channels of the TC buffer for smooth transition in bitrate swithing within 1 CPE and TD decorr. on and off */ num_tc_buffer_mem = min( hTcBuffer->nchan_buffer_full, CPE_CHANNELS ); - mvr2r( hTcBuffer->tc_buffer, tc_buffer_mem, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); + if ( st_ivas->hDecoderConfig->Opt_tsm ) + { + mvr2r( hTcBuffer->tc_buffer, tc_buffer_mem, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); + } #endif /* if granularity changes, adapt subframe_nb_slots */ @@ -2503,7 +2506,10 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( } #ifdef FIX_NCHAN_BUFFERS - mvr2r( tc_buffer_mem, hTcBuffer->tc_buffer, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); + if ( st_ivas->hDecoderConfig->Opt_tsm ) + { + mvr2r( tc_buffer_mem, hTcBuffer->tc_buffer, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); + } #endif return IVAS_ERR_OK; -- GitLab From 7b562139e9c49b75d49488619030d3ed4d411054 Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 5 May 2025 17:43:38 +0200 Subject: [PATCH 3/6] fix MASA non-JBM BR switching crash --- lib_dec/ivas_jbm_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 6a02f16c8d..281c42344a 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -2395,7 +2395,7 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( #ifdef FIX_NCHAN_BUFFERS /* 2 channels of the TC buffer for smooth transition in bitrate swithing within 1 CPE and TD decorr. on and off */ num_tc_buffer_mem = min( hTcBuffer->nchan_buffer_full, CPE_CHANNELS ); - if ( st_ivas->hDecoderConfig->Opt_tsm ) + if ( st_ivas->hDecoderConfig->Opt_tsm && num_tc_buffer_mem == CPE_CHANNELS ) { mvr2r( hTcBuffer->tc_buffer, tc_buffer_mem, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); } @@ -2506,7 +2506,7 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( } #ifdef FIX_NCHAN_BUFFERS - if ( st_ivas->hDecoderConfig->Opt_tsm ) + if ( st_ivas->hDecoderConfig->Opt_tsm && num_tc_buffer_mem == CPE_CHANNELS && hTcBuffer->nchan_buffer_full == CPE_CHANNELS ) { mvr2r( tc_buffer_mem, hTcBuffer->tc_buffer, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); } -- GitLab From e0cdbf2fece164a5232cedba1fb01c82b3a5f63a Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 5 May 2025 18:28:27 +0200 Subject: [PATCH 4/6] deactivate update under FIX_NCHAN_BUFFERS --- lib_dec/ivas_jbm_dec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 281c42344a..6abc131289 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -2508,7 +2508,8 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( #ifdef FIX_NCHAN_BUFFERS if ( st_ivas->hDecoderConfig->Opt_tsm && num_tc_buffer_mem == CPE_CHANNELS && hTcBuffer->nchan_buffer_full == CPE_CHANNELS ) { - mvr2r( tc_buffer_mem, hTcBuffer->tc_buffer, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); + // Note: keep deactivated for the moment to ensure BE results for 'stv' + // mvr2r( tc_buffer_mem, hTcBuffer->tc_buffer, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); } #endif -- GitLab From 99a7a9fd488cf95db7ec03018be76262384f5dd7 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 8 May 2025 19:50:15 +0200 Subject: [PATCH 5/6] revert the MASA discontinuity fix --- lib_dec/ivas_jbm_dec.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 6abc131289..76bd1eb61f 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -2384,23 +2384,10 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( { int16_t nsamp_to_allocate, n_samp_full, n_samp_residual, offset, nchan_residual; int16_t ch_idx; -#ifdef FIX_NCHAN_BUFFERS - float tc_buffer_mem[CPE_CHANNELS * MAX_JBM_L_FRAME48k]; - int16_t num_tc_buffer_mem; -#endif DECODER_TC_BUFFER_HANDLE hTcBuffer; hTcBuffer = st_ivas->hTcBuffer; -#ifdef FIX_NCHAN_BUFFERS - /* 2 channels of the TC buffer for smooth transition in bitrate swithing within 1 CPE and TD decorr. on and off */ - num_tc_buffer_mem = min( hTcBuffer->nchan_buffer_full, CPE_CHANNELS ); - if ( st_ivas->hDecoderConfig->Opt_tsm && num_tc_buffer_mem == CPE_CHANNELS ) - { - mvr2r( hTcBuffer->tc_buffer, tc_buffer_mem, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); - } - -#endif /* if granularity changes, adapt subframe_nb_slots */ if ( n_samples_granularity != hTcBuffer->n_samples_granularity ) { @@ -2505,14 +2492,6 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( } } -#ifdef FIX_NCHAN_BUFFERS - if ( st_ivas->hDecoderConfig->Opt_tsm && num_tc_buffer_mem == CPE_CHANNELS && hTcBuffer->nchan_buffer_full == CPE_CHANNELS ) - { - // Note: keep deactivated for the moment to ensure BE results for 'stv' - // mvr2r( tc_buffer_mem, hTcBuffer->tc_buffer, num_tc_buffer_mem * NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); - } - -#endif return IVAS_ERR_OK; } -- GitLab From c33eac652d289426e3b83c1b3ab9b4ad6de10054 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 21 May 2025 11:36:55 +0200 Subject: [PATCH 6/6] separate renderers' buffer sizes fixes under FIX_RENDERER_STACK --- lib_com/options.h | 2 +- lib_dec/ivas_dirac_dec.c | 8 ++++---- lib_rend/ivas_crend.c | 12 ++++++------ lib_rend/ivas_dirac_dec_binaural_functions.c | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 6e8e3ef693..79d397dc52 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -162,7 +162,7 @@ #define TMP_FIX_1119_SPLIT_RENDERING_VOIP /* FhG: Add error check for unsupported config: split rendering with VoIP mode */ #define UNIFIED_DECODING_PATHS_LEFTOVERS /* VA: issue 880: remove leftovers after NONBE_UNIFIED_DECODING_PATHS */ #define FIX_NCHAN_BUFFERS /* VA: issue 1322: Correct the number of float buffers (channels) at the decoder */ - +#define FIX_RENDERER_STACK /* VA: issue 1322: reduction of renderers' buffers size */ /* #################### End BE switches ################################## */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index ade39c535b..d7ee741ca9 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1554,7 +1554,7 @@ void ivas_dirac_dec_render( uint16_t slot_size, n_samples_sf, ch, nchan_intern; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; -#ifdef FIX_NCHAN_BUFFERS +#ifdef FIX_RENDERER_STACK float *p_output_f[MAX_OUTPUT_CHANNELS]; float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; #else @@ -1570,7 +1570,7 @@ void ivas_dirac_dec_render( for ( ch = 0; ch < nchan_intern; ch++ ) { output_f_local[ch] = output_f_local_buff[ch]; -#ifdef FIX_NCHAN_BUFFERS +#ifdef FIX_RENDERER_STACK p_output_f[ch] = output_f[ch]; #else set_zero( output_f_local_buff[ch], nSamplesAsked ); @@ -1601,7 +1601,7 @@ void ivas_dirac_dec_render( for ( ch = 0; ch < nchan_intern; ch++ ) { -#ifdef FIX_NCHAN_BUFFERS +#ifdef FIX_RENDERER_STACK /* move to output */ if ( !( ( st_ivas->hDirACRend->hOutSetup.separateChannelEnabled ) && ( st_ivas->hDirACRend->hOutSetup.separateChannelIndex == ch || st_ivas->hDirACRend->hOutSetup.separateChannelIndex + 1 == ch ) ) ) { @@ -1618,7 +1618,7 @@ void ivas_dirac_dec_render( ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } -#ifndef FIX_NCHAN_BUFFERS +#ifndef FIX_RENDERER_STACK for ( ch = 0; ch < nchan_intern; ch++ ) { if ( !( ( st_ivas->hDirACRend->hOutSetup.separateChannelEnabled ) && ( st_ivas->hDirACRend->hOutSetup.separateChannelIndex == ch || st_ivas->hDirACRend->hOutSetup.separateChannelIndex + 1 == ch ) ) ) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index b0c9631bdc..6872f4d945 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1501,7 +1501,7 @@ static ivas_error ivas_rend_crendConvolver( const float *pFreq_filt_re, *pFreq_filt_im; float *pFreq_buf_re = NULL, *pFreq_buf_im = NULL; float *pFreq_buf2_re = NULL, *pFreq_buf2_im = NULL; -#ifdef FIX_NCHAN_BUFFERS +#ifdef FIX_RENDERER_STACK float pOut[2 /*Re,Im*/ * L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; float tmp_out_re[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES], tmp_out_im[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; #else @@ -1713,7 +1713,7 @@ ivas_error ivas_rend_crendProcessSubframe( int16_t subframe_idx, subframe_len; int16_t nchan_out, nchan_in, ch, first_sf, last_sf, slot_size, slots_to_render; float *tc_local[MAX_OUTPUT_CHANNELS]; -#ifdef FIX_NCHAN_BUFFERS +#ifdef FIX_RENDERER_STACK float *p_output[BINAURAL_CHANNELS]; float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; #else @@ -1757,7 +1757,7 @@ ivas_error ivas_rend_crendProcessSubframe( for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { p_pcm_tmp[ch] = pcm_tmp[ch]; -#ifdef FIX_NCHAN_BUFFERS +#ifdef FIX_RENDERER_STACK p_output[ch] = output[ch]; #endif } @@ -1840,7 +1840,7 @@ ivas_error ivas_rend_crendProcessSubframe( { tc_local[ch] += subframe_len; } -#ifndef FIX_NCHAN_BUFFERS +#ifndef FIX_RENDERER_STACK for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { p_pcm_tmp[ch] += subframe_len; @@ -1857,7 +1857,7 @@ ivas_error ivas_rend_crendProcessSubframe( return IVAS_ERR_INVALID_INPUT_FORMAT; } -#ifdef FIX_NCHAN_BUFFERS +#ifdef FIX_RENDERER_STACK for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { /* move to output */ @@ -1871,7 +1871,7 @@ ivas_error ivas_rend_crendProcessSubframe( ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_len ); } -#ifndef FIX_NCHAN_BUFFERS +#ifndef FIX_RENDERER_STACK /* move to output */ for ( ch = 0; ch < nchan_out; ch++ ) { diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 8aa7b94d58..6e25b6888d 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -456,7 +456,7 @@ void ivas_dirac_dec_binaural_render( uint16_t nchan_out; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; -#ifndef FIX_NCHAN_BUFFERS +#ifndef FIX_RENDERER_STACK float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; int16_t output_length; #endif @@ -468,7 +468,7 @@ void ivas_dirac_dec_binaural_render( #endif for ( ch = 0; ch < nchan_out; ch++ ) { -#ifdef FIX_NCHAN_BUFFERS +#ifdef FIX_RENDERER_STACK output_f_local[ch] = output_f[ch]; #else output_f_local[ch] = output_f_local_buff[ch]; @@ -491,7 +491,7 @@ void ivas_dirac_dec_binaural_render( #ifdef DEBUGGING assert( slots_to_render == 0 ); #endif -#ifndef FIX_NCHAN_BUFFERS +#ifndef FIX_RENDERER_STACK output_length = 0; #endif for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) @@ -504,7 +504,7 @@ void ivas_dirac_dec_binaural_render( output_f_local[ch] += n_samples_sf; } -#ifndef FIX_NCHAN_BUFFERS +#ifndef FIX_RENDERER_STACK output_length += n_samples_sf; #endif @@ -512,7 +512,7 @@ void ivas_dirac_dec_binaural_render( ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } -#ifndef FIX_NCHAN_BUFFERS +#ifndef FIX_RENDERER_STACK for ( ch = 0; ch < nchan_out; ch++ ) { mvr2r( output_f_local_buff[ch], output_f[ch], output_length ); -- GitLab