68 lines
4.4 KiB
Markdown
68 lines
4.4 KiB
Markdown
# HANDOFF — session state
|
|
|
|
> Current operational state, read right after `TASKS.md`. Trust this file as the
|
|
> truth of what is in flight — do not re-derive from git/fs unless it points at
|
|
> a problem. Conventions: [`schema.md`](schema.md). Rewrite this file at session
|
|
> end, compaction, or any interruption.
|
|
|
|
## Session state (last updated: 2026-08-13)
|
|
|
|
- **Branch:** `main`. The **game audio bar + mic status dot + always-on capture**
|
|
work is **uncommitted** (see list below). The last committed+pushed baseline is
|
|
`ea250c0` (social bar click-toggle).
|
|
- **This session (audio UX follow-up):** per the creator's requests —
|
|
1. The MIC label is now a **button with a status dot** (`Models/MicStatus`:
|
|
green = capturing, yellow = requested mic problem, red = no device).
|
|
2. **Mic capture runs for the app's lifetime** (started at startup via
|
|
`StartMicCaptureAsync`, disposed in `Shutdown`; `BeginGoLive`/`StopStream`
|
|
no longer start/stop the mixer) so both meters preview live.
|
|
3. A **game audio bar** (desktop/game — meter + mute + volume, mirror of the
|
|
mic bar) sits centered beneath the preview and appears only while a
|
|
**full-screen game is producing sound** (decision: fullscreen + loopback
|
|
sound; **silence never hides an active bar** — the creator's final rule).
|
|
Show after ~500ms of fullscreen+sound, hide ~1s after leaving fullscreen.
|
|
- **Uncommitted files:** `MainWindow.xaml`/`.cs`, `ViewModels/MainViewModel.cs`,
|
|
`Services/Audio/{IAudioSource,WasapiMicAudioSource,WasapiLoopbackAudioSource,AudioMixer}.cs`,
|
|
new `Models/MicStatus.cs`, new `Services/{IGameAudioDetector,GameAudioHysteresis,GameAudioDetector}.cs`,
|
|
`ytLive.Tests/AudioMixerTests.cs`, new `GameAudioHysteresisTests.cs` +
|
|
`GameAudioDetectorTests.cs`, memory docs (TASKS.md, ai.md, Services/index.md,
|
|
ViewModels/index.md, Models/index.md, HANDOFF).
|
|
- **Verified:** build 0 warnings, 0 errors; **167 tests passing** (full suite,
|
|
after the final rebuild).
|
|
- **Landmines:**
|
|
- Never set a local `Canvas.SetTop` on the social bar — a local value permanently
|
|
overrides `{Binding SocialBarTop}` (the `ClearValue` lesson from 5.5).
|
|
- `AudioMixer` meter `Push` is unconditional **by design now**: `OnMicSample`/
|
|
`OnLoopbackSample` compute the level first, then raise the event — a
|
|
`?.Invoke(meter.Push(...))` short-circuit skipped the meter update when
|
|
nothing was subscribed (found by `RestartMic_ResetsLevel`, fixed).
|
|
- `MicConnected` comes from the source `Started` event, raised right after
|
|
`StartRecording()` succeeds — tests must `MarkStarted()` the fake source
|
|
before asserting connection state.
|
|
- Zero mic devices at startup = red dot AND the mixer is never started, so
|
|
loopback + the game bar can't run either (no capture at all) — acceptable.
|
|
- The game detector is polled on the UI thread via a 250ms `DispatcherTimer`;
|
|
`OnGameAudioPollTick` wraps `Poll()` in try/catch + `AppLog`.
|
|
- The pump reads the active scene on a background thread while the UI can still
|
|
edit it — a concurrent-mutation exception is contained (logged + `Failed` +
|
|
the pump stops), not a crash.
|
|
- `StopAsync` must stop the encoder (closes stdin) **before** awaiting the pump
|
|
loop — closing stdin unblocks a write stuck on pipe backpressure; the reverse
|
|
order deadlocks.
|
|
- Tests never instantiate `MainViewModel` directly except the round-clip
|
|
integration test (a real `MainWindow`), which never goes live — keep it that way.
|
|
- Sandbox can't reach outbound HTTPS — `HttpSocialValidator` stub-handler tests
|
|
only, never the real instance.
|
|
- **Next step:** commit + push the audio UX follow-up (the whole uncommitted set
|
|
above in one commit). Then TASK 4 ship step 6 — health stats: bind
|
|
`FramePump.HealthUpdated` (bitrate/FPS/duration) into the bottom bar. Nothing
|
|
else queued — do not expand the task queue on your own. Optional, not queued:
|
|
rewriting the healed entry's `ProfileUrl` to
|
|
`https://mastodon.llamachile.tube/@gramps` (user must say the word).
|
|
|
|
- **Secret/DB/port facts live:** OAuth client id/secret in `Helpers/OAuthCredentials.cs`;
|
|
OAuth session token in `Helpers/TokenStore.cs` (DPAPI → `%APPDATA%\ytLlive\ytLlive.auth`);
|
|
layout DB `%APPDATA%\ytLlive\ytLlive.db` (schema v8; `SocialEntry.Software`
|
|
column is a column-presence migration like the others, no version bump); OAuth callback
|
|
`http://localhost:8765/oauth2/callback`; crash log `%APPDATA%\ytLlive\startup.log`.
|