TASK 24 post-pause polish batch (creator's 8 review issues, 2026-08-15): (1) desktop/game audio volume slider + (2) mute were no-ops — the AudioMixer's gain Func seams defaulted to unity because the VM never passed them; new AudioGainProvider (Services/Audio/) wires MicMuted/MicVolume/GameMuted/GameAudioVolume into the mixer at construction, read live each mix tick, so sliders and mutes are stream-honest; the game bar also scales TRAX locally via new MusicPlayer.LocalGain (UpdateTraxLocalGain on every game volume/mute change + on load) so the creator HEARS the controls work on the music in the headphones. (3) TRAX played once then stopped — OnPlaybackStopped only looped on Position>=Length (unreliable for MediaFoundationReader); now any clean stop rewinds + replays, errors/explicit stops surface via PlaybackEnded; unused using dropped. (4+6) TRAX moved right of Socials in the footer's left cluster (centered under scenes/sources); the mic cluster is now MIC + meter + mute + volume. (5) mic source persists — LayoutStore gains a Settings key/value table (SaveMicSourceName/LoadMicSourceName); the VM saves on pick and restores before the mixer's first Start, so a restart reconnects the same vetted device (green) or reports it missing (yellow). (7) Backdrop's missing trashcan shifted the edit/eye icons right — new HiddenBoolToVisibilityConverter keeps the trash column reserved (Hidden, not Collapsed) so every source row's icons stay in fixed columns. (8) a 1px hairline with top/bottom padding separates scenes from sources in the left panel. Docs in the same commit: ai.md (gains honest + drive TRAX locally, TRAX loops, mic persistence, footer layout), TASKS.md TASK 24, HANDOFF.md shipped state, ViewModels/index.md. ONE integration test: AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback (real mixer + provider gains through the pipe harness: scaled loopback audible, silence after mute). Build 0 warnings, 197 tests passing
This commit is contained in:
@@ -562,7 +562,7 @@ the validator → persisted), compositor bar overlay (top/bottom + above-flash),
|
||||
|
||||
**Goal:** Create/bind broadcasts, monitor YouTube-side stream health — the v3 way.
|
||||
|
||||
### Status: ⏳ Not started — runs AFTER the TASK 9 audio milestone (creator's pick, 2026-08-14); `_currentBroadcastId` is already stashed from TASK 4 for its bind/transition work
|
||||
### Status: ⏳ Not started — runs AFTER the TASK 24 polish batch (creator's pick, 2026-08-15); `_currentBroadcastId` is already stashed from TASK 4 for its bind/transition work
|
||||
|
||||
1. ☐ Broadcast creation — title/description/privacy/scheduledStartTime via API, with the v3 flags above
|
||||
2. ☐ Reusable stream — create once, cache + reuse; bind to broadcast
|
||||
@@ -716,6 +716,50 @@ planning — those are separate line-item tasks. TASK 23 owns billing + unlock +
|
||||
|
||||
---
|
||||
|
||||
## TASK 24 — Post-pause polish batch: the creator's 8 review issues (2026-08-15, shipped)
|
||||
|
||||
**Status: ✅ SHIPPED 2026-08-15 — 197 tests passing, 0 warnings (ONE integration test:
|
||||
`AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback`).**
|
||||
|
||||
The creator reviewed the TASK 9 build and filed 8 issues. All fixed in one branch on `main`:
|
||||
|
||||
1. ✅ **Desktop/game audio volume slider had no effect** (headset OR stream) — the `AudioMixer`'s
|
||||
`micGain`/`loopbackGain` seams defaulted to unity because the VM never passed them; the sliders
|
||||
were decorative. Fixed: new `AudioGainProvider` (`Services/Audio/`) hands `MicMuted`/`MicVolume`/
|
||||
`GameMuted`/`GameAudioVolume` to the mixer at construction, read live each mix tick.
|
||||
2. ✅ **Desktop/game mute button had no effect** — same root cause; `GameMuted` now 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).
|
||||
3. ✅ **TRAX played once then stopped** — `MusicPlayer.OnPlaybackStopped` only looped when
|
||||
`Position >= Length`, unreliable for `MediaFoundationReader`; now any clean stop
|
||||
(`e.Exception == null`) rewinds + replays; only errors/explicit stops surface via `PlaybackEnded`.
|
||||
4. ✅ **TRAX/MIC buttons swapped** — the footer's mic cluster is now MIC + meter + mute + volume; TRAX
|
||||
no longer sits between MIC and the (mic-specific) meter.
|
||||
5. ✅ **Mic source persists across restarts** — `LayoutStore` gained a `Settings` key/value table
|
||||
(`SaveMicSourceName`/`LoadMicSourceName`); the VM saves on pick and restores before the mixer's
|
||||
first `Start`, so a restart reconnects the same already-vetted device (green dot) or reports it
|
||||
missing (yellow) instead of falling back to the default endpoint.
|
||||
6. ✅ **TRAX moved right of Socials** — both centered under the scenes/sources listboxes (footer line
|
||||
1, left cluster).
|
||||
7. ✅ **Backdrop's icons shifted right** — the trash button's `Collapsed` released its column; a new
|
||||
`HiddenBoolToVisibilityConverter` keeps the slot reserved (`Hidden`), so edit/eye stay in their
|
||||
fixed columns for every source row.
|
||||
8. ✅ **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
|
||||
|
||||
1. **The gain seams are the one source of truth** — `AudioGainProvider` is a thin seam (four Funcs)
|
||||
so the mixer contract and the mute⇔zero-volume rule are testable without constructing the VM.
|
||||
2. **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.
|
||||
3. **Persist the DisplayName, not the device ID** — the FriendlyName match was already the mic's
|
||||
identity end-to-end; `Settings` just makes it survive restarts.
|
||||
|
||||
---
|
||||
|
||||
## Backlog (future versions)
|
||||
|
||||
1. v0.2 — Recording to local file (recordings carry the branding flash — see TASK 3 / `ai.md` Monetization)
|
||||
|
||||
Reference in New Issue
Block a user