summaryrefslogtreecommitdiff
path: root/silk/fixed/burg_modified_FIX.c
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2016-06-19 14:44:55 -0400
committerJean-Marc Valin <jmvalin@jmvalin.ca>2016-06-19 14:44:55 -0400
commit7252c25849956e4ebec793cb5d3678049d0e7fc3 (patch)
treeaae8fab666973d91d662bfd979a2a1129e33278e /silk/fixed/burg_modified_FIX.c
parentddea3a6fbfa5727e8d7c4d1a8943bb72862a90ee (diff)
downloadopus-7252c25849956e4ebec793cb5d3678049d0e7fc3.tar.gz
Fixes signed integer overflow in fixed-point Burg
We just explicitly allow the overflow with silk_MLA_ovflw() since the result seems to be correct because the overflows cancel each other.
Diffstat (limited to 'silk/fixed/burg_modified_FIX.c')
-rw-r--r--silk/fixed/burg_modified_FIX.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/silk/fixed/burg_modified_FIX.c b/silk/fixed/burg_modified_FIX.c
index be79e11d..17d0e099 100644
--- a/silk/fixed/burg_modified_FIX.c
+++ b/silk/fixed/burg_modified_FIX.c
@@ -150,8 +150,11 @@ void silk_burg_modified_c(
C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */
- tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
- tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
+ /* We sometimes have get overflows in the multiplications (even beyond +/- 2^32),
+ but they cancel each other and the real result seems to always fit in a 32-bit
+ signed integer. This was determined experimentally, not theoretically (unfortunately). */
+ tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
+ tmp2 = silk_MLA_ovflw( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
}
tmp1 = -tmp1; /* Q17 */
tmp2 = -tmp2; /* Q17 */