diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index d5a3c8b..50efbc7 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -15,7 +15,7 @@ Design reference: [`specs/2026-06-04-human-experience-filter-design.md`](./super |---|---------------------------------|---------------|----------| | 1 | Catalog & Selection Core | ✅ Done | everything | | 2 | Ingest & Tagging / Review tools | ✅ Done | a real library | -| 3 | Player Runtime (Pi) | ⏳ Next | the room runs | +| 3 | Player Runtime (Pi) | ⏳ In progress | the room runs | | 4 | Arduino Firmware (control panel)| ◻ Not started | real knobs | | 5 | ~~Procedural Side Walls~~ | ❌ Dropped | — (superseded) | @@ -95,29 +95,60 @@ was `validate_catalog` + `index_by_id`. --- -## 3. Player Runtime (Pi) ⏳ (next) +## 3. Player Runtime (Pi) ⏳ (in progress) -**Goal:** the thing that makes the room run — read the controls, pick media, play -it across the single panoramic projector. +**Goal:** the thing that makes the room run — read the controls, **alter** the +neutral base footage toward the knob state, and play it across the single +panoramic projector. Per the machine-altered-perception revision the knobs no +longer *select* a pre-tagged clip; they drive an **alteration engine** (design +§4/§5) over a small neutral base library. -**Delivers (`player/`):** +**Slice 1 — alteration engine + player core (pure logic) ✅ Done.** Merged to +`main` (session 0006); 56 tests. The new `player/` package, with all I/O +(video/audio/serial) behind injected interfaces: -- Read the five control values from the Arduino over USB serial. -- Call `hef.selection.select()` on each change; loop the chosen 5–15 min segment - until the knobs move; **crossfade** on change. -- `None` mode → fade to black + silence. -- Drive the **single panoramic projector** spanning the three walls with the real - selected video (no primary/side split; no side-wall feed — sub-project 5 dropped). +- `player/controls.py` — `Controls`, the full panel state (7-way content dial + + 4 experience knobs + volume + brightness); the serial-contract data shape + shared with sub-project 4. +- `player/content.py` — `resolve_content`, the §6 7-way dial → (audio source, + video on/off) table. +- `player/alteration.py` — `plan_alteration`, knob vector → `RenderPlan` + (mood `ColorGrade` with center=identity §5; Left `AnalyticalOverlay`; Right + `Restyle`), encoding the §4.2 layering rule (substrate vs overlay; Left & Right + stack). +- `player/state.py` — `Player`, the state machine that diffs successive controls + into transitions (`FADE_TO_BLACK`/`FADE_FROM_BLACK` on video on/off, + `CROSSFADE` on clip/restyle-variant swap, `LIVE_UPDATE` for the continuous + grade/overlay/level ops per §4.3, `NONE` when unchanged). -**Depends on:** sub-project 1 (`select`); a populated catalog from sub-project 2 -to be meaningful, but can be developed against a hand-authored catalog and a -**keyboard/serial stand-in** before firmware exists. -**Done when:** given a catalog and a stream of control values, it plays the -correct segment, loops, crossfades, and goes dark on `None` — testable with the -serial input mocked. -**Hardware:** Raspberry Pi 5 (holds the drive + catalog). +Plan: [`2026-06-05-player-alteration-core.md`](./superpowers/plans/2026-06-05-player-alteration-core.md). + +**Remaining slices (not started):** + +- **Runtime renderer** — drive the single panoramic projector via mpv/ffmpeg; + GPU shaders for the luma-keyed mood grade + analytical-overlay compositing; + realize crossfade/fade timing and the 5–15 min loop. (Open decision: player + stack — mpv via IPC vs. ffmpeg vs. custom.) +- **Serial input** — real USB-serial reader on the Pi + the **3⇄4 framing + contract** with the firmware (the keyboard/serial stand-in already works via a + `Controls` stream). +- **White-noise generation** — runtime white/pink noise for that content position. +- **Offline v2v variant pipeline** — author the pre-baked Right restyle variants + (the only paid AI step, design §9) + the multilingual label/string tables + TTS. +- **Catalog model changes** — audio *source* + "neutral base" vs "altered + variant" flag (sub-project 2 territory, design §13). + +**Depends on:** sub-project 1 (`Coordinate`); a neutral base library from +sub-project 2 to be meaningful, but developable against a hand-authored library +and a **keyboard/serial stand-in** before firmware exists. +**Done when:** given a base library and a stream of control values, it plays the +correct altered segment, loops, crossfades, and goes dark on `Off` — the +decision logic is covered (slice 1, serial mocked); the renderer realizes it. +**Hardware:** Raspberry Pi 5 (holds the drive + base library + variants). **Open decisions:** player stack (mpv via IPC vs. ffmpeg vs. custom); whether the -player hard-restricts to `approved` records. +player hard-restricts to `approved` records (the `approved_only` flag is plumbed +but inert until backed by a real catalog); knob→strength calibration (the §3 vs +§4.2/§5 reconciliation — see the slice-1 plan / session 0006 transcript). ---