fixed (bug) Audio device switch killing playback via stale SDL device id
build-dev / nix-build (push) Successful in 45s

recreateMixerOnDevice destroyed the active mixer before opening the
replacement. MIX_DestroyMixer quits SDL audio at refcount 0, tearing down
the device registry and renumbering device ids, so the cached id being
reopened went stale ('Invalid audio device instance ID') and the app went
permanently mute. Open the new mixer first while the old device is alive,
then tear the old one down; a failed switch now keeps the current output
playing instead of killing audio. Also log SDL_GetError() on open failure.
This commit is contained in:
NeilClack
2026-08-28 16:18:36 -05:00
parent d60a8bd7fb
commit 42b915bd25
3 changed files with 53 additions and 23 deletions
+5 -2
View File
@@ -111,8 +111,11 @@ private:
// Recreates the mixer on the given playback device id (0 = system default).
// Called with mutex_ held. Preserves playback state: whichever track was
// playing on the active slot is reloaded and resumed at full gain, an
// in-progress fade is restarted. Returns false on failure (previous mixer is
// left destroyed but the app remains safe to keep running muted).
// in-progress fade is restarted. The replacement mixer is opened before the
// current one is destroyed so SDL's device ids stay valid (destroy-first
// quits the whole audio subsystem and orphans the id being opened).
// Returns false on failure without touching the current mixer, so the
// existing output keeps playing.
bool recreateMixerOnDevice(SDL_AudioDeviceID targetId);
config::ConfigManager* configManager_ = nullptr;