summaryrefslogtreecommitdiff
path: root/src/modules/alsa/alsa-mixer.c
diff options
context:
space:
mode:
authorBenjamin Valentin <benpicco@googlemail.com>2020-12-28 19:45:08 +0100
committerTanu Kaskinen <tanuk@iki.fi>2021-01-18 17:36:12 +0200
commit10ac01a2066b3d0a58ecc3e3db98dd43c284a209 (patch)
tree77da1980c704a32335c6ddf5a1c0a8bea7836c02 /src/modules/alsa/alsa-mixer.c
parent4868fcf5f344af613172f61d9105c02f3f07e1ab (diff)
alsa-mixer: disable has_dB if max_dB is negative
Volume scaling in dB mode is broken if max dB is negative. I have a Nobsound USB amplifier (1908:2220) that reports a dB range of -127.07 dB to -128 dB in Alsa. While this is likely a driver/device bug, in my naive imagination userspace wouldn't bother too much with the absolute values and just set out_dB(percent) = min_dB + (max_dB - min_dB) * percent However, this is not what PulseAudio is doing, instead max_dB is used as base_volume with which the desired software volume is multiplied while min_dB does not seem to be taken into account. The result is that with this device only a tiny portion of the volume slider is usable. Setting it to 97% already reaches min_dB which effectively turns any (software) audio knob to an on/off switch. To work around this, simply set the has_dB flag to false if max_dB is negative. This falls back to using raw Alsa values (ranging from 0 - 255), now the settings in pavucontrol perfectly mirror those in alsamixer. Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/447>
Diffstat (limited to 'src/modules/alsa/alsa-mixer.c')
-rw-r--r--src/modules/alsa/alsa-mixer.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index a6e6672ad..1cfc42633 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -1711,6 +1711,14 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
else
e->has_dB = snd_mixer_selem_get_capture_dB_range(me, &min_dB, &max_dB) >= 0;
+ /* Assume decibel data to be incorrect if max_dB is negative. */
+ if (e->has_dB && max_dB < 0) {
+ pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("The decibel volume range for element %s (%li dB - %li dB) has negative maximum. "
+ "Disabling the decibel range.", buf, min_dB, max_dB);
+ e->has_dB = false;
+ }
+
/* Check that the kernel driver returns consistent limits with
* both _get_*_dB_range() and _ask_*_vol_dB(). */
if (e->has_dB && !e->db_fix) {