Skip to content

playback: fall back to raw-range mapping for Alsa mixers without dB info - #1731

Open
qianc wants to merge 1 commit into
librespot-org:devfrom
qianc:alsa-mixer-no-db-fallback
Open

playback: fall back to raw-range mapping for Alsa mixers without dB info#1731
qianc wants to merge 1 commit into
librespot-org:devfrom
qianc:alsa-mixer-no-db-fallback

Conversation

@qianc

@qianc qianc commented Jul 20, 2026

Copy link
Copy Markdown

Some Alsa mixer controls expose no dB information at all — most notably the Alsa pulse plugin's Master, which maps onto the PulseAudio sink volume. AlsaMixer::open() currently fails hard for such controls:

Invalid state { Could not get Alsa softvol dB range. ALSA function 'snd_ctl_get_dB_range' failed with error 'No such file or directory (2)' }

making them unusable as --mixer alsa targets.

What this PR does

When snd_ctl_get_dB_range reports that no dB information is available, fall back to mapping the volume linearly onto the control's raw volume range instead of erroring out:

  • VolumeCtrl is forced to Linear, since without dB information other taper curves cannot be applied faithfully.
  • The softvol antilog compensation is skipped for these controls. It exists to counteract Alsa's internal linear-to-dB conversion in the softvol plugin, which does not happen when the raw volume is applied directly.

For PulseAudio specifically, a linear raw mapping is the desired behavior: PA's raw volume scale is already perceptually (cubically) tapered (e.g. raw 50% = −18.06 dB), so the Connect volume slider tracks the sink volume 1:1.

Motivation / use case

Running librespot with --backend pulseaudio on a headless device (raspotify on a Pi 4 with an IQaudIO DAC), where the DAC's hardware Digital control spans −103.5..0 dB — too wide a range for a usable taper, and separate from the PulseAudio sink volume that other audio sources go through. With this change,

--mixer alsa --alsa-mixer-device pulse --alsa-mixer-control Master

lets Spotify Connect control the PulseAudio sink (master) volume directly, affecting all streams on the sink with a sensible taper.

Testing

  • Verified on a Raspberry Pi 4 (aarch64, Debian bookworm, PulseAudio 16.1) with the setup above: the mixer now opens (log: Alsa mixer control has no dB information ..., falling back to linear mapping on the raw volume range), the Connect volume slider tracks the PulseAudio sink volume (pactl / alsamixer -D pulse Master) ~1:1 in both directions, and playback through the pulseaudio backend is unaffected.
  • Regular hardware mixer controls (with dB info) are unaffected; the fallback only engages on the previous hard-error path.

🤖 Generated with Claude Code

Some Alsa mixer controls expose no dB information at all, most notably
the Alsa pulse plugin's `Master`, which maps onto the PulseAudio sink
volume. AlsaMixer::open() failed with "Could not get Alsa softvol dB
range" for such controls, making them unusable as `--mixer alsa`
targets.

Instead of failing, map the volume linearly onto the control's raw
range and force `VolumeCtrl::Linear`, since without dB information
other taper curves cannot be applied faithfully. The softvol antilog
compensation is also skipped for these controls: it counteracts Alsa's
internal linear-to-dB conversion, which does not happen when the raw
volume is applied directly. For PulseAudio a linear raw mapping is the
desired behavior anyway, as its raw volume scale is already
perceptually (cubically) tapered.

This allows `--mixer alsa --alsa-mixer-device pulse
--alsa-mixer-control Master` to control the PulseAudio sink (master)
volume from Spotify Connect while playing back through the pulseaudio
backend.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@qianc
qianc force-pushed the alsa-mixer-no-db-fallback branch from 4e49aae to 45c0c2b Compare July 20, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant