From 4a7027b27e2d962dedc63360a45db5ff74dc1131 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jmvalin@jmvalin.ca> Date: Thu, 27 Oct 2011 13:51:21 -0400 Subject: [PATCH] Allow wrap-around in silk_LPC_analysis_filter() --- silk/LPC_analysis_filter.c | 18 ++++++++++-------- silk/SigProc_FIX.h | 3 +++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/silk/LPC_analysis_filter.c b/silk/LPC_analysis_filter.c index a8d1c3339..5fc4349bd 100644 --- a/silk/LPC_analysis_filter.c +++ b/silk/LPC_analysis_filter.c @@ -58,18 +58,20 @@ void silk_LPC_analysis_filter( in_ptr = &in[ ix - 1 ]; out32_Q12 = silk_SMULBB( in_ptr[ 0 ], B[ 0 ] ); - out32_Q12 = silk_SMLABB( out32_Q12, in_ptr[ -1 ], B[ 1 ] ); - out32_Q12 = silk_SMLABB( out32_Q12, in_ptr[ -2 ], B[ 2 ] ); - out32_Q12 = silk_SMLABB( out32_Q12, in_ptr[ -3 ], B[ 3 ] ); - out32_Q12 = silk_SMLABB( out32_Q12, in_ptr[ -4 ], B[ 4 ] ); - out32_Q12 = silk_SMLABB( out32_Q12, in_ptr[ -5 ], B[ 5 ] ); + /* Allowing wrap around so that two wraps can cancel each other. The rare + cases where the result wraps around can only be triggered by invalid streams*/ + out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -1 ], B[ 1 ] ); + out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -2 ], B[ 2 ] ); + out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -3 ], B[ 3 ] ); + out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -4 ], B[ 4 ] ); + out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -5 ], B[ 5 ] ); for( j = 6; j < d; j += 2 ) { - out32_Q12 = silk_SMLABB( out32_Q12, in_ptr[ -j ], B[ j ] ); - out32_Q12 = silk_SMLABB( out32_Q12, in_ptr[ -j - 1 ], B[ j + 1 ] ); + out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -j ], B[ j ] ); + out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -j - 1 ], B[ j + 1 ] ); } /* Subtract prediction */ - out32_Q12 = silk_SUB32( silk_LSHIFT( (opus_int32)in_ptr[ 1 ], 12 ), out32_Q12 ); + out32_Q12 = silk_SUB32_ovflw( silk_LSHIFT( (opus_int32)in_ptr[ 1 ], 12 ), out32_Q12 ); /* Scale to Q0 */ out32 = silk_RSHIFT_ROUND( out32_Q12, 12 ); diff --git a/silk/SigProc_FIX.h b/silk/SigProc_FIX.h index 24052ff9c..d24eac6f2 100644 --- a/silk/SigProc_FIX.h +++ b/silk/SigProc_FIX.h @@ -421,6 +421,9 @@ static inline opus_int32 silk_ROR32( opus_int32 a32, opus_int rot ) (just standard two's complement implementation-specific behaviour) */ #define silk_SUB32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) - (opus_uint32)(b))) +/* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */ +#define silk_SMLABB_ovflw(a32, b32, c32) (silk_ADD32_ovflw((a32) , ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32)))) + /* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode)*/ #define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32)) #ifndef silk_SMLABB_ovflw -- GitLab