From 8e2135bd0ded893d56d440b3d11a96b143d32d03 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 9 Jul 2025 06:38:32 +0530 Subject: [PATCH 1/2] Precision improvement changes for 3GPP Issues #1787 and #1788 Link #1787, #1788 --- lib_com/ivas_dirac_com_fx.c | 89 ++++++++--------------------- lib_rend/ivas_dirac_ana_fx.c | 64 +++++++++++++++++---- lib_rend/ivas_mcmasa_ana_fx.c | 104 +++++++++++++++++++++++++++------- lib_rend/ivas_omasa_ana_fx.c | 87 +++++++++++++++++++++------- lib_rend/ivas_prot_rend_fx.h | 13 +++-- 5 files changed, 235 insertions(+), 122 deletions(-) diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index befeb273c..735bbddaa 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -793,109 +793,66 @@ void computeDiffuseness_fixed( ) { Word32 intensity_slow[DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX]; + Word16 intensity_slow_e[DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX]; Word32 intensity_slow_abs[CLDFB_NO_CHANNELS_MAX]; Word64 intensity_slow_abs_64[CLDFB_NO_CHANNELS_MAX]; Word16 intensity_slow_abs_q[CLDFB_NO_CHANNELS_MAX]; Word32 energy_slow[CLDFB_NO_CHANNELS_MAX]; + Word16 energy_slow_e[CLDFB_NO_CHANNELS_MAX]; Word16 i, j, k; Word32 tmp = 0; move32(); Word32 *p_tmp; const Word32 *p_tmp_c; - Word16 min_q_shift1, min_q_shift2, exp1, exp2, q_tmp; + Word16 exp1, exp2, q_tmp; Word16 q_ene, q_intensity; /* Compute Intensity slow and energy slow buffer_intensity and buffer_energy */ - set_zero_fx( intensity_slow, i_mult( DIRAC_NUM_DIMS, CLDFB_NO_CHANNELS_MAX ) ); + set_zero_fx( intensity_slow, ( DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX ) ); + set16_fx( intensity_slow_e, 0, ( DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX ) ); set_zero_fx( intensity_slow_abs, CLDFB_NO_CHANNELS_MAX ); set_zero_fx( energy_slow, CLDFB_NO_CHANNELS_MAX ); - - /* Calculate max possible shift for the buffer buffer_energy and buffer_intensity */ - min_q_shift1 = Q31; - move16(); - min_q_shift1 = s_min( min_q_shift1, getScaleFactor32( buffer_energy, i_mult( DIRAC_NO_COL_AVG_DIFF, num_freq_bands ) ) ); - min_q_shift1 = sub( min_q_shift1, find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF ) ); - - min_q_shift2 = Q31; - move16(); - FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) - { - FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ ) - { - min_q_shift2 = s_min( min_q_shift2, getScaleFactor32( buffer_intensity[i][j], num_freq_bands ) ); - } - } - min_q_shift2 = sub( min_q_shift2, find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF ) ); - - q_ene = add( q_factor_energy[0], min_q_shift1 ); - move16(); - q_intensity = add( q_factor_intensity[0], min_q_shift2 ); - move16(); + set16_fx( energy_slow_e, 0, CLDFB_NO_CHANNELS_MAX ); FOR( i = 0; i < DIRAC_NO_COL_AVG_DIFF; ++i ) { /* Energy slow */ p_tmp_c = buffer_energy + i * num_freq_bands; - q_tmp = add( q_factor_energy[i], min_q_shift1 ); - - - Word16 shift_q = sub( q_tmp, q_ene ); - Word32 shiftEquiv = L_add( 0, 0 ); - Word16 shift_qtotal; - if ( shift_q < 0 ) - { - shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); - } - if ( shift_q >= 0 ) - { - shiftEquiv = L_add( 0x7FFFFFFF, 0 ); - } - shift_qtotal = sub( min_q_shift1, s_max( shift_q, 0 ) ); - FOR( k = 0; k < num_freq_bands; k++ ) { - tmp = L_shl( p_tmp_c[k], shift_qtotal ); - energy_slow[k] = Madd_32_32_r( tmp, energy_slow[k], shiftEquiv ); + energy_slow[k] = BASOP_Util_Add_Mant32Exp( p_tmp_c[k], sub( 31, q_factor_energy[i] ), energy_slow[k], energy_slow_e[k], &energy_slow_e[k] ); move32(); } - - q_ene = s_min( q_ene, q_tmp ); - - /* Intensity slow */ - q_tmp = add( q_factor_intensity[i], min_q_shift2 ); - - shift_q = sub( q_tmp, q_intensity ); - if ( shift_q < 0 ) - { - shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); - } - if ( shift_q >= 0 ) - { - shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); - } - shift_qtotal = sub( min_q_shift2, s_max( shift_q, 0 ) ); - FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) { p_tmp = buffer_intensity[j][i]; FOR( k = 0; k < num_freq_bands; k++ ) { - tmp = L_shl( p_tmp[k], shift_qtotal ); - intensity_slow[j * num_freq_bands + k] = Madd_32_32_r( tmp, intensity_slow[j * num_freq_bands + k], shiftEquiv ); + intensity_slow[j * num_freq_bands + k] = BASOP_Util_Add_Mant32Exp( p_tmp[k], sub( 31, q_factor_intensity[i] ), intensity_slow[j * num_freq_bands + k], intensity_slow_e[j * num_freq_bands + k], &intensity_slow_e[j * num_freq_bands + k] ); move32(); } } + } + Word16 max_e; + maximum_fx( energy_slow_e, CLDFB_NO_CHANNELS_MAX, &max_e ); + q_ene = sub( 31, max_e ); + FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { + energy_slow[i] = L_shr( energy_slow[i], sub( max_e, energy_slow_e[i] ) ); // scaling to q_ene + move32(); + } - q_intensity = s_min( q_intensity, q_tmp ); + maximum_fx( intensity_slow_e, DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX, &max_e ); + q_intensity = sub( 31, max_e ); + FOR( i = 0; i < DIRAC_NUM_DIMS * num_freq_bands; i++ ) + { + intensity_slow[i] = L_shr( intensity_slow[i], sub( max_e, intensity_slow_e[i] ) ); // scaling to q_intensity + move32(); } - min_q_shift1 = getScaleFactor32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ) ); - min_q_shift1 = sub( min_q_shift1, idiv1616( add( find_guarded_bits_fx( DIRAC_NUM_DIMS ), 1 ), 2 ) ); - scale_sig32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ), min_q_shift1 ); - q_intensity = add( q_intensity, min_q_shift1 ); FOR( k = 0; k < num_freq_bands; k++ ) { intensity_slow_abs_64[k] = 0; diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index fcea6a6eb..5f0f8a3a4 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -293,6 +293,7 @@ static void ivas_dirac_param_est_ana_fx( Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; + Word16 intensity_real_q[MASA_FREQUENCY_BANDS]; Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS]; @@ -308,6 +309,10 @@ static void ivas_dirac_param_est_ana_fx( Word16 numAnalysisChannels; Word16 inp_q; Word16 intensity_q, reference_power_q; + Word16 temp_e, sf, scaled_data_q, s, shift = 31; + move16(); + Word32 temp; + Word64 W_temp; num_freq_bands = hDirAC->nbands; /* l_ts = input_frame / CLDFB_NO_COL_MAX; */ l_ts = shr( input_frame, 4 ); @@ -320,6 +325,16 @@ static void ivas_dirac_param_est_ana_fx( move16(); move16(); move16(); + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + shift = s_min( shift, L_norm_arr( data_fx[i], input_frame ) ); + } + shift = sub( shift, find_guarded_bits_fx( l_ts ) ); + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + scale_sig32( data_fx[i], input_frame, shift ); + } + scaled_data_q = add( data_q, shift ); /* do processing over all CLDFB time slots */ FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) @@ -356,14 +371,14 @@ static void ivas_dirac_param_est_ana_fx( FOR( ts = mrange[0]; ts < mrange[1]; ts++ ) { - Word16 cr_q = MAX_16, ci_q = MAX_16, sf, c_e; - inp_q = data_q; // Input Q of data_fx + Word16 cr_q = MAX_16, ci_q = MAX_16, c_e; + inp_q = scaled_data_q; // Q of data_fx after scaling move16(); move16(); move16(); FOR( i = 0; i < numAnalysisChannels; i++ ) { - inp_q = data_q; + inp_q = scaled_data_q; move16(); cldfbAnalysis_ts_fx_var_q( &( data_fx[i][l_ts * ts] ), Foa_RealBuffer_fx[i], Foa_ImagBuffer_fx[i], l_ts, hDirAC->cldfbAnaEnc[i], &inp_q ); cr_q = s_min( cr_q, getScaleFactor32( Foa_RealBuffer_fx[i], l_ts ) ); @@ -386,19 +401,38 @@ static void ivas_dirac_param_est_ana_fx( move16(); FOR( j = brange[0]; j < brange[1]; j++ ) { - Word32 temp = L_add( Mult_32_32( Foa_RealBuffer_fx[0][j], Foa_RealBuffer_fx[0][j] ), Mult_32_32( Foa_ImagBuffer_fx[0][j], Foa_ImagBuffer_fx[0][j] ) ); // Q-> 2*inp_q - 31, e = 31 - (2*inp_q - 31) = 62 - 2*inp_q = 2*(31 - inp_q) = 2*c_e - hDirAC->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->energy_fx[block_m_idx][band_m_idx], hDirAC->energy_e[block_m_idx][band_m_idx], temp, shl( c_e, 1 ), &hDirAC->energy_e[block_m_idx][band_m_idx] ); + W_temp = W_mac_32_32( W_mult_32_32( Foa_RealBuffer_fx[0][j], Foa_RealBuffer_fx[0][j] ), Foa_ImagBuffer_fx[0][j], Foa_ImagBuffer_fx[0][j] ); // Q-> 2*inp_q + 1 + sf = W_norm( W_temp ); + temp = W_extract_h( W_shl( W_temp, sf ) ); // 2*inp_q + 1 + sf - 32 + temp_e = sub( 63 - 1, add( shl( inp_q, 1 ), sf ) ); // 31 - ( 2 * inp_q + 1 + sf - 32 ) + hDirAC->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->energy_fx[block_m_idx][band_m_idx], hDirAC->energy_e[block_m_idx][band_m_idx], temp, temp_e, &hDirAC->energy_e[block_m_idx][band_m_idx] ); move32(); } } /* Direction estimation */ - computeIntensityVector_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */ - intensity_q = sub( 31, shl( c_e, 1 ) ); + computeIntensityVector_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, intensity_real_q, inp_q ); + + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], 0, intensity_real_q ); - computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ), NULL ); /* Power estimation for diffuseness */ - computeReferencePower_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); //( 2 * ( scale_fact - Q1 ) - 31 - 1 ); // computeReferencePower_ana( hDirAC->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power[ts], num_freq_bands ); + computeReferencePower_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); //( 2 * ( scale_fact - Q1 ) - 31 - 1 ); reference_power_q = sub( shl( inp_q, 1 ), 30 ); + + /* Aligning intensity_real to a common Q-factor */ + minimum_fx( intensity_real_q, num_freq_bands, &intensity_q ); + + Word16 tmp; + FOR( i = 0; i < num_freq_bands; i++ ) + { + tmp = sub( intensity_q, intensity_real_q[i] ); + intensity_real_fx[0][i] = L_shl( intensity_real_fx[0][i], tmp ); + move32(); + intensity_real_fx[1][i] = L_shl( intensity_real_fx[1][i], tmp ); + move32(); + intensity_real_fx[2][i] = L_shl( intensity_real_fx[2][i], tmp ); + move32(); + } + /* Fill buffers of length "averaging_length" time slots for intensity and energy */ hDirAC->index_buffer_intensity = add( ( hDirAC->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */ move16(); @@ -426,7 +460,13 @@ static void ivas_dirac_param_est_ana_fx( move32(); hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], hDirAC->direction_vector_e[2][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), shl( c_e, 1 ), &hDirAC->direction_vector_e[2][block_m_idx][band_m_idx] ); move32(); - diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[band_m_idx], diffuseness_e[band_m_idx], L_shl( Mult_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), 1 ), sub( shl( c_e, 1 ), 1 ), &diffuseness_e[band_m_idx] ); + + W_temp = W_mult0_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ); + s = W_norm( W_temp ); + temp = W_extract_h( W_shl( W_temp, s ) ); + temp_e = sub( 63, add( add( reference_power_q, diffuseness_q ), s ) ); // 31 - ( reference_power_q + diffuseness_q + s - 32 ) + + diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[band_m_idx], diffuseness_e[band_m_idx], temp, temp_e, &diffuseness_e[band_m_idx] ); move32(); renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], reference_power_fx[ts][band_m_idx], sub( shl( c_e, 1 ), 1 ), &renormalization_factor_diff_e[band_m_idx] ); @@ -479,6 +519,10 @@ static void ivas_dirac_param_est_ana_fx( } } + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + scale_sig32( data_fx[i], input_frame, negate( shift ) ); + } return; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index 99af8a0af..489dd72bf 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -529,7 +529,10 @@ void ivas_mcmasa_param_est_ana_fx( Word32 FoaEven_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 FoaEven_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; + Word16 intensity_real_q[MASA_FREQUENCY_BANDS]; Word32 intensity_even_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; + Word16 intensity_even_real_q[MASA_FREQUENCY_BANDS]; + Word16 intensity_q, intensity_even_q; Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; Word32 vertical_diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; @@ -571,6 +574,11 @@ void ivas_mcmasa_param_est_ana_fx( Word16 i1, i2, i3; Word16 numAnalysisChannels; Word16 spreadCoh_e; + Word64 W_temp; + Word32 temp; + Word16 temp_e; + Word16 sf, scaled_data_q, s, shift = 31; + move16(); num_freq_bins = hMcMasa->cldfbAnaEnc[0]->no_channels; move16(); num_freq_bands = hMcMasa->nbands; @@ -580,6 +588,18 @@ void ivas_mcmasa_param_est_ana_fx( set16_fx( q_vdv, 31, MASA_FREQUENCY_BANDS ); set16_fx( out_exp, 30, MASA_FREQUENCY_BANDS ); + + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + shift = s_min( shift, L_norm_arr( data_fx[i], input_frame ) ); + } + shift = sub( shift, find_guarded_bits_fx( l_ts ) ); + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + scale_sig32( data_fx[i], input_frame, shift ); + } + scaled_data_q = add( q_data, shift ); + /* do processing over all CLDFB time slots */ FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) { @@ -625,14 +645,14 @@ void ivas_mcmasa_param_est_ana_fx( FOR( ts = mrange[0]; ts < mrange[1]; ts++ ) { - Word16 cr_q = MAX_16, ci_q = MAX_16, sf, c_e; + Word16 cr_q = MAX_16, ci_q = MAX_16, c_e; move16(); move16(); - Word16 inp_q = q_data; + Word16 inp_q = scaled_data_q; move16(); FOR( i = 0; i < numAnalysisChannels; i++ ) { - inp_q = q_data; + inp_q = scaled_data_q; move16(); cldfbAnalysis_ts_fx_var_q( &( data_fx[i][i_mult( l_ts, ts )] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hMcMasa->cldfbAnaEnc[i], &inp_q ); cr_q = s_min( cr_q, getScaleFactor32( Chnl_ImagBuffer_fx[i], l_ts ) ); @@ -659,8 +679,12 @@ void ivas_mcmasa_param_est_ana_fx( { FOR( i = 0; i < numAnalysisChannels; i++ ) { - Word32 temp = L_add( Mult_32_32( Chnl_RealBuffer_fx[i][j], Chnl_RealBuffer_fx[i][j] ), Mult_32_32( Chnl_ImagBuffer_fx[i][j], Chnl_ImagBuffer_fx[i][j] ) ); // Q-> 2*inp_q - 31, e = 31 - (2*inp_q - 31) = 62 - 2*inp_q = 2*(31 - inp_q) = 2*c_e - hMcMasa->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->energy_fx[block_m_idx][band_m_idx], hMcMasa->energy_e[block_m_idx][band_m_idx], temp, shl( c_e, 1 ), &hMcMasa->energy_e[block_m_idx][band_m_idx] ); + W_temp = W_mac_32_32( W_mult_32_32( Chnl_RealBuffer_fx[i][j], Chnl_RealBuffer_fx[i][j] ), Chnl_ImagBuffer_fx[i][j], Chnl_ImagBuffer_fx[i][j] ); // Q-> 2*inp_q + 1 + sf = W_norm( W_temp ); + temp = W_extract_h( W_shl( W_temp, sf ) ); // 2 * inp_q + 1 + sf - 32 + temp_e = sub( 31 + 31, add( shl( inp_q, 1 ), sf ) ); // e = 31 - (2 * inp_q + 1 + sf - 32) + + hMcMasa->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->energy_fx[block_m_idx][band_m_idx], hMcMasa->energy_e[block_m_idx][band_m_idx], temp, temp_e, &hMcMasa->energy_e[block_m_idx][band_m_idx] ); move32(); } } @@ -751,14 +775,39 @@ void ivas_mcmasa_param_est_ana_fx( } /* Direction estimation */ - computeIntensityVector_ana_fx( hMcMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */ + computeIntensityVector_ana_fx( hMcMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, intensity_real_q, inp_q ); - computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ), - NULL ); /* Q direction_vector_fx = Q30*/ + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], 0, + intensity_real_q ); /* Q direction_vector_fx = Q30*/ /* Power and intensity estimation for diffuseness */ - computeIntensityVector_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, num_freq_bands, intensity_even_real_fx ); /*2*inp_q-31*/ - computeReferencePower_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); /*2*inp_q-30*/ + computeIntensityVector_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, num_freq_bands, intensity_even_real_fx, intensity_even_real_q, inp_q ); + + computeReferencePower_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); /*2*inp_q-30*/ + + /* Aligning intensity_real and intensity_even_real to a common Q-factor */ + minimum_fx( intensity_real_q, num_freq_bands, &intensity_q ); + minimum_fx( intensity_even_real_q, num_freq_bands, &intensity_even_q ); + + Word16 tmp; + FOR( i = 0; i < num_freq_bands; i++ ) + { + tmp = sub( intensity_q, intensity_real_q[i] ); + intensity_real_fx[0][i] = L_shl( intensity_real_fx[0][i], tmp ); + move32(); + intensity_real_fx[1][i] = L_shl( intensity_real_fx[1][i], tmp ); + move32(); + intensity_real_fx[2][i] = L_shl( intensity_real_fx[2][i], tmp ); + move32(); + + tmp = sub( intensity_even_q, intensity_even_real_q[i] ); + intensity_even_real_fx[0][i] = L_shl( intensity_even_real_fx[0][i], tmp ); + move32(); + intensity_even_real_fx[1][i] = L_shl( intensity_even_real_fx[1][i], tmp ); + move32(); + intensity_even_real_fx[2][i] = L_shl( intensity_even_real_fx[2][i], tmp ); + move32(); + } /* Fill buffers of length "averaging_length" time slots for intensity and energy */ hMcMasa->index_buffer_intensity = add( ( hMcMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */ @@ -769,7 +818,7 @@ void ivas_mcmasa_param_est_ana_fx( /* only real part needed */ Copy32( intensity_even_real_fx[i], &( hMcMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); } - hMcMasa->buffer_intensity_real_q[index - 1] = sub( shl( inp_q, 1 ), 31 ); + hMcMasa->buffer_intensity_real_q[index - 1] = intensity_even_q; move16(); Copy32( reference_power_fx[ts], &( hMcMasa->buffer_energy_fx[i_mult( index - 1, num_freq_bands )] ), num_freq_bands ); hMcMasa->buffer_energy_q[index - 1] = sub( shl( inp_q, 1 ), 30 ); @@ -779,7 +828,7 @@ void ivas_mcmasa_param_est_ana_fx( IF( !hMcMasa->isHorizontalSetup ) { Copy32( intensity_real_fx[2], &( hMcMasa->buffer_intensity_real_vert_fx[index - 1][0] ), num_freq_bands ); - hMcMasa->buffer_intensity_real_vert_q[index - 1] = sub( shl( inp_q, 1 ), 31 ); + hMcMasa->buffer_intensity_real_vert_q[index - 1] = intensity_q; move16(); computeVerticalDiffuseness_fx( hMcMasa->buffer_intensity_real_vert_fx, hMcMasa->buffer_energy_fx, num_freq_bands, vertical_diffuseness_vector_fx, hMcMasa->buffer_intensity_real_vert_q, hMcMasa->buffer_energy_q ); // Q vertical_diffuseness_vector_fx = 31 v_min_fx( diffuseness_vector_fx, out_exp, vertical_diffuseness_vector_fx, q_vdv, diffuseness_vector_fx, out_exp, num_freq_bands ); @@ -790,7 +839,14 @@ void ivas_mcmasa_param_est_ana_fx( hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), shl( c_e, 1 ), &hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx] ); hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), shl( c_e, 1 ), &hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx] ); hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), shl( c_e, 1 ), &hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx] ); - diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[band_m_idx], diffuseness_e[band_m_idx], L_shl( Mult_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), 1 ), sub( shl( c_e, 1 ), 1 ), &diffuseness_e[band_m_idx] ); + + W_temp = W_mult0_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ); + s = W_norm( W_temp ); + temp = W_extract_h( W_shl( W_temp, s ) ); + temp_e = sub( 32, add( sub( Q30, sub( shl( c_e, 1 ), 1 ) ), s ) ); // 31 - ( (31 - sub( shl( c_e, 1 ), 1 )) + diffuseness_q + s - 32 ) + + diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[band_m_idx], diffuseness_e[band_m_idx], temp, temp_e, &diffuseness_e[band_m_idx] ); + renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], reference_power_fx[ts][band_m_idx], sub( shl( c_e, 1 ), 1 ), &renormalization_factor_diff_e[band_m_idx] ); move32(); move32(); @@ -827,7 +883,7 @@ void ivas_mcmasa_param_est_ana_fx( { FOR( j = i; j < numAnalysisChannels; j++ ) { - Word32 temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( COVls[band_m_idx].xr_fx[i][j], COVls[band_m_idx].xr_fx[i][j] ), shl( COVls[band_m_idx].xr_e[i][j], 1 ), Mult_32_32( COVls[band_m_idx].xi_fx[i][j], COVls[band_m_idx].xi_fx[i][j] ), shl( COVls[band_m_idx].xi_e[i][j], 1 ), &absCOVls_e[i][j] ); + temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( COVls[band_m_idx].xr_fx[i][j], COVls[band_m_idx].xr_fx[i][j] ), shl( COVls[band_m_idx].xr_e[i][j], 1 ), Mult_32_32( COVls[band_m_idx].xi_fx[i][j], COVls[band_m_idx].xi_fx[i][j] ), shl( COVls[band_m_idx].xi_e[i][j], 1 ), &absCOVls_e[i][j] ); absCOVls_fx[i][j] = Sqrt32( temp, &absCOVls_e[i][j] ); move32(); } @@ -880,7 +936,7 @@ void ivas_mcmasa_param_est_ana_fx( move16(); } Word16 temp_exp = add( lsEnergy_e[i1], lsEnergy_e[i2] ); - Word32 temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_exp ); + temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_exp ); tempCoh_e = 0; move16(); tempCoh_fx = L_shl( BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i2], temp, &tempCoh_e ), 16 ); @@ -932,8 +988,8 @@ void ivas_mcmasa_param_est_ana_fx( move16(); i3 = hMcMasa->rightNearest[i1]; move16(); - Word16 temp_e = add( lsEnergy_e[i2], lsEnergy_e[i3] ); - Word32 temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i2], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e ); + temp_e = add( lsEnergy_e[i2], lsEnergy_e[i3] ); + temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i2], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e ); IF( LT_16( i2, i3 ) ) { stereoCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i2][i3], temp, &stereoCoh_e ); @@ -1190,6 +1246,12 @@ void ivas_mcmasa_param_est_ana_fx( } } } + + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + scale_sig32( data_fx[i], input_frame, negate( shift ) ); + } + return; } @@ -1611,7 +1673,7 @@ void ivas_create_masa_out_meta_fx( /* Direct-to-total ratio */ FOR( band = 0; band < numFrequencyBands; band++ ) { - extOutMeta->directToTotalRatio[0][sf][band] = (UWord8) L_shr( energyRatio[sf][band], sub( energyRatio_q, 8 ) ); // Q8 + extOutMeta->directToTotalRatio[0][sf][band] = (UWord8) L_shr( Mpy_32_16_1( energyRatio[sf][band], UINT8_MAX ), sub( energyRatio_q, 15 ) ); // Q0 move16(); extOutMeta->directToTotalRatio[1][sf][band] = 0; move16(); @@ -1620,7 +1682,7 @@ void ivas_create_masa_out_meta_fx( /* Spread coherence */ FOR( band = 0; band < numFrequencyBands; band++ ) { - extOutMeta->spreadCoherence[0][sf][band] = (UWord8) L_shr( spreadCoherence[sf][band], sub( spreadCoherence_q, 8 ) ); // Q8 + extOutMeta->spreadCoherence[0][sf][band] = (UWord8) L_shr( Mpy_32_16_1( spreadCoherence[sf][band], UINT8_MAX ), sub( spreadCoherence_q, 15 ) ); // Q0 move16(); extOutMeta->spreadCoherence[1][sf][band] = 0; move16(); @@ -1629,14 +1691,14 @@ void ivas_create_masa_out_meta_fx( /* Diffuse-to-total ratio = 1 - sum(direct-to-total ratios) */ FOR( band = 0; band < numFrequencyBands; band++ ) { - extOutMeta->diffuseToTotalRatio[sf][band] = (UWord8) sub( UINT8_MAX, (UWord8) L_shr( energyRatio[sf][band], sub( energyRatio_q, 8 ) ) ); // Q8 + extOutMeta->diffuseToTotalRatio[sf][band] = (UWord8) sub( UINT8_MAX, (UWord8) L_shr( Mpy_32_16_1( energyRatio[sf][band], UINT8_MAX ), sub( energyRatio_q, 15 ) ) ); // Q0 move16(); } /* Surround coherence */ FOR( band = 0; band < numFrequencyBands; band++ ) { - extOutMeta->surroundCoherence[sf][band] = (UWord8) L_shr( surroundingCoherence[sf][band], sub( surroundingCoherence_q, 8 ) ); // Q8 + extOutMeta->surroundCoherence[sf][band] = (UWord8) L_shr( Mpy_32_16_1( surroundingCoherence[sf][band], UINT8_MAX ), sub( surroundingCoherence_q, 15 ) ); // Q0 move16(); } } diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index c9ed32d26..fe9ffbea3 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -362,6 +362,7 @@ static void ivas_omasa_param_est_ana_fx( Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; + Word16 intensity_real_q[MASA_FREQUENCY_BANDS]; Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; Word16 diffuseness_q = 0; @@ -523,15 +524,29 @@ static void ivas_omasa_param_est_ana_fx( v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); // Q: Chnl_RealBuffer_q v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); // Q: Chnl_ImagBuffer_q } - computeIntensityVector_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */ - intensity_q = sub( 31, shl( c_e, 1 ) ); + computeIntensityVector_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, intensity_real_q, inp_q ); - computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ), NULL ); /* Q direction_vector_fx = Q30*/ + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], 0, intensity_real_q ); /* Q direction_vector_fx = Q30*/ /* Power estimation for diffuseness */ computeReferencePower_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); // 2 * inputq - 30 reference_power_q = sub( shl( inp_q, 1 ), 30 ); + /* Aligning intensity_real to a common Q-factor */ + minimum_fx( intensity_real_q, num_freq_bands, &intensity_q ); + + Word16 tmp; + FOR( i = 0; i < num_freq_bands; i++ ) + { + tmp = sub( intensity_q, intensity_real_q[i] ); + intensity_real_fx[0][i] = L_shl( intensity_real_fx[0][i], tmp ); + move32(); + intensity_real_fx[1][i] = L_shl( intensity_real_fx[1][i], tmp ); + move32(); + intensity_real_fx[2][i] = L_shl( intensity_real_fx[2][i], tmp ); + move32(); + } + /* Fill buffers of length "averaging_length" time slots for intensity and energy */ hOMasa->index_buffer_intensity = add( ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */ move16(); @@ -761,8 +776,9 @@ void computeIntensityVector_ana_fx( Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal Qx */ Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input sig Qx */ const Word16 num_frequency_bands, /* i : Number of frequency bands */ - Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity 2 * Qx -31 */ -) + Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS], /* o : Intensity */ + Word16 q_intensity_real[MASA_FREQUENCY_BANDS], + Word16 inp_q ) { /* Reminder * X = a + ib; Y = c + id @@ -771,33 +787,66 @@ void computeIntensityVector_ana_fx( Word16 i, j; Word32 real, img; Word16 brange[2]; - + Word16 shift_value = add( shl( inp_q, 1 ), 1 ); + Word16 tmp_norm; FOR( i = 0; i < num_frequency_bands; i++ ) { brange[0] = band_grouping[i]; move16(); brange[1] = band_grouping[i + 1]; move16(); + Word16 num_bins = sub( brange[1], brange[0] ); + Word16 gb = find_guarded_bits_fx( num_bins ); + Word16 norm; - intensity_real[0][i] = 0; - move32(); - intensity_real[1][i] = 0; - move32(); - intensity_real[2][i] = 0; - move32(); + Word64 tmp_1 = 0, tmp_2 = 0, tmp_3 = 0; + move64(); + move64(); + move64(); FOR( j = brange[0]; j < brange[1]; j++ ) { - real = Cldfb_RealBuffer[0][j]; // Qx - img = Cldfb_ImagBuffer[0][j]; // Qx - /* Intensity is XYZ order, audio is WYZX order. */ - intensity_real[0][i] = L_add( intensity_real[0][i], L_add( Mpy_32_32( Cldfb_RealBuffer[3][j], real ), Mpy_32_32( Cldfb_ImagBuffer[3][j], img ) ) ); // output Q = 2 * Qx -31 + real = Cldfb_RealBuffer[0][j]; move32(); - intensity_real[1][i] = L_add( intensity_real[1][i], L_add( Mpy_32_32( Cldfb_RealBuffer[1][j], real ), Mpy_32_32( Cldfb_ImagBuffer[1][j], img ) ) ); // output Q = 2 * Qx -31 - move32(); - intensity_real[2][i] = L_add( intensity_real[2][i], L_add( Mpy_32_32( Cldfb_RealBuffer[2][j], real ), Mpy_32_32( Cldfb_ImagBuffer[2][j], img ) ) ); // output Q = 2 * Qx -31 + img = Cldfb_ImagBuffer[0][j]; move32(); + Word64 t1, t2, t3; + t1 = W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[3][j], real ), Cldfb_ImagBuffer[3][j], img ); /* 2 * q_cldfb + 1 */ + t2 = W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[1][j], real ), Cldfb_ImagBuffer[1][j], img ); /* 2 * q_cldfb + 1 */ + t3 = W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[2][j], real ), Cldfb_ImagBuffer[2][j], img ); /* 2 * q_cldfb + 1 */ + t1 = W_shr( t1, gb ); + t2 = W_shr( t2, gb ); + t3 = W_shr( t3, gb ); + /* Intensity is XYZ order, audio is WYZX order. */ + tmp_1 = W_add( tmp_1, t1 ); /* 2 * q_cldfb + 1 */ + tmp_2 = W_add( tmp_2, t2 ); /* 2 * q_cldfb + 1 */ + tmp_3 = W_add( tmp_3, t3 ); /* 2 * q_cldfb + 1 */ + } + norm = 63; + move16(); + IF( tmp_1 != 0 ) + { + tmp_norm = W_norm( tmp_1 ); + norm = s_min( norm, tmp_norm ); + } + IF( tmp_2 != 0 ) + { + tmp_norm = W_norm( tmp_2 ); + norm = s_min( norm, tmp_norm ); + } + IF( tmp_3 != 0 ) + { + tmp_norm = W_norm( tmp_3 ); + norm = s_min( norm, tmp_norm ); } + norm = sub( norm, 32 ); + intensity_real[0][i] = W_shl_sat_l( tmp_1, norm ); // shift_value - (gb - norm) + move32(); + intensity_real[1][i] = W_shl_sat_l( tmp_2, norm ); // shift_value - (gb - norm) + move32(); + intensity_real[2][i] = W_shl_sat_l( tmp_3, norm ); // shift_value - (gb - norm) + q_intensity_real[i] = sub( shift_value, sub( gb, norm ) ); + move16(); } return; diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index 7c5c02c71..6b34bcffe 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -1428,12 +1428,13 @@ void ivas_omasa_ana_close( OMASA_ANA_HANDLE *hOMasa /* i/o: analysis OMASA handle */ ); void computeIntensityVector_ana_fx( - const Word16 *band_grouping, /* i : Band grouping for estimation */ - Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal Qx */ - Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal Qx */ - const Word16 num_frequency_bands, /* i : Number of frequency bands */ - Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector 2 * Qx -31 */ -); + const Word16 *band_grouping, /* i : Band grouping for estimation */ + Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal Qx */ + Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input sig Qx */ + const Word16 num_frequency_bands, /* i : Number of frequency bands */ + Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS], /* o : Intensity */ + Word16 q_intensity_real[MASA_FREQUENCY_BANDS], + Word16 inp_q ); void computeReferencePower_ana_fx( const Word16 *band_grouping, /* i : Band grouping for estimation */ -- GitLab From dd858bd334a3bcfa1b65c1e3e6869528918df36e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 9 Jul 2025 11:53:09 +0530 Subject: [PATCH 2/2] Reverted changes in computeDiffuseness_fixed to resolve regressions --- lib_com/ivas_dirac_com_fx.c | 89 +++++++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 23 deletions(-) diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 735bbddaa..befeb273c 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -793,66 +793,109 @@ void computeDiffuseness_fixed( ) { Word32 intensity_slow[DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX]; - Word16 intensity_slow_e[DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX]; Word32 intensity_slow_abs[CLDFB_NO_CHANNELS_MAX]; Word64 intensity_slow_abs_64[CLDFB_NO_CHANNELS_MAX]; Word16 intensity_slow_abs_q[CLDFB_NO_CHANNELS_MAX]; Word32 energy_slow[CLDFB_NO_CHANNELS_MAX]; - Word16 energy_slow_e[CLDFB_NO_CHANNELS_MAX]; Word16 i, j, k; Word32 tmp = 0; move32(); Word32 *p_tmp; const Word32 *p_tmp_c; - Word16 exp1, exp2, q_tmp; + Word16 min_q_shift1, min_q_shift2, exp1, exp2, q_tmp; Word16 q_ene, q_intensity; /* Compute Intensity slow and energy slow buffer_intensity and buffer_energy */ - set_zero_fx( intensity_slow, ( DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX ) ); - set16_fx( intensity_slow_e, 0, ( DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX ) ); + set_zero_fx( intensity_slow, i_mult( DIRAC_NUM_DIMS, CLDFB_NO_CHANNELS_MAX ) ); set_zero_fx( intensity_slow_abs, CLDFB_NO_CHANNELS_MAX ); set_zero_fx( energy_slow, CLDFB_NO_CHANNELS_MAX ); - set16_fx( energy_slow_e, 0, CLDFB_NO_CHANNELS_MAX ); + + /* Calculate max possible shift for the buffer buffer_energy and buffer_intensity */ + min_q_shift1 = Q31; + move16(); + min_q_shift1 = s_min( min_q_shift1, getScaleFactor32( buffer_energy, i_mult( DIRAC_NO_COL_AVG_DIFF, num_freq_bands ) ) ); + min_q_shift1 = sub( min_q_shift1, find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF ) ); + + min_q_shift2 = Q31; + move16(); + FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ ) + { + min_q_shift2 = s_min( min_q_shift2, getScaleFactor32( buffer_intensity[i][j], num_freq_bands ) ); + } + } + min_q_shift2 = sub( min_q_shift2, find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF ) ); + + q_ene = add( q_factor_energy[0], min_q_shift1 ); + move16(); + q_intensity = add( q_factor_intensity[0], min_q_shift2 ); + move16(); FOR( i = 0; i < DIRAC_NO_COL_AVG_DIFF; ++i ) { /* Energy slow */ p_tmp_c = buffer_energy + i * num_freq_bands; + q_tmp = add( q_factor_energy[i], min_q_shift1 ); + + + Word16 shift_q = sub( q_tmp, q_ene ); + Word32 shiftEquiv = L_add( 0, 0 ); + Word16 shift_qtotal; + if ( shift_q < 0 ) + { + shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); + } + if ( shift_q >= 0 ) + { + shiftEquiv = L_add( 0x7FFFFFFF, 0 ); + } + shift_qtotal = sub( min_q_shift1, s_max( shift_q, 0 ) ); + FOR( k = 0; k < num_freq_bands; k++ ) { - energy_slow[k] = BASOP_Util_Add_Mant32Exp( p_tmp_c[k], sub( 31, q_factor_energy[i] ), energy_slow[k], energy_slow_e[k], &energy_slow_e[k] ); + tmp = L_shl( p_tmp_c[k], shift_qtotal ); + energy_slow[k] = Madd_32_32_r( tmp, energy_slow[k], shiftEquiv ); move32(); } + + q_ene = s_min( q_ene, q_tmp ); + + /* Intensity slow */ + q_tmp = add( q_factor_intensity[i], min_q_shift2 ); + + shift_q = sub( q_tmp, q_intensity ); + if ( shift_q < 0 ) + { + shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); + } + if ( shift_q >= 0 ) + { + shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); + } + shift_qtotal = sub( min_q_shift2, s_max( shift_q, 0 ) ); + FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) { p_tmp = buffer_intensity[j][i]; FOR( k = 0; k < num_freq_bands; k++ ) { - intensity_slow[j * num_freq_bands + k] = BASOP_Util_Add_Mant32Exp( p_tmp[k], sub( 31, q_factor_intensity[i] ), intensity_slow[j * num_freq_bands + k], intensity_slow_e[j * num_freq_bands + k], &intensity_slow_e[j * num_freq_bands + k] ); + tmp = L_shl( p_tmp[k], shift_qtotal ); + intensity_slow[j * num_freq_bands + k] = Madd_32_32_r( tmp, intensity_slow[j * num_freq_bands + k], shiftEquiv ); move32(); } } - } - Word16 max_e; - maximum_fx( energy_slow_e, CLDFB_NO_CHANNELS_MAX, &max_e ); - q_ene = sub( 31, max_e ); - FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - energy_slow[i] = L_shr( energy_slow[i], sub( max_e, energy_slow_e[i] ) ); // scaling to q_ene - move32(); - } - maximum_fx( intensity_slow_e, DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX, &max_e ); - q_intensity = sub( 31, max_e ); - FOR( i = 0; i < DIRAC_NUM_DIMS * num_freq_bands; i++ ) - { - intensity_slow[i] = L_shr( intensity_slow[i], sub( max_e, intensity_slow_e[i] ) ); // scaling to q_intensity - move32(); + q_intensity = s_min( q_intensity, q_tmp ); } + min_q_shift1 = getScaleFactor32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ) ); + min_q_shift1 = sub( min_q_shift1, idiv1616( add( find_guarded_bits_fx( DIRAC_NUM_DIMS ), 1 ), 2 ) ); + scale_sig32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ), min_q_shift1 ); + q_intensity = add( q_intensity, min_q_shift1 ); FOR( k = 0; k < num_freq_bands; k++ ) { intensity_slow_abs_64[k] = 0; -- GitLab