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.
This commit is contained in:
Jean-Marc Valin 2011-10-12 12:58:52 -04:00
parent d84c8d1fd8
commit d5158a42d1
2 changed files with 8 additions and 8 deletions

View file

@ -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 );

View file

@ -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;