From 4d386408b80762fd726b85cf4b3c4923be40ee8b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 14:07:06 +0530 Subject: [PATCH] Fix for 3GPP issue 1004: Modulation artifact in OMASA at 24 kbps using LTV 3ISM 2TC input and output to MONO Link #1004, #1363 Fixes 3GPP issue #1363: Assert in BASOP decoder function protoSignalComputation2_fx when fed with BASOP encoder MASA bitstream --- lib_rend/ivas_dirac_rend_fx.c | 93 ++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index cc8e4d8bd..958a23a3f 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -1692,7 +1692,7 @@ void protoSignalComputation2_fx( Word32 min_sum_total_ratio_fx, min_sum_total_ratio_db_fx; Word32 sum_total_ratio_fx[MASA_SUM_FREQ_RANGE_BINS]; Word16 q_sum_total_ratio; - Word32 a_fx, b_fx; + Word32 a_fx, b_fx, a2_fx, b2_fx; Word16 interpolatorSpaced_fx, interpolatorDmx_fx; Word32 tempSpaced_fx, tempDmx_fx; Word16 q_shift, min_q_shift, exp, q_temp, temp_q_shift, q_temp2; @@ -1700,6 +1700,7 @@ void protoSignalComputation2_fx( Word64 W_tmp1, W_tmp2; Word64 reference_power_64fx[CLDFB_NO_CHANNELS_MAX]; Word16 q_reference_power_64fx; + Word16 head_room, q_Left_Right_power; /* Calculate maximum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */ min_q_shift = Q31; move16(); @@ -1866,8 +1867,10 @@ void protoSignalComputation2_fx( a_fx = 21474836; /*0.01 in Q31*/ /* Temporal smoothing coefficient */ move32(); b_fx = L_sub( ONE_IN_Q31, a_fx ); /* Temporal smoothing coefficient q31*/ - // a2_fx = 214748365; /*0.1 in Q31*/ /* Temporal smoothing coefficient */ - // b2_fx = L_sub( ONE_IN_Q31, a2_fx ); /* Temporal smoothing coefficient */ + move32(); + a2_fx = 214748365; /*0.1 in Q31*/ /* Temporal smoothing coefficient */ + move32(); + b2_fx = L_sub( ONE_IN_Q31, a2_fx ); /* Temporal smoothing coefficient */ IF( stereo_type_detect->interpolator > 0 ) { @@ -1890,6 +1893,23 @@ void protoSignalComputation2_fx( q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); q_temp2 = sub( add( add( q_cldfb, temp_q_shift ), add( q_cldfb, temp_q_shift ) ), 31 ); + head_room = 63; + move16(); + FOR( l = 0; l < num_freq_bands; l++ ) + { + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + + W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); + W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); + + head_room = s_min( head_room, W_norm( W_add( W_tmp1, W_tmp2 ) ) ); + } + head_room = sub( head_room, find_guarded_bits_fx( num_freq_bands ) ); + q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift ), 1 ), sub( head_room, 32 ) ); + FOR( l = 0; l < num_freq_bands; l++ ) { re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift @@ -1904,26 +1924,26 @@ void protoSignalComputation2_fx( /* Compute reference power */ // Left_power_fx = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); // 2*(q_cldfb+min_q_shift) - Left_power_fx = W_extract_l( W_shr( W_tmp1, 31 ) ); + Left_power_fx = W_extract_h( W_shl( W_tmp1, head_room ) ); // q_Left_Right_power // Right_power_fx = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); // 2*(q_cldfb+min_q_shift) - Right_power_fx = W_extract_l( W_shr( W_tmp2, 31 ) ); + Right_power_fx = W_extract_h( W_shl( W_tmp2, head_room ) ); // q_Left_Right_power // reference_power_fx[l] = L_add( Left_power_fx, Right_power_fx ); reference_power_64fx[l] = W_add( W_tmp1, W_tmp2 ); // 2*(q_cldfb+min_q_shift) move64(); - left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // 2*(q_cldfb+min_q_shift) -31 + left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power + right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); - total_bb_power_fx = L_add( total_bb_power_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 + total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power IF( GT_16( l, MASA_HI_FREQ_START_BIN ) ) { - left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // 2*(q_cldfb+min_q_shift) -31 + left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // q_Left_Right_power + right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // q_Left_Right_power // total_hi_power_fx = L_add( total_hi_power_fx, reference_power_fx[l] ); - total_hi_power_fx = L_add( total_hi_power_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 + total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power } IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) @@ -1960,12 +1980,17 @@ void protoSignalComputation2_fx( test(); IF( ( stereo_type_detect->sum_power_fx[l] == 0 ) && ( stereo_type_detect->total_power_fx[l] == 0 ) ) { - sum_total_ratio_fx[l] = MAX_16; // q15 + sum_total_ratio_fx[l] = MAX_32; // q15 + move32(); + } + ELSE IF( stereo_type_detect->total_power_fx[l] == 0 ) + { + sum_total_ratio_fx[l] = MAX_32; // q15 move32(); } ELSE { - sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], L_add( stereo_type_detect->total_power_fx[l], EPSILON_FX ), &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) + sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], stereo_type_detect->total_power_fx[l], &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) move32(); q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp ) ) ); sum_total_ratio_fx[l] = L_shl( sum_total_ratio_fx[l], sub( Q15, q_sum_total_ratio ) ); // q15 @@ -2237,45 +2262,45 @@ void protoSignalComputation2_fx( } } - temp = Mpy_32_32( a_fx, left_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_left_bb_power ) ) + temp = Mpy_32_32( a_fx, left_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ) { - stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_left_bb_power = q_temp; + stereo_type_detect->q_left_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->left_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_left_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ) ); // stereo_type_detect->q_left_bb_power + stereo_type_detect->left_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ), b_fx, stereo_type_detect->left_bb_power_fx ); // stereo_type_detect->q_left_bb_power move32(); } - temp = Mpy_32_32( a_fx, right_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_right_bb_power ) ) + temp = Mpy_32_32( a_fx, right_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ) { - stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_right_bb_power = q_temp; + stereo_type_detect->q_right_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->right_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_right_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ) ); // stereo_type_detect->q_right_bb_power + stereo_type_detect->right_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ), b_fx, stereo_type_detect->right_bb_power_fx ); // stereo_type_detect->q_right_bb_power move32(); } - temp = Mpy_32_32( a_fx, total_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_total_bb_power ) ) + temp = Mpy_32_32( a_fx, total_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ) { - stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_total_bb_power = q_temp; + stereo_type_detect->q_total_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->total_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_total_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ) ); // stereo_type_detect->q_total_bb_power + stereo_type_detect->total_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ), b_fx, stereo_type_detect->total_bb_power_fx ); // stereo_type_detect->q_total_bb_power move32(); } @@ -2293,8 +2318,7 @@ void protoSignalComputation2_fx( q_lr_bb_power = stereo_type_detect->q_right_bb_power; move16(); } - q_lr_bb_power = sub( q_lr_bb_power, 1 ); /* = (lr_bb_power_fx * 2) */ - + q_lr_bb_power = sub( q_lr_bb_power, 1 ); /* = (lr_bb_power_fx * 2) */ temp = BASOP_Util_Divide3232_Scale_cadence( lr_bb_power_fx, L_add( stereo_type_detect->total_bb_power_fx, EPSILON_FX ), &exp ); // Q(31-(exp+stereo_type_detect->q_total_bb_power-q_lr_bb_power)) exp = sub( 31, add( sub( 31, exp ), sub( q_lr_bb_power, stereo_type_detect->q_total_bb_power ) ) ); temp = BASOP_Util_Log2( temp ); // q25 @@ -2305,15 +2329,15 @@ void protoSignalComputation2_fx( // 20480 = 10 in Q11 lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21 - stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); + stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); move32(); stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); move16(); - stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, right_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); + stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); move32(); stereo_type_detect->q_right_hi_power = sub( 31, stereo_type_detect->q_right_hi_power ); move16(); - stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); + stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); move32(); stereo_type_detect->q_total_hi_power = sub( 31, stereo_type_detect->q_total_hi_power ); move16(); @@ -2330,8 +2354,7 @@ void protoSignalComputation2_fx( move32(); q_lr_hi_power = stereo_type_detect->q_right_hi_power; } - q_lr_hi_power = sub( q_lr_hi_power, 1 ); /* = (q_lr_hi_power * 2) */ - + q_lr_hi_power = sub( q_lr_hi_power, 1 ); /* = (q_lr_hi_power * 2) */ temp = BASOP_Util_Divide3232_Scale_cadence( lr_hi_power_fx, L_add( stereo_type_detect->total_hi_power_fx, EPSILON_FX ), &exp ); // Q=31-(exp+ stereo_type_detect->q_total_hi_power-q_lr_hi_power) exp = sub( 31, add( sub( 31, exp ), sub( q_lr_hi_power, stereo_type_detect->q_total_hi_power ) ) ); temp = BASOP_Util_Log2( temp ); // q25 -- GitLab