1
0
Fork 0

Prevent a multiplication overflow and more accuracy by using floats for attack rate loop

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3956
This commit is contained in:
Sjoerd van der Berg 2016-01-30 16:09:04 +00:00
parent dc4aabb403
commit 0d868c990f

View file

@ -1237,6 +1237,7 @@ void Chip::Setup( Bit32u rate ) {
EnvelopeSelect( i, index, shift );
linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 )));
}
Bit32s attackDiffs[62];
//Generate the best matching attack rate
for ( Bit8u i = 0; i < 62; i++ ) {
Bit8u index, shift;
@ -1267,22 +1268,23 @@ void Chip::Setup( Bit32u rate ) {
if ( lDiff < bestDiff ) {
bestDiff = lDiff;
bestAdd = guessAdd;
//We hit an exactly matching sample count
if ( !bestDiff )
break;
}
//Linear correction factor, not exactly perfect but seems to work
double correct = (original - diff) / (double)original;
guessAdd = (Bit32u)(guessAdd * correct);
//Below our target
if ( diff < 0 ) {
//Better than the last time
Bit32s mul = ((original - diff) << 12) / original;
guessAdd = ((guessAdd * mul) >> 12);
//Always add one here for rounding, an overshoot will get corrected by another pass decreasing
guessAdd++;
} else if ( diff > 0 ) {
Bit32s mul = ((original - diff) << 12) / original;
guessAdd = (guessAdd * mul) >> 12;
guessAdd--;
}
}
attackRates[i] = bestAdd;
//Keep track of the diffs for some debugging
attackDiffs[i] = bestDiff;
}
for ( Bit8u i = 62; i < 76; i++ ) {
//This should provide instant volume maximizing