Frame the option space for a MIDI-triggered sampler consuming ReaSampler
banks: the extension-format ceiling (verified vs. vendored SDK headers),
the bank-as-shared-artifact seam, scope tiers, and the forks for Daniel.
An item inserted onto an already-split folder in Design mode sat on the
correct lane but stayed invisible until a manual toggle: mintManagedLanes
returned on the idempotent no-op path before its UpdateArrange call. Force
the redraw there so the item appears immediately.
Pool grid on top, LICE-drawn named-banks tab strip below with overflow-scroll
(new pure tab_strip seam, unit-tested). Full-height toggles, unmistakable
active-bank readout distinct from the shown tab, tab context menu
(activate/rename/delete/evacuate/create) with rich confirm-on-non-empty-delete,
and move/copy via menu + drag with drop-highlighting. Fold-in: deserialize
auto-disambiguates duplicate folded bank names instead of rejecting the book.
Add three MIDI-bindable item actions mirroring the track tag family, routed
through the shared hookcommand: retag selected items' membership then re-drive
mint/apply so each lands on its mode's managed lane (manual-lane items exempt),
all in one undo block. Extract shared item_read seam, simplify applyMintPlan's
lane-count pass, and guard reconcile against unregistered-mode lanes.
Drive C_LANESCOLLAPSED=2 and hide lane buttons only on tracks the tool itself splits
(gated on the pre-write I_FREEMODE read, so user comp-lane display prefs are never
stomped). Lazy-mint managed lanes only for modes with own content, never an empty
reserved lane; confinement holds via C_LANEPLAYS on the lone lane.
planLaneMinting now takes the model + folder tree and splits a track visible in
2+ modes that carries own media (own-item span OR folder derived-visibility),
fixing an item dropped on a cross-mode folder leaking into every mode. Show-both
tracks are never force-split.
Linear amplitude-to-pixel mapping made -20 dBFS content reach only
10% of cell height and -40 dBFS round to zero. Replace with a dB
scale (floor kDisplayFloorDb = -60 dB, in bank_grid.h) so quiet
content is visible. Pure helper compressAmplitudeForDisplay() lives
in bank_grid; drawThumbnail() calls it. Five new unit tests cover
full-scale, zero, mid-levels, floor clamping, and sign preservation.
Adds the two missing removal capabilities: sample-level remove (Phase B
point B5, index-only) and the prune file-lifecycle path (new Phase R, the
sole file-deleting op), resolving the dangling capture/prune reference.
Adds CONTEXT.md spec, PLAN.md points, and a product note; surfaces forks
R-A..R-E for decision.
Bank_panel labels surface each capture action's current key binding
(kbd_getTextFromCmd, unbound-safe); clickable buttons fire the actions
through the existing command-id contract. Pure/shell split noted per point.
Settle the reshaped Milestone 10: thin capture-recipe fingerprint and
bank-only re-capture; P3/P4 closed as moot. Remove the pending-picks
banner in PLAN.md and stamp the provenance product note as settled.
Pure planLaneMinting decides which tracks hold >1 mode's content and which managed
lane each item lands on; view.cpp applies it (I_FREEMODE/I_NUMFIXEDLANES/P_LANENAME/
I_FIXEDLANE) under one undo block, driven off the auto-tag detection tick. Manual lanes
and their items are never touched. Load-time reconcile rebuilds ownership from durable
lane names before reapplying active-mode visibility.
Cut the null-test verify action and pre-FX-dry mechanism (Daniel's
call); keep provenance + re-capture-from-source. Sample.provenance
already exists/round-trips (M1), so M10 populates and consumes it. Add
docs/product/provenance.md with dual-canvas forks P1-P4 and the leaned
bank-only path; rewrite PLAN.md M10 as a proposal pending fork picks.
The detector re-armed its GuidBaseline on a pointer compare (proj != lastProject),
a weaker signal than persist's GUID-primary identity. On a load onto a recycled
ReaProject* the baseline never reset, so the just-loaded project's pre-existing
tracks diffed against the previous project and were mass-tagged into the active
mode — opening a Design-saved project mis-tagged its Arrange tracks. Re-arm now
rides persist's authoritative load signal via bankPanelNotifyProjectLoaded().
markTailDirty() called MarkProjectDirty() but never called
saveToActiveProject(), so the new tail value was never written
to SetProjExtState. On unsaved projects saveToActiveProject()
no-ops cleanly, resolving the companion Major at the same time.
Relocate TailSetting into ReaSamplerSession; persist serializes it to
a new forever-stable "tail_setting" ext-state key (load-per-project,
save-on-save). Footer scroll-wheel adjusts Manual length in 250ms
steps; label now shows "Tail: Manual X.Xs". Pure step/label/JSON
round-trip covered by tests.
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.