rosalina: fix volume slider override value calculation

Below 50%, the volume slider moves the dB value twice as fast. When
linearly interpolating the value in dB (lerp in log-scale), we need to
account for that fact to match how the MCU firmware handles the actual
volume slider.
This commit is contained in:
TuxSH 2026-02-11 02:41:03 +01:00
parent 21f0d64ee8
commit e35972ea82

View File

@ -420,8 +420,30 @@ static Result SysConfigMenu_ApplyVolumeOverride(void)
s8 i2s2Volume;
if (currVolumeSliderOverride >= 0)
{
i2s1Volume = -128 + (((float)currVolumeSliderOverride/100.f) * 108);
i2s2Volume = i2s1Volume;
// Considering I found this table inside MCU fw bin (at around offset 0x1200 in the raw bin):
// 127, 126, 125, ... 56
// which corresponds to round(127 - 71 * (i/63)) modulo some rounding error, it is certain
// that the MCU writes to "Page 0/Register 117: VOL/MICDET-Pin Gain" using linear interpolation
// to map the slider position (0..63) to the raw gain values, using 127 ("reserved") as "mute".
// Indeed, the value used in all calibration data for shutter volume is -10 dB, which maps to 56.
// However, if you look at the definition of reg 0,117 closely, you will notice that the mapping
// to the 7-bit value is piecewise, with half the resolution (double the slope) for values mapping
// to -28 dB or lower, which means that the slider increases volume twice as fast below 50% position.
// LERP like MCU does, round to nearest integer
u8 rawPinGain = 127 - (71 * currVolumeSliderOverride + 50) / 100;
s8 volume;
if (rawPinGain <= 90)
volume = 36 - rawPinGain;
else if (rawPinGain >= 91 && rawPinGain <= 126)
volume = 126 - 2 * rawPinGain;
else
volume = -128; // mute
i2s1Volume = volume;
i2s2Volume = volume;
}
else
{