From 2f1639748e4148bfcac8298173314991ff6223bb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 18 Nov 2024 12:05:30 +0530 Subject: [PATCH] Fix for 3GPP issue 1012: IVAS_rend OMASA to MASA2 rendering crashes link #1012 --- lib_rend/ivas_masa_merge.c | 27 ++++++++-- lib_rend/ivas_omasa_ana.c | 106 +++++++++++++++++++++++++++++++------ lib_rend/lib_rend.c | 29 ++++++++++ 3 files changed, 144 insertions(+), 18 deletions(-) diff --git a/lib_rend/ivas_masa_merge.c b/lib_rend/ivas_masa_merge.c index 734751f2d..64f387438 100644 --- a/lib_rend/ivas_masa_merge.c +++ b/lib_rend/ivas_masa_merge.c @@ -307,13 +307,24 @@ void diffuse_meta_merge_1x1_fx( tmp = BASOP_Util_Divide1616_Scale( inMeta->directToTotalRatio[0][sf][band], UINT8_MAX, &scale ); energyTimesRatio_fx = Mpy_32_16_r( inEne_fx[sf][band], tmp ); /* Q( 31 - ( nEne_e[sf] + scale ) ) */ energyTimesRatio_e = add( inEne_e[sf], scale ); + + IF( GT_16( inEne_e[sf], inEneISM_e[sf] ) ) + { + total_nrg_fx = L_add( L_shr( inEne_fx[sf][band], 1 ), L_shr( inEneISM_fx[sf][band], add( sub( inEne_e[sf], inEneISM_e[sf] ), 1 ) ) ); /* Q(30 - inEne_e[sf]) */ + total_nrg_e = add( inEne_e[sf], 1 ); + } + ELSE + { + total_nrg_fx = L_add( L_shr( inEneISM_fx[sf][band], 1 ), L_shr( inEne_fx[sf][band], add( sub( inEneISM_e[sf], inEne_e[sf] ), 1 ) ) ); /* Q(30 - inEneISM_e[sf]) */ + total_nrg_e = add( inEneISM_e[sf], 1 ); + } /* target is original MASA diffuseness */ - tmp = BASOP_Util_Divide1616_Scale( inMeta->directToTotalRatio[0][sf][band], UINT8_MAX, &scale ); + tmp = BASOP_Util_Divide1616_Scale( inMeta->diffuseToTotalRatio[sf][band], UINT8_MAX, &scale ); total_diff_nrg_fx = Mpy_32_16_r( inEne_fx[sf][band], tmp ); /* Q( 31 - ( nEne_e[sf] + scale ) ) */ total_diff_nrg_e = add( inEne_e[sf], scale ); /* criterion is mean of ISM ratio and new ratio */ - dir_ratio_ism_fx = L_deposit_h( BASOP_Util_Divide1616_Scale( inMeta->directToTotalRatio[0][sf][band], UINT8_MAX, &dir_ratio_ism_e ) ); + dir_ratio_ism_fx = L_deposit_h( BASOP_Util_Divide1616_Scale( inMetaISM->directToTotalRatio[0][sf][band], UINT8_MAX, &dir_ratio_ism_e ) ); tmp = BASOP_Util_Divide3232_Scale( total_diff_nrg_fx, L_add( total_nrg_fx, EPSILON_FX ), &scale ); L_tmp1 = L_deposit_h( tmp ); /* Q( 31 - ( scale + total_nrg_e - total_diff_nrg_e ) ) */ scale = add( scale, sub( total_diff_nrg_e, total_nrg_e ) ); @@ -359,7 +370,17 @@ void diffuse_meta_merge_1x1_fx( outMeta->directToTotalRatio[0][sf][band] = (UWord8) imult1616( extract_l( L_shr( new_dir_ratio_fx, sub( 31, new_dir_ratio_e ) ) ), UINT8_MAX ); move16(); - new_diff_ratio_fx = L_sub( L_shl( 1, sub( 31, new_dir_ratio_e ) ), new_dir_ratio_fx ); + IF( GT_16( sub( 31, new_dir_ratio_e ), Q30 ) ) + { + new_dir_ratio_fx = L_shr( new_dir_ratio_fx, sub( sub( 31, new_dir_ratio_e ), Q30 ) ); /* Q30 */ + new_dir_ratio_e = 1; + move16(); + new_diff_ratio_fx = L_sub( ONE_IN_Q30, new_dir_ratio_fx ); /* Q30 */ + } + ELSE + { + new_diff_ratio_fx = L_sub( L_shl( 1, sub( 31, new_dir_ratio_e ) ), new_dir_ratio_fx ); /* Q(31 - new_dir_ratiio_e) */ + } outMeta->diffuseToTotalRatio[sf][band] = (UWord8) imult1616( extract_l( L_shr( new_diff_ratio_fx, new_dir_ratio_e ) ), UINT8_MAX ); move16(); } diff --git a/lib_rend/ivas_omasa_ana.c b/lib_rend/ivas_omasa_ana.c index 5fa4901b7..65a570c53 100644 --- a/lib_rend/ivas_omasa_ana.c +++ b/lib_rend/ivas_omasa_ana.c @@ -739,10 +739,8 @@ static void ivas_omasa_param_est_ana_fx( Word32 reference_power_fx[MASA_FREQUENCY_BANDS]; Word32 Chnl_RealBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX]; - Word16 Chnl_RealBuffer_q = 0; - move16(); - Word16 Chnl_ImagBuffer_q = 0; - move16(); + Word16 Chnl_RealBuffer_q[MAX_NUM_OBJECTS]; + Word16 Chnl_ImagBuffer_q[MAX_NUM_OBJECTS]; Word32 Chnl_ImagBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX]; Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; @@ -759,6 +757,7 @@ static void ivas_omasa_param_est_ana_fx( move16(); Word32 norm_tmp_fx; Word16 scale; + Word16 tmp_ener_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; Word32 dir_v_fx[DIRAC_NUM_DIMS], L_tmp1, L_tmp2; Word16 dir_v_q, norm_tmp_q; @@ -781,6 +780,9 @@ static void ivas_omasa_param_est_ana_fx( Word16 intensity_q; Word16 direction_q, reference_power_q; + set16_zero_fx( Chnl_RealBuffer_q, MAX_NUM_OBJECTS ); + set16_zero_fx( Chnl_ImagBuffer_q, MAX_NUM_OBJECTS ); + /* Compute ISM to FOA matrices */ FOR( i = 0; i < nchan_ism; i++ ) { @@ -841,16 +843,29 @@ static void ivas_omasa_param_est_ana_fx( set_zero_fx( diffuseness_m_fx, hOMasa->nbands ); set_zero_fx( hOMasa->energy_fx[block_m_idx], MASA_FREQUENCY_BANDS ); + set16_fx( tmp_ener_e[block_m_idx], 0, MASA_FREQUENCY_BANDS ); + FOR( ts = mrange[0]; ts < mrange[1]; ts++ ) { FOR( i = 0; i < nchan_ism; i++ ) { - Word16 in_q; - in_q = data_f_q; + Word16 in_q = Q11; move16(); + /* Keep input to cldfbAnalysis_ts_fx in Q11 */ + IF( NE_16( in_q, data_f_q ) ) + { + scale_sig32( &( data_f_fx[i][i_mult( l_ts, ts )] ), l_ts, sub( in_q, data_f_q ) ); /* Q11 */ + } + cldfbAnalysis_ts_fx( &( data_f_fx[i][i_mult( l_ts, ts )] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &in_q ); + /* Restore data_f_fx to it's original Q */ + IF( NE_16( data_f_q, Q11 ) ) + { + scale_sig32( &( data_f_fx[i][i_mult( l_ts, ts )] ), l_ts, sub( data_f_q, Q11 ) ); /* Q(data_f_q) */ + } + FOR( Word16 ind = 0; ind < CLDFB_NO_CHANNELS_MAX; ind++ ) { Chnl_RealBuffer_fx[i][ind] = L_shr( Chnl_RealBuffer_fx[i][ind], 4 ); // Q: in_q - 4 @@ -859,8 +874,34 @@ static void ivas_omasa_param_est_ana_fx( move32(); } - Chnl_RealBuffer_q = sub( in_q, 4 ); - Chnl_ImagBuffer_q = sub( in_q, 4 ); + Chnl_RealBuffer_q[i] = sub( in_q, 4 ); + move16(); + Chnl_ImagBuffer_q[i] = sub( in_q, 4 ); + move16(); + } + + IF( GT_16( nchan_ism, 1 ) ) + { + Word16 anaBuf_com_q; + minimum_fx( Chnl_RealBuffer_q, nchan_ism, &anaBuf_com_q ); + + FOR( i = 0; i < nchan_ism; i++ ) + { + IF( NE_16( anaBuf_com_q, Chnl_RealBuffer_q[i] ) ) + { + FOR( Word16 ind = 0; ind < CLDFB_NO_CHANNELS_MAX; ind++ ) + { + Chnl_RealBuffer_fx[i][ind] = L_shr( Chnl_RealBuffer_fx[i][ind], sub( Chnl_RealBuffer_q[i], anaBuf_com_q ) ); // Q: anaBuf_com_q + move32(); + Chnl_ImagBuffer_fx[i][ind] = L_shr( Chnl_ImagBuffer_fx[i][ind], sub( Chnl_ImagBuffer_q[i], anaBuf_com_q ) ); // Q: anaBuf_com_q + move32(); + } + Chnl_ImagBuffer_q[i] = anaBuf_com_q; + move16(); + Chnl_RealBuffer_q[i] = anaBuf_com_q; + move16(); + } + } } @@ -875,12 +916,21 @@ static void ivas_omasa_param_est_ana_fx( { FOR( i = 0; i < nchan_ism; i++ ) { - L_tmp1 = Mpy_32_32( Chnl_RealBuffer_fx[i][j], Chnl_RealBuffer_fx[i][j] ); // Chnl_RealBuffer_q + Chnl_RealBuffer_q - 31 - L_tmp2 = Mpy_32_32( Chnl_ImagBuffer_fx[i][j], Chnl_ImagBuffer_fx[i][j] ); // Chnl_ImagBuffer_q + Chnl_ImagBuffer_q - 31 - hOMasa->energy_fx[block_m_idx][band_m_idx] = L_add( hOMasa->energy_fx[block_m_idx][band_m_idx], L_add( L_tmp1, L_tmp2 ) ); // Chnl_RealBuffer_q + Chnl_RealBuffer_q - 31 + Word16 tmp_e, tmp_r_q, tmp_i_q; + Word32 tmp_r, tmp_i, L_tmp_sum; + tmp_r_q = norm_l( Chnl_RealBuffer_fx[i][j] ); + tmp_r = L_shl( Chnl_RealBuffer_fx[i][j], tmp_r_q ); /* Q(Chnl_RealBuffer_q[i] + tmp_r_q) */ + tmp_r_q = add( tmp_r_q, Chnl_RealBuffer_q[i] ); + L_tmp1 = Mpy_32_32( tmp_r, tmp_r ); /* Q(2*tmp_r_q - 31)*/ + tmp_r_q = sub( add( tmp_r_q, tmp_r_q ), 31 ); + tmp_i_q = norm_l( Chnl_ImagBuffer_fx[i][j] ); + tmp_i = L_shl( Chnl_ImagBuffer_fx[i][j], tmp_i_q ); /* Q(Chnl_ImagBuffer_q[i] + tmp_i_q)*/ + tmp_i_q = add( tmp_i_q, Chnl_ImagBuffer_q[i] ); + tmp_i_q = sub( add( tmp_i_q, tmp_i_q ), 31 ); + L_tmp2 = Mpy_32_32( tmp_i, tmp_i ); /* Q(2*tmp_i_q - 31) */ + L_tmp_sum = BASOP_Util_Add_Mant32Exp( L_tmp1, sub( 31, tmp_r_q ), L_tmp2, sub( 31, tmp_i_q ), &tmp_e ); /* Q(31 - tmp_e) */ + hOMasa->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->energy_fx[block_m_idx][band_m_idx], tmp_ener_e[block_m_idx][band_m_idx], L_tmp_sum, tmp_e, &tmp_ener_e[block_m_idx][band_m_idx] ); /* Q(31 - tmp_ener_e[block_m_idx][band_m_idx]) */ move32(); - hOMasa->energy_q = sub( add( Chnl_RealBuffer_q, Chnl_RealBuffer_q ), 31 ); - move16(); } } } @@ -939,7 +989,7 @@ static void ivas_omasa_param_est_ana_fx( move32(); } } - foa_q = sub( Chnl_ImagBuffer_q, 5 ); + foa_q = sub( Chnl_ImagBuffer_q[0], 5 ); computeIntensityVector_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); intensity_q = sub( shl( add( foa_q, Q1 ), 1 ), 31 ); @@ -951,7 +1001,7 @@ static void ivas_omasa_param_est_ana_fx( /* Power estimation for diffuseness */ computeReferencePower_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx, num_freq_bands ); // 2 * inputq - 30 - reference_power_q = sub( shl( Chnl_ImagBuffer_q, 1 ), 30 ); + reference_power_q = sub( shl( Chnl_ImagBuffer_q[0], 1 ), 30 ); /* 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 */ @@ -1049,6 +1099,32 @@ static void ivas_omasa_param_est_ana_fx( } } + Word16 q_ener_min = MAX_16; + move16(); + FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + Word16 e_max; + maximum_fx( tmp_ener_e[block_m_idx], num_freq_bands, &e_max ); + e_max = sub( 31, e_max ); + if ( GT_16( q_ener_min, e_max ) ) + { + q_ener_min = e_max; + move16(); + } + } + + FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ ) + { + hOMasa->energy_fx[block_m_idx][band_m_idx] = L_shr( hOMasa->energy_fx[block_m_idx][band_m_idx], sub( sub( 31, tmp_ener_e[block_m_idx][band_m_idx] ), q_ener_min ) ); /* Q(q_ener_min) */ + move32(); + } + } + + hOMasa->energy_q = q_ener_min; + move16(); + *spreadCoherence_q = 0; move16(); *surroundingCoherence_q = 0; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 2094ce820..8abafc8f8 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -10194,6 +10194,11 @@ static void renderIsmToMasa( push_wmops( "renderIsmToMasa" ); + FOR( i = 0; i < MAX_NUM_OBJECTS; i++ ) + { + set32_fx( tmpRendBuffer_fx[i], 0, L_FRAME48k ); + } + copyBufferTo2dArray_fx( ismInput->base.inputBuffer, tmpRendBuffer_fx ); Word16 input_e[MAX_NUM_OBJECTS], max_e; @@ -12309,6 +12314,7 @@ static void renderMasaToMasa( Word16 q_cldfb = *outAudio.pq_fact; Word16 q_cldfb_out = *outAudio.pq_fact; Word16 scale_factor = 31; + Word16 scale_fac_arr[MASA_MAX_TRANSPORT_CHANNELS]; move16(); move16(); move16(); @@ -12342,6 +12348,29 @@ static void renderMasaToMasa( scale_factor = sub( scale_factor, 1 ); scale_sig32( Chan_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, scale_factor ); /* Q(q_cldfb_out + scale_factor) */ scale_sig32( Chan_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, scale_factor ); /* Q(q_cldfb_out + scale_factor) */ + scale_fac_arr[i] = scale_factor; + move16(); + } + + scale_factor = MAX_16; + move16(); + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + scale_factor = s_min( scale_factor, scale_fac_arr[i] ); + } + + FOR( i = 0; i < numAnalysisChannels; i++ ) + { + IF( NE_16( scale_factor, scale_fac_arr[i] ) ) + { + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + Chan_RealBuffer_fx[i][j] = L_shr( Chan_RealBuffer_fx[i][j], sub( scale_fac_arr[i], scale_factor ) ); /* Q(q_cldfb_out+scale_factor) */ + move32(); + Chan_ImagBuffer_fx[i][j] = L_shr( Chan_ImagBuffer_fx[i][j], sub( scale_fac_arr[i], scale_factor ) ); /* Q(q_cldfb_out+scale_factor) */ + move32(); + } + } } Word16 q_add = sub( 31, add( scale_factor, q_cldfb_out ) ); -- GitLab