snd_mixer_selem_ask_playback_dB_vol() and snd_mixer_selem_ask_playback_vol_dB() are inconsistent between each other when SND_CTL_TLVT_DB_MINMAX_MUTE is enabled. Similarly for snd_mixer_selem_get_playback_dB after setting volume dB_vol returned.
Version: alsa-lib-1.2.15.3-3.fc44.x86_64
In Pipewire, we have
if ((r = snd_mixer_selem_ask_playback_dB_vol(me, value_dB, rounding, &val)) < 0)
return r;
if ((r = snd_mixer_selem_ask_playback_vol_dB(me, val, &dB)) < 0)
return r;
In the problem case value_dB = -3259 and rounding = +1 but I'm seeing
(gdb) p val
$55 = 1
(gdb) p dB
$56 = -9999999
The val = 1 is correct (the device is muted only at HW volume 0), but dB from snd_mixer_selem_ask_playback_vol_dB is wrong, the device is not muted at volume 1. (The inconsistency results to Pipewire volume control being broken at low volume.)
The device in question is "1532:055e Razer USA, Ltd Razer Nommo V2 X" -- it is muted at lowest ALSA hw volume 0, and anything > 0 is not muted (so it needs the mixer_playback_min_mute quirk).
In snd_tlv_convert_to_dB:
snd_tlv_convert_to_dB (tlv=0x7b460cd21610, rangemin=0, rangemax=7248, volume=1, db_gain=0x7b260b455e40) at control/tlv.c:212
254 if (*db_gain < mindb)
(gdb) p type
$80 = 5
(gdb) p mindb
$72 = -2837
(gdb) p maxdb
$73 = -6
The *db_gain = (maxdb - mindb) * (volume - rangemin) / (rangemax - rangemin) + mindb results to *db_gain == mindb and the function returns with SND_CTL_TLV_DB_GAIN_MUTE which is wrong.
Reverting 41039b4 appears to fix it for me (get dB == -2837). Alternatively one could change snd_tlv_convert_from_dB to match so the rounding is right.
I don't understand the new logic, doesn't SND_CTL_TLVT_DB_MINMAX_MUTE mean that the lowest hardware volume value is muted? (Also, the ALSA 1/100 dB values round to zero earlier than the USB 1/256 dB ones.)
Link: https://gitlab.freedesktop.org/pipewire/pipewire/-/work_items/5235 (I also have access to similar device locally)
snd_mixer_selem_ask_playback_dB_vol() and snd_mixer_selem_ask_playback_vol_dB() are inconsistent between each other when SND_CTL_TLVT_DB_MINMAX_MUTE is enabled. Similarly for
snd_mixer_selem_get_playback_dBafter setting volume dB_vol returned.Version: alsa-lib-1.2.15.3-3.fc44.x86_64
In Pipewire, we have
In the problem case
value_dB = -3259androunding = +1but I'm seeingThe
val = 1is correct (the device is muted only at HW volume 0), but dB from snd_mixer_selem_ask_playback_vol_dB is wrong, the device is not muted at volume 1. (The inconsistency results to Pipewire volume control being broken at low volume.)The device in question is "1532:055e Razer USA, Ltd Razer Nommo V2 X" -- it is muted at lowest ALSA hw volume 0, and anything > 0 is not muted (so it needs the mixer_playback_min_mute quirk).
In snd_tlv_convert_to_dB:
The
*db_gain = (maxdb - mindb) * (volume - rangemin) / (rangemax - rangemin) + mindbresults to*db_gain == mindband the function returns with SND_CTL_TLV_DB_GAIN_MUTE which is wrong.Reverting 41039b4 appears to fix it for me (get
dB == -2837). Alternatively one could change snd_tlv_convert_from_dB to match so the rounding is right.I don't understand the new logic, doesn't SND_CTL_TLVT_DB_MINMAX_MUTE mean that the lowest hardware volume value is muted? (Also, the ALSA 1/100 dB values round to zero earlier than the USB 1/256 dB ones.)
Link: https://gitlab.freedesktop.org/pipewire/pipewire/-/work_items/5235 (I also have access to similar device locally)