From fa37f6ff730daea058bdb9f1f2284d8c877f0ce1 Mon Sep 17 00:00:00 2001 From: naghibza Date: Thu, 2 Oct 2025 15:00:20 +0200 Subject: [PATCH 1/4] correct scale values in ivas_dirac_dec_binaural_process_output_fx() --- lib_com/options.h | 2 +- .../ivas_dirac_dec_binaural_functions_fx.c | 90 ++++++++++++++++--- 2 files changed, 78 insertions(+), 14 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 3271222de..1c00188f2 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -107,7 +107,7 @@ #define FIX_1962_FORMAT_CONV_SPECTRAL_DIFF /* FhG: Improved precision of targetEnergy in ivas_ls_setup_conversion_process_mdct_fx() */ #define FIX_2003_CON_TCX_OVERFLOW /* FhG: Use a dynamic scaling factor for the synth buffer at the output of con_tcx_ivas_fx() */ #define OPT_TCXLTP_FILTER_LOOP /* FhG: optimize loop in tcx_ltp_synth_filter */ - +#define FIX_2049_DIFF_IN_DECORR_TAIL /* FhG: correct scale values in ivas_dirac_dec_binaural_process_output_fx() */ /* #################### Start BASOP porting switches ############################ */ diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index e2bb6efb0..968959d33 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -109,8 +109,11 @@ typedef struct parambin_rend_config_data *------------------------------------------------------------------------*/ static void ivas_dirac_dec_binaural_internal_fx( Decoder_Struct *st_ivas, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, Word32 *output_f[] /*Q11*/, const Word16 nchan_transport, const Word16 subframe ); - +#ifdef FIX_2049_DIFF_IN_DECORR_TAIL +static void ivas_dirac_dec_decorrelate_slot_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const Word16 num_freq_bands, const Word16 slot, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME] /*q_inp*/[CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word16 q_inp, Word32 decRe[][CLDFB_NO_CHANNELS_MAX], Word32 decIm[][CLDFB_NO_CHANNELS_MAX], Word16 *q_out ); +#else static void ivas_dirac_dec_decorrelate_slot_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const Word16 num_freq_bands, const Word16 slot, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME] /*q_inp*/[CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word16 q_inp, Word32 decRe[][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 decIm[] /*q_inp*/[CLDFB_NO_CHANNELS_MAX] ); +#endif static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 subframe, Word32 *subFrameTotalEne, Word16 *subFrameTotalEne_e, Word32 *IIReneLimiter, Word16 q ); @@ -1261,8 +1264,15 @@ static void ivas_dirac_dec_decorrelate_slot_fx( Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ Word16 q_inp, +#ifdef FIX_2049_DIFF_IN_DECORR_TAIL + Word32 decRe[][CLDFB_NO_CHANNELS_MAX], + Word32 decIm[][CLDFB_NO_CHANNELS_MAX], + Word16 *q_out +#else Word32 decRe[][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ - Word32 decIm[][CLDFB_NO_CHANNELS_MAX] /*q_inp*/ ) + Word32 decIm[][CLDFB_NO_CHANNELS_MAX] /*q_inp*/ +#endif +) { Word16 offset, ch, bin; Word32 onset_filter_fx[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */ @@ -1314,7 +1324,11 @@ static void ivas_dirac_dec_decorrelate_slot_fx( move32(); } } +#ifdef FIX_2049_DIFF_IN_DECORR_TAIL + *q_out = q_decorrelatedFrameInterleaved; +#else // q_decorrelatedFrameInterleaved will be same as q_inp/q_protoFrame // +#endif return; } @@ -2734,8 +2748,11 @@ static void ivas_dirac_dec_binaural_process_output_fx( move16(); move16(); move16(); - +#ifdef FIX_2049_DIFF_IN_DECORR_TAIL + Word32 decSlotRe_fx[CLDFB_SLOTS_PER_SUBFRAME][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX], decSlotIm_fx[CLDFB_SLOTS_PER_SUBFRAME][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; +#else Word32 decSlotRe_fx[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX], decSlotIm_fx[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; +#endif Word32 outSlotRe_fx[CLDFB_NO_CHANNELS_MAX], outSlotIm_fx[CLDFB_NO_CHANNELS_MAX]; Word16 q_inp[6][CLDFB_SLOTS_PER_SUBFRAME]; Word16 interpVal_fx; @@ -2745,7 +2762,11 @@ static void ivas_dirac_dec_binaural_process_output_fx( move16(); Word16 ch_len = s_max( 4, numInChannels ); Word16 eff_q; - +#ifdef FIX_2049_DIFF_IN_DECORR_TAIL + Word16 q_decSlot[CLDFB_SLOTS_PER_SUBFRAME]; + Word16 q_decSlotMin = 31; + move16(); +#endif IF( processReverb ) { @@ -2792,7 +2813,38 @@ static void ivas_dirac_dec_binaural_process_output_fx( move16(); } +#ifdef FIX_2049_DIFF_IN_DECORR_TAIL + IF( !hDiracDecBin->useTdDecorr && ( max_band_decorr > 0 ) ) + { + FOR( slot = 0; slot < nSlots; slot++ ) + { + ivas_dirac_dec_decorrelate_slot_fx( hDiracDecBin, nBins, slot, inRe_fx, inIm_fx, q_input, decSlotRe_fx[slot], decSlotIm_fx[slot], &q_decSlot[slot] ); + q_decSlotMin = s_min( q_decSlotMin, q_decSlot[slot] ); + } + + Word16 q_tmp = add( q_input, sub( add( q_inp_mix, q_mat ), hDiracDecBin->q_processMtxPrev ) ); + Word16 q_shift = sub( q_decSlotMin, q_tmp ); + IF( GT_32( q_decSlotMin, q_tmp ) ) + { + q_decSlotMin = sub( q_decSlotMin, q_shift ); + } + ELSE + { + q_inp_mix = add( q_inp_mix, q_shift ); + cldfb_state_shift = add( cldfb_state_shift, q_shift ); + } + + FOR( Word16 ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + FOR( slot = 0; slot < nSlots; slot++ ) + { + scale_sig32( decSlotRe_fx[slot][ch], nBins, sub( q_decSlotMin, q_decSlot[slot] ) ); + scale_sig32( decSlotIm_fx[slot][ch], nBins, sub( q_decSlotMin, q_decSlot[slot] ) ); + } + } + } +#endif eff_q = sub( add( q_inp_mix, q_mat ), 15 ); FOR( Word16 i = 0; i < ch_len; i++ ) @@ -2853,19 +2905,31 @@ static void ivas_dirac_dec_binaural_process_output_fx( { if ( recompute == 1 ) { +#ifndef FIX_2049_DIFF_IN_DECORR_TAIL ivas_dirac_dec_decorrelate_slot_fx( hDiracDecBin, nBins, slot, inRe_fx, inIm_fx, q_inp_mix, decSlotRe_fx, decSlotIm_fx ); +#endif FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { +#ifdef FIX_2049_DIFF_IN_DECORR_TAIL + Copy32( decSlotRe_fx[slot][chA], decorrRe_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); + Copy32( decSlotIm_fx[slot][chA], decorrIm_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); +#else Copy32( decSlotRe_fx[chA], decorrRe_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); Copy32( decSlotIm_fx[chA], decorrIm_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); +#endif } } else { FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { +#ifdef FIX_2049_DIFF_IN_DECORR_TAIL + Copy32( decorrRe_fx[chA][slot], decSlotRe_fx[slot][chA], CLDFB_NO_CHANNELS_MAX ); + Copy32( decorrIm_fx[chA][slot], decSlotIm_fx[slot][chA], CLDFB_NO_CHANNELS_MAX ); +#else Copy32( decorrRe_fx[chA][slot], decSlotRe_fx[chA], CLDFB_NO_CHANNELS_MAX ); Copy32( decorrIm_fx[chA][slot], decSlotIm_fx[chA], CLDFB_NO_CHANNELS_MAX ); +#endif } } } @@ -2893,8 +2957,13 @@ static void ivas_dirac_dec_binaural_process_output_fx( } ELSE { +#ifdef FIX_2049_DIFF_IN_DECORR_TAIL + decSlotRePointer_fx = decSlotRe_fx[slot][chB]; + decSlotImPointer_fx = decSlotIm_fx[slot][chB]; +#else decSlotRePointer_fx = decSlotRe_fx[chB]; decSlotImPointer_fx = decSlotIm_fx[chB]; +#endif } } ELSE @@ -2903,24 +2972,20 @@ static void ivas_dirac_dec_binaural_process_output_fx( decSlotImPointer_fx = NULL; } - FOR( bin = 0; bin < nBins; bin++ ) { Word16 gain; /* Mixing using the formulated processing matrix M */ gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxRe_fx[chA][chB][bin] ) ); // Q11 - - outSlotRe_fx[bin] = Madd_32_16( outSlotRe_fx[bin], inRe_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result - outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], inIm_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result + outSlotRe_fx[bin] = Madd_32_16( outSlotRe_fx[bin], inRe_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result + outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], inIm_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result move32(); move32(); gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxImPrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxIm_fx[chA][chB][bin] ) ); // Q11 - // interpVal * hDiracDecBin->processMtxIm[chA][chB][bin]; outSlotRe_fx[bin] = Msub_32_16( outSlotRe_fx[bin], inIm_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], inRe_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result - move32(); move32(); @@ -2935,7 +3000,6 @@ static void ivas_dirac_dec_binaural_process_output_fx( move32(); move32(); - gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] ) ); // Q11 outSlotRe_fx[bin] = Msub_32_16( outSlotRe_fx[bin], decSlotImPointer_fx[bin], gain ); // q_inp_mix-4//q_result outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], decSlotRePointer_fx[bin], gain ); // q_inp_mix-4//q_result @@ -2945,7 +3009,6 @@ static void ivas_dirac_dec_binaural_process_output_fx( } } - IF( processReverb ) { /* Combine second (reverb) part with the first (HRTF) part to obtain binaural output signal with room effect */ @@ -2953,7 +3016,6 @@ static void ivas_dirac_dec_binaural_process_output_fx( v_add_fx( outSlotIm_fx, reverbIm_fx[chA][slot], outSlotIm_fx, CLDFB_NO_CHANNELS_MAX ); } - outSlotRePr_fx = &( outSlotRe_fx[0] ); outSlotImPr_fx = &( outSlotIm_fx[0] ); @@ -2962,6 +3024,7 @@ static void ivas_dirac_dec_binaural_process_output_fx( /* provide the data outside in CLDFB domain => mainly for split rendering */ Copy32( outSlotRePr_fx, outRe_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); Copy32( outSlotImPr_fx, outIm_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); + Scale_sig32( outRe_fx[chA][slot], CLDFB_NO_CHANNELS_MAX, sub( Q6, q_result ) ); // Q6 Scale_sig32( outIm_fx[chA][slot], CLDFB_NO_CHANNELS_MAX, sub( Q6, q_result ) ); // Q6 } @@ -2974,6 +3037,7 @@ static void ivas_dirac_dec_binaural_process_output_fx( } } } + if ( recompute == 1 ) { *q_out = sub( q_result, 1 ); -- GitLab From 5bf77d20fd62309d3faae6a6cbfb5a7afb4c6296 Mon Sep 17 00:00:00 2001 From: naghibza Date: Thu, 2 Oct 2025 16:09:27 +0200 Subject: [PATCH 2/4] improve decSlot[] precision. --- .../ivas_dirac_dec_binaural_functions_fx.c | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 968959d33..8f063a897 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -2819,6 +2819,17 @@ static void ivas_dirac_dec_binaural_process_output_fx( FOR( slot = 0; slot < nSlots; slot++ ) { ivas_dirac_dec_decorrelate_slot_fx( hDiracDecBin, nBins, slot, inRe_fx, inIm_fx, q_input, decSlotRe_fx[slot], decSlotIm_fx[slot], &q_decSlot[slot] ); + + Word16 scf = s_min( getScaleFactor32( decSlotRe_fx[slot][0], nBins ), getScaleFactor32( decSlotRe_fx[slot][1], nBins ) ); + scf = s_min( scf, getScaleFactor32( decSlotIm_fx[slot][0], nBins ) ); + scf = s_min( scf, getScaleFactor32( decSlotIm_fx[slot][1], nBins ) ); + + scale_sig32( decSlotRe_fx[slot][0], nBins, scf ); + scale_sig32( decSlotRe_fx[slot][1], nBins, scf ); + scale_sig32( decSlotIm_fx[slot][0], nBins, scf ); + scale_sig32( decSlotIm_fx[slot][1], nBins, scf ); + q_decSlot[slot] += scf; + q_decSlotMin = s_min( q_decSlotMin, q_decSlot[slot] ); } @@ -2848,11 +2859,9 @@ static void ivas_dirac_dec_binaural_process_output_fx( eff_q = sub( add( q_inp_mix, q_mat ), 15 ); FOR( Word16 i = 0; i < ch_len; i++ ) - { FOR( Word16 j = 0; j < nSlots; j++ ) { - scale_sig32( inRe_fx[i][j], nBins, q_inp_mix ); /*q_input + q_inp_mix*/ scale_sig32( inIm_fx[i][j], nBins, q_inp_mix ); /*q_input + q_inp_mix*/ test(); @@ -2977,8 +2986,9 @@ static void ivas_dirac_dec_binaural_process_output_fx( Word16 gain; /* Mixing using the formulated processing matrix M */ gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxRe_fx[chA][chB][bin] ) ); // Q11 - outSlotRe_fx[bin] = Madd_32_16( outSlotRe_fx[bin], inRe_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result - outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], inIm_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result + + outSlotRe_fx[bin] = Madd_32_16( outSlotRe_fx[bin], inRe_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result + outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], inIm_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result move32(); move32(); @@ -2995,14 +3005,16 @@ static void ivas_dirac_dec_binaural_process_output_fx( { gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] ) ); // Q11 // interpVal * hDiracDecBin->processMtxDecRe[chA][chB][bin]; + outSlotRe_fx[bin] = Madd_32_16( outSlotRe_fx[bin], decSlotRePointer_fx[bin], gain ); // q_inp_mix-4//q_result outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], decSlotImPointer_fx[bin], gain ); // q_inp_mix-4//q_result move32(); move32(); gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] ) ); // Q11 - outSlotRe_fx[bin] = Msub_32_16( outSlotRe_fx[bin], decSlotImPointer_fx[bin], gain ); // q_inp_mix-4//q_result - outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], decSlotRePointer_fx[bin], gain ); // q_inp_mix-4//q_result + + outSlotRe_fx[bin] = Msub_32_16( outSlotRe_fx[bin], decSlotImPointer_fx[bin], gain ); // q_inp_mix-4//q_result + outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], decSlotRePointer_fx[bin], gain ); // q_inp_mix-4//q_result move32(); move32(); } @@ -3024,7 +3036,6 @@ static void ivas_dirac_dec_binaural_process_output_fx( /* provide the data outside in CLDFB domain => mainly for split rendering */ Copy32( outSlotRePr_fx, outRe_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); Copy32( outSlotImPr_fx, outIm_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); - Scale_sig32( outRe_fx[chA][slot], CLDFB_NO_CHANNELS_MAX, sub( Q6, q_result ) ); // Q6 Scale_sig32( outIm_fx[chA][slot], CLDFB_NO_CHANNELS_MAX, sub( Q6, q_result ) ); // Q6 } -- GitLab From 1410ed2c7d5bc1857e67c700c5a7d1b58b8f0034 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 3 Oct 2025 22:34:48 +0200 Subject: [PATCH 3/4] empty commit to push -- GitLab From 7dbf16159c6001b4e8ebd4c6940c4d521bb9697b Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 3 Oct 2025 23:19:39 +0200 Subject: [PATCH 4/4] empty commit -- GitLab