REAPER-free and VST3-free voice engine with bounded stealing, ADSR
envelope, key/velocity keymap resolution, and repitch from root note
with loop-point sustain. Test target links neither SDK.
Vendor Steinberg VST3 SDK (v3.7.9_build_61); add reasampler_vst.vst3 as a second, additive build artifact with pure editor-geometry + bridge-marshal helpers under CTest.
computeSlotRectsForDrop adds cols slots past maxSlot; classifyCardDrag and
drawCardDropTarget use it instead of the render rects. doReorderDrop already
accepts any non-negative slot. New tests cover beyond-extent resolves,
empty-bank trailing row, gap pixels still miss, empty-cell within-extent works.
Button faces now show only the short label (keybinding moved to hover tooltip as
"name — binding"). Cancel RT joins the overflow menu alongside Capture RT. Re-capture
sits between the capture and placement clusters. Toolbar heights 40->28.
Top-bar rare-capture variants move to a right-anchored More popup; short faces gain
hover-delay full-name tooltips (prefix stripped); bottom bar becomes four opposite-mode
Item/Track tag buttons + Show Both (Toggle/Activates dropped); wider cluster gaps. New
pure overflow_menu/mode_enable/tooltip modules, CTest-covered. Same actions, same contract.
Top toolbar = capture+placement, bottom toolbar = Design-View verbs, footer = narrow Arrange|Design toggle + count + Tail button + set-apart Prune. New pure footer_bar module; Tail is now a real kit button.
Finish roleColor/roleColorState for the three-accent enum, re-map every
Accent consumer (primary leads live; Pool/Banks titles categorical
secondary/tertiary), make spectralColor a lime->teal->purple three-stop
sweep, and re-lock the WCAG-floor tests on the grey ladder.
New pure action_bar module (clusters, keybinding sub-labels, overflow, hit-test) supersedes the flat M11 strip; bank_panel chrome/buttons/tabs/grid now draw through the L1 kit by role with hover. Expose draw_kit::toLice in header to fix drawThumbnail forward-refs. CTest 27/27.
Pure drag_out (gesture boundary + path-list assembly) + Windows OLE
CF_HDROP / SWELL file-list shell; bank_panel hands off when a dragged
selection leaves the client area. COPY-ONLY mask; internal drag intact.
New pure action_buttons module (strip layout/hit-test + label format,
CTest-covered). Panel strip fires capture/insert/provenance actions via
NamedCommandLookup + Main_OnCommand; labels from kbd_getTextFromCmd.
Extend BANK_PRUNE_FOLDER from report-only to dry-run→confirm-with-manifest→
delete exactly the pure-core orphan set (fresh recompute, stale entries skipped).
Windows routes to Recycle Bin (SHFileOperation+FOF_ALLOWUNDO), else unlink.
New pure prune_button module + footer button dispatching the action id. No
ext-state write, no undo point (deletion is not REAPER-undoable).
Add ReaSamplerSession::pruneDryRun enumerating the resolved current bank
folder, feeding the R1 core, and returning a PruneReport (count/bytes/list).
New pure bankRelativeForName + buildPruneReport keep spelling and tally
testable. Register forever-stable BANK_PRUNE_FOLDER action, report-only. No deletion.
Item scope now reads the active take's FX chain via TakeFX_* (new
fxChainIdentityForItems helper), not the owning track's chain.
normalizeSlashes lowercases on _WIN32 for detectParent. Stale
comments corrected; case-fold tests added.
Pure provenance core (recipe fingerprint, FX-chain identity, parent
detection) + shell reads; capture stamps provenance on resample-from-sample;
re-capture regenerates a provenanced sample from its source, never touching
the timeline. Adds BankIndex/BankBook in-place update. CTest-covered.
hashWavContent walks RIFF chunks and feeds only fmt body + data payload
through FNV-1a ('W' domain-separation prefix), skipping bext/iXML/LIST that
REAPER embeds with per-render origination timestamps. Fallback to whole-file
hashBytes for non-WAV. Wired into both capture commit paths.
Legacy entries keep their stored whole-file hash; a re-capture will not
collapse onto a pre-fix entry -- a one-time clean capture resolves it.
Compile-time channel flag forks a fully isolated reaper_reasampler_beta
(namespace, command-id prefix, action names, dock ident, -beta render) from
one auditable app_version definition. Stable identity byte-unchanged.
contentHash was left empty on every capture; hashReferencedElsewhere returns
false for empty hashes, so every remove looked like a last reference. Add
FNV-1a hashBytes to capture_paths, wire into both commit paths. NOTE: this
activates index dedup-by-hash in production — a bit-identical re-capture now
collapses onto the existing entry instead of adding a duplicate (spec-intended).
Version "0.9.01" sourced once from CMake via configure_file'd header; pure
app_version module (parse/compare/classify) with CTest. Stamp rides the persist
save seam under "reasampler"/"version"; absent stamp reads as pre-versioning.
On-demand "show version" action, no startup print.
Pure OwnedFileManifest (relative paths, dedup, JSON round-trip) persisted
under sibling owned_files ext-state key; both capture commit paths record;
joins the R-B undo-reload set. Phase R prune consumes it later.
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.
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.
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().
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.