From 83634ea88c8cdd01be731d9b974e2a0f64dccc41 Mon Sep 17 00:00:00 2001 From: Tapani Pihlajakuja Date: Mon, 13 Apr 2026 15:00:20 +0300 Subject: [PATCH 1/6] Fix BASOP issue 2529 by correcting scalings --- lib_com/options.h | 1 + lib_enc/ivas_masa_enc_fx.c | 4 ++++ lib_rend/lib_rend_fx.c | 17 +++++++++++++++++ lib_util/masa_file_reader.c | 20 ++++++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 8d06feb49..1ce6c7eba 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -129,6 +129,7 @@ #define FIX_BASOP_2513_EXTRA_RETURN_REND_OPEN /* Nokia: BASOP issue 2513: Removes extra return block */ #define FIX_BASOP_2514_EFAP_PORTING_ERROR /* Nokia: BASOP issue 2514: Fix wrongly ported line */ #define FIX_BASOP_2516_REND_CUSTOM_LAYOUT_PORT_BUG /* Nokia: BASOP issue 2516: Fix porting bug in setting planar state for custom layout in renderer */ +#define FIX_BASOP_2529_MASA_RATIO_SCALINGS /* Nokia: BASOP issue 2529: Fix MASA ratio scalings and verifications */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 8a957b267..47cd54408 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -2317,8 +2317,12 @@ static void compensate_energy_ratios_fx( hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = ONE_IN_Q30; // Q30 move32(); } +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + ELSE IF( GT_32( L_abs( L_sub( ratioSum, ONE_IN_Q30 ) ), 2 ) ) // else if ( ratioSum != 1.0f ) from float with minor rounding tolerance +#else // ELSE IF( NE_32( ratioSum, ONE_IN_Q30 ) ) ELSE /* Removing the check against 1 works well!!! */ +#endif { Word16 exp_diff; FOR( dir = 0; dir < numDirs; dir++ ) diff --git a/lib_rend/lib_rend_fx.c b/lib_rend/lib_rend_fx.c index c5a943893..f4b3cd981 100644 --- a/lib_rend/lib_rend_fx.c +++ b/lib_rend/lib_rend_fx.c @@ -9141,7 +9141,11 @@ static void renderMasaToMasa( inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = ONE_IN_Q30; move32(); } +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + ELSE IF( GT_32( L_abs( L_sub( ratioSum_fx, ONE_IN_Q30 ) ), 2 ) ) // else if ( ratioSum != 1.0f ) from float with minor rounding tolerance +#else ELSE IF( NE_32( ratioSum_fx, ONE_IN_Q30 ) ) +#endif { Word16 tmp_e = 0; move16(); @@ -9173,16 +9177,29 @@ static void renderMasaToMasa( FOR( dir = 0; dir < numDirs; dir++ ) { outMeta->directionIndex[dir][sf][band] = index_theta_phi_16_fx( &inMeta->directional_meta[dir].elevation_fx[sf][band], &inMeta->directional_meta[dir].azimuth_fx[sf][band], masaInput->hMasaPrerend->sph_grid16 ); +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + outMeta->directToTotalRatio[dir][sf][band] = (UWord8) W_extract_h( W_mult_32_16( inMeta->directional_meta[dir].energy_ratio_fx[sf][band], UINT8_MAX << 1 ) ); +#else outMeta->directToTotalRatio[dir][sf][band] = (UWord8) L_shr( inMeta->directional_meta[dir].energy_ratio_fx[sf][band], Q22 ); +#endif outMeta->diffuseToTotalRatio[sf][band] = (UWord8) sub( outMeta->diffuseToTotalRatio[sf][band], outMeta->directToTotalRatio[dir][sf][band] ); +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + outMeta->spreadCoherence[dir][sf][band] = (UWord8) W_extract_h( W_mult_32_16(L_deposit_h( inMeta->directional_meta[dir].spread_coherence_fx[sf][band] ), UINT8_MAX << 1 ) ); +#else outMeta->spreadCoherence[dir][sf][band] = (UWord8) shr( inMeta->directional_meta[dir].spread_coherence_fx[sf][band], Q7 ); +#endif move16(); move16(); move16(); move16(); } + +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + outMeta->surroundCoherence[sf][band] = (UWord8) W_extract_h( W_mult_32_16( L_deposit_h( inMeta->common_meta.surround_coherence_fx[sf][band] ), UINT8_MAX << 1 ) ); +#else outMeta->surroundCoherence[sf][band] = (UWord8) shr( inMeta->common_meta.surround_coherence_fx[sf][band], Q7 ); +#endif move16(); } } diff --git a/lib_util/masa_file_reader.c b/lib_util/masa_file_reader.c index 6cc7e8a7a..04ffdbfaa 100644 --- a/lib_util/masa_file_reader.c +++ b/lib_util/masa_file_reader.c @@ -194,7 +194,11 @@ ivas_error MasaFileReader_readNextFrame( for ( b = 0; b < MASA_FREQUENCY_BANDS; b++ ) { +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + hMeta->directional_meta[i].energy_ratio_fx[j][b] = (Word32) ( ( (int64_t) readOther[b] * ONE_IN_Q30 + 254 ) / 255 ); // Q30 +#else hMeta->directional_meta[i].energy_ratio_fx[j][b] = (Word32) ( readOther[b] * ONE_IN_Q22 ); // Q30 +#endif } /* Spread coherence */ @@ -205,7 +209,11 @@ ivas_error MasaFileReader_readNextFrame( for ( b = 0; b < MASA_FREQUENCY_BANDS; b++ ) { +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + hMeta->directional_meta[i].spread_coherence_fx[j][b] = (Word16) ( ( (int32_t) readOther[b] * ONE_IN_Q15 + 254 ) / 255 ); // Q15 +#else hMeta->directional_meta[i].spread_coherence_fx[j][b] = (Word16) ( readOther[b] * ONE_IN_Q7 ); // Q15 +#endif } } @@ -218,7 +226,11 @@ ivas_error MasaFileReader_readNextFrame( for ( b = 0; b < MASA_FREQUENCY_BANDS; b++ ) { +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + hMeta->common_meta.diffuse_to_total_ratio_fx[j][b] = (Word32) ( ( (int64_t) readOther[b] * ONE_IN_Q30 + 254 ) / 255 ); // Q30 +#else hMeta->common_meta.diffuse_to_total_ratio_fx[j][b] = (Word32) ( readOther[b] * ONE_IN_Q22 ); // Q30 +#endif } /* Surround coherence */ @@ -229,8 +241,12 @@ ivas_error MasaFileReader_readNextFrame( for ( b = 0; b < MASA_FREQUENCY_BANDS; b++ ) { +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + hMeta->common_meta.surround_coherence_fx[j][b] = (Word16) ( ( (int32_t) readOther[b] * ONE_IN_Q15 + 254 ) / 255 ); // Q15 +#else hMeta->common_meta.surround_coherence_fx[j][b] = shl( (Word16) readOther[b], 7 ); // Q8->Q15 move16(); +#endif } /* Remainder-to-total ratio */ @@ -241,8 +257,12 @@ ivas_error MasaFileReader_readNextFrame( for ( b = 0; b < MASA_FREQUENCY_BANDS; b++ ) { +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + hMeta->common_meta.remainder_to_total_ratio_fx[j][b] = (Word32) ( ( (int64_t) readOther[b] * ONE_IN_Q30 + 254 ) / 255 ); // Q30 +#else hMeta->common_meta.remainder_to_total_ratio_fx[j][b] = L_shl( (Word32) readOther[b], Q22 ); // Q8 -> Q30 move32(); +#endif } } -- GitLab From 487ec7139bd2bcedbd87fdc5fd181b6391379b69 Mon Sep 17 00:00:00 2001 From: Tapani Pihlajakuja Date: Mon, 13 Apr 2026 16:11:39 +0300 Subject: [PATCH 2/6] Clang format --- lib_rend/lib_rend_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/lib_rend_fx.c b/lib_rend/lib_rend_fx.c index f4b3cd981..a1e186846 100644 --- a/lib_rend/lib_rend_fx.c +++ b/lib_rend/lib_rend_fx.c @@ -9184,7 +9184,7 @@ static void renderMasaToMasa( #endif outMeta->diffuseToTotalRatio[sf][band] = (UWord8) sub( outMeta->diffuseToTotalRatio[sf][band], outMeta->directToTotalRatio[dir][sf][band] ); #ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS - outMeta->spreadCoherence[dir][sf][band] = (UWord8) W_extract_h( W_mult_32_16(L_deposit_h( inMeta->directional_meta[dir].spread_coherence_fx[sf][band] ), UINT8_MAX << 1 ) ); + outMeta->spreadCoherence[dir][sf][band] = (UWord8) W_extract_h( W_mult_32_16( L_deposit_h( inMeta->directional_meta[dir].spread_coherence_fx[sf][band] ), UINT8_MAX << 1 ) ); #else outMeta->spreadCoherence[dir][sf][band] = (UWord8) shr( inMeta->directional_meta[dir].spread_coherence_fx[sf][band], Q7 ); #endif -- GitLab From ae0ed8995557bd99585e28d7df99a30b3db71031 Mon Sep 17 00:00:00 2001 From: Tapani Pihlajakuja Date: Mon, 13 Apr 2026 23:38:38 +0300 Subject: [PATCH 3/6] Add saturation for ratio sums to guard against overflow with malformed metadata. --- lib_enc/ivas_masa_enc_fx.c | 8 ++++++++ lib_rend/lib_rend_fx.c | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 47cd54408..4e868cde5 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -2303,9 +2303,17 @@ static void compensate_energy_ratios_fx( move32(); FOR( dir = 0; dir < numDirs; dir++ ) { +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + ratioSum = L_add_sat( ratioSum, hMeta->directional_meta[dir].energy_ratio_fx[sf][band] ); // Q30 +#else ratioSum = L_add( ratioSum, hMeta->directional_meta[dir].energy_ratio_fx[sf][band] ); // Q30 +#endif } +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + ratioSum = L_add_sat( ratioSum, hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); // Q30 +#else ratioSum = L_add( ratioSum, hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); // Q30 +#endif IF( ratioSum == 0 ) { diff --git a/lib_rend/lib_rend_fx.c b/lib_rend/lib_rend_fx.c index a1e186846..3a124f085 100644 --- a/lib_rend/lib_rend_fx.c +++ b/lib_rend/lib_rend_fx.c @@ -9127,9 +9127,17 @@ static void renderMasaToMasa( move32(); FOR( dir = 0; dir < numDirs; dir++ ) { +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + ratioSum_fx = L_add_sat( ratioSum_fx, inMeta->directional_meta[dir].energy_ratio_fx[sf][band] ); +#else ratioSum_fx = L_add( ratioSum_fx, inMeta->directional_meta[dir].energy_ratio_fx[sf][band] ); +#endif } +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + ratioSum_fx = L_add_sat( ratioSum_fx, inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); +#else ratioSum_fx = L_add( ratioSum_fx, inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); +#endif IF( ratioSum_fx == 0 ) { -- GitLab From 24b2cd2c23a12ebde7b57b9e188e91fd00887aab Mon Sep 17 00:00:00 2001 From: Tapani Pihlajakuja Date: Tue, 14 Apr 2026 13:28:31 +0300 Subject: [PATCH 4/6] Remove saturation and instead accumulate in Q29 for proper normalization. --- lib_enc/ivas_masa_enc_fx.c | 14 +++++++++++--- lib_rend/lib_rend_fx.c | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 4e868cde5..bbd96c49f 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -2304,13 +2304,13 @@ static void compensate_energy_ratios_fx( FOR( dir = 0; dir < numDirs; dir++ ) { #ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS - ratioSum = L_add_sat( ratioSum, hMeta->directional_meta[dir].energy_ratio_fx[sf][band] ); // Q30 + ratioSum = L_add( ratioSum, L_shr( hMeta->directional_meta[dir].energy_ratio_fx[sf][band], 1 ) ); // accumulate in Q29 #else ratioSum = L_add( ratioSum, hMeta->directional_meta[dir].energy_ratio_fx[sf][band] ); // Q30 #endif } #ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS - ratioSum = L_add_sat( ratioSum, hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); // Q30 + ratioSum = L_add( ratioSum, L_shr( hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], 1 ) ); // accumulate in Q29 #else ratioSum = L_add( ratioSum, hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); // Q30 #endif @@ -2326,7 +2326,7 @@ static void compensate_energy_ratios_fx( move32(); } #ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS - ELSE IF( GT_32( L_abs( L_sub( ratioSum, ONE_IN_Q30 ) ), 2 ) ) // else if ( ratioSum != 1.0f ) from float with minor rounding tolerance + ELSE IF( GT_32( L_abs( L_sub( ratioSum, ONE_IN_Q29 ) ), 1 ) ) // else if ( ratioSum != 1.0f ) from float with minor rounding tolerance #else // ELSE IF( NE_32( ratioSum, ONE_IN_Q30 ) ) ELSE /* Removing the check against 1 works well!!! */ @@ -2338,13 +2338,21 @@ static void compensate_energy_ratios_fx( hMeta->directional_meta[dir].energy_ratio_fx[sf][band] = BASOP_Util_Divide3232_Scale_newton( hMeta->directional_meta[dir].energy_ratio_fx[sf][band], ratioSum, &exp_diff ); move32(); +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + hMeta->directional_meta[dir].energy_ratio_fx[sf][band] = L_shl( hMeta->directional_meta[dir].energy_ratio_fx[sf][band], sub( exp_diff, Q2 ) ); // back to Q30 +#else hMeta->directional_meta[dir].energy_ratio_fx[sf][band] = L_shl( hMeta->directional_meta[dir].energy_ratio_fx[sf][band], sub( exp_diff, Q1 ) ); // Q30 +#endif move32(); } hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = BASOP_Util_Divide3232_Scale_newton( hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], ratioSum, &exp_diff ); move32(); +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = L_shl( hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], sub( exp_diff, Q2 ) ); // back to Q30 +#else hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = L_shl( hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], sub( exp_diff, Q1 ) ); // Q30 +#endif move32(); } } diff --git a/lib_rend/lib_rend_fx.c b/lib_rend/lib_rend_fx.c index 115055022..7d73c0098 100644 --- a/lib_rend/lib_rend_fx.c +++ b/lib_rend/lib_rend_fx.c @@ -9126,13 +9126,13 @@ static void renderMasaToMasa( FOR( dir = 0; dir < numDirs; dir++ ) { #ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS - ratioSum_fx = L_add_sat( ratioSum_fx, inMeta->directional_meta[dir].energy_ratio_fx[sf][band] ); + ratioSum_fx = L_add( ratioSum_fx, L_shr(inMeta->directional_meta[dir].energy_ratio_fx[sf][band], 1) ); // accumulate in Q29 #else ratioSum_fx = L_add( ratioSum_fx, inMeta->directional_meta[dir].energy_ratio_fx[sf][band] ); #endif } #ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS - ratioSum_fx = L_add_sat( ratioSum_fx, inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); + ratioSum_fx = L_add( ratioSum_fx, L_shr(inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], 1) ); // accumulate in Q29 #else ratioSum_fx = L_add( ratioSum_fx, inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); #endif @@ -9148,7 +9148,7 @@ static void renderMasaToMasa( move32(); } #ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS - ELSE IF( GT_32( L_abs( L_sub( ratioSum_fx, ONE_IN_Q30 ) ), 2 ) ) // else if ( ratioSum != 1.0f ) from float with minor rounding tolerance + ELSE IF( GT_32( L_abs( L_sub( ratioSum_fx, ONE_IN_Q29 ) ), 1 ) ) // else if ( ratioSum != 1.0f ) from float with minor rounding tolerance #else ELSE IF( NE_32( ratioSum_fx, ONE_IN_Q30 ) ) #endif @@ -9160,7 +9160,11 @@ static void renderMasaToMasa( FOR( dir = 0; dir < numDirs; dir++ ) { tmp = BASOP_Util_Divide3232_Scale_newton( inMeta->directional_meta[dir].energy_ratio_fx[sf][band], ratioSum_fx, &tmp_e ); +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + inMeta->directional_meta[dir].energy_ratio_fx[sf][band] = L_shl( tmp, sub( tmp_e, 2 ) ); /* Back to Q30 */ +#else inMeta->directional_meta[dir].energy_ratio_fx[sf][band] = L_shl( tmp, sub( tmp_e, 1 ) ); /* Q30 */ +#endif move32(); } tmp_e = 0; @@ -9168,7 +9172,11 @@ static void renderMasaToMasa( tmp = 0; move32(); tmp = BASOP_Util_Divide3232_Scale_newton( inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], ratioSum_fx, &tmp_e ); +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = L_shl( tmp, sub( tmp_e, 2 ) ); /* Back to Q30 */ +#else inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = L_shl( tmp, sub( tmp_e, 1 ) ); /* Q30 */ +#endif move32(); } } -- GitLab From 5544e596de8c13df21ed5644c4ffea989c8b71e9 Mon Sep 17 00:00:00 2001 From: Tapani Pihlajakuja Date: Tue, 14 Apr 2026 14:35:47 +0300 Subject: [PATCH 5/6] clang format --- lib_rend/lib_rend_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/lib_rend_fx.c b/lib_rend/lib_rend_fx.c index 3161dab16..21bcaa2f8 100644 --- a/lib_rend/lib_rend_fx.c +++ b/lib_rend/lib_rend_fx.c @@ -9146,13 +9146,13 @@ static void renderMasaToMasa( FOR( dir = 0; dir < numDirs; dir++ ) { #ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS - ratioSum_fx = L_add( ratioSum_fx, L_shr(inMeta->directional_meta[dir].energy_ratio_fx[sf][band], 1) ); // accumulate in Q29 + ratioSum_fx = L_add( ratioSum_fx, L_shr( inMeta->directional_meta[dir].energy_ratio_fx[sf][band], 1 ) ); // accumulate in Q29 #else ratioSum_fx = L_add( ratioSum_fx, inMeta->directional_meta[dir].energy_ratio_fx[sf][band] ); #endif } #ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS - ratioSum_fx = L_add( ratioSum_fx, L_shr(inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], 1) ); // accumulate in Q29 + ratioSum_fx = L_add( ratioSum_fx, L_shr( inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], 1 ) ); // accumulate in Q29 #else ratioSum_fx = L_add( ratioSum_fx, inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); #endif -- GitLab From 5625915ef1766141d4d907becde53499ae4d629d Mon Sep 17 00:00:00 2001 From: Tapani Pihlajakuja Date: Thu, 16 Apr 2026 11:34:08 +0300 Subject: [PATCH 6/6] Minor code review comment fix. --- lib_rend/lib_rend_fx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_rend/lib_rend_fx.c b/lib_rend/lib_rend_fx.c index 21bcaa2f8..1c10f3488 100644 --- a/lib_rend/lib_rend_fx.c +++ b/lib_rend/lib_rend_fx.c @@ -9017,7 +9017,11 @@ static void renderMasaToMasa( IVAS_REND_AudioBuffer outAudio ) { Word16 sf, band, dir, numDirs; +#ifdef FIX_BASOP_2529_MASA_RATIO_SCALINGS + Word32 ratioSum_fx; /* Q29 for accumulation */ +#else Word32 ratioSum_fx; /* Q30 */ +#endif MASA_DECODER_EXT_OUT_META_HANDLE outMeta; MASA_METADATA_FRAME *inMeta; Word32 tmpBuffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; -- GitLab