Skip to content

Reject capture-tagged boost controls in ALSA volume auto-detection#269

Open
rpardini wants to merge 1 commit into
Sendspin:mainfrom
rpardini:pr/Reject-capture-tagged-boost-controls-in-ALSA-volume-auto-detection
Open

Reject capture-tagged boost controls in ALSA volume auto-detection#269
rpardini wants to merge 1 commit into
Sendspin:mainfrom
rpardini:pr/Reject-capture-tagged-boost-controls-in-ALSA-volume-auto-detection

Conversation

@rpardini

Copy link
Copy Markdown
  • 🍃 _has_playback_volume() accepts a bare volume capability (in addition to pvolume) to support TAS58xx-based amplifier HATs, whose output PGA is playback-only and reports Capabilities: volume rather than pvolume. But ALSA also tags bidirectional analog gain stages with bare volume when a codec driver registers them via SOC_SINGLE_TLV / SOC_DOUBLE_TLV without a "Playback"/"Capture" qualifier in the control name. Those are capture-side gain stages, disconnected from the playback chain, and were being misdetected as playback-volume elements.
  • 🍀 Concrete case: Realtek RT5616 analog codec (FriendlyElec NanoPC-T6, RK3588). Its "ADC Boost", "IN1 Boost", and "IN2 Boost" controls each report bare volume with both a Playback channels: and a Capture channels: line. "ADC Boost" enumerates before the real playback elements in scontrols order, and none of RT5616's genuine playback controls (DAC1/HP/OUT) match _PREFERRED_ELEMENTS (Digital/Master/PCM) — so find_mixer_element() returned "ADC Boost". Hardware-volume mode then silently adjusted an unused capture boost stage with zero audible effect on playback loudness.
  • 🌵 Fix: only accept a bare volume / volume-joined match when the element's sget output has no Capture channels: line, i.e. it is genuinely output-only (the real TAS58xx case). The pvolume branch is an unambiguous true positive and is left unchanged. With this, RT5616 correctly falls back to DAC1 (the first genuine pvolume element in enumeration order). The existing TAS58xx fixtures have no Capture channels: line and remain detected. Assisted-by: Claude Opus 4.8 noreply@anthropic.com

- `_has_playback_volume()` accepts a bare `volume` capability (in addition
  to `pvolume`) to support TAS58xx-based amplifier HATs, whose output PGA
  is playback-only and reports `Capabilities: volume` rather than
  `pvolume`. But ALSA also tags bidirectional analog gain stages with bare
  `volume` when a codec driver registers them via SOC_SINGLE_TLV /
  SOC_DOUBLE_TLV without a "Playback"/"Capture" qualifier in the control
  name. Those are capture-side gain stages, disconnected from the playback
  chain, and were being misdetected as playback-volume elements.
- Concrete case: Realtek RT5616 analog codec (FriendlyElec NanoPC-T6,
  RK3588). Its "ADC Boost", "IN1 Boost", and "IN2 Boost" controls each
  report bare `volume` with *both* a `Playback channels:` and a `Capture
  channels:` line. "ADC Boost" enumerates before the real playback
  elements in `scontrols` order, and none of RT5616's genuine playback
  controls (DAC1/HP/OUT) match `_PREFERRED_ELEMENTS`
  (Digital/Master/PCM) — so `find_mixer_element()` returned "ADC Boost".
  Hardware-volume mode then silently adjusted an unused capture boost
  stage with zero audible effect on playback loudness.
- Fix: only accept a bare `volume` / `volume-joined` match when the
  element's `sget` output has no `Capture channels:` line, i.e. it is
  genuinely output-only (the real TAS58xx case). The `pvolume` branch is
  an unambiguous true positive and is left unchanged. With this, RT5616
  correctly falls back to DAC1 (the first genuine pvolume element in
  enumeration order). The existing TAS58xx fixtures have no `Capture
  channels:` line and remain detected.

Assisted-by: Claude Opus 4.8 <noreply@anthropic.com>
@rpardini rpardini marked this pull request as ready for review June 27, 2026 09:07
Copilot AI review requested due to automatic review settings June 27, 2026 09:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens ALSA mixer auto-detection to avoid misclassifying capture-side “boost” controls (tagged with bare volume) as playback volume controls, while preserving support for TAS58xx-based amplifier HATs that legitimately expose playback volume as volume.

Changes:

  • Update _has_playback_volume() to accept bare volume only when the amixer sget output has no Capture channels: line (keeping pvolume handling unchanged).
  • Add RT5616-focused fixtures and tests to ensure capture-side boost elements are rejected and discovery falls back to a real playback pvolume control (DAC1).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
sendspin/alsa_volume.py Refines playback-volume detection to reject ambiguous volume controls that expose capture channels.
tests/test_alsa_volume.py Adds RT5616 regression coverage ensuring capture-side boosts aren’t selected and find_mixer_element() chooses a real playback element.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants