#686

feat(audio): add auto_disable_steam_audio option to toggle Steam audio devices

Openfunkyotcwants to merge intofrom

Summary

Adds an opt-in Windows configuration setting (auto_disable_steam_audio, default disabled) that automatically manages the visibility of the Steam Streaming Speakers and Steam Streaming Microphone endpoints across streaming sessions:

  • On session start (CONNECT): snapshots the current non-Steam default render and capture endpoints, shows (SetEndpointVisibility(..., TRUE)) both Steam endpoints — enumerating with DEVICE_STATEMASK_ALL so hidden endpoints are found — and points the capture roles at Steam Streaming Microphone. Render default routing stays with normal sink selection (virtual_sink / keep_sink_default / host audio preferences).
  • On terminal session end (DISCONNECT): restores the snapshotted defaults for any role still owned by a Steam endpoint and hides (SetEndpointVisibility(..., FALSE)) both devices, so they neither clutter the Windows device list nor capture audio outside a stream.
  • Resumable app handoff: the toggle ownership flag rides along with the retained audio context, so a reconnect neither re-enables nor re-snapshots, and the flag does not leak into the next session.
  • Crash safety: the hide writes the same visibility marker upstream uses for its fallback, and the marker is cleared once the endpoints are shown again. On startup with the option on, any leftover state is hidden again; with the option off, a marker left behind by a crash re-shows both endpoints (including the microphone, which upstream's marker healing does not cover).
  • WebUI V1 & V2: exposed in both WebUI V2 (src_assets/common/assets/web/) and WebUI V1 (src_assets/common/assets/web-legacy/), allowed as a per-client/per-app override, and documented in docs/configuration.md.

Rebased onto current master

This branch was 495 commits behind and conflicted in src/audio.cpp, src/audio.h, src/platform/common.h, src/platform/windows/audio.cpp and tests/CMakeLists.txt.

master had in the meantime rebuilt the audio subsystem: audio_ctx_t moved to audio_context.h, platf::audio_control_t moved to platform/audio.h, session lifecycle moved into audio::context_manager_t, and the Windows endpoint code was reorganised around audio::role_control_t with crash-safe visibility markers. The merge takes that implementation as the base and reimplements the feature on top of it rather than keeping the old wiring:

  • platf::audio_control_t gains snapshot_default_devices(), enable_steam_audio_devices() and disable_steam_audio_devices() (no-ops / -1 on platforms without Steam devices).
  • audio::context_manager_t owns the toggle state machine and calls those hooks on context start and restore; the auto-toggle flag is injected through context_environment_t so audio_context.cpp still has no config dependency.
  • The Windows implementation reuses the existing role_policy_t bookkeeping, endpoint matching and marker helpers; find_device_id gained a direction + state-mask variant so hidden capture endpoints can be found.
  • The pure policy (src/audio_steam_toggle_policy.*) and the WebUI/config/docs changes are unchanged.

Worth noting for review: master already hides Steam Streaming Speakers temporarily as part of its fallback (hide → pick fallback → show), and never touches the microphone. This change is what leaves the endpoints hidden while idle and routes capture.

Testing

  • tests/unit/test_steam_audio_toggle_policy.cpp — 8 policy cases (disabled config, enable, no-op enable, disconnect without enable, disconnect with/without snapshot, config change while enabled, full round trip).
  • tests/unit/test_audio_context.cpp — 4 new cases driving the real context_manager_t (connect enables + terminal end disables, disabled config touches nothing, retained handoff keeps the devices on without re-snapshotting, failed enable rolls back so no disable is scheduled), alongside the existing role/context/transition suites.
  • tests/audio_snapshot component project and test_component_audio_snapshot both build with -Wall -Wextra -Werror; ctest -R "audio|steam" is green (15/16; the one "Not Run" is test_component_steam_artwork, which was not part of the targeted build).
  • WebUI V1/V2 parity: node --experimental-strip-types scripts/v2-parity.test.ts — 19/19.
  • Full Windows build (MSYS2 UCRT64, gcc 16.2): src/platform/windows/audio.cpp and the whole sunshine target compile.

Not verified locally: an actual streaming session on Windows with the option enabled (sound-panel visibility, capture routing, resumable reconnect) — that still needs a manual pass on a Steam-configured host.