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,69 @@
|
||||
# src/core/capture — pure logic behind the capture pillar
|
||||
|
||||
## Scope
|
||||
|
||||
Pure, REAPER-free logic behind the capture pillar: path arithmetic, the RIFF/WAV
|
||||
codec, render-settings/FX-scope/tail-mode mapping, `InsertMedia` mode-bit
|
||||
computation, the realtime-record state machine, and batch-capture planning.
|
||||
Does **not** include: the REAPER-bound capture backends themselves
|
||||
(`shell/capture`), the docked panel's tail-toggle window/click-handling
|
||||
(`shell/panel`), or the `InsertMedia` call/undo-block mechanics
|
||||
(`shell/capture`'s `insert.cpp`).
|
||||
|
||||
## Invariants
|
||||
|
||||
The repo-wide precision invariants (null test, bit-identical repeats,
|
||||
non-destructive, exact bounds, relative-paths-only, capture FX scope) are
|
||||
authoritative in root `CLAUDE.md` — reference them, don't re-copy them.
|
||||
Detail specific to these pure modules:
|
||||
|
||||
- **No silent time-stretch, made checkable.** `insert_plan` never sets the &4
|
||||
("stretch/loop to fit time sel") bit; `kStretchToTimeSelBit` is exposed
|
||||
precisely so a test can assert it is never present in any computed
|
||||
`InsertMedia` mode.
|
||||
- **Tail is a three-state mode (`docs/product/capture-tail.md`), not a
|
||||
per-action variant:** None (exact bounds, byte-identical, the only mode for
|
||||
null-test/verify captures), Auto (generous 8 s tail then trim trailing
|
||||
silence to -72 dB surgical normalize), Manual (fixed length, clamped to the 8
|
||||
s cap, no trim). `render_settings` owns the offline RENDER_* mapping;
|
||||
`tail_control` owns the panel-facing toggle/cycle/clamp/label logic sharing
|
||||
the same `TailMode` enum and the same 8 s / -72 dB constants (single source
|
||||
of truth — do not hardcode a second copy in either module).
|
||||
- **Capture FX scope is enforced via FX-bypass + gain-neutralize, not a render
|
||||
bit.** `render_settings::fxBypassPlanFor` selects which tracks (self /
|
||||
ancestors / master) get their FX bypassed for a given `CaptureScope`; there
|
||||
is no master capture scope (to capture the master, render a track instead).
|
||||
- **Relative paths only, by construction.** `capture_paths::BankPaths`
|
||||
separates the absolute render directory REAPER needs from the
|
||||
project-relative path the `BankIndex` stores; `bankRelativeForName` spells an
|
||||
enumerated folder entry the identical way `deriveBankPaths` spelled it at
|
||||
capture time, so the prune core's exact-string match cannot drift.
|
||||
- **Project-identity transition is GUID-primary.** `capture_paths`'s
|
||||
`classifyProjectTransition` checks the minted GUID before the live
|
||||
`ReaProject*` object, specifically because REAPER can recycle a closed
|
||||
project's pointer address onto an unrelated project.
|
||||
|
||||
## Modules
|
||||
|
||||
- `wav_codec` — chunk walker + layout parse + float32 build + size-field patch + content hashes; the single pure RIFF/WAV owner (`wav_trim` is retired; `wav_codec` is the sole owner).
|
||||
- `capture_realtime` (`core/capture`, **renamed from `realtime_record` in Q-W3** — the Q-9 naming rider: pure module takes the stem, the shell takes the suffix, matching `drag_out`/`drag_out_win`) — the M8 realtime-record pure logic: capture scope + FX-tap point → `I_RECMODE`/`I_RECMODE_FLAGS` values, wet/dry → tap point, the recorded-file → `Sample` mapping, and the async record-phase state machine. Depends on `bank_model` for the plain `Sample`/`SourceMode` types. The transport/temp-track/send recipe lives in the shell (`shell/capture/capture_realtime_shell.cpp` + `capture_realtime_finalize.cpp`).
|
||||
- `batch_capture` — pure batch-capture planner: maps source ranges to capture units and aggregates results.
|
||||
- `capture_paths` — the REAPER-free path arithmetic behind offline capture: bank-subfolder + unique-filename derivation (`deriveBankPaths`, forward-slash form, no filesystem touch), the absolute-render-dir vs. project-relative-index-path split (`BankPaths`), the persist-side inverse (`resolveBankFile`, `projectDirOfRpp`), the Save-As bank-relocation plan (`deriveRelocationPlan`), and the GUID-primary project-identity classifier (`classifyProjectTransition` → `NoOp`/`Load`/`SaveAsRelocate`) the persist-poll timer drives.
|
||||
- `insert_plan` — the REAPER-free logic behind the `insert` shell (M6): computes the `InsertMedia` `mode` bitmask from an `InsertOptions` struct (placement target, tempo-conform ratio, preserve-pitch flag), guaranteeing the &4 stretch-to-time-selection bit is never set and that no tempo bits are set when `conform == None`.
|
||||
- `render_settings` — the REAPER-free logic behind the capture action family: `SourceMode` → `RENDER_SETTINGS` bit mapping, `P_RAZOREDITS` string parsing + range-union bounds, razor-else-time range inference, the FX-scope bypass plan (`fxBypassPlanFor`), the tail-mode → `RENDER_TAILFLAG`/`RENDER_NORMALIZE`/`RENDER_TRIMEND` mapping (`tailRenderSettingsFor`) and its realtime-window analog (`realtimeRecordWindowEnd`), and the capture-action taxonomy table (`captureActionTable`) `main.cpp` iterates to register the CAPTURE_ITEM/CAPTURE_TRACK family.
|
||||
- `tail_control` — the REAPER-free logic behind the docked `bank_panel`'s tail-mode toggle: the cycle order (None → Auto → Manual → None), the Manual-length clamp/scroll-wheel fine-adjust (`clampManualMs`/`adjustManualMs`, 250 ms/notch, 2000 ms default), the toggle's label text (e.g. "Tail: Manual 2.0s"), and the `TailSetting` JSON round-trip persist stores per-project.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- `render_settings`'s `RENDER_SETTINGS`/`RENDER_NORMALIZE`/`RENDER_TAILFLAG`/
|
||||
`RENDER_TRIMEND` bit values are transcribed verbatim from the SDK header
|
||||
(`reaper_plugin_functions.h` lines ~3041/~3047/~3051/~3062) — re-verify
|
||||
against the header before changing any bit value, per the root `CLAUDE.md`
|
||||
API-verification rule.
|
||||
- `kRenderPreFaderStems` (&8192) is deliberately **not** used — REAPER offline
|
||||
render has no true pre-FX "dry" bit; FX scoping is done entirely by the
|
||||
FX-bypass-around-render mechanism, never by a render bit.
|
||||
- `tail_control`'s `kDefaultManualTailMs`/`kManualStepMs` and
|
||||
`render_settings`'s `kMaxTailMs`/`kAutoTrimThresholdDb` are separate constants
|
||||
in separate files by design (panel-facing default/step vs. runaway-guard cap)
|
||||
— don't conflate them when touching either.
|
||||
Reference in New Issue
Block a user