Mcu32
Well-known member
Two numerical issues in control_sgtl5000.cpp
The calculations immediately produce values larger than 255, so assigning the result to uint8_t truncates the value to its lowest 8 bits before it is passed to write().
A calculated value such as:
0x39BC
becomes:
0xBC
when stored in uint8_t.
The exact final width can then be limited when writing to the codec registers, rather than accidentally losing the upper bits during the calculation.
Register width: 16 bit.
There's even an old issue on GitHub about this already.
*coef++ = (int)(b0 + 0.499);
*coef++ = (int)(b1 + 0.499);
*coef++ = (int)(b2 + 0.499);
*coef++ = (int)(a1 + 0.499);
*coef++ = (int)(a2 + 0.499);
This works approximately as intended for positive values, but it is not symmetric for negative values because conversion from floating point to int truncates toward zero.
1. autoVolumeControl() uses uint8_t for values that are calculated much larger
thresh, att and dec are declared as uint8_t.The calculations immediately produce values larger than 255, so assigning the result to uint8_t truncates the value to its lowest 8 bits before it is passed to write().
A calculated value such as:
0x39BC
becomes:
0xBC
when stored in uint8_t.
The exact final width can then be limited when writing to the codec registers, rather than accidentally losing the upper bits during the calculation.
Register width: 16 bit.
There's even an old issue on GitHub about this already.
2. calcBiquad() does not round negative coefficients correctly
At the end of calcBiquad() the coefficients are converted using:*coef++ = (int)(b0 + 0.499);
*coef++ = (int)(b1 + 0.499);
*coef++ = (int)(b2 + 0.499);
*coef++ = (int)(a1 + 0.499);
*coef++ = (int)(a2 + 0.499);
This works approximately as intended for positive values, but it is not symmetric for negative values because conversion from floating point to int truncates toward zero.
Last edited: