Auto/Manual/Off tail handling for realtime track-tap capture. Auto scans
recorded PCM backward for last frame above -72 dB and truncates the wav
header-aware (8 s cap); Manual pads a fixed tail; Off is byte-identical.
wav_trim rejects WAVE_FORMAT_EXTENSIBLE with non-float SubFormat GUID.
Drives fixed-lane C_LANEPLAYS for managed lanes only (name-keyed, ordinal-renumber
safe) in the view shell; diffs live track/item GUIDs on the panel timer to auto-tag
new content to the active mode, first-poll-guarded. Pure guid_diff + lane_keys
modules unit-tested; folds in Wave-1 polish.
Replace the ...-with-tail variant actions with a pure tail_control module +
a docked-panel footer toggle (Off/Auto/Manual) read by CAPTURE_ITEM/TRACK.
Default None (byte-identical); Manual fixed 2s, in-memory session lifetime.
Tail mechanism unchanged; retired the variant ids.
Add TailMode{None,Auto,Manual} + derived -72dB TRIMEND + 8s cap in render_settings;
wire into OfflineRenderBackend with snapshot/restore of the tail settings; add
CAPTURE_ITEM_TAIL/CAPTURE_TRACK_TAIL variant actions (plain actions stay exact-bounds).
Extends the REAPER-free view_mode_model for per-item mode membership via fixed
lanes: lane->mode C_LANEPLAYS mapping, managed-vs-manual lane-ownership index,
managed-only item-lane ops in the toggle planner, "which lanes may this toggle
touch" query, auto-tag decision (manual-lane items exempt), and JSON round-trip
of the lane index. D1 behavior and tests unchanged.
Capture is now item + track only (master removed as a scope; still bypassed
as out-of-scope chain). Realtime records the selected track's own output via
per-track post-fader sends into a hidden temp track, fixing the silent file.
Timer-driven realtime capture behind ICaptureBackend (begin/tick/abort via
OnTimer, non-blocking). Records master into a hidden temp track, moved to the
bank non-destructively with idempotent restore across every terminal path.
Pure phase machine unit-tested. Track/item deferred; realtime is non-deterministic.
Mirrors capture: when membership is non-empty and the project has no .rpp,
Main_SaveProject(proj, true) prompts Save-As before persisting; cancel leaves
the in-session tag state intact and warns via console.
Design View actions mutated the model but never pushed it to ext-state, so
tags/active-mode/snapshots were lost on save/reopen. Add persistViewState()
(saveToActiveProject) after each handler's apply/reapply.
FxBypassGuard now snapshots/restores D_VOL, D_PAN, D_WIDTH, D_PANLAW, I_PANMODE
alongside I_FXEN for every bypassed track (forcing stereo-pan mode for an
unambiguous render), so Track/Item captures are uncolored by parent/folder/master
fader and routing. All restored on every path.
Add ViewModeModel::reconcile(liveGuids) to prune snapshots of deleted
tracks; wire it into applyMode before planning. Keep membership so
undo-delete (same GUID) preserves the Design tag.
Replace the four capture modes with item/track/master scope actions. Each infers
its range (razor-else-time) and enforces FX scope via non-destructive
FX-bypass-around-render (RAII I_FXEN snapshot/restore over ancestors + master).
Corrects the defect of items captured through parent FX.
New pure mode_switch module (header-rect -> N equal segment rects + point hit-test, unit-tested) plus a segmented switch in the bank_panel header: one lit segment per registered mode, click activates via view::applyMode. Grid offset below the header.
Four wet capture actions route to OfflineRenderBackend (snapshot/restore
RENDER_*, 32-bit float), produce a Sample, add to the bank, persist. Pure
render_settings maps source mode to RENDER_SETTINGS and parses P_RAZOREDITS
(tested). No arrange insertion. True dry deferred to M10.
visibleTracks pass 1 now evaluates every node (parent or leaf) by its own
membership, so an untagged folder carrying its own FX/media shows in Arrange
(its default) as well as any mode derived from its children. Adds case-matrix
tests; updates the nested-Arrange assertion to the corrected rule.
Wire both insert actions to CurrentTrack (InsertMedia base 0). Per selected
track: SetOnlyTrackSelected, reset cursor to snapshot, InsertMedia; then restore
original selection + cursor. No-op when no track selected. Corrected stale
extraflags / new-track / preservePitch comments.
Only capture a track's pre-park snapshot when none exists, so a re-park while
already parked no longer overwrites it with hidden-state zeros (leaves vanished
after toggling twice). Undo label now names the actual target mode.
InsertMedia-driven placement reading the bank panel selection, undo-wrapped.
Native length by default; conform-to-tempo is an explicit second action, never
a silent stretch. Pure mode-bit logic (insert_plan) unit-tested.
planToggle now enumerates all leaves in the FolderTree instead of only tagged
membership entries, so untagged (Arrange-member) tracks park in Design and
restore in Arrange. applyMode calls TrackList_AdjustWindows + UpdateArrange so
changes render immediately. Correct the stale "tagged-only" invariant comments.
classifyProjectTransition now checks the stored GUID first, then the pointer,
fixing the w10 regression where a recycled ReaProject* address stopped the bank
reloading. poll()'s fork re-GUID gate is bound to !sameProjectObject. Full
transition matrix pinned in tests.
Pure bank_grid gains hit-test, selection-update, and arrow-nav math with
tests; the panel wires mouse multi-select, keyboard nav via an accelerator
hook, and stock PlayPreview/StopPreview audition with a leak-free preview
lifecycle. Read-only: no arrange insertion, no project/bank mutation.
Register toggle/activate/tag/untag/show-both actions driving the D2
shell and D3 model; reapply saved active mode on project load via a
persist load-signal seam. Shared guidString helper; pure nextModeId
unit-tested.
M4's GUID-only classifier read a tab-switch between two Save-As forks (shared
copied GUID, different paths) as a Save-As and clobbered a bank. Thread
sameProjectObject into classifyProjectTransition: a different object always
Loads, never relocates; a forked sibling gets re-GUID'd to diverge.
applyMode now drives B_SHOWINTCP/B_SHOWINMIXER for every parent node
from visibleTracks(tree, targetMode); parents are never parked. Adds
restoreFxOffline by-index remap hazard note.
Docked SWELL window toggled by a new action, drawing the current bank as
per-sample min/max thumbnails (PCM_source + peaks) with an in-memory cache.
Pure grid-layout/cache-key math in bank_grid (tested). Renames peaks::Sample
-> AudioSample to avoid colliding with bank_model::Sample.
Add forever-stable "view_state" key under the "reasampler" namespace.
saveToActiveProject additionally serializes the ViewModeModel;
loadFromProject restores it on every load path, defaulting on an
absent/malformed key. Model state only — no visibility apply (D4).
Reads I_FOLDERDEPTH into a FolderTree (pure view_tree helper, unit-tested),
snapshots to-be-parked tracks before parking, runs the D1 planner, and applies
park/restore flag + per-FX-offline writes under an undo block. Master and
mute/solo untouched; acts only on tagged tracks.
After capture, saveToActiveProject wrote ext state but left the project
clean, so Ctrl+S was a no-op and the bank was silently lost on close.
Also flushes the Save-As re-GUID on the normal save flow.
Serialize BankIndex to project ext state ('reasampler'), reload on project
load, resolve paths project-relative. Save-As copies the bank to the new .rpp;
identity keyed off a minted GUID (not the recycled ReaProject*) so project
switches don't clobber banks. Pure classifyProjectTransition tested.