docs: reflect D2-W2 landing in PLAN.md / COMPLETED.md
Remove D2-W2 from PLAN.md; append completed entry to COMPLETED.md. Track-level auto-tag/park live; item-lane DAW verify deferred to post-D2-W3 (lane minting). D2-W3 left open.
This commit is contained in:
@@ -284,6 +284,51 @@ round-trip of the lane index. REAPER-free, unit-tested; mirror of D1. CONTEXT.md
|
||||
|
||||
---
|
||||
|
||||
## D2-W2 — shell: lane application + new-content detection
|
||||
**Goal:** The view shell applies the planner's managed-lane ops in the DAW and the
|
||||
bank_panel timer detects new content and auto-tags it to the active mode. Resolves
|
||||
the two flagged implementation design points (I_FIXEDLANE reorder/renumber
|
||||
fragility; the auto-tag / manual-lane detection heuristic). See CONTEXT.md
|
||||
§Two-canvas sub-phase (Module architecture — shell; New-content detection).
|
||||
**Verify (in DAW):** Toggling a mode shows + plays only the active mode's managed
|
||||
lane, hides + silences the inactive-mode lane, and **never touches a manual lane**
|
||||
(its `C_LANEPLAYS` stays exactly as the user set it); new content created while a
|
||||
mode is active is tagged to that mode; pre-existing content stays Arrange (no
|
||||
mass-tag on the first poll after open).
|
||||
**Depends on:** D2-W1.
|
||||
|
||||
- [x] Apply managed-lane ops in the view shell (`I_FREEMODE`/`I_FIXEDLANE`/
|
||||
`C_LANEPLAYS`/`B_FIXEDLANE_HIDDEN` via the item/track info setters;
|
||||
`UpdateTimeline()` after `I_FREEMODE`); **managed lanes only, never manual**.
|
||||
Verify every flag name/signature against the SDK header.
|
||||
- [x] New-content detection on the bank_panel timer: diff the live track/item GUID
|
||||
set against the previous poll; tag any GUID new since the last poll to the
|
||||
then-active mode, with a **first-poll-after-open guard** (pre-existing ⇒ Arrange,
|
||||
no mass-tag) and the **manual-lane exemption** (items in a manual lane not tagged).
|
||||
- [x] Resolve the manual-lane detection heuristic (which new items are exempt) and
|
||||
the `I_FIXEDLANE` lane-identity fragility (index survival across lane
|
||||
reorder/renumber/deletion) — the two open design points from CONTEXT.md.
|
||||
- [x] D2-W1 review polish: document the one-managed-lane-per-mode-per-track
|
||||
exclusivity assumption in `laneModeState` (comment / debug-guard); clarify the
|
||||
`serialize()` one-line style note; optional round-trip tests for the
|
||||
last-writer-wins lane-replace contract.
|
||||
|
||||
**Notes/decisions:**
|
||||
- Two new pure modules added with unit tests: `guid_diff` (diffs live track/item
|
||||
GUID sets between polls) and `lane_keys` (manages lane identity via durable
|
||||
`P_LANENAME` rather than the renumber-prone `I_FIXEDLANE` ordinal, reconciled each
|
||||
apply — the resolution to the lane-identity fragility design point). CTest green.
|
||||
- **Manual-lane protection:** a single pure predicate `isOnManualLane` is the
|
||||
exclusive gate; manual lanes — including REAPER's default unnamed fixed lanes —
|
||||
are provably never driven or auto-tagged.
|
||||
- **Track-level auto-tag and park behavior is live.** Item-lane show/hide is
|
||||
correctly structured but is a provable no-op on real projects until D2-W3 mints
|
||||
the `reasampler:`-prefixed named lanes. End-to-end DAW verification of item-lane
|
||||
show/hide is sequenced after D2-W3 for this reason.
|
||||
- W1 review polish was folded in during this wave.
|
||||
|
||||
---
|
||||
|
||||
## Milestone 7 — capture action family
|
||||
**Goal:** Bindable capture actions for master / selected tracks / selected items /
|
||||
razor area, each with wet-dry + tail options. CONTEXT.md §actions, Build order 7.
|
||||
@@ -433,3 +478,38 @@ path.
|
||||
- **Follow-ons noted, not done:** Manual fine-adjust UI; per-project persistence of
|
||||
the toggle (currently extension-session lifetime, resets to None on unload); T2
|
||||
realtime tail.
|
||||
|
||||
---
|
||||
|
||||
## T2 — realtime tail (follow-on to T1)
|
||||
**Goal:** The parallel tail path for the M8 realtime backend, which does not drive
|
||||
`RENDER_*`: record an 8 s-capped tail window past the range end, then **trim in a
|
||||
PCM decay-scan** to the -72 dB point (Manual = record fixed tail, skip the scan).
|
||||
See `docs/product/capture-tail.md` §The realtime path.
|
||||
**Verify (in DAW):** A realtime Auto capture of a decaying source records ≥ the range
|
||||
then trims at the -72 dB decay point (± inherent realtime tolerance); realtime tail is
|
||||
**not** asserted bit-identical (documented non-determinism).
|
||||
**Depends on:** T1, M8.
|
||||
|
||||
- [x] Record `[start, end + clamp(tail, 8 s)]` (extend the record time selection in
|
||||
`capture_realtime.cpp`); Manual skips the scan, Auto proceeds to it.
|
||||
- [x] Pure decay-scan helper alongside `peaks`: `lastFrameAboveThreshold(interleaved,
|
||||
channels, frames, linearThreshold) -> frameIndex` (backward scan, per-frame max-abs
|
||||
across channels, no fold); unit-tested with a synthetic decaying ramp. (Spec §realtime
|
||||
path option (a) — recommended over bending `computeEnvelope`.)
|
||||
- [x] Realtime shell: read the recorded wav PCM into a float buffer, find the trim
|
||||
frame, rewrite the file truncated (new I/O the backend does not do today).
|
||||
|
||||
**Notes/decisions:**
|
||||
- New pure module `wav_trim` (`src/wav_trim.{h,cpp}`): 32-bit-float WAV parse + header-aware
|
||||
truncate plan (RIFF/data size rewrite). Rejects WAVE_FORMAT_EXTENSIBLE with non-float
|
||||
SubFormat GUID. Depends on `peaks` for the `AudioSample` float alias. Unit-tested via a
|
||||
new `wav_trim_tests` CTest target.
|
||||
- `peaks` gained `lastFrameAboveThreshold` (backward PCM scan, per-frame max-abs across
|
||||
channels, no fold) for the Auto decay scan.
|
||||
- **Auto/Manual/Off semantics.** Auto: records `[start, end + 8 s cap]`, scans backward
|
||||
for the last frame above -72 dBFS, truncates the WAV header-aware at that frame. Manual:
|
||||
records `[start, end + fixed tail]`, skips the scan. Off: byte-identical to the pre-tail
|
||||
exact-bounds capture.
|
||||
- **Realtime tail is non-deterministic by design** (inherent to the realtime backend).
|
||||
Bit-identical repeats are not asserted for the realtime path; this is documented, not a defect.
|
||||
|
||||
@@ -65,39 +65,6 @@ landed milestone.
|
||||
|
||||
---
|
||||
|
||||
# Milestone T — capture tail (rider on the offline render path)
|
||||
|
||||
> **Rider, not a new pillar.** Tail preservation wires into the already-shipped
|
||||
> offline `OfflineRenderBackend` (M3/M7) — no new backend, no new render trigger.
|
||||
> It takes a **T** tag (not an M-number) because it is an enhancement to landed
|
||||
> capture, sequenced independently of M8–M11. Authoritative spec:
|
||||
> **`docs/product/capture-tail.md`** (full `RENDER_*` values, the surgical
|
||||
> `RENDER_NORMALIZE`, the realtime parallel path, invariant interactions,
|
||||
> acceptance criteria, DAW-confirm items). Parameters set by Daniel: auto-trim
|
||||
> threshold **-72 dB**, max-tail cap **8 s**. When a point lands, doc-keeper moves
|
||||
> it to `COMPLETED.md`.
|
||||
|
||||
## T2 — realtime tail (follow-on to T1)
|
||||
**Goal:** The parallel tail path for the M8 realtime backend, which does not drive
|
||||
`RENDER_*`: record an 8 s-capped tail window past the range end, then **trim in a
|
||||
PCM decay-scan** to the -72 dB point (Manual = record fixed tail, skip the scan).
|
||||
See `docs/product/capture-tail.md` §The realtime path.
|
||||
**Verify (in DAW):** A realtime Auto capture of a decaying source records ≥ the range
|
||||
then trims at the -72 dB decay point (± inherent realtime tolerance); realtime tail is
|
||||
**not** asserted bit-identical (documented non-determinism).
|
||||
**Depends on:** T1, M8.
|
||||
|
||||
- [ ] Record `[start, end + clamp(tail, 8 s)]` (extend the record time selection in
|
||||
`capture_realtime.cpp`); Manual skips the scan, Auto proceeds to it.
|
||||
- [ ] Pure decay-scan helper alongside `peaks`: `lastFrameAboveThreshold(interleaved,
|
||||
channels, frames, linearThreshold) -> frameIndex` (backward scan, per-frame max-abs
|
||||
across channels, no fold); unit-tested with a synthetic decaying ramp. (Spec §realtime
|
||||
path option (a) — recommended over bending `computeEnvelope`.)
|
||||
- [ ] Realtime shell: read the recorded wav PCM into a float buffer, find the trim
|
||||
frame, rewrite the file truncated (new I/O the backend does not do today).
|
||||
|
||||
---
|
||||
|
||||
# Phase D2 — Two-canvas (item-level mode projection; additive to D1)
|
||||
|
||||
> **Design View sub-phase.** Extends D1's track-level mode projection to **item
|
||||
@@ -111,36 +78,7 @@ then trims at the -72 dB decay point (± inherent realtime tolerance); realtime
|
||||
> spec. Product framing: `docs/product/design-view.md` §Two-canvas direction. When a
|
||||
> point lands, doc-keeper moves it to `COMPLETED.md`.
|
||||
>
|
||||
> **D2-W1 (pure lane extension) has landed** — see `COMPLETED.md`.
|
||||
|
||||
## D2-W2 — shell: lane application + new-content detection
|
||||
**Goal:** The view shell applies the planner's managed-lane ops in the DAW and the
|
||||
bank_panel timer detects new content and auto-tags it to the active mode. Resolves
|
||||
the two flagged implementation design points (I_FIXEDLANE reorder/renumber
|
||||
fragility; the auto-tag / manual-lane detection heuristic). See CONTEXT.md
|
||||
§Two-canvas sub-phase (Module architecture — shell; New-content detection).
|
||||
**Verify (in DAW):** Toggling a mode shows + plays only the active mode's managed
|
||||
lane, hides + silences the inactive-mode lane, and **never touches a manual lane**
|
||||
(its `C_LANEPLAYS` stays exactly as the user set it); new content created while a
|
||||
mode is active is tagged to that mode; pre-existing content stays Arrange (no
|
||||
mass-tag on the first poll after open).
|
||||
**Depends on:** D2-W1.
|
||||
|
||||
- [ ] Apply managed-lane ops in the view shell (`I_FREEMODE`/`I_FIXEDLANE`/
|
||||
`C_LANEPLAYS`/`B_FIXEDLANE_HIDDEN` via the item/track info setters;
|
||||
`UpdateTimeline()` after `I_FREEMODE`); **managed lanes only, never manual**.
|
||||
Verify every flag name/signature against the SDK header.
|
||||
- [ ] New-content detection on the bank_panel timer: diff the live track/item GUID
|
||||
set against the previous poll; tag any GUID new since the last poll to the
|
||||
then-active mode, with a **first-poll-after-open guard** (pre-existing ⇒ Arrange,
|
||||
no mass-tag) and the **manual-lane exemption** (items in a manual lane not tagged).
|
||||
- [ ] Resolve the manual-lane detection heuristic (which new items are exempt) and
|
||||
the `I_FIXEDLANE` lane-identity fragility (index survival across lane
|
||||
reorder/renumber/deletion) — the two open design points from CONTEXT.md.
|
||||
- [ ] D2-W1 review polish: document the one-managed-lane-per-mode-per-track
|
||||
exclusivity assumption in `laneModeState` (comment / debug-guard); clarify the
|
||||
`serialize()` one-line style note; optional round-trip tests for the
|
||||
last-writer-wins lane-replace contract.
|
||||
> **D2-W1 (pure lane extension) and D2-W2 (shell: lane application + new-content detection) have landed** — see `COMPLETED.md`.
|
||||
|
||||
## D2-W3 — actions, persist wiring, panel UI
|
||||
**Goal:** Any new lane/mode-management actions, the persist slice serializing the
|
||||
|
||||
Reference in New Issue
Block a user