docs(TODO-1.0): fold in Daniel's answers — radio none-state, knot curve-drag, Filter ranges/label, dual-state Spline EGs
This commit is contained in:
+118
-58
@@ -9,6 +9,12 @@ post-Q layout at execution time. Each item preserves Daniel's raw ask verbatim
|
|||||||
as the source of truth, then breaks it into behavior, open questions, and an
|
as the source of truth, then breaks it into behavior, open questions, and an
|
||||||
observable acceptance gate.
|
observable acceptance gate.
|
||||||
|
|
||||||
|
A follow-up answer round from Daniel (2026-07-28) settled most of the open
|
||||||
|
questions. Each item now carries his follow-up verbatim alongside the original
|
||||||
|
ask; settled answers are folded into **Behavior** (marked *settled by
|
||||||
|
follow-up*), and only the genuinely unresolved remainder stays under **Open
|
||||||
|
questions**.
|
||||||
|
|
||||||
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.
|
||||||
@@ -34,6 +40,12 @@ in sequence or together, but 1 and 2 are prerequisites for 3's full surface.
|
|||||||
> contrasts poorly against the primary green waveform display. Change those to
|
> contrasts poorly against the primary green waveform display. Change those to
|
||||||
> tertiary purple.
|
> tertiary purple.
|
||||||
|
|
||||||
|
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||||||
|
|
||||||
|
> yes, one overlay (or none). Everything besides Hold and Sustain, right? "is
|
||||||
|
> 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.
|
||||||
|
|
||||||
**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
|
||||||
@@ -46,11 +58,22 @@ contrast failure.
|
|||||||
gains a radio switch in the corner of its deck. Selecting a deck's radio
|
gains a radio switch in the corner of its deck. Selecting a deck's radio
|
||||||
makes *that* envelope the one displayed and editable in the graphic waveform
|
makes *that* envelope the one displayed and editable in the graphic waveform
|
||||||
overlay — replacing today's behavior where the Amp AHDSR is always the
|
overlay — replacing today's behavior where the Amp AHDSR is always the
|
||||||
displayed envelope.
|
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.
|
||||||
|
*(Settled by follow-up.)*
|
||||||
- **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,
|
||||||
range **0.1 to 10**.
|
range **0.1 to 10**.
|
||||||
|
- **Which segments are sloped.** **Every stage except Hold and Sustain** — for
|
||||||
|
an AHDSR that is Attack, Decay, and Release; for the Pitch AD, both stages.
|
||||||
|
*(Settled by follow-up.)*
|
||||||
|
- **Linear neutral.** Exponent **1.0 is the linear neutral** (y = x^1.0 is
|
||||||
|
linear). *(Settled by follow-up — emphatically.)*
|
||||||
|
- **Curve editing in the overlay.** Dragging on a segment in the overlay
|
||||||
|
**adds a round mid-segment knot** whose drag adjusts that segment's curve —
|
||||||
|
the overlay is a curve-edit surface in its own right, alongside (not instead
|
||||||
|
of) the inner dial. *(Settled by follow-up.)*
|
||||||
- **Inner dial on curvable-segment knobs.** Every knob-deck radial knob that
|
- **Inner dial on curvable-segment knobs.** Every knob-deck radial knob that
|
||||||
controls a sloped, curvable segment gains an **inner dial**: its own inner
|
controls a sloped, curvable segment gains an **inner dial**: its own inner
|
||||||
arc, its own hover accent (tertiary purple), its own needle, and its own
|
arc, its own hover accent (tertiary purple), its own needle, and its own
|
||||||
@@ -63,30 +86,28 @@ contrast failure.
|
|||||||
|
|
||||||
**Open questions.**
|
**Open questions.**
|
||||||
|
|
||||||
- **Radio exclusivity + default.** "Radio" implies exactly one envelope is
|
- **Default overlay selection on open.** Exclusivity and the none-state are
|
||||||
overlay-active at a time across all decks — confirm that reading, and
|
settled; what is the default when the editor opens — the Amp AHDSR (today's
|
||||||
confirm the Amp AHDSR remains the default selection on open.
|
behavior) or none?
|
||||||
- **Which segments are "sloped."** Per envelope type, which segments carry a
|
- **Pre-existing instances.** Should saved instances from before this change
|
||||||
curve dial? (E.g. Attack/Decay/Release obviously slope; Hold and Sustain
|
load with every curve at the linear equivalent (exponent 1.0) so their sound
|
||||||
presumably do not — needs Daniel's confirmation per stage.)
|
is unchanged? (The neutral point itself is settled; this is only the
|
||||||
- **Curve default and neutral point.** Is exponent 1.0 the linear/neutral
|
load-behavior half. The product requirement is "old instances sound
|
||||||
default, and should existing saved instances load with all curves at the
|
identical.")
|
||||||
linear-equivalent so their sound is unchanged? (Persistence extension is
|
|
||||||
implied; the product requirement is only "old instances sound identical.")
|
|
||||||
- **Curve editing in the overlay.** Is the curve exponent editable *from the
|
|
||||||
overlay itself* (e.g. dragging a segment's belly), or is the inner dial the
|
|
||||||
sole curve-edit affordance and the overlay edits node positions only?
|
|
||||||
Daniel's ask specifies the dial; overlay curve-drag is not stated either way.
|
|
||||||
|
|
||||||
**Acceptance criteria.**
|
**Acceptance criteria.**
|
||||||
|
|
||||||
- Each envelope deck shows a corner radio switch; activating one puts that
|
- Each envelope deck shows a corner radio switch; activating one puts that
|
||||||
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.
|
immediately. At most one envelope is overlay-active; with none active, the
|
||||||
|
overlay draws no envelope.
|
||||||
- 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
|
||||||
notes.
|
notes. Hold and Sustain knobs carry no inner dial.
|
||||||
|
- Dragging on an overlay segment adds a round mid-segment knot; dragging the
|
||||||
|
knot adjusts that segment's curve, and the segment's inner dial reflects the
|
||||||
|
same value.
|
||||||
- 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
|
||||||
@@ -105,6 +126,13 @@ contrast failure.
|
|||||||
> mod amt, then the AHDSR controls as described above. The knob deck row will
|
> mod amt, then the AHDSR controls as described above. The knob deck row will
|
||||||
> then be relaid out in signal flow order: pitch -> filter -> amp
|
> then be relaid out in signal flow order: pitch -> filter -> amp
|
||||||
|
|
||||||
|
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||||||
|
|
||||||
|
> modes beyond the pass filters will be added later. cutoff range full audio
|
||||||
|
> spectrum, log scaled, fully open to fully closed, Q should go from 0.1 to 10
|
||||||
|
> 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"
|
||||||
|
|
||||||
**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.
|
||||||
@@ -120,28 +148,35 @@ AHDSR envelope, and make the knob-deck row read in signal-flow order.
|
|||||||
- **Parameters.** Mode, cutoff, Q, and mod amt — then the AHDSR controls,
|
- **Parameters.** Mode, cutoff, Q, and mod amt — then the AHDSR controls,
|
||||||
treated exactly as item 1 specifies (curvable sloped segments with inner
|
treated exactly as item 1 specifies (curvable sloped segments with inner
|
||||||
dials, overlay editability via the filter deck's radio switch).
|
dials, overlay editability via the filter deck's radio switch).
|
||||||
|
*(Ranges settled by follow-up:)*
|
||||||
|
- **Mode:** high-pass and low-pass now; **modes beyond the pass filters are
|
||||||
|
explicitly deferred to later.**
|
||||||
|
- **Cutoff:** the **full audio spectrum, log scaled**, from fully open to
|
||||||
|
fully closed.
|
||||||
|
- **Q:** **0.1 to 10** (the curve-exponent range again), scaled so **√2 sits
|
||||||
|
at the center** of the control.
|
||||||
|
- **Mod amt:** **bipolar, −100% to +100%**, targeting **cutoff** — covering
|
||||||
|
the full range from either end.
|
||||||
|
- **Per-voice.** The filter processes **per voice** — each sounding voice runs
|
||||||
|
its own filter with its own envelope state. *(Settled by follow-up.)*
|
||||||
|
- **Label.** The user-facing deck-group label is **"Filter"**. "MM preamp" is
|
||||||
|
working shorthand for the DSP lineage, not UI text. *(Settled by
|
||||||
|
follow-up.)*
|
||||||
- **Deck reorder.** The knob deck row is relaid out in signal-flow order:
|
- **Deck reorder.** The knob deck row is relaid out in signal-flow order:
|
||||||
**pitch → filter → amp**.
|
**pitch → filter → amp**.
|
||||||
|
|
||||||
**Open questions.**
|
**Open questions.**
|
||||||
|
|
||||||
- **Mode list.** Is mode a discrete selector, and over exactly which entries?
|
- **Other mod sources.** Mod amt targeting cutoff is settled; whether any
|
||||||
"Resonant high and lowpass" confirms HP and LP; whether band-pass/notch or
|
other mod sources (velocity, key-tracking) are in scope now or deferred is
|
||||||
multiple slopes exist depends on the Cortex-M4 source and Daniel's intent.
|
unstated.
|
||||||
- **Ranges and units.** Cutoff range (Hz), Q range, and mod-amt range/polarity
|
- **Parameter storage: per-zone or per-instance.** Per-voice *processing* is
|
||||||
(unipolar or bipolar?) are unstated — likely settled by the Cortex-M4 code
|
settled, but it is compatible with either storage side. Existing playback
|
||||||
plus a Daniel call at implementation time.
|
parameters live per-zone with Sample/Zone panel parity; VOICE and MASTER are
|
||||||
- **Mod routing.** "Mod amt" presumably scales the filter AHDSR's modulation of
|
per-instance exceptions. Which side do the filter *parameters* fall on?
|
||||||
cutoff — confirm the target is cutoff and whether any other mod sources
|
|
||||||
(velocity, key-tracking) are in scope now or deferred.
|
|
||||||
- **Scope: per-zone or per-instance.** Existing playback parameters live
|
|
||||||
per-zone with Sample/Zone panel parity; VOICE and MASTER are per-instance
|
|
||||||
exceptions. Which side does the filter fall on?
|
|
||||||
- **Neutral default.** Should the filter default to a bypass/neutral state so
|
- **Neutral default.** Should the filter default to a bypass/neutral state so
|
||||||
pre-existing saved instances (and freshly loaded captures) sound unchanged
|
pre-existing saved instances (and freshly loaded captures) sound unchanged
|
||||||
until the user engages it?
|
until the user engages it?
|
||||||
- **Display name.** Is "MM Preamp Filter" the user-facing label for the deck
|
|
||||||
group, or working shorthand?
|
|
||||||
|
|
||||||
**Acceptance criteria.**
|
**Acceptance criteria.**
|
||||||
|
|
||||||
@@ -149,11 +184,18 @@ AHDSR envelope, and make the knob-deck row read in signal-flow order.
|
|||||||
pipeline point: the filter acts on pitched (post-pitch-envelope) signal, and
|
pipeline point: the filter acts on pitched (post-pitch-envelope) signal, and
|
||||||
the amp envelope still shapes the filtered result (audible ordering:
|
the amp envelope still shapes the filtered result (audible ordering:
|
||||||
pitch → filter → amp).
|
pitch → filter → amp).
|
||||||
- Mode, cutoff, Q, and mod-amt controls appear in a filter deck group; the
|
- Mode, cutoff, Q, and mod-amt controls appear in a deck group labeled
|
||||||
filter AHDSR gets the full item-1 treatment (curve inner dials, corner radio
|
**"Filter"**; the filter AHDSR gets the full item-1 treatment (curve inner
|
||||||
switch, tertiary-purple overlay editing).
|
dials, corner radio switch, tertiary-purple overlay editing).
|
||||||
|
- Cutoff sweeps the full audio spectrum on a log scale, from fully open to
|
||||||
|
fully closed; Q spans 0.1 → 10 with √2 at the control's center; mod amt at
|
||||||
|
−100% and at +100% each drive cutoff across the full range, from opposite
|
||||||
|
ends.
|
||||||
- High Q audibly emphasizes the cutoff region (resonance) in both HP and LP
|
- High Q audibly emphasizes the cutoff region (resonance) in both HP and LP
|
||||||
modes.
|
modes.
|
||||||
|
- Two simultaneously sounding voices at different envelope phases are filtered
|
||||||
|
independently (per-voice processing is audible, not a shared instance-wide
|
||||||
|
filter).
|
||||||
- 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
|
- A project saved before this change reopens sounding identical (pending the
|
||||||
neutral-default confirmation above).
|
neutral-default confirmation above).
|
||||||
@@ -180,6 +222,15 @@ AHDSR envelope, and make the knob-deck row read in signal-flow order.
|
|||||||
> for the velocity-amp transfer curve as well as the pitch, filter, and amp EGs
|
> for the velocity-amp transfer curve as well as the pitch, filter, and amp EGs
|
||||||
> (if they are in spline mode).
|
> (if they are in spline mode).
|
||||||
|
|
||||||
|
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||||||
|
|
||||||
|
> dual state, save but inactive. Default Curve Spline is a smooth y=1-x. Gate
|
||||||
|
> mode is not available when the Spline is used, spline always covers the full
|
||||||
|
> sample length. The spline curves don't have to rise AND fall, they also
|
||||||
|
> aren't globally monotone, the default curve is a smooth downward slope over
|
||||||
|
> the length. all the soft points between any hard points will be
|
||||||
|
> smooth/monotone.
|
||||||
|
|
||||||
**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
|
||||||
@@ -189,6 +240,22 @@ so sharp corners are possible, not everything smoothed.
|
|||||||
|
|
||||||
- **Mode toggle per EG.** Every processor that has an envelope (pitch, filter,
|
- **Mode toggle per EG.** Every processor that has an envelope (pitch, filter,
|
||||||
amp) can switch its Staged EG to a **Spline EG**.
|
amp) can switch its Staged EG to a **Spline EG**.
|
||||||
|
- **Dual state — save but inactive.** Both the Staged and the Spline state are
|
||||||
|
persisted; switching modes keeps the inactive one **saved but inactive**. No
|
||||||
|
conversion, no discard — round-tripping Staged↔Spline restores the other
|
||||||
|
mode's shape untouched. *(Settled by follow-up.)*
|
||||||
|
- **Gate unavailable in Spline mode.** Gate mode is **not available while a
|
||||||
|
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
|
||||||
|
model. *(Settled by follow-up.)*
|
||||||
|
- **Not globally monotone.** Spline contours **don't have to rise and fall and
|
||||||
|
are not globally monotone**; the monotone guarantee is per-segment — **all
|
||||||
|
soft points between any hard points are smooth/monotone** (no overshoot
|
||||||
|
between adjacent points). *(Settled by follow-up.)*
|
||||||
|
- **Default contour.** A new Spline EG defaults to a **smooth y = 1 − x** — a
|
||||||
|
smooth downward slope over the full sample length. (Read as the Spline-EG
|
||||||
|
default contour; not a change to the velocity→amp transfer curve's existing
|
||||||
|
default.) *(Settled by follow-up.)*
|
||||||
- **Spline foundation.** The Spline EG is based on the monotonic splines used
|
- **Spline foundation.** The Spline EG is based on the monotonic splines used
|
||||||
for the velocity curve. The spline algorithm is singly implemented and
|
for the velocity curve. The spline algorithm is singly implemented and
|
||||||
multi-referenced; the enhancement below applies to that one implementation
|
multi-referenced; the enhancement below applies to that one implementation
|
||||||
@@ -210,30 +277,17 @@ so sharp corners are possible, not everything smoothed.
|
|||||||
|
|
||||||
**Open questions.**
|
**Open questions.**
|
||||||
|
|
||||||
- **Staged↔Spline toggle semantics.** What happens to a Staged EG's values
|
- **Time-axis storage.** Full-sample coverage is settled ("spline always
|
||||||
when toggling to Spline mode and back? (Convert the staged shape into an
|
covers the full sample length"); what remains is only whether the stored
|
||||||
initial spline? Keep two independent per-mode states? Discard?) Daniel has
|
contour is normalized to the sample length (so it rescales when a
|
||||||
not said — this materially shapes both UX and persistence and needs his
|
different-length capture loads) or anchored some other way.
|
||||||
call.
|
|
||||||
- **Gate-mode sustain/release.** A Staged Gate envelope holds at Sustain and
|
|
||||||
releases on note-off; a spline contour drawn "over the full sample length"
|
|
||||||
is a pure time function. How do note-off, sustain, and looped playback map
|
|
||||||
onto a Spline EG in Gate mode? (Trigger/one-shot is the natural fit; Gate
|
|
||||||
needs a stated rule.)
|
|
||||||
- **Time axis.** Is the contour's time axis normalized to the sample length
|
|
||||||
(so it rescales with the sample) or absolute seconds? "Over the full sample
|
|
||||||
length" suggests sample-relative — confirm, especially for looped sustain.
|
|
||||||
- **Monotonicity meaning.** The velocity spline is monotone to prevent
|
|
||||||
overshoot on a transfer curve. An EG contour must rise and fall; presumably
|
|
||||||
"monotonic" here means the per-segment no-overshoot property (values never
|
|
||||||
exceed the segment's endpoints), not a globally monotone function — confirm
|
|
||||||
the intended guarantee.
|
|
||||||
- **Point-editing grammar.** Point add/delete gestures and any point-count
|
- **Point-editing grammar.** Point add/delete gestures and any point-count
|
||||||
bound are unstated. The velocity-curve popup already established right-click
|
bound are unstated. The velocity-curve popup already established right-click
|
||||||
node delete — reuse of that grammar seems natural but is Daniel's call.
|
node delete — reuse of that grammar seems natural but is Daniel's call.
|
||||||
- **Interaction with item-1 curve dials.** In Spline mode, do the staged
|
- **Staged controls while Spline is active.** Sound-wise the staged EG is
|
||||||
segment knobs/inner dials go inert (shape comes wholly from the spline), or
|
inactive in Spline mode (settled by dual-state). Still open at the UI level:
|
||||||
is some hybrid intended? Presumably the former — confirm.
|
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.**
|
||||||
|
|
||||||
@@ -245,8 +299,14 @@ so sharp corners are possible, not everything smoothed.
|
|||||||
adjacent segment, and the discontinuous slope is audible where the
|
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.
|
sample length exactly as drawn — including contours that rise and fall
|
||||||
|
freely (no globally-monotone restriction), with no overshoot between any
|
||||||
|
adjacent pair of points.
|
||||||
|
- 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
|
||||||
|
as a pure time function over the full sample length.
|
||||||
|
- Staged↔Spline round-trip preserves both states: switch to Spline, draw,
|
||||||
|
switch back — the staged values are exactly as left; switch forward again —
|
||||||
|
the spline contour is exactly as drawn. Both survive save/reload.
|
||||||
- The velocity→amp transfer-curve editor supports the same control-click
|
- The velocity→amp transfer-curve editor supports the same control-click
|
||||||
hard/smooth toggle with identical rendering behavior.
|
hard/smooth toggle with identical rendering behavior.
|
||||||
- Staged↔Spline toggling behaves per the answered open question above (that
|
|
||||||
answer gates this item's completion definition).
|
|
||||||
|
|||||||
Reference in New Issue
Block a user