From 297028fc8274f22c19a68d5ffd90479432e7e06f Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 13 Nov 2025 08:52:59 +0100 Subject: [PATCH 1/3] Fix crashes from issue #2232. Look at CLDFB states additionally to the input for dynamic scale. Similar to MR !2555 , issues #2217 and #2219 --- lib_com/options.h | 2 ++ lib_isar/isar_splitRendererPost.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 6a092898a..61127a55d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -109,6 +109,8 @@ #define NONBE_FIX_2206_SATURATE_ALTERNATIVE #define FIX_2226_ISAR_PRE_CRASH_CLDFB_NO_CHANNELS /* Dolby: Fix crash of ISAR pre-renderer due to an attempt of re-scaling uninitialized values in the CLDFB filter bank */ +#define NONBE_FIX_ISSUE_2232_CHECK_CLDFB_STATES /* FhG: Adjust scaleFactor according to st->cldfbSyn->cldfb_state_fx too to avoid overflow in cldfbSynthesis_ivas_fx() */ + /* ################### End FIXES switches ########################### */ /* #################### Start BASOP porting switches ############################ */ diff --git a/lib_isar/isar_splitRendererPost.c b/lib_isar/isar_splitRendererPost.c index 1d734bed0..0bfd5fc25 100644 --- a/lib_isar/isar_splitRendererPost.c +++ b/lib_isar/isar_splitRendererPost.c @@ -1819,6 +1819,9 @@ static void isar_rend_CldfbSplitPostRendProcessTdIn( RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx]; ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx]; scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); +#ifdef NONBE_FIX_ISSUE_2232_CHECK_CLDFB_STATES + scaleFactor = s_min( scaleFactor, getScaleFactor32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length ) ); +#endif } scaleFactor = s_min( sub( scaleFactor, 6 ), Q24 ); // guarded bits FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) -- GitLab From 77a30532025bd6520e354f89a5808e455da198dc Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 13 Nov 2025 11:44:45 +0100 Subject: [PATCH 2/3] Use L_norm_arr instead of getScaleFactor32 for CLDFB dynamic scale to avoid low precision for first frame. Apply same headroom search to CLDFB states to second occurance to the problem being fixed in previous changes. --- lib_isar/isar_splitRendererPost.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib_isar/isar_splitRendererPost.c b/lib_isar/isar_splitRendererPost.c index 0bfd5fc25..9ff9761f9 100644 --- a/lib_isar/isar_splitRendererPost.c +++ b/lib_isar/isar_splitRendererPost.c @@ -1818,9 +1818,11 @@ static void isar_rend_CldfbSplitPostRendProcessTdIn( { RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx]; ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx]; - scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); #ifdef NONBE_FIX_ISSUE_2232_CHECK_CLDFB_STATES - scaleFactor = s_min( scaleFactor, getScaleFactor32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length ) ); + scaleFactor = s_min( scaleFactor, s_min( L_norm_arr( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), L_norm_arr( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); + scaleFactor = s_min( scaleFactor, L_norm_arr( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_length ) ); +#else + scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); #endif } scaleFactor = s_min( sub( scaleFactor, 6 ), Q24 ); // guarded bits @@ -1883,7 +1885,12 @@ void isar_rend_CldfbSplitPostRendProcess( { RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx]; ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx]; +#ifdef NONBE_FIX_ISSUE_2232_CHECK_CLDFB_STATES + scaleFactor = s_min( scaleFactor, s_min( L_norm_arr( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), L_norm_arr( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); + scaleFactor = s_min( scaleFactor, L_norm_arr( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_length ) ); +#else scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); +#endif } scaleFactor = s_min( sub( scaleFactor, 6 ), Q24 ); // guarded bits -- GitLab From 835b7cec147d6f72b9ee870ba59f4ed6e618ed51 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 13 Nov 2025 13:44:24 +0100 Subject: [PATCH 3/3] Use num_cldfb_bands instead of CLDFB_NO_CHANNELS_MAX for searching headroom and rescaling as suggested by @malenovskyvl --- lib_isar/isar_splitRendererPost.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib_isar/isar_splitRendererPost.c b/lib_isar/isar_splitRendererPost.c index 9ff9761f9..272dc45c8 100644 --- a/lib_isar/isar_splitRendererPost.c +++ b/lib_isar/isar_splitRendererPost.c @@ -1819,7 +1819,7 @@ static void isar_rend_CldfbSplitPostRendProcessTdIn( RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx]; ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx]; #ifdef NONBE_FIX_ISSUE_2232_CHECK_CLDFB_STATES - scaleFactor = s_min( scaleFactor, s_min( L_norm_arr( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), L_norm_arr( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); + scaleFactor = s_min( scaleFactor, s_min( L_norm_arr( RealBuffer_fx[slot_idx], num_cldfb_bands ), L_norm_arr( ImagBuffer_fx[slot_idx], num_cldfb_bands ) ) ); scaleFactor = s_min( scaleFactor, L_norm_arr( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_length ) ); #else scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); @@ -1828,8 +1828,13 @@ static void isar_rend_CldfbSplitPostRendProcessTdIn( scaleFactor = s_min( sub( scaleFactor, 6 ), Q24 ); // guarded bits FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { +#ifdef NONBE_FIX_ISSUE_2232_CHECK_CLDFB_STATES + Scale_sig32( RealBuffer_fx[slot_idx], num_cldfb_bands, scaleFactor ); + Scale_sig32( ImagBuffer_fx[slot_idx], num_cldfb_bands, scaleFactor ); +#else Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); +#endif } Q_cldfb = add( scaleFactor, Q_in ); Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) ); @@ -1886,7 +1891,7 @@ void isar_rend_CldfbSplitPostRendProcess( RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx]; ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx]; #ifdef NONBE_FIX_ISSUE_2232_CHECK_CLDFB_STATES - scaleFactor = s_min( scaleFactor, s_min( L_norm_arr( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), L_norm_arr( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); + scaleFactor = s_min( scaleFactor, s_min( L_norm_arr( RealBuffer_fx[slot_idx], num_cldfb_bands ), L_norm_arr( ImagBuffer_fx[slot_idx], num_cldfb_bands ) ) ); scaleFactor = s_min( scaleFactor, L_norm_arr( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_length ) ); #else scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); @@ -1896,8 +1901,13 @@ void isar_rend_CldfbSplitPostRendProcess( scaleFactor = s_min( sub( scaleFactor, 6 ), Q24 ); // guarded bits FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { +#ifdef NONBE_FIX_ISSUE_2232_CHECK_CLDFB_STATES + Scale_sig32( RealBuffer_fx[slot_idx], num_cldfb_bands, scaleFactor ); + Scale_sig32( ImagBuffer_fx[slot_idx], num_cldfb_bands, scaleFactor ); +#else Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); +#endif } Q_cldfb = scaleFactor + Q_cldfb_in; Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) ); -- GitLab