87509bcf99
TASKS.md is now the index (status table, open items, research pointer). 33 files: 32 task files + 1 research facts file. The full take-saga narrative and all design decisions are preserved verbatim; the catalog makes the queue readable without opening every task body. Schema and AGENTS.md updated to reflect the new layout.
3.3 KiB
3.3 KiB
TASK 11 — Post-pause polish batch: the creator's 8 review issues (2026-08-15, shipped)
Catalog:
TASKS.md— status and requirements live here.
Status: ✅ SHIPPED 2026-08-15 — 197 tests passing, 0 warnings (ONE integration test:
AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback).
The creator reviewed the TASK 8 build and filed 8 issues. All fixed in one branch on main:
- ✅ Desktop/game audio volume slider had no effect (headset OR stream) — the
AudioMixer'smicGain/loopbackGainseams defaulted to unity because the VM never passed them; the sliders were decorative. Fixed: newAudioGainProvider(Services/Audio/) handsMicMuted/MicVolume/GameMuted/GameAudioVolumeto the mixer at construction, read live each mix tick. - ✅ Desktop/game mute button had no effect — same root cause;
GameMutednow zeroes the loopback on the stream. Locally,MusicPlayer.LocalGain(new) is scaled by the game bar on every volume/mute change + on TRAX load, so the creator hears the control work on the music (the track rides the loopback channel, so it ducks locally exactly as it does on stream). - ✅ TRAX played once then stopped —
MusicPlayer.OnPlaybackStoppedonly looped whenPosition >= Length, unreliable forMediaFoundationReader; now any clean stop (e.Exception == null) rewinds + replays; only errors/explicit stops surface viaPlaybackEnded. - ✅ TRAX/MIC buttons swapped — TRAX no longer sits between MIC and the (mic-specific) meter; the footer's mic cluster is MIC + meter + mute + volume.
- ✅ Mic source persists across restarts —
LayoutStoregained aSettingskey/value table (SaveMicSourceName/LoadMicSourceName); the VM saves on pick and restores before the mixer's firstStart, so a restart reconnects the same already-vetted device (green dot) or reports it missing (yellow) instead of falling back to the default endpoint. - ✅ TRAX moved into the game audio bar — left of the "Desktop Audio" label in the preview overlay (the creator's follow-up pick), no longer in the footer; its tooltip teaches the clicks ("left-click pauses/plays, right-click chooses a track").
- ✅ Backdrop's icons shifted right — the trash button's
Collapsedreleased its column; a newHiddenBoolToVisibilityConverterkeeps the slot reserved (Hidden), so edit/eye stay in their fixed columns for every source row. - ✅ No separation between scenes and sources — a 1px hairline with top/bottom padding now sits between the two listboxes in the left panel.
Design decisions
- The gain seams are the one source of truth —
AudioGainProvideris a thin seam (four Funcs) so the mixer contract and the mute⇔zero-volume rule are testable without constructing the VM. - Stream-honest AND locally audible — the game bar's controls now do two things: scale the loopback on the stream and scale the music in the headphones. Native game audio is untouched (system output, OBS-style non-monitored); an OBS-style monitor loop is out of scope.
- Persist the DisplayName, not the device ID — the FriendlyName match was already the mic's
identity end-to-end;
Settingsjust makes it survive restarts.