From 534b184c9d6a9e52f39e7c751870c2f3a5244a33 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 6 Nov 2024 18:31:02 +0530 Subject: [PATCH] Fix for 3GPP issue 964: ParamISM: High MLD for ParamISM, 32 kbps, high frequency content missing --- lib_rend/ivas_dirac_dec_binaural_functions.c | 177 +++++++------------ 1 file changed, 65 insertions(+), 112 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index e0d8fa302..6ff9685bf 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -1231,8 +1231,7 @@ static void ivas_dirac_dec_binaural_internal_fx( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ); move16(); } - Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME] = { 0 }; - move16(); + Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME]; FOR( Word16 ind = 0; ind < 6; ind++ ) { FOR( Word16 ind2 = 0; ind2 < 4; ind2++ ) @@ -1533,36 +1532,9 @@ static void ivas_dirac_dec_binaural_internal_fx( } } - Word16 shift = 31; - move16(); - Word32 Cldfb_RealBuffer_inTmp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Cldfb_ImagBuffer_inTmp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - FOR( i = 0; i < 2; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - shift = s_min( shift, getScaleFactor32( Cldfb_RealBuffer_in_fx[i][j], CLDFB_NO_CHANNELS_MAX ) ); - shift = s_min( shift, getScaleFactor32( Cldfb_ImagBuffer_in_fx[i][j], CLDFB_NO_CHANNELS_MAX ) ); - } - } - - Word16 q = add( q_inp, shift ); - - FOR( i = 0; i < 2; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - FOR( Word16 k = 0; k < 60; k++ ) - { - Cldfb_RealBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_RealBuffer_in_fx[i][j][k], shift ); // q - Cldfb_ImagBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_in_fx[i][j][k], shift ); // q - move32(); - move32(); - } - } - } - - ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_inTmp_fx, Cldfb_ImagBuffer_inTmp_fx, Rmat_fx, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q ); + test(); + ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) ) { @@ -2282,7 +2254,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric UWord8 applyLowBitRateEQ; Word16 dirac_read_idx; Word32 subFrameTotalEne_fx[CLDFB_NO_CHANNELS_MAX]; - Word16 q_subFrameTotalEne; + Word16 subFrameTotalEne_e[CLDFB_NO_CHANNELS_MAX]; PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_GAIN_CACHE_SIZE]; IVAS_FORMAT ivas_format; MC_MODE mc_mode; @@ -2290,6 +2262,9 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word16 nchan_transport; Word16 gainCacheBaseIndex; Word16 q_earlyPartEneCorrection; + Word16 exp, exp1; + Word64 temp64; + Word32 temp; separateCenterChannelRendering = hConfig->separateCenterChannelRendering; move16(); @@ -2334,6 +2309,8 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric set32_fx( frameMeanDiffusenessEneWeight_fx, 0, CLDFB_NO_CHANNELS_MAX ); + set16_fx( subFrameTotalEne_e, 0, CLDFB_NO_CHANNELS_MAX ); + FOR( idx = 0; idx < MAX_GAIN_CACHE_SIZE; idx++ ) { gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ @@ -2372,44 +2349,43 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe]; move16(); + exp = sub( 63, shl( q, 1 ) ); // exp for the energy (inRe_fx * inRe_fx + inIm_fx * inIm_fx) computed below + /* Calculate input covariance matrix */ FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) { FOR( bin = 0; bin < nBins; bin++ ) { - hDiracDecBin->ChCrossRe_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossRe_fx[bin], hDiracDecBin->ChCrossRe_e[bin], - L_add( L_shr( Mpy_32_32( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] ), 1 ), L_shr( Mpy_32_32( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ), 1 ) ), sub( 63, shl( q, 1 ) ), &hDiracDecBin->ChCrossRe_e[bin] ); - hDiracDecBin->ChCrossIm_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossIm_fx[bin], hDiracDecBin->ChCrossIm_e[bin], - L_sub( L_shr( Mpy_32_32( inRe_fx[0][slot][bin], inIm_fx[1][slot][bin] ), 1 ), L_shr( Mpy_32_32( inIm_fx[0][slot][bin], inRe_fx[1][slot][bin] ), 1 ) ), sub( 63, shl( q, 1 ) ), &hDiracDecBin->ChCrossIm_e[bin] ); - - inRe_fx[0][slot][bin] = L_shr( inRe_fx[0][slot][bin], 2 ); - inRe_fx[1][slot][bin] = L_shr( inRe_fx[1][slot][bin], 2 ); - inIm_fx[0][slot][bin] = L_shr( inIm_fx[0][slot][bin], 2 ); - inIm_fx[1][slot][bin] = L_shr( inIm_fx[1][slot][bin], 2 ); - - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { Word32 instEne_fx; - - instEne_fx = Mpy_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] ); // 2q - 31 - instEne_fx = L_add( instEne_fx, Mpy_32_32( inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // 2q - 31 - hDiracDecBin->ChEne_fx[ch][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[ch][bin], hDiracDecBin->ChEne_e[ch][bin], instEne_fx, sub( 66, shl( q, 1 ) ), &hDiracDecBin->ChEne_e[ch][bin] ); - subFrameTotalEne_fx[bin] = L_add( subFrameTotalEne_fx[bin], L_shr( instEne_fx, 1 ) ); // 2q - 32 + temp64 = W_mult0_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] ); // 2q + temp64 = W_add( temp64, W_mult0_32_32( inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // 2q + exp1 = W_norm( temp64 ); + instEne_fx = W_extract_h( W_shl( temp64, exp1 ) ); // 2q - 32 + exp1 + /* exp of instEne_fx = 31 - (2q -32 + exp1) = 63 - 2q - exp1 = exp - exp1*/ + + hDiracDecBin->ChEne_fx[ch][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[ch][bin], hDiracDecBin->ChEne_e[ch][bin], instEne_fx, sub( exp, exp1 ), &hDiracDecBin->ChEne_e[ch][bin] ); + subFrameTotalEne_fx[bin] = BASOP_Util_Add_Mant32Exp( subFrameTotalEne_fx[bin], subFrameTotalEne_e[bin], instEne_fx, sub( exp, exp1 ), &subFrameTotalEne_e[bin] ); move32(); move32(); } + temp64 = W_mult0_32_32( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] ); // 2q + temp64 = W_add( temp64, W_mult0_32_32( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ) ); // 2q + exp1 = W_norm( temp64 ); + temp = W_extract_h( W_shl( temp64, exp1 ) ); // // 2q - 32 + exp1 + hDiracDecBin->ChCrossRe_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossRe_fx[bin], hDiracDecBin->ChCrossRe_e[bin], temp, sub( exp, exp1 ), &hDiracDecBin->ChCrossRe_e[bin] ); + move32(); + + temp64 = W_mult0_32_32( inRe_fx[0][slot][bin], inIm_fx[1][slot][bin] ); // 2q + temp64 = W_sub( temp64, W_mult0_32_32( inIm_fx[0][slot][bin], inRe_fx[1][slot][bin] ) ); // 2q + exp1 = W_norm( temp64 ); + temp = W_extract_h( W_shl( temp64, exp1 ) ); // // 2q - 32 + exp1 + hDiracDecBin->ChCrossIm_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossIm_fx[bin], hDiracDecBin->ChCrossIm_e[bin], temp, sub( exp, exp1 ), &hDiracDecBin->ChCrossIm_e[bin] ); + move32(); } } - q = sub( q, 2 ); - q_subFrameTotalEne = sub( shl( q, 1 ), 32 ); - /* Apply EQ at low bit rates */ IF( applyLowBitRateEQ != 0 ) { @@ -2417,12 +2393,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric FOR( bin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET; bin < lastEqBin; bin++ ) { - subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[bin] ); // 2q -32 + subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[bin] ); // exp = subFrameTotalEne_e[bin] move32(); } FOR( ; bin < nBins; bin++ ) { - subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[lastEqBin] ); // 2q -32 + subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[lastEqBin] ); // exp = subFrameTotalEne_e[bin] move32(); } } @@ -2433,22 +2409,33 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric { Word32 tempRe, tempIm; Word32 subFrameSumEne_fx[CLDFB_NO_CHANNELS_MAX]; + Word16 subFrameSumEne_e[CLDFB_NO_CHANNELS_MAX]; set32_fx( subFrameSumEne_fx, 0, CLDFB_NO_CHANNELS_MAX ); + set16_fx( subFrameSumEne_e, 0, CLDFB_NO_CHANNELS_MAX ); FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) { FOR( bin = 0; bin < nBins; bin++ ) { - tempRe = L_add( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] ); // q - tempIm = L_add( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ); // q - subFrameSumEne_fx[bin] = L_add( subFrameSumEne_fx[bin], L_add( L_shr( Mpy_32_32( tempRe, tempRe ), 1 ), L_shr( Mpy_32_32( tempIm, tempIm ), 1 ) ) ); // 2q -32 + tempRe = L_add( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] ); // q + tempIm = L_add( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ); // q + temp64 = W_add( W_mult0_32_32( tempRe, tempRe ), W_mult0_32_32( tempIm, tempIm ) ); // 2q + exp1 = W_norm( temp64 ); + temp64 = W_shl( temp64, exp1 ); // 2q + exp1 + subFrameSumEne_fx[bin] = BASOP_Util_Add_Mant32Exp( subFrameSumEne_fx[bin], subFrameTotalEne_e[bin], W_extract_h( temp64 ), sub( exp /* 63 - 2q */, exp1 ) /*31 - (2q + exp1 - 32)*/, &subFrameTotalEne_e[bin] ); move32(); } } FOR( bin = 0; bin < nBins; bin++ ) { - subFrameTotalEne_fx[bin] = L_max( subFrameTotalEne_fx[bin], subFrameSumEne_fx[bin] ); // 2q -32 - move32(); + temp = L_shl_sat( subFrameTotalEne_fx[bin], sub( subFrameTotalEne_e[bin], subFrameSumEne_e[bin] ) ); // subFrameSumEne_e[bin] + IF( GT_32( subFrameSumEne_fx[bin], temp ) ) + { + subFrameTotalEne_fx[bin] = subFrameSumEne_fx[bin]; + move32(); + subFrameTotalEne_e[bin] = subFrameSumEne_e[bin]; + move16(); + } } } @@ -2475,7 +2462,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric * the early spectrum of the BRIR data, using the spectral correction data in * hBinaural->earlyPartEneCorrection[bin], based on the BRIR set. */ meanEnePerCh_fx = Mpy_32_32( hDiracDecBin->earlyPartEneCorrection_fx[bin], subFrameTotalEne_fx[bin] ); // Q( q_meanEnePerCh ) - q_meanEnePerCh = sub( add( q_earlyPartEneCorrection, q_subFrameTotalEne ), 30 ); + q_meanEnePerCh = add( sub( q_earlyPartEneCorrection, subFrameTotalEne_e[bin] ), 1 ); // q_earlyPartEneCorrection + 31 - subFrameTotalEne_e[bin] - 31 + Q1(0.5f) /* Determine direct part target covariance matrix (for 1 or 2 directions) */ FOR( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ ) { @@ -2808,7 +2795,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric test(); IF( ( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) ) && LT_16( bin, BINAURAL_COHERENCE_DIFFERENCE_BINS ) ) { - Word32 diffuseFieldCoherence_fx, temp; + Word32 diffuseFieldCoherence_fx; Word16 tmp_exp; temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioX_fx[bin], hDiracDecBin->diffuseFieldCoherenceX_fx[bin] ), 0, Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioY_fx[bin], hDiracDecBin->diffuseFieldCoherenceY_fx[bin] ), 0, &tmp_exp ); diffuseFieldCoherence_fx = BASOP_Util_Add_Mant32Exp( temp, tmp_exp, Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioZ_fx[bin], hDiracDecBin->diffuseFieldCoherenceZ_fx[bin] ), 0, &tmp_exp ); @@ -2823,21 +2810,14 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } /* Store parameters for formulating average diffuseness over frame */ - hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_add( hDiracDecBin->frameMeanDiffuseness_fx[bin], L_shl( diffEneValForDecorrelationReduction_fx, sub( q_meanEnePerCh, q_diffEneValForDecorrelationReduction ) ) ); // Q(q_meanEnePerCh) + Word32 frameMeanDiffuseness = BASOP_Util_Add_Mant32Exp( hDiracDecBin->frameMeanDiffuseness_fx[bin], 2 /*Q29*/, diffEneValForDecorrelationReduction_fx, sub( 31, q_diffEneValForDecorrelationReduction ), &exp1 ); // exp = exp1 frameMeanDiffusenessEneWeight_fx[bin] = L_add( frameMeanDiffusenessEneWeight_fx[bin], meanEnePerCh_fx ); move32(); - move32(); - } - /* Formulate average diffuseness over frame */ - Word16 e; - FOR( bin = 0; bin < nBins; bin++ ) - { - e = 0; - move16(); - hDiracDecBin->frameMeanDiffuseness_fx[bin] = BASOP_Util_Divide3232_Scale( hDiracDecBin->frameMeanDiffuseness_fx[bin], L_max( EPSILLON_FX, frameMeanDiffusenessEneWeight_fx[bin] ), &e ); - hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( hDiracDecBin->frameMeanDiffuseness_fx[bin], add( 14, e ) ); // Q29 - move32(); + /* Formulate average diffuseness over frame */ + frameMeanDiffuseness = BASOP_Util_Divide3232_Scale_cadence( frameMeanDiffuseness, L_max( EPSILLON_FX, frameMeanDiffusenessEneWeight_fx[bin] ), &exp ); // exp = exp + 31 - q_meanEnePerCh - exp1 + exp = sub( exp, sub( sub( 31, q_meanEnePerCh ), exp1 ) ); + hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 move32(); } @@ -2867,16 +2847,16 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move16(); den = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEnePrev_fx[0][bin], hDiracDecBin->ChEnePrev_e[0][bin], hDiracDecBin->ChEnePrev_fx[1][bin], hDiracDecBin->ChEnePrev_e[1][bin], &den_e ); den = L_max( 1, den ); - IIReneLimiter_fx = BASOP_Util_Divide3232_Scale_cadence( num, den, &e ); - e = add( sub( num_e, den_e ), add( 5, e ) ); - IF( L_shr_sat( IIReneLimiter_fx, sub( 31, e ) ) > 0 ) + IIReneLimiter_fx = BASOP_Util_Divide3232_Scale_cadence( num, den, &exp ); + exp = add( sub( num_e, den_e ), add( 5, exp ) ); + IF( L_shr_sat( IIReneLimiter_fx, sub( 31, exp ) ) > 0 ) { IIReneLimiter_fx = ONE_IN_Q31; /*Q31*/ move32(); } ELSE { - IIReneLimiter_fx = L_shl( IIReneLimiter_fx, e ); /*Q31*/ + IIReneLimiter_fx = L_shl( IIReneLimiter_fx, exp ); /*Q31*/ } hDiracDecBin->ChCrossRe_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossRe_fx[bin], qualityBasedSmFactor_fx ); @@ -7969,36 +7949,9 @@ static void ivas_masa_ext_rend_parambin_internal_fx( } } - Word16 shift = 31; - move16(); - Word32 Cldfb_RealBuffer_inTmp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Cldfb_ImagBuffer_inTmp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - FOR( i = 0; i < 2; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - shift = s_min( shift, getScaleFactor32( Cldfb_RealBuffer_in_fx[i][j], CLDFB_NO_CHANNELS_MAX ) ); - shift = s_min( shift, getScaleFactor32( Cldfb_ImagBuffer_in_fx[i][j], CLDFB_NO_CHANNELS_MAX ) ); - } - } - - Word16 q = add( q_inp, shift ); - - FOR( i = 0; i < 2; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - FOR( Word16 k = 0; k < 60; k++ ) - { - Cldfb_RealBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_RealBuffer_in_fx[i][j][k], shift ); // q - Cldfb_ImagBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_in_fx[i][j][k], shift ); // q - move32(); - move32(); - } - } - } - - ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_inTmp_fx, Cldfb_ImagBuffer_inTmp_fx, Rmat_fx, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, NULL, q ); + test(); + ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, NULL, q_inp ); /* Always using CLDFB decorrelation in MASA EXT renderer */ max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr; -- GitLab