diff options
author | Felicia Lim <flim@google.com> | 2017-07-05 17:36:56 -0700 |
---|---|---|
committer | Felicia Lim <flim@google.com> | 2017-07-07 09:42:55 -0700 |
commit | 0c2090c324e4f2ba2a8621c8b083559bab74c7c5 (patch) | |
tree | fea1ab0038bc4102569d1ab4ee57a0f973895570 /silk/sum_sqr_shift.c | |
parent | a7703b70699299f078a189e19b6915120cded732 (diff) | |
download | libopus-0c2090c324e4f2ba2a8621c8b083559bab74c7c5.tar.gz |
Opus 1.2.1android-o-iot-preview-5o-iot-preview-5
Change-Id: I551f1de5c5e121ac1275334e67c7e0f96ab18114
Test: - verified builds for arm*/mips*/x86*
- checked functionality using an emulator and stagefright
Diffstat (limited to 'silk/sum_sqr_shift.c')
-rw-r--r-- | silk/sum_sqr_shift.c | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/silk/sum_sqr_shift.c b/silk/sum_sqr_shift.c index 129df191..4fd0c3d7 100644 --- a/silk/sum_sqr_shift.c +++ b/silk/sum_sqr_shift.c @@ -41,43 +41,40 @@ void silk_sum_sqr_shift( ) { opus_int i, shft; - opus_int32 nrg_tmp, nrg; + opus_uint32 nrg_tmp; + opus_int32 nrg; - nrg = 0; - shft = 0; - len--; - for( i = 0; i < len; i += 2 ) { - nrg = silk_SMLABB_ovflw( nrg, x[ i ], x[ i ] ); - nrg = silk_SMLABB_ovflw( nrg, x[ i + 1 ], x[ i + 1 ] ); - if( nrg < 0 ) { - /* Scale down */ - nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); - shft = 2; - i+=2; - break; - } + /* Do a first run with the maximum shift we could have. */ + shft = 31-silk_CLZ32(len); + /* Let's be conservative with rounding and start with nrg=len. */ + nrg = len; + for( i = 0; i < len - 1; i += 2 ) { + nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); + nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); + nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); } - for( ; i < len; i += 2 ) { + if( i < len ) { + /* One sample left to process */ + nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); + nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); + } + silk_assert( nrg >= 0 ); + /* Make sure the result will fit in a 32-bit signed integer with two bits + of headroom. */ + shft = silk_max_32(0, shft+3 - silk_CLZ32(nrg)); + nrg = 0; + for( i = 0 ; i < len - 1; i += 2 ) { nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); - nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, (opus_uint32)nrg_tmp, shft ); - if( nrg < 0 ) { - /* Scale down */ - nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); - shft += 2; - } + nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); } - if( i == len ) { + if( i < len ) { /* One sample left to process */ nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); } - /* Make sure to have at least one extra leading zero (two leading zeros in total) */ - if( nrg & 0xC0000000 ) { - nrg = silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); - shft += 2; - } + silk_assert( nrg >= 0 ); /* Output arguments */ *shift = shft; |