Repository navigation
fix(audio): a failed output switch no longer rolls back the session - #109
Merged
Merged
Conversation
With SoundVolumeView a failed /SetDefault was ignored and the session went on. The Core Audio backend throws instead, and ConsoleEngine.Start does not catch it: an error in SetOutput made MainViewModel roll the whole start back (Engine.Stop) after the screens had already been switched. The two polling paths (auto-switch and pending target) called SetOutput unguarded too. TrySetOutput logs the error in Portuguese and lets the session continue; the switch is only recorded (AudioDeviceId, LastAudioSwitchName) when it worked. The session menu's manual output choice still reports its error to the user. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Important
The fixed-output failure path leaves session audio state inconsistent with the actual output, so the session menu can report and control the wrong device.
Reviewed changes The review covers the best-effort output-switch handling and its manual test checklist.
- Best-effort switching
ConsoleEnginelogs failed startup and polling switches, continues the session, and completes audio watching. - Manual verification
docs/TESTING.mdadds a checklist item for a failed switch during a session start.
GPT Luna | 𝕏
| if (target is { IsActive: true }) | ||
| { | ||
| Audio.SetOutput(config.AudioDeviceId); | ||
| TrySetOutput(config.AudioDeviceId); |
Contributor
There was a problem hiding this comment.
If this switch fails, State.AudioDeviceId still contains the configured target set earlier in Start, but the OS default remains on the previous output. The session menu treats this field as the current output for its label, selection, and volume/mute actions, so it can show and control the wrong device.
Technical details
# Keep session audio state accurate after a failed startup switch
## Affected sites
- `src/ConsoleMode/Services/ConsoleEngine.cs:45` — initializes `State.AudioDeviceId` to the configured target before the switch attempt.
- `src/ConsoleMode/Services/ConsoleEngine.cs:141` — now ignores the failed `TrySetOutput` result and continues with that target in state.
- `src/ConsoleMode/ViewModels/MainViewModel.SessionMenu.cs:131-145` — treats `State.AudioDeviceId` as the current output for the menu label, volume, and mute.
- `src/ConsoleMode/ViewModels/MainViewModel.SessionMenu.cs:202-204` — marks that target as selected in the output picker.
## Required outcome
- After a failed startup switch, the session menu's displayed/selected output and volume/mute operations must correspond to the actual current output, rather than the requested target that failed.
lippdev
added a commit
to nextestudios/consolemode
that referenced
this pull request
Sep 30, 2026
The fixes merged since 1.6.0-alpha.2 were missing from CHANGELOG.md and CHANGELOG.en-US.md: the failed audio output switch (lippdev#109) and the primary display from Windows' own flag (lippdev#110), plus the rtss-cli-only package. The Playnite item now points at the PR number (lippdev#83) instead of the issue. docs/TESTING.md gets the two manual checks those fixes need (cloned screens and a slow-starting Playnite). Co-Authored-By: Claude Sonnet 5.5 <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
With SoundVolumeView (1.5) a failed
/SetDefaultwas ignored: the session went on without the audio switch. The Core Audio backend (1.6 alpha, #91) throws instead (Marshal.ThrowExceptionForHR), andConsoleEngine.Startdoesn't catch it. An error inAudio.SetOutputtherefore madeMainViewModelroll the whole start back withEngine.Stop(), after the desk screens had already been switched. The two polling paths (UpdateAutoSwitch,UpdatePendingTarget) calledSetOutputunguarded too (the loop catches and logs, but then never completes the audio watch and retries forever).Fix
ConsoleEngine.TrySetOutputlogsÁudio: não foi possível trocar para …and lets the session continue. The switch is only recorded (AudioDeviceId,LastAudioSwitchName) when it worked, and the audio watch is completed either way (same as 1.5). The session menu's manual output choice is untouched: it is a user action and still shows its error.What I checked on a real machine
Driving the shipped
ConsoleMode.dllby reflection against SoundVolumeView as reference:/ShowDisabledDevices 1 /ShowUnpluggedDevices 1, as 1.5 called it) is identical: same 4 outputs, same names, sameFriendlyIds, same default, volume 67 vs 66.9 %.IPolicyConfig.SetDefaultEndpointandSetEndpointVisibilityreturnS_OK(on the endpoints that were already default / visible, so nothing changed).So the happy path works; this PR is about not turning a rare COM error into an aborted session.
Tests
ConsoleEngineneeds Win32, so there is no unit test; added a manual item todocs/TESTING.md. Build OK, 144 tests pass. No changelog entry: nothing user-visible changes when audio works.🤖 Generated with Claude Code