Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/xiph/opus.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2011-10-12 20:58:52 +0400
committerJean-Marc Valin <jmvalin@jmvalin.ca>2011-10-12 20:58:52 +0400
commitd5158a42d1010e3a2c4431dbada17314496b6ce3 (patch)
treec2e3384a118d02989abf14aa7318f9e76af98464 /silk/float
parentd84c8d1fd89ee138d8e496f54708eb080ee1ff0a (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.c12
-rw-r--r--silk/float/pitch_analysis_core_FLP.c4
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;