docs: 1.0 documentation restructure
Split root CLAUDE.md into 19 per-directory files scoped to their source area. Roll v0 history into docs/ARCHIVE.md; retire CONTEXT.md, CONTEXT-ARCHIVE.md, PLAN.md, COMPLETED.md. Move plan docs under docs/. Rescue 9 live deferrals into docs/TODO.md.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
# src/shell/capture — REAPER-facing capture backends and action bodies
|
||||
|
||||
## Scope
|
||||
|
||||
Everything that turns a capture request into a rendered file + populated `Sample`,
|
||||
plus the action bodies that drive capture from REAPER's UI/action list: the two
|
||||
concrete capture backends (offline render, realtime record), scope/source
|
||||
resolution, the realtime in-flight state machine, single- and batch-capture
|
||||
orchestration, insert-to-timeline, provenance stamping, and the shared
|
||||
`MediaItem*`/`MediaTrack*` GUID-read helpers. Pure decision logic (what counts as
|
||||
an orphan, how a range maps to capture units, etc.) lives in the corresponding
|
||||
`core/` modules this shell calls into — this directory is the REAPER API surface
|
||||
only.
|
||||
|
||||
## Invariants
|
||||
|
||||
This directory implements, but does not restate, the repo-wide capture precision
|
||||
invariants (null test, bit-identical repeats, non-destructive, exact bounds,
|
||||
relative-paths-only) and the load-bearing capture/placement separation — see root
|
||||
`CLAUDE.md` §Precision invariants and §The load-bearing principle. Shell-specific
|
||||
detail not covered there:
|
||||
|
||||
- **FX-bypass guard ordering.** `scope_resolve` reads the M10 provenance-assembly
|
||||
inputs (track/item selection, FX-chain identity) BEFORE the FX-bypass guard
|
||||
neutralizes the in-scope chain — provenance must see the chain as it really is,
|
||||
not as capture temporarily leaves it.
|
||||
- **Realtime capture drives off REAPER's transport across timer ticks** —
|
||||
`capture_realtime_shell` cannot block REAPER's UI for the duration of a realtime
|
||||
record, so `begin`/`tick`/`abort` are async by construction and the temp-track +
|
||||
send recipe lives in the shell, not the pure core.
|
||||
- **`RunInsertSelected` is the one deliberate exception to capture-never-places**
|
||||
(see `capture_orchestrator` below) — every other capture entry point writes only
|
||||
a file + index entry.
|
||||
|
||||
## Modules
|
||||
|
||||
- `capture` — two CONCRETE backends with deliberately different lifecycles (no shared interface — the former `ICaptureBackend` was deleted in Q-W3, T4-26: one deriver, zero polymorphic call sites): `OfflineRenderBackend` (deterministic default, synchronous) and `RealtimeRecordBackend` (async begin/tick/abort). Input: `CaptureRequest`. Output: finished file + populated `Sample` handed to `bank_model`.
|
||||
- `scope_resolve` (`shell/capture`) — scope/source resolution shared by every capture entry point (Q-W3 hoist out of `main.cpp`): razor-else-time range inference, selected-track/selected-item-owning-track collection with canonical GUIDs, and the M10 provenance-assembly inputs (read BEFORE the FX-bypass guard neutralizes the in-scope chain).
|
||||
- `capture_orchestrator` (`shell/capture`) — single-capture orchestration + the realtime/insert action bodies (Q-W3 hoist, T4-02): `renderOffline` (one offline render under the scope's FX-bypass guard), `captureAndIndexOne` (render + provenance stamp + bank add + owned-manifest record, unpersisted), `RunCapture`/`RunCaptureItemAssign`, `RunCaptureRealtimeTrack`/`RunCancelRealtime` (the realtime action bodies — the in-flight state lives in `realtime_lifecycle`), and `RunInsertSelected` (the ONE deliberate exception to capture-never-places).
|
||||
- `capture_batch` (`shell/capture`) — the batch-capture family + re-capture-from-source (Q-W3 hoist, T4-02): `RunBatchCaptureItems` (one sample per selected item), `RunBatchCaptureRazor` (one sample per razor area), `RunRecaptureFromSource` (regenerate a provenanced sample from its recorded source's current state, bank-only). Every unit routes through `capture_orchestrator` so every precision invariant holds; persist is batched to one ext-state write per action.
|
||||
- `realtime_lifecycle` (`shell/capture`) — the in-flight realtime-capture state machine + globals (Q-W3 hoist): the action starts it, `OnTimer` drives it per tick via `DriveRealtimeCapture` (a single-pointer-test idle fast path — load-bearing hot-path guardrail), `CommitRealtimeResult` lands a finished capture in the bank, `AbortRealtimeCaptureForUnload` tears down cleanly on extension unload.
|
||||
- `capture_realtime_shell` (`shell/capture`) — the async realtime-record backend surface (Q-W6 split of the former fat `capture.h`): `RealtimeRecordBackend::begin`/`tick`/`abort`, transport-driven across timer ticks (a realtime record cannot block REAPER's UI for its own duration). Deliberately shares NO interface with the offline backend — the lifecycles genuinely differ (the former `ICaptureBackend` interface was deleted in Q-W3, T4-26).
|
||||
- `capture_realtime_finalize` (`shell/capture`) — the file-side half of the realtime-record shell (Q-W3, T4-08): discovers the file REAPER actually recorded, moves it into the bank, runs the Auto-tail PCM decay-scan trim, and populates the finished `Sample`.
|
||||
- `insert` — placement via `InsertMedia`. **Conform-to-project-tempo is an explicit opt-in flag, never silent stretching.**
|
||||
- `provenance_shell` — FX-chain identity queries via `TrackFX_*`/`TakeFX_*` APIs; feeds the pure `provenance` fingerprint builder. Stamps `Sample.provenance` on capture; ambiguous/mixed cases record nothing conservatively.
|
||||
- `track_guid` — shared `MediaTrack*` → canonical GUID-string formatter; single source of truth for membership keys.
|
||||
- `item_read` — the ONE place a `MediaItem*` is read for its canonical GUID string (`itemGuid`) and for the durable `P_LANENAME` of the fixed lane it sits on (`itemLaneName`); extracted from previously-duplicated `itemGuid`/`itemLaneName` pairs in `view.cpp` and `bank_panel.cpp` — the item-read analog of `track_guid`'s single `MediaTrack*`→GUID-key formatter. Callers must already know the track is fixed-lane (`I_FREEMODE==2`) before calling `itemLaneName`; the pure `isOnManualLane` predicate handles the non-fixed-lane case separately.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- This directory's governing precision invariants are the repo-wide capture
|
||||
invariants in root `CLAUDE.md`, not a standalone spec block here.
|
||||
- `capture` and `capture_realtime_shell` deliberately share NO common interface with
|
||||
each other (the former `ICaptureBackend` was removed) — do not reintroduce one
|
||||
without a real second polymorphic call site.
|
||||
Reference in New Issue
Block a user