René's URL Explorer Experiment


Title: alsa_volume.py: get_state() reads Capture volume instead of Playback on mixed-channel mixer elements · Issue #236 · Sendspin/sendspin-python-cli · GitHub

Open Graph Title: alsa_volume.py: get_state() reads Capture volume instead of Playback on mixed-channel mixer elements · Issue #236 · Sendspin/sendspin-python-cli

X Title: alsa_volume.py: get_state() reads Capture volume instead of Playback on mixed-channel mixer elements · Issue #236 · Sendspin/sendspin-python-cli

Description: On USB DACs where the ALSA mixer element exposes both Capture and Playback channels (e.g. CX31993+MAX97220 Headset element), AlsaVolumeController.get_state() returns the wrong volume. Root cause: get_state() runs amixer -M -c sget and se...

Open Graph Description: On USB DACs where the ALSA mixer element exposes both Capture and Playback channels (e.g. CX31993+MAX97220 Headset element), AlsaVolumeController.get_state() returns the wrong volume. Root cause: g...

X Description: On USB DACs where the ALSA mixer element exposes both Capture and Playback channels (e.g. CX31993+MAX97220 Headset element), AlsaVolumeController.get_state() returns the wrong volume. Root cause: g...

Opengraph URL: https://github.com/Sendspin/sendspin-python-cli/issues/236

X: @github

direct link

Domain: github.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"alsa_volume.py: get_state() reads Capture volume instead of Playback on mixed-channel mixer elements","articleBody":"  On USB DACs where the ALSA mixer element exposes both Capture and Playback channels (e.g. CX31993+MAX97220 Headset element), AlsaVolumeController.get_state() returns the wrong volume.                                                                 \n                                                                                                                                                                                                                                                          \n  Root cause:\n\n  get_state() runs amixer -M -c \u003ccard> sget \u003celement> and searches the full output with _VOLUME_RE.search(output), which matches the first [XX%] it finds. On the CX31993+MAX97220, the Headset element outputs Capture before Playback:\n\n```\n  Simple mixer control 'Headset',0\n    Capabilities: pvolume cvolume cvolume-joined pswitch pswitch-joined cswitch cswitch-joined\n    Playback channels: Front Left - Front Right\n    Capture channels: Mono\n    Limits: Playback 0 - 148 Capture 0 - 148\n    Mono: Capture 140 [85%] [-4.00dB] [on]\n    Front Left: Playback 75 [20%] [-36.50dB] [off]\n    Front Right: Playback 75 [20%] [-36.50dB] [off]\n```\n\n  The regex matches [85%] (Capture/mic input) instead of [20%] (Playback). The same issue affects the mute switch detection — it reads Capture [on] instead of Playback [off].\n\n  Impact:\n\n  When MA calls _refresh_client_info() on sync group playback start, it reads get_player_volume() from each client. Affected clients report 85% (the Capture value), and MA overwrites their tracked volume. The sync leader (which may use a different\n  DAC without this issue) keeps its correct volume, but all affected followers jump to 85%.\n\n  set_state() is not affected — it correctly targets playback explicitly in the amixer command.\n\n  Test data:\n\n  The amixer -M output above can be used as a test fixture to verify the fix. Expected parse result should be volume=20, muted=True (from the Playback lines), not volume=85, muted=False (from the Capture line).\n\n  Suggested fix:\n\n  Replace get_state() in AlsaVolumeController with:\n\n  async def get_state(self) -> tuple[int, bool]:\n      \"\"\"Read ALSA mixer volume and mute state.\"\"\"\n      proc = await asyncio.create_subprocess_exec(\n          \"amixer\",\n          \"-M\",\n          \"-c\",\n          self._card,\n          \"sget\",\n          self._element,\n          stdout=asyncio.subprocess.PIPE,\n          stderr=asyncio.subprocess.PIPE,\n      )\n      stdout, stderr = await proc.communicate()\n      if proc.returncode != 0:\n          raise RuntimeError(\n              f\"amixer sget failed (exit {proc.returncode}): \"\n              f\"{stderr.decode().strip() if stderr else '(empty)'}\"\n          )\n\n      output = stdout.decode()\n\n      # Filter for Playback lines to avoid matching Capture channel values\n      # on mixer elements that expose both (e.g. CX31993+MAX97220 Headset).\n      # Falls back to full output for elements without separate Playback lines.\n      playback_lines = [l for l in output.splitlines() if \"Playback\" in l and \"%\" in l]\n      vol_match = (\n          _VOLUME_RE.search(playback_lines[0])\n          if playback_lines\n          else _VOLUME_RE.search(output)\n      )\n\n      playback_switch_lines = [l for l in output.splitlines() if \"Playback\" in l and \"[o\" in l]\n      switch_match = (\n          _SWITCH_RE.search(playback_switch_lines[0])\n          if playback_switch_lines\n          else _SWITCH_RE.search(output)\n      )\n\n      if vol_match is None:\n          raise RuntimeError(f\"Could not parse volume from amixer output: {output!r}\")\n\n      volume = int(vol_match.group(1))\n      muted = switch_match.group(1) == \"off\" if switch_match else False\n      return volume, muted\n\n  Affected hardware: Any ALSA mixer element with both Capture and Playback channels where Capture appears first in amixer output. Confirmed on CX31993+MAX97220 USB DAC (Headset element).","author":{"url":"https://github.com/1liminal1","@type":"Person","name":"1liminal1"},"datePublished":"2026-04-28T02:02:38Z","url":"https://github.com/Sendspin/sendspin-python-cli/issues/236"}

react-profiling0
react-import-mapreact,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@d5750093facf
route-pattern/_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format)
route-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:9a2a4919-eb5b-afb8-97ee-5925d13b2921
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-id8038:A2B38:F0528F:138FC17:6AED575C
html-safe-noncef4121d559e83613f65d0502e712bdee8fba35132282731ff62352fc0b868bb52
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4MDM4OkEyQjM4OkYwNTI4RjoxMzhGQzE3OjZBRUQ1NzVDIiwidmlzaXRvcl9pZCI6Ijg2MjgzODA4ODA4NDA1MTgwNSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmac028943ed482855b7e61eded66ae32e87b04a56995b51cd6c47b3b6fe57d68ae3
hovercard-subject-tagissue:4340045822
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/Sendspin/sendspin-python-cli/236/issue_layout
twitter:imagehttps://opengraph.githubassets.com/e6026fdc50dc1eeb67aaab86f5e3abe3c31074836ad75a97623dacdb66d6e5bb/Sendspin/sendspin-python-cli/issues/236
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/e6026fdc50dc1eeb67aaab86f5e3abe3c31074836ad75a97623dacdb66d6e5bb/Sendspin/sendspin-python-cli/issues/236
og:image:altOn USB DACs where the ALSA mixer element exposes both Capture and Playback channels (e.g. CX31993+MAX97220 Headset element), AlsaVolumeController.get_state() returns the wrong volume. Root cause: g...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:username1liminal1
hostnamegithub.com
expected-hostnamegithub.com
None56fb42677ae87ed3e64410323d67980aa65d0485568a7858f874e7edfc6d1c11
turbo-cache-controlno-preview
go-importgithub.com/Sendspin/sendspin-python-cli git https://github.com/Sendspin/sendspin-python-cli.git
octolytics-dimension-user_id214994244
octolytics-dimension-user_loginSendspin
octolytics-dimension-repository_id1109978202
octolytics-dimension-repository_nwoSendspin/sendspin-python-cli
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id1109978202
octolytics-dimension-repository_network_root_nwoSendspin/sendspin-python-cli
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release9c9a37e2423ed382cf39f70b5aa4b4858b40a3b0
ui-targetfull
theme-color#1e2327
color-schemelight dark
react-app-nameissues

Links:

Skip to contenthttps://github.com/Sendspin/sendspin-python-cli/issues/236#start-of-content
Reloadhttps://github.com/Sendspin/sendspin-python-cli/issues/236
Reloadhttps://github.com/Sendspin/sendspin-python-cli/issues/236
Reloadhttps://github.com/Sendspin/sendspin-python-cli/issues/236
https://github.com/Sendspin/sendspin-python-cli
New issuehttps://github.com/login?return_to=https://github.com/Sendspin/sendspin-python-cli/issues/236
New issuehttps://github.com/login?return_to=https://github.com/Sendspin/sendspin-python-cli/issues/236
#237https://github.com/Sendspin/sendspin-python-cli/pull/237
alsa_volume.py: get_state() reads Capture volume instead of Playback on mixed-channel mixer elementshttps://github.com/Sendspin/sendspin-python-cli/issues/236#top
#237https://github.com/Sendspin/sendspin-python-cli/pull/237
https://github.com/balloob
https://github.com/copilot-swe-agent
https://github.com/1liminal1
1liminal1https://github.com/1liminal1
on Apr 28, 2026https://github.com/Sendspin/sendspin-python-cli/issues/236#issue-4340045822
balloobhttps://github.com/balloob
Copilothttps://github.com/apps/copilot-swe-agent
balloobhttps://github.com/balloob
on Apr 28, 2026https://github.com/Sendspin/sendspin-python-cli/issues/236#event-24949513618
Copilothttps://github.com/apps/copilot-swe-agent
Scope ALSA `get_state()` to Playback channels on mixed Capture/Playback controls #237https://github.com/Sendspin/sendspin-python-cli/pull/237
on Apr 28, 2026https://github.com/Sendspin/sendspin-python-cli/issues/236#event-24949521776
balloobhttps://github.com/balloob
completedhttps://github.com/Sendspin/sendspin-python-cli/issues?q=is%3Aissue%20state%3Aclosed%20archived%3Afalse%20reason%3Acompleted
#237https://github.com/Sendspin/sendspin-python-cli/pull/237
on Apr 28, 2026https://github.com/Sendspin/sendspin-python-cli/issues/236#event-24949933312
Sign up for freehttps://github.com/signup?return_to=https://github.com/Sendspin/sendspin-python-cli/issues/236
Sign in to commenthttps://github.com/login?return_to=https://github.com/Sendspin/sendspin-python-cli/issues/236
balloobhttps://github.com/balloob
Copilothttps://github.com/apps/copilot-swe-agent
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.