capture: state the bounds tolerance as empirical, refuse unmeasurable renders, keep refused ones for diagnosis

The one-frame bound is not provable for a per-edge renderer; the test now shows where it breaks. Refused renders move out of the bank instead of being deleted, so the DAW experiment has something to read.
This commit is contained in:
2026-08-02 07:23:30 -04:00
parent a91df760cc
commit 2005f90c66
14 changed files with 339 additions and 126 deletions
+4 -2
View File
@@ -26,8 +26,10 @@ Checks for Θ, Ξ, and Ψ work that no unit test can close. Build **Release**, i
- [ ] Same source: track scope × time selection, and track scope × razor — same exact window (`PLAN.md:2136`)
- [ ] One razor-union case (two disjoint areas, one track) — lands the requested window, no `ReaSampler capture failed:` line (`PLAN.md:2137`)
- [ ] Capture an item whose extent already equals the window — still lands, unchanged (the byte-identity regression floor) (`docs/COMPLETED.md:829`)
- [ ] **Open blocker.** A live capture refused with a 38-frame shortfall (195216 of 195254 at 48 kHz). Set View → time unit to Samples, then over the same range run **track** scope and **item** scope in turn and report the refusal's `Render source:` line plus both frame counts, and whether the media under the range ends before the range does
- [ ] Same range extended ~1 s past all media, track scope — a full-length file with trailing silence means postprocessing is off; a short file means a trailing-silence trim is firing despite `RENDER_NORMALIZE &(4<<16)`
- [ ] **Open blocker — root cause unknown; the three steps below are the experiment** (both live hypotheses and what is NOT yet excluded: `docs/TODO.md` §An offline capture can be refused for a short render). A live capture over [0.000000s, 4.067797s) was refused 38 frames short (195216 of 195254 at 48 kHz). Set View → time unit to Samples first
- [ ] **Step 1 — does the item-scope render bound itself to the media?** This only tests anything if item scope actually reaches REAPER's selected-items render, and it does that ONLY when the selected items' extent already equals the requested window (`itemExtentPrintsWindow`, `src/core/capture/render_window.h`); otherwise item scope re-sources through the items' own tracks — the same source track scope uses, so the two runs would test one thing twice. So: snap the time selection to the item's exact start and end, run **item** scope, then **track** scope over the identical range. Report both `Render source:` lines and both frame counts. **If both lines read `selected tracks via master`, the item path was NOT exercised** — the extents did not match; re-snap and repeat before concluding anything
- [ ] **Step 2 — full-length or short?** Extend the same range ~1 s past the end of all media, **track** scope. Landing with the full range (no refusal, the card reads the extended length) rules out BOTH a trailing-silence trim and a content-extent bound at once. A short render does NOT tell them apart: a trim firing despite `RENDER_NORMALIZE &(4<<16)` and a render bounding itself to content extent produce the same count. Report which happened, then run step 3
- [ ] **Step 3 — where are the missing frames?** A refused render is kept deliberately, not deleted: it is moved to `<project folder>/reasampler_refused/`. **Follow the path in the refusal line, not this sentence** — if the move itself failed the file stays in the bank folder, unindexed, and the line says which happened. Insert it against the source over the same range and report whether the head aligns. Frames missing from the TAIL with an aligned head fits either a tail trim or a content-extent bound; a head offset fits neither and is a start-position defect. Also report whether the media under the range ends before the range does. Delete `reasampler_refused/` when done — nothing in the bank references it
## Names and channels