docs(TODO-1.0): fold second answer round — items 1-2 fully settled, item 3 down to point bounds and popup gesture convergence

This commit is contained in:
2026-07-28 18:59:46 -04:00
parent 78a214b247
commit 678274c19b
+101 -35
View File
@@ -15,6 +15,11 @@ ask; settled answers are folded into **Behavior** (marked *settled by
follow-up*), and only the genuinely unresolved remainder stays under **Open follow-up*), and only the genuinely unresolved remainder stays under **Open
questions**. questions**.
A **second follow-up round** (2026-07-28, same day) settled nearly all of the
remainder. Each item carries that round's verbatim as a third provenance block;
answers are folded the same way (marked *settled by second follow-up*). Items 1
and 2 now have no open questions; item 3 retains two narrow ones.
Ordering note: item 1's curve/overlay treatment explicitly anticipates item 2's Ordering note: item 1's curve/overlay treatment explicitly anticipates item 2's
filter envelope ("filter to be added"), and item 3 layers on both. They can land filter envelope ("filter to be added"), and item 3 layers on both. They can land
in sequence or together, but 1 and 2 are prerequisites for 3's full surface. in sequence or together, but 1 and 2 are prerequisites for 3's full surface.
@@ -46,6 +51,15 @@ in sequence or together, but 1 and 2 are prerequisites for 3's full surface.
> 1.0 the linear neutral" CLAUDE, y=x^1.0 is linear!! of course! yes dragging > 1.0 the linear neutral" CLAUDE, y=x^1.0 is linear!! of course! yes dragging
> on the segment (add a round knot midsegment) adjusts the curve. > on the segment (add a round knot midsegment) adjusts the curve.
**Daniel's second follow-up (verbatim, 2026-07-28).**
> default overlay none
> what about the curves?
("what about the curves?" is Daniel turning the pre-existing-instances
question back — the answer recorded below is derived from this doc's own
acceptance criterion, not a Daniel quote.)
**Intent.** Grow the envelope-overlay editor from an amp-only fixture into the **Intent.** Grow the envelope-overlay editor from an amp-only fixture into the
shared graphical surface for every envelope in the instrument, and give every shared graphical surface for every envelope in the instrument, and give every
envelope shapeable (non-linear) segments — while fixing the blue-on-green envelope shapeable (non-linear) segments — while fixing the blue-on-green
@@ -61,6 +75,16 @@ contrast failure.
displayed envelope. The switch is exclusive: **one overlay-active envelope at displayed envelope. The switch is exclusive: **one overlay-active envelope at
a time, or none** — no-envelope-shown is a valid state, not an error. a time, or none** — no-envelope-shown is a valid state, not an error.
*(Settled by follow-up.)* *(Settled by follow-up.)*
- **Default overlay: none.** The editor opens with **no envelope selected**
the none-state is the default, replacing today's always-on Amp AHDSR.
*(Settled by second follow-up.)*
- **Pre-existing instances load at exponent 1.0.** Saved instances from before
this change load **every curve at exponent 1.0** — the linear neutral — so
their audible envelope behavior is unchanged. *(Derived, not a Daniel quote:
1.0 is the settled linear neutral, and the acceptance criterion "a project
saved before this change reopens with unchanged audible envelope behavior"
admits no other default. Daniel prompted the question; this is the only
answer consistent with what he has already settled.)*
- **Segment curve values on all envelopes.** Amp AHDSR, Pitch AD, and Filter - **Segment curve values on all envelopes.** Amp AHDSR, Pitch AD, and Filter
AHDSR all gain an editable curve value per *sloped* segment. The curve is an AHDSR all gain an editable curve value per *sloped* segment. The curve is an
exponential function; the per-segment parameter is the exponent scalar, exponential function; the per-segment parameter is the exponent scalar,
@@ -86,14 +110,8 @@ contrast failure.
**Open questions.** **Open questions.**
- **Default overlay selection on open.** Exclusivity and the none-state are - None remaining — both prior questions (default overlay selection,
settled; what is the default when the editor opens — the Amp AHDSR (today's pre-existing-instance curve loading) closed by the second follow-up round.
behavior) or none?
- **Pre-existing instances.** Should saved instances from before this change
load with every curve at the linear equivalent (exponent 1.0) so their sound
is unchanged? (The neutral point itself is settled; this is only the
load-behavior half. The product requirement is "old instances sound
identical.")
**Acceptance criteria.** **Acceptance criteria.**
@@ -101,6 +119,8 @@ contrast failure.
envelope in the overlay, editable there, and the overlay tracks the switch envelope in the overlay, editable there, and the overlay tracks the switch
immediately. At most one envelope is overlay-active; with none active, the immediately. At most one envelope is overlay-active; with none active, the
overlay draws no envelope. overlay draws no envelope.
- The editor opens with no envelope overlay-active (default is none, not the
Amp AHDSR).
- Every curvable-segment knob shows the inner dial (inner arc, tertiary-purple - Every curvable-segment knob shows the inner dial (inner arc, tertiary-purple
hover accent, needle, numeric label); sweeping it through 0.1 → 10 visibly hover accent, needle, numeric label); sweeping it through 0.1 → 10 visibly
reshapes the overlay segment and audibly reshapes the envelope on played reshapes the overlay segment and audibly reshapes the envelope on played
@@ -111,7 +131,7 @@ contrast failure.
- Overlay envelope segments render in tertiary purple and are clearly legible - Overlay envelope segments render in tertiary purple and are clearly legible
against the primary green waveform. against the primary green waveform.
- A project saved before this change reopens with unchanged audible envelope - A project saved before this change reopens with unchanged audible envelope
behavior. behavior: every curve loads at exponent 1.0.
--- ---
@@ -133,6 +153,13 @@ contrast failure.
> again, scaled around root 2 at the center. mod amt targets cutoff, -100% - > again, scaled around root 2 at the center. mod amt targets cutoff, -100% -
> +100% to cover full range from either end. per-voice. label it "Filter" > +100% to cover full range from either end. per-voice. label it "Filter"
**Daniel's second follow-up (verbatim, 2026-07-28).**
> oh, zone.
> yes, filter is off by default
> velocity and keytracking with the rest, not deffered. Same idea as the amp
> velocity transfer curve and pitch key tracking
**Intent.** Add the instrument's first filter stage — resonant high-pass and **Intent.** Add the instrument's first filter stage — resonant high-pass and
low-pass — as a new fixed point in the per-voice signal path, with its own low-pass — as a new fixed point in the per-voice signal path, with its own
AHDSR envelope, and make the knob-deck row read in signal-flow order. AHDSR envelope, and make the knob-deck row read in signal-flow order.
@@ -159,6 +186,19 @@ AHDSR envelope, and make the knob-deck row read in signal-flow order.
the full range from either end. the full range from either end.
- **Per-voice.** The filter processes **per voice** — each sounding voice runs - **Per-voice.** The filter processes **per voice** — each sounding voice runs
its own filter with its own envelope state. *(Settled by follow-up.)* its own filter with its own envelope state. *(Settled by follow-up.)*
- **Per-zone storage.** The filter's parameters are **stored per-zone**,
alongside the other playback parameters — Sample/Zone panel parity applies,
same as the existing per-zone controls (VOICE and MASTER remain the
per-instance exceptions). *(Settled by second follow-up.)*
- **Off by default.** The filter **defaults to off** — pre-existing saved
instances and freshly loaded captures sound unchanged until the user engages
it. *(Settled by second follow-up.)*
- **Velocity and key-tracking modulation — in this item, not deferred.** The
filter gains **velocity** and **key-tracking** modulation now, alongside the
mod-amt/envelope path: the same idea as the amp's velocity transfer curve
and the pitch key-tracking, respectively, applied to the filter. The
follow-up establishes the parallel, not new ranges or control layout — those
follow the cited precedents. *(Settled by second follow-up.)*
- **Label.** The user-facing deck-group label is **"Filter"**. "MM preamp" is - **Label.** The user-facing deck-group label is **"Filter"**. "MM preamp" is
working shorthand for the DSP lineage, not UI text. *(Settled by working shorthand for the DSP lineage, not UI text. *(Settled by
follow-up.)* follow-up.)*
@@ -167,16 +207,8 @@ AHDSR envelope, and make the knob-deck row read in signal-flow order.
**Open questions.** **Open questions.**
- **Other mod sources.** Mod amt targeting cutoff is settled; whether any - None remaining — all three prior questions (other mod sources, parameter
other mod sources (velocity, key-tracking) are in scope now or deferred is storage side, neutral default) closed by the second follow-up round.
unstated.
- **Parameter storage: per-zone or per-instance.** Per-voice *processing* is
settled, but it is compatible with either storage side. Existing playback
parameters live per-zone with Sample/Zone panel parity; VOICE and MASTER are
per-instance exceptions. Which side do the filter *parameters* fall on?
- **Neutral default.** Should the filter default to a bypass/neutral state so
pre-existing saved instances (and freshly loaded captures) sound unchanged
until the user engages it?
**Acceptance criteria.** **Acceptance criteria.**
@@ -196,9 +228,16 @@ AHDSR envelope, and make the knob-deck row read in signal-flow order.
- Two simultaneously sounding voices at different envelope phases are filtered - Two simultaneously sounding voices at different envelope phases are filtered
independently (per-voice processing is audible, not a shared instance-wide independently (per-voice processing is audible, not a shared instance-wide
filter). filter).
- Filter parameters follow Sample/Zone panel parity: they appear and edit on
both surfaces, and each zone carries its own filter settings (two zones with
different filter settings audibly differ).
- Velocity and key-tracking modulation of the filter ship with this item and
are audible — velocity following the amp-velocity-transfer-curve pattern,
key-tracking following the pitch-key-tracking pattern.
- The deck row reads pitch → filter → amp left-to-right. - The deck row reads pitch → filter → amp left-to-right.
- A project saved before this change reopens sounding identical (pending the - The filter is off by default: a project saved before this change reopens
neutral-default confirmation above). sounding identical, and a freshly loaded capture sounds unchanged until the
filter is engaged.
--- ---
@@ -231,6 +270,13 @@ AHDSR envelope, and make the knob-deck row read in signal-flow order.
> the length. all the soft points between any hard points will be > the length. all the soft points between any hard points will be
> smooth/monotone. > smooth/monotone.
**Daniel's second follow-up (verbatim, 2026-07-28).**
> normalize the spline eg length to the full width, it should represent the
> time axis of the actual sample visually 1:1
> left click add, alt-click delete, cntrl-click toggles point hard or soft.
> spline active -> stage knobs disabled.
**Intent.** Offer a free-drawn alternative to every staged envelope: the user **Intent.** Offer a free-drawn alternative to every staged envelope: the user
switches any EG from Staged to Spline mode and draws the contour directly, with switches any EG from Staged to Spline mode and draws the contour directly, with
the monotonic-spline machinery already proven by the velocity curve — enhanced the monotonic-spline machinery already proven by the velocity curve — enhanced
@@ -248,6 +294,21 @@ so sharp corners are possible, not everything smoothed.
Spline EG is active**; the spline **always covers the full sample length** Spline EG is active**; the spline **always covers the full sample length**
a pure time function over the sample, i.e. the Trigger/one-shot playback a pure time function over the sample, i.e. the Trigger/one-shot playback
model. *(Settled by follow-up.)* model. *(Settled by follow-up.)*
- **Time axis: normalized, visually 1:1.** The spline contour is **normalized
to the full sample length**, and the overlay represents **the time axis of
the actual sample visually 1:1** — the contour's full width maps directly
onto the displayed sample. Consequently a different-length capture rescales
the stored contour to its own length. *(Settled by second follow-up.)*
- **Point-editing grammar.** **Left-click adds a point; alt-click deletes a
point; control-click toggles a point hard/smooth.** Alt-click-delete
supersedes the earlier speculation that the velocity-curve popup's
right-click-delete grammar would be reused. *(Settled by second follow-up;
control-click hard/smooth confirms the original ask.)*
- **Staged controls disabled while Spline is active.** While a Spline EG is
active, that envelope's **staged segment knobs are disabled** — inert, not
merely inaudible — including their item-1 inner curve dials (the dial is
part of the knob). The dormant staged state is edited only by switching back
to Staged mode. *(Settled by second follow-up.)*
- **Not globally monotone.** Spline contours **don't have to rise and fall and - **Not globally monotone.** Spline contours **don't have to rise and fall and
are not globally monotone**; the monotone guarantee is per-segment — **all are not globally monotone**; the monotone guarantee is per-segment — **all
soft points between any hard points are smooth/monotone** (no overshoot soft points between any hard points are smooth/monotone** (no overshoot
@@ -277,26 +338,24 @@ so sharp corners are possible, not everything smoothed.
**Open questions.** **Open questions.**
- **Time-axis storage.** Full-sample coverage is settled ("spline always - **Point-count bounds.** The add/delete/toggle gestures are settled, but any
covers the full sample length"); what remains is only whether the stored minimum/maximum point count is unstated (a floor of two endpoints seems
contour is normalized to the sample length (so it rescales when a implied by full-length coverage; a ceiling, if any, is Daniel's call).
different-length capture loads) or anchored some other way. - **Velocity-curve popup gesture convergence.** The Spline-EG grammar is
- **Point-editing grammar.** Point add/delete gestures and any point-count alt-click delete, but the existing velocity-curve popup shipped with
bound are unstated. The velocity-curve popup already established right-click right-click node delete. Since the enhanced spline serves both, does the
node delete — reuse of that grammar seems natural but is Daniel's call. popup migrate to the alt-click grammar for consistency, keep right-click, or
- **Staged controls while Spline is active.** Sound-wise the staged EG is accept both?
inactive in Spline mode (settled by dual-state). Still open at the UI level:
do the staged segment knobs/inner dials stay editable (editing the dormant
staged state) or go inert/greyed until the user switches back?
**Acceptance criteria.** **Acceptance criteria.**
- Each of the pitch, filter, and amp EGs offers a Staged/Spline mode switch; - Each of the pitch, filter, and amp EGs offers a Staged/Spline mode switch;
in Spline mode the overlay (via the item-1 radio switch) shows and edits the in Spline mode the overlay (via the item-1 radio switch) shows and edits the
drawn contour, and played notes audibly follow it. drawn contour, and played notes audibly follow it.
- Control-click toggles any point hard/smooth; points are smooth by default; a - Left-click on the contour adds a point at that position; alt-click on a
hard point renders a visible sharp angle with no smoothing on either point deletes it; control-click toggles it hard/smooth. Points are smooth by
adjacent segment, and the discontinuous slope is audible where the default; a hard point renders a visible sharp angle with no smoothing on
either adjacent segment, and the discontinuous slope is audible where the
modulation target makes it so (e.g. a pitch EG corner). modulation target makes it so (e.g. a pitch EG corner).
- A contour of several segments joined at hard points plays back over the full - A contour of several segments joined at hard points plays back over the full
sample length exactly as drawn — including contours that rise and fall sample length exactly as drawn — including contours that rise and fall
@@ -305,6 +364,13 @@ so sharp corners are possible, not everything smoothed.
- A freshly created Spline EG shows the smooth y = 1 x default contour. - A freshly created Spline EG shows the smooth y = 1 x default contour.
- While a Spline EG is active, Gate mode is not selectable; the spline plays - While a Spline EG is active, Gate mode is not selectable; the spline plays
as a pure time function over the full sample length. as a pure time function over the full sample length.
- The overlay contour spans the full displayed sample width, 1:1 with the
sample's time axis; loading a different-length capture rescales the contour
to the new sample length (normalized storage), with the drawn shape
preserved proportionally.
- While a Spline EG is active, that envelope's staged segment knobs and their
inner curve dials render disabled and reject edits; switching back to Staged
re-enables them with values exactly as left.
- Staged↔Spline round-trip preserves both states: switch to Spline, draw, - Staged↔Spline round-trip preserves both states: switch to Spline, draw,
switch back — the staged values are exactly as left; switch forward again — switch back — the staged values are exactly as left; switch forward again —
the spline contour is exactly as drawn. Both survive save/reload. the spline contour is exactly as drawn. Both survive save/reload.