diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index d31f2ff089176cd3403b5b615ac7c4d967ac75eb..f0d9405638fd411b9d271c6f2723815f950a2459 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -476,6 +476,8 @@ void ivas_analy_sp_fx( Word32 Ltmp; Word16 *pt_fft; Word16 exp, tmp; + Word16 resultant_q; + Word16 exp2; Word64 LEtot; LEtot = 0; move64(); @@ -679,16 +681,12 @@ void ivas_analy_sp_fx( } exp = L_norm_arr( Bin_E, L_FFT / 2 ); - IF( GE_16( exp, sub( *q_Bin_E, Q22 ) ) ) - { - scale_sig32( Bin_E, L_FFT / 2, sub( *q_Bin_E, Q22 ) ); // *q_Bin_E - } - ELSE - { - scale_sig32( Bin_E + L_FFT / 2, L_FFT / 2, sub( Q22, *q_Bin_E ) ); // Q22 - *q_Bin_E = Q22; - move16(); - } + exp2 = L_norm_arr( Bin_E + L_FFT / 2, L_FFT / 2 ); + resultant_q = s_min( Q22, s_min( add( *q_Bin_E, exp2 ), add( exp, Q22 ) ) ); // calculating resultant q after scaling + scale_sig32( Bin_E, L_FFT / 2, sub( resultant_q, Q22 ) ); // Q22=>resultant_q + scale_sig32( Bin_E + L_FFT / 2, L_FFT / 2, sub( resultant_q, *q_Bin_E ) ); // q_Bin_E=>resultant_q + *q_Bin_E = resultant_q; + move16(); return; } diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 736d838c288782dfd71790efb66a1dd606405aaa..3e4b29acc89d49d257c20161b0abb89760e2a587 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -147,6 +147,7 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 Word16 i; Word16 bIsAttackPresent, attackIndex; Word16 attackRatioThreshold_1_5; + Word64 W_tmp1, W_tmp2, W_tmp3; (void) nPastSubblocks; (void) nSubblocks; @@ -161,8 +162,8 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 bIsAttackPresent = FALSE; attackIndex = -1; /* Search for the last attack in the subblocks */ - if ( s_or( (Word16) GT_32( L_shr( pSubblockNrg[-1], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-1], attackRatioThreshold ) ), - L_sub( L_shr( pSubblockNrg[-2], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-2], attackRatioThreshold ) ) > 0 ) ) + IF( s_or( (Word16) GT_32( L_shr( pSubblockNrg[-1], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-1], attackRatioThreshold ) ), + L_sub( L_shr( pSubblockNrg[-2], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-2], attackRatioThreshold ) ) > 0 ) ) { move16(); bIsAttackPresent = TRUE; @@ -172,7 +173,10 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 FOR( i = 0; i < NSUBBLOCKS; i++ ) { - IF( GT_32( L_shr( pSubblockNrg[i], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[i], attackRatioThreshold ) ) ) + W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1 ); + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); + + IF( GT_64( W_tmp1, W_tmp2 ) ) { if ( i < 6 ) { @@ -180,22 +184,44 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 bIsAttackPresent = TRUE; } - if ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + IF( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) { move16(); attackIndex = i; + W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1 ); + W_tmp2 = W_add( W_tmp2, W_shr( W_tmp2, 3 ) ); // pAccSubblockNrg[i] * 1.125f + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); + if ( s_and( (Word16) LT_64( W_tmp1, W_tmp2 ), s_or( (Word16) EQ_16( i, 2 ), (Word16) EQ_16( i, 6 ) ) ) ) + { + attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */ + } } } ELSE /* no attack, but set index anyway in case of strong energy increase */ { - IF( s_and( ( (Word16) GT_32( L_shr( pSubblockNrg[i], 1 + ATTACKTHRESHOLD_E ), Mpy_32_16_1( pSubblockNrg[sub( i, 1 )], attackRatioThreshold_1_5 ) ) ), - ( L_sub( L_shr( pSubblockNrg[i], 1 + ATTACKTHRESHOLD_E ), Mpy_32_16_1( pSubblockNrg[sub( i, 2 )], attackRatioThreshold_1_5 ) ) > 0 ) ) ) + W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i - 1], attackRatioThreshold_1_5 ), 1 ); + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ( ATTACKTHRESHOLD_E + 1 ) ) ); + W_tmp3 = W_shr( W_mult_32_16( pAccSubblockNrg[i - 2], attackRatioThreshold_1_5 ), 1 ); + + IF( s_and( ( (Word16) GT_64( W_tmp1, W_tmp2 ) ), + ( W_sub( W_tmp1, W_tmp3 ) > 0 ) ) ) { - if ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + IF( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) { move16(); attackIndex = i; + + W_tmp2 = W_mult_32_16( pSubblockNrg[i - 1], attackRatioThreshold ); + W_tmp3 = W_mult_32_16( pSubblockNrg[i - 2], attackRatioThreshold ); + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); + + if ( s_and( (Word16) s_or( (Word16) LT_64( W_tmp1, W_tmp2 ), (Word16) + LT_64( W_tmp1, W_tmp3 ) ), + s_or( (Word16) EQ_16( i, 2 ), (Word16) EQ_16( i, 6 ) ) ) ) + { + attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */ + } } } }