# DAW verification — track-scope capture over a multi-track selection What a DAW pass must establish for the multi-track track capture, and the exact numbers or strings to read off. Nothing below can be closed by a unit test: every item depends on what REAPER actually does with a render request. **Build to use.** Release, installed into `UserPlugins/`, REAPER restarted — extensions load at startup only. Set the docked panel's tail toggle to **None** before every cell; Auto adds an 8 s window and Manual a fixed one, and both would invalidate the frame-count readings. **Project to use.** One saved project, project sample rate pinned to 48000. Two audio tracks, `A` and `B`, each holding one item at least 30 s long, with *audibly different* content (a tone on `A`, a drum loop on `B`). One folder track `F` with `A` and `B` as its children, used only in §5. --- ## 1. The regression floor — single-track track capture is unchanged Select **track `A` only**. Make a time selection from **10.000 s to 12.000 s**. Run *ReaSampler: capture selected track(s)*. Read off: - A file appears in the project's bank folder, and one new card appears on the panel. - The card's length reads **2.000 s**; its frame count is **96000** (`round(12.0 × 48000) − round(10.0 × 48000)`). The backend refuses the capture with `BoundsMismatch` if the render is more than one frame off that, so a landed capture already proves the number to ±1 — what you are confirming here is that it landed at all. - The REAPER console shows **no** `ReaSampler capture failed:` line. - Track `A` is still the only selected track afterwards. Repeat with a **razor area** on `A` over the same 10–12 s span and no time selection: same three readings. **This is the byte-identical floor.** If either cell now refuses, the change is wrong — the refusal must fire only above one track. ## 2. The defect cell — two selected tracks now refuse Select **`A` and `B` together**. Time selection 10.000–12.000 s. Run *capture selected track(s)*. Read off: - The console prints exactly: `ReaSampler capture failed: A track capture renders the selected tracks through the master, and more than one track cannot land as a single file. Capture one track at a time, or route them into a folder/bus track and capture that (a folder's own output is its children summed).` - **No** new card on the panel, and **no** new `.wav` in the bank folder (check the folder directly — a stray file with nothing indexing it would mean the refusal fired too late). - `A` and `B` are both still selected, both still unmuted, and neither track's fader, pan, or FX-bypass state changed. The refusal returns before any guard is constructed, so there should be nothing to restore — this reading is what confirms that. Repeat with a **razor area spanning both tracks** and no time selection: identical readings. Note that the track *selection* is what the refusal counts — a razor over two tracks with only `A` selected is a one-track capture and must still succeed (§1). ## 3. The decisive observation — what `&128` actually writes **This is the one that retires an inference, and it is the reason `docs/TODO.md` still carries an entry.** The refusal in §2 rests on reading the SDK header's single-file bit `&(4<<16)` as applying to item/razor sources only, never to `&128` — so N selected tracks are believed to produce N files. That has never been observed. Drive REAPER's own Render dialog by hand, with the extension out of the loop: 1. Select `A` and `B`. 2. File → Render. **Source:** *Selected tracks (stems)* — the dialog wording for `&128`. **Bounds:** *Custom time range*, 10.000 to 12.000 s. 3. **File name:** a literal stem with **no wildcards at all** — e.g. `stemprobe`. Clear `$track` / `$item` / anything else from the pattern; the extension writes exactly one literal stem, so the probe must too. 4. Render to an empty scratch folder. Read off — **the file count in that folder**: - **Two files** (however REAPER disambiguated them, or one file that visibly got overwritten): the inference holds, the §2 refusal is correct, and the `docs/TODO.md` entry can be closed by writing this observation into `src/shell/capture/CLAUDE.md` as fact. - **One file containing `A` and `B` summed** (confirm by ear, or by nulling it against a master render of the same range with only `A` and `B` unmuted): the inference is wrong, the §2 refusal costs a working capture, and the track-scope half should be narrowed back per the `docs/TODO.md` entry. The item-scope half stays either way. Also record **what REAPER named the files** — that decides whether a future correct multi-track capture could ever be built on this source at all. ## 4. Recapture replays the same answer Take a **single-track** track capture that carries provenance (capture a range on `A` whose source item is itself a bank sample, so `detectParent` fires), select its card, and run *re-capture from source*. It must regenerate — same audio, same 96000 frames. Then construct the multi-track case: a recorded recipe whose `trackGuids` names two tracks. The reachable way to get one is to have captured it before this change; if no such entry exists in any project, record that this cell was **not exercised** rather than inventing one. When it is exercised, read off: - `ReaSampler re-capture failed:` followed by the **same** message text as §2. - The bank entry is untouched — same file, same hash, same card. ## 5. The way out actually works Route `A` and `B` into folder `F`. Select **`F` only**, time selection 10.000–12.000 s, capture track scope. Read off: one card, 2.000 s, and the audio contains **both** `A` and `B`. This is what the refusal message tells the user to do, so it has to be true. ## 6. Realtime still accepts a multi-track selection Select `A` and `B`. Run *ReaSampler: capture selected track(s) in realtime* over the same range. Read off: **one** card, and its audio contains both tracks. Realtime taps each source track with a send into one temp track, so it sums where the offline render cannot — the divergence from §2 is deliberate and this cell is what confirms it is real. ## 7. Mono collapse — what is and is not reachable Capture a range on a track whose content is dead-center (a mono source panned center, or a duplicated-channel file). Read off: - The panel card reports **1 channel**. - The console shows **no** `the lossless mono collapse ... landed intact, as captured.` line. **Not DAW-reachable:** the collapse's *failure* branch. It fires only if the captured file cannot be read, or its temporary rewrite cannot be written or renamed, inside the same call that just rendered the file — there is no manual way to inject that fault between the render and the rename. The branch is covered only at its reporting seam (`tests/test_wav_codec.cpp`, `testCollapseOutcomesReportDistinctly`), and its console line has never been seen in a running REAPER. If you ever do see it, the capture in question is intact and correctly measured — only the size win was lost.