One taper, one modifier law: extract param_taper, raise the stage ceiling to 10 s, and make the AHDSR schematic axis the taper itself

This commit is contained in:
2026-08-01 19:09:19 -04:00
parent e589addc54
commit 3eb72d01c4
23 changed files with 1208 additions and 193 deletions
+16 -1
View File
@@ -6,6 +6,7 @@
#ifdef _WIN32
#include "core/instrument/ui/deck_values.h" // snapDeckParamNorm (Shift's whole-unit table)
#include "core/instrument/ui/knob_deck.h" // hitTestDeck / layoutDeck
#include "core/instrument/ui/param_slider.h" // knobDragValue (grab-anchored drag)
#include "shell/instrument/editor_internal.h"
@@ -97,6 +98,7 @@ bool ReaSamplerEditor::mouseDownDeck(const FaceLayout& fl, int x, int y) {
dragParamId_ = inner ? static_cast<int>(curve) : hit.id;
dragInnerCellId_ = inner ? hit.id : -1;
dragKnobStartValue_ = deckControlNorm(dragParamId_);
dragMods_ = dragModifiers();
// Processor-side knobs (voice count / master gain) are transient live writes with no
// parameter-set mutation, so they need no rollback snapshot.
dragStartParams_ = params_;
@@ -150,7 +152,20 @@ void ReaSamplerEditor::dragDeck(int x, int y) {
// value at grab (up = increase), so the value tracks relative motion and never jumps on
// grab. Live feedback; parameter-set commits land on WM_LBUTTONUP.
(void)x;
applyDeckKnob(dragParamId_, knobDragValue(dragKnobStartValue_, y - dragStartY_));
const DragModifiers mods = dragModifiers();
if (mods != dragMods_) {
// Re-anchor (see dragMods_). Reading the anchor back off the control also means a Shift
// RELEASE re-anchors from the SNAPPED value, so the knob does not spring back.
dragKnobStartValue_ = deckControlNorm(dragParamId_);
dragStartY_ = y;
dragMods_ = mods;
}
double norm = knobDragValue(dragKnobStartValue_, y - dragStartY_, mods);
// The preview-velocity sentinel (-2) and the discrete controls have no whole unit to snap to.
if (mods.shift && dragParamId_ >= 0) {
norm = snapDeckParamNorm(static_cast<DeckParam>(dragParamId_), norm);
}
applyDeckKnob(dragParamId_, norm);
// A live control is delivered on every move, not only on release — that is the whole
// point: the note already sounding tracks the hand on the knob.
if (dragCommitsLive(DragKind::kDeckKnob, dragParamId_)) commitLive();