fix(viewer): route audio_output to a live PulseAudio sink on x86/arm64#3209
Open
vpetersson wants to merge 3 commits into
Open
fix(viewer): route audio_output to a live PulseAudio sink on x86/arm64#3209vpetersson wants to merge 3 commits into
vpetersson wants to merge 3 commits into
Conversation
On x86 and arm64 SBCs the HDMI / 3.5mm output selector was a no-op: every setting collapsed to QMediaDevices::defaultAudioOutput() (the PulseAudio default sink), so audio followed whatever sink pulse defaulted to rather than the port the user picked (forum #6749 — Dell Latitude, HDMI selected but sound only on the internal speakers). Discover sinks at runtime via `pactl list short sinks` and map the setting onto the matching sink by its standardised profile token (hdmi-* / analog-*), returning the sink name for VideoView::resolveAlsaDevice to match. Fall back to `default` when pulse is unreachable or no sink matches, preserving prior behaviour. Raspberry Pi paths (fixed vc4hdmi* / Headphones card names) are unchanged. Validated across the full testbed fleet: x86 and Rock Pi 4 route hdmi/local to the correct sink (Rock Pi `local` moved audio off the HDMI default sink to the analog sink, verified RUNNING); Pi 2/3/4/5 device resolution unchanged. Fixes #3208 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes the viewer’s audio_output routing on non-Raspberry-Pi devices (x86 + generic arm64) by resolving the configured output to an actual, currently-available PulseAudio sink instead of always following PulseAudio’s default sink.
Changes:
- Added runtime PulseAudio sink discovery (
pactl list short sinks) and selection logic to mapaudio_output(hdmi/local) to a matching sink on x86/arm64, with a safe fallback todefault. - Refactored Raspberry Pi ALSA-device resolution into a dedicated
_pi_alsa_device()path while keeping Pi behavior unchanged (including the existing Pi 5 “local → HDMI” behavior). - Expanded unit tests to cover sink selection,
pactlparsing, x86/arm64 routing, and fallback behavior (issue #3208).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/anthias_viewer/media_player.py |
Implements PulseAudio sink listing/selection for x86/arm64 while preserving Pi-specific ALSA mapping and adding transition-based logging. |
tests/test_media_player.py |
Adds unit coverage for sink selection, pactl parsing, and the new arm64/x86 routing + fallback paths. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Cache `pactl list short sinks` for a short TTL so a fast-rotating playlist doesn't spawn a subprocess on every play()/set_asset(); the window is short enough to pick up an HDMI hotplug within seconds, and only successful lists are cached. - Note in `_pi_alsa_device` that the Pi 5 `local` selection resolves to the connected HDMI device (no analog jack; the UI hides 3.5mm). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
_select_pulse_sink assigned a 4-tuple then a 3-tuple to `keywords`; mypy inferred the fixed-length type from the first branch and rejected the second. Annotate as `tuple[str, ...]`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Problem
On x86 and arm64 (non-Raspberry-Pi) boards, the HDMI / 3.5mm audio output selector in Settings is a no-op.
get_alsa_audio_device()collapsed every setting toQMediaDevices::defaultAudioOutput()(the PulseAudio default sink), so playback audio followed whatever sink pulse defaulted to instead of the port the user chose.Reported on the forum (Dell Latitude E5570, Debian 13): HDMI selected in the UI but sound only played through the internal analog speakers; selecting 3.5mm changed nothing.
Root cause, in
src/anthias_viewer/media_player.py:defaultbefore even readingsettings['audio_output'].hdmi→default;local→plughw:CARD=Headphones(a Pi-only card that matches nothing on x86, so it also fell back to the default sink).Whether HDMI or analog happened to work was pure luck of which sink PulseAudio defaulted to.
Fix
On non-Pi (Qt 6 + PulseAudio) boards, discover sinks at runtime with
pactl list short sinksand map the setting onto the matching sink by its standardised profile token in the sink name:hdmi→ the HDMI sink (*.hdmi-*/iec958/displayport)local→ the analog / headphone sink (*.analog-*/headphone/speaker)The bare sink name is returned;
VideoView::resolveAlsaDevicealready matches it againstQAudioDevice::id()(no C++ change needed). Falls back todefaultwhen pulse is unreachable or no matching sink exists, preserving prior behaviour. Raspberry Pi paths (fixedvc4hdmi*/Headphonescard names) are unchanged.The profile token — not the card name — is the discriminator: on the reporter's Dell both an analog and an HDMI sink live on the same HDA card, so card name alone can't tell them apart.
Testing
pactlparsing, and the arm64/x86 routing paths. Full suite green;ruff check+ruff format --checkclean.localroutes to the analog sink live; HDMI sink only exists with a display attached (headless testbed correctly falls back to default).localmoved audio to the analog sink (verifiedRUNNING), proving the runtime sink actually overrides the default end-to-end;hdmiroutes to the HDMI sink.Fixes #3208