diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2016-06-19 14:44:55 -0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2016-06-19 14:44:55 -0400 |
commit | 7252c25849956e4ebec793cb5d3678049d0e7fc3 (patch) | |
tree | aae8fab666973d91d662bfd979a2a1129e33278e | |
parent | ddea3a6fbfa5727e8d7c4d1a8943bb72862a90ee (diff) | |
download | opus-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.
-rw-r--r-- | silk/fixed/burg_modified_FIX.c | 7 |
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 */ |