Skip to content

Fix ALSA hardware volume detection for CARD=<name> and bare sysdefault devices - #279

Merged
OnFreund merged 1 commit into
mainfrom
claude/jolly-taussig-3e6f5a
Sep 17, 2026
Merged

OnFreund merged 1 commit into
mainfrom
claude/jolly-taussig-3e6f5a

Conversation

@OnFreund

@OnFreund OnFreund commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • parse_alsa_card() in sendspin/alsa_volume.py only recognized PortAudio's numeric hw:N,M card annotation. Devices selected via --audio-device using the plughw:CARD=<name>,DEV=<n> / dmix:CARD=<name>,DEV=<n> convention — often needed because raw hw:N,M bypasses ALSA's plug/dmix conversion layer and fails to open for playback at all — weren't recognized, so hardware volume control silently fell back to software volume even when a real mixer element existed.
  • parse_alsa_card() now also extracts the card's string name from a CARD=<name> pattern, and find_mixer_element()/AlsaVolumeController/async_check_alsa_available() were generalized to accept int | str card identifiers. Confirmed via the amixer source that -c resolves either a numeric index or a card name through snd_card_get_index() internally, so passing the name straight through works.
  • Also handles PortAudio's bare sysdefault/default device enumeration (no card info at all in the name), which turned up in real-world testing on an ODROID-N2. Since the string carries no card identity, this cross-references aplay -L's fully-qualified hints (e.g. sysdefault:CARD=ODROIDN2) to recover the card, and only resolves when exactly one hint matches — on a system with multiple cards each exposing their own default hint, it backs off to software volume rather than guessing which one is meant.

Test plan

  • uv run ruff check --fix .
  • uv run ruff format .
  • uv run mypy sendspin — no issues
  • uv run pytest tests/ -q — 150 passed (11 new tests covering CARD=<name> parsing, the plughw/dmix discovery flow, and the bare-sysdefault resolution including the ambiguous multi-card and no-hint cases)

🤖 Generated with Claude Code

parse_alsa_card() only matched PortAudio's hw:N,M numeric card form,
so devices selected via --audio-device using the plughw:/dmix:
CARD=<name> convention (needed to reach ALSA's plug/dmix conversion
layer, since raw hw:N,M often fails to open for playback) silently
fell back to software volume even when a real hardware mixer existed.

Also handle PortAudio's bare "sysdefault"/"default" enumeration, which
carries no card info at all: cross-reference aplay -L's fully-qualified
hints (e.g. sysdefault:CARD=vc4hdmi) to recover the card, backing off
to software volume only when the match is ambiguous (multiple cards
each exposing their own default hint) rather than guessing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@OnFreund
OnFreund requested a review from balloob September 12, 2026 08:38
@OnFreund
OnFreund merged commit 92934c1 into main Sep 17, 2026
2 checks passed
@OnFreund
OnFreund deleted the claude/jolly-taussig-3e6f5a branch September 17, 2026 08:44
@maximmaxim345 maximmaxim345 added the bugfix Fixes a bug label Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants