diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2011-10-12 20:58:52 +0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2011-10-12 20:58:52 +0400 |
commit | d5158a42d1010e3a2c4431dbada17314496b6ce3 (patch) | |
tree | c2e3384a118d02989abf14aa7318f9e76af98464 /silk/float | |
parent | d84c8d1fd89ee138d8e496f54708eb080ee1ff0a (diff) |
Fixes a numerical accuracy issue in the pitch search
The energy "sliding window" was using double accumulation with
float multiplications. This forces the multiplications to be
double as well.
Diffstat (limited to 'silk/float')
-rw-r--r-- | silk/float/energy_FLP.c | 12 | ||||
-rw-r--r-- | silk/float/pitch_analysis_core_FLP.c | 4 |
2 files changed, 8 insertions, 8 deletions
diff --git a/silk/float/energy_FLP.c b/silk/float/energy_FLP.c index 86767da3..f43143d5 100644 --- a/silk/float/energy_FLP.c +++ b/silk/float/energy_FLP.c @@ -41,18 +41,18 @@ double silk_energy_FLP( double result; /* 4x unrolled loop */ - result = 0.0f; + result = 0.0; dataSize4 = dataSize & 0xFFFC; for( i = 0; i < dataSize4; i += 4 ) { - result += data[ i + 0 ] * data[ i + 0 ] + - data[ i + 1 ] * data[ i + 1 ] + - data[ i + 2 ] * data[ i + 2 ] + - data[ i + 3 ] * data[ i + 3 ]; + result += data[ i + 0 ] * (double)data[ i + 0 ] + + data[ i + 1 ] * (double)data[ i + 1 ] + + data[ i + 2 ] * (double)data[ i + 2 ] + + data[ i + 3 ] * (double)data[ i + 3 ]; } /* add any remaining products */ for( ; i < dataSize; i++ ) { - result += data[ i ] * data[ i ]; + result += data[ i ] * (double)data[ i ]; } silk_assert( result >= 0.0 ); diff --git a/silk/float/pitch_analysis_core_FLP.c b/silk/float/pitch_analysis_core_FLP.c index a90859b4..8e661590 100644 --- a/silk/float/pitch_analysis_core_FLP.c +++ b/silk/float/pitch_analysis_core_FLP.c @@ -610,11 +610,11 @@ calculated recursively. lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 ); for( i = 1; i < lag_diff; i++ ) { /* remove part outside new window */ - energy -= basis_ptr[sf_length - i] * basis_ptr[sf_length - i]; + energy -= basis_ptr[sf_length - i] * (double)basis_ptr[sf_length - i]; silk_assert( energy >= 0.0 ); /* add part that comes into window */ - energy += basis_ptr[ -i ] * basis_ptr[ -i ]; + energy += basis_ptr[ -i ] * (double)basis_ptr[ -i ]; silk_assert( energy >= 0.0 ); silk_assert( lag_counter < SCRATCH_SIZE ); scratch_mem[lag_counter] = (silk_float)energy; |