1059 lines
56 KiB
Markdown
1059 lines
56 KiB
Markdown
# TODO-1.0
|
||
|
||
Post-1.0 queue for ReaSampler — chiefly the 9000 instrument, plus two
|
||
extension-side bugs. Items 1–3 are the first batch, in Daniel's ordering
|
||
(2026-07-28); items 4–13 are a second batch (2026-07-28, later the same day);
|
||
item 14 is a third, single-item batch (2026-07-28, later again).
|
||
Deliberately specified at the level of product
|
||
intent, user-visible behavior, and acceptance criteria — **no implementation
|
||
design, no file/module references**. These were authored while Phase Q was
|
||
restructuring the tree; the implementing engineer maps each spec onto the
|
||
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
|
||
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**.
|
||
|
||
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*).
|
||
|
||
A **third follow-up round** (2026-07-28, same day) settled item 3's last two
|
||
questions (point-count ceiling; delete gesture — reversing the second round's
|
||
alt-click answer back to right-click). **All three first-batch items now have
|
||
no open questions; the first batch is fully settled at the product level.**
|
||
|
||
A **second batch** from Daniel (2026-07-28) appends items 4–13 — a mix of bug
|
||
reports and enhancements. His message numbered them 1, 2, 3, 4, 3, 4, 5, 6, 7,
|
||
8 (two items labelled 3 and two labelled 4). His *sequence* is preserved
|
||
exactly; each item carries an unambiguous doc number continuing from 3, with
|
||
his original label recorded in the heading (e.g. *his 3, second*) so his
|
||
message maps onto the doc. Each item is marked **Bug** or **Enhancement**;
|
||
item 9 is explicitly both — a suspected regression plus a feature spec. Bugs
|
||
are recorded compactly (symptom, expected behavior, acceptance gate) with **no
|
||
root-cause analysis** — same no-code-reads constraint as the first batch.
|
||
|
||
A **second-batch follow-up round** (2026-07-28, same day) answered items 7, 8,
|
||
and 11. Item 7 closes clean. Item 11's answer **supersedes the original ask's
|
||
button placement** — a new VELOCITY deck group replaces the per-section
|
||
placement, MASTER being reserved for later post-voice-mixer concerns. Item 8's
|
||
answer is a **spec change, not a clarification**: the pitch envelope's AD
|
||
becomes an **AHD** (a Hold stage is added), and the doc's own prose (items 1
|
||
and 8) is updated to match — Daniel's verbatim asks stay exactly as originally
|
||
written.
|
||
|
||
A **second-batch second follow-up round** (2026-07-28, same day) closed item
|
||
8's last two questions — Hold's 0–100% reference, and the scope of the
|
||
1:1-overlay/combined-bound policy. **With that, no open question then in the
|
||
doc awaited a Daniel decision.** Everything still marked open in items 1–13 is
|
||
verify-or-propose-at-implementation, not a blocker: item 9's loop-point
|
||
regression verification and its spec details (crossfade units, storage
|
||
confirmation, editing surface — each carries its own resolve-at-review path in
|
||
the item), and item 11's does-a-user-facing-pitch-velocity-curve-already-exist
|
||
check. Nothing in items 1–13 is blocked on Daniel.
|
||
|
||
A **third batch** (2026-07-28, later again) appends item 14 — a single
|
||
consolidation enhancement: in Trigger mode the amp envelope's
|
||
fade-in-length/fade-out-length pair is replaced by item 8's AHD (with item 1's
|
||
curves), so the amp envelope's staged shape follows the playback mode —
|
||
Gate → AHDSR, Trigger → AHD. Item 8's sustain-stage scope rule then covers the
|
||
amp envelope literally, not just by analogy (a one-line cross-reference is
|
||
added there). Item 14 arrived carrying one question awaiting a Daniel
|
||
decision — whether item 2's filter AHDSR follows the same mode-driven shape —
|
||
answered by the round below. Its other open question (stage-value state across
|
||
the Gate/Trigger switch) is propose-at-implementation-review, not
|
||
Daniel-blocking.
|
||
|
||
A **third-batch follow-up round** (2026-07-28, same day) answered item 14's
|
||
filter question: **the filter envelope follows the same mode-driven shape** —
|
||
Gate → AHDSR, Trigger → AHD. Item 8's scope rule now governs all three
|
||
envelopes uniformly (the general statement lives in item 14; item 2 carries a
|
||
cross-reference), and item 14's remaining stage-value question now covers the
|
||
filter envelope too. **With that, no open question anywhere in the doc awaits
|
||
a Daniel decision.** Everything still open across all 14 items is
|
||
verify-or-propose-at-implementation: item 9's loop-point regression
|
||
verification and its spec details, item 11's
|
||
does-a-pitch-velocity-curve-already-exist check, and item 14's
|
||
shared-vs-per-mode stage-value question. Nothing in items 1–14 is blocked on
|
||
Daniel.
|
||
|
||
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
|
||
in sequence or together, but 1 and 2 are prerequisites for 3's full surface.
|
||
Second-batch interactions: the three bugs (4–6) are independent of the
|
||
enhancement chain and can land at any time. Item 8 edits the same overlay
|
||
surface as item 1 and is cheapest folded into or immediately after that work;
|
||
item 10's per-ring reset presupposes item 1's inner dials; item 11's filter
|
||
velocity curve presupposes item 2's filter (though its button now homes in
|
||
item 11's own VELOCITY deck, not the Filter deck); item 9's
|
||
loop-sustain is a Gate-mode (Staged) feature and composes with item 3's
|
||
Gate-unavailable-in-Spline rule. Item 13 (anti-aliasing audit) touches nearly
|
||
every surface the other items repaint — sequencing it after the layout/knob
|
||
work (1, 8, 10, 11, 12) likely avoids doing the polish twice; that is an
|
||
observation, not a decision. Item 14 (third batch) rides directly on item 8's
|
||
AHD definition and item 1's curve treatment — cheapest folded into or
|
||
immediately after that combined work — and repaints amp-deck/overlay surface
|
||
that items 10 and 13 later polish; its filter half (the filter envelope
|
||
following the same mode-driven shape) necessarily lands with or after item 2.
|
||
|
||
---
|
||
|
||
## 1 — Envelope editor: per-deck radio switch, segment curve dials, overlay recolor
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> The VST envelope editor visual is a great start but we need to add some
|
||
> features. The Amp AHDSR is currently always displayed. We need to add a radio
|
||
> switch to the corner of each env knob deck which makes THAT envelope editable
|
||
> via the graphic waveform overlay. This is currently the amp and pitch
|
||
> envelopes, with filter to be added (see below). All envelopes (amp AHDSR,
|
||
> Pitch AD, Filter AHDSR) should be enhanced to have editable segment curve
|
||
> values. This should be an exponential function with the exponent scalar
|
||
> parameter for each sloped segment having possible values from 0.1 to 10. The
|
||
> knob deck radial knobs for the sloped curvable segments will have an INNER
|
||
> dial, with its own inner arc, hover accent (tertiary purple), needle, and
|
||
> numerical label which controls the curve for that sloped segment. Also the
|
||
> graphical envelope editor draws its segments in secondary blue, which
|
||
> contrasts poorly against the primary green waveform display. Change those to
|
||
> 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.
|
||
|
||
**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
|
||
shared graphical surface for every envelope in the instrument, and give every
|
||
envelope shapeable (non-linear) segments — while fixing the blue-on-green
|
||
contrast failure.
|
||
|
||
**Behavior.**
|
||
|
||
- **Radio switch per envelope deck.** Each envelope knob-deck group (currently
|
||
AMP ENVELOPE and PITCH ENV; the filter envelope joins when item 2 lands)
|
||
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
|
||
overlay — replacing today's behavior where the Amp AHDSR is always the
|
||
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.)*
|
||
- **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 AHD (AD in the
|
||
original ask; item 8's follow-up adds the Hold stage), and Filter AHDSR all
|
||
gain an editable curve value per *sloped* segment. The curve is an
|
||
exponential function; the per-segment parameter is the exponent scalar,
|
||
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 AHD (A→H→D since
|
||
item 8's spec change), Attack and Decay — its Hold, like every Hold, is flat
|
||
and carries no curve dial. *(Settled by follow-up; the pitch reading updated
|
||
for item 8's AD→AHD change.)*
|
||
- **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
|
||
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
|
||
numerical label. The inner dial controls the curve exponent for that
|
||
segment; the outer knob keeps controlling the segment's time/level value as
|
||
today.
|
||
- **Overlay recolor.** The graphical envelope editor's segments change from
|
||
secondary blue to **tertiary purple** (secondary blue contrasts poorly
|
||
against the primary green waveform behind it).
|
||
|
||
**Open questions.**
|
||
|
||
- None remaining — both prior questions (default overlay selection,
|
||
pre-existing-instance curve loading) closed by the second follow-up round.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- Each envelope deck shows a corner radio switch; activating one puts that
|
||
envelope in the overlay, editable there, and the overlay tracks the switch
|
||
immediately. At most one envelope is overlay-active; with none active, the
|
||
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
|
||
hover accent, needle, numeric label); sweeping it through 0.1 → 10 visibly
|
||
reshapes the overlay segment and audibly reshapes the envelope on played
|
||
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
|
||
against the primary green waveform.
|
||
- A project saved before this change reopens with unchanged audible envelope
|
||
behavior: every curve loads at exponent 1.0.
|
||
|
||
---
|
||
|
||
## 2 — MM preamp Filter: resonant HP/LP stage in the voice pipeline
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> MM preamp Filter: We must implement a new processing point in the sampler
|
||
> audio pipeline, after pitch env, before amp, for filtering. The processor for
|
||
> this will be based on code I wrote for the cortex M4 for resonant high and
|
||
> lowpass filtering. The filter will have parameters for mode, cutoff, Q, and
|
||
> 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
|
||
|
||
**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"
|
||
|
||
**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
|
||
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.
|
||
|
||
**Behavior.**
|
||
|
||
- **Pipeline position.** A new processing point in the sampler audio pipeline:
|
||
**after the pitch envelope, before the amp stage.**
|
||
- **DSP source.** The filter processor is based on Daniel's own Cortex-M4
|
||
resonant high/lowpass filter code. **That code is an input Daniel supplies at
|
||
implementation time** — it is not in this repo and this spec does not
|
||
characterize it beyond "resonant high and lowpass."
|
||
- **Parameters.** Mode, cutoff, Q, and mod amt — then the AHDSR controls,
|
||
treated exactly as item 1 specifies (curvable sloped segments with inner
|
||
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.
|
||
- **Mode-driven envelope shape.** The filter envelope follows the playback
|
||
mode exactly as the amp does: **Gate → AHDSR, Trigger → AHD** — see item 14,
|
||
where the policy is stated in full. *(Settled by item 14's follow-up.)*
|
||
- **Per-voice.** The filter processes **per voice** — each sounding voice runs
|
||
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
|
||
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:
|
||
**pitch → filter → amp**.
|
||
|
||
**Open questions.**
|
||
|
||
- None remaining — all three prior questions (other mod sources, parameter
|
||
storage side, neutral default) closed by the second follow-up round.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- With the filter engaged, played notes are audibly filtered at the specified
|
||
pipeline point: the filter acts on pitched (post-pitch-envelope) signal, and
|
||
the amp envelope still shapes the filtered result (audible ordering:
|
||
pitch → filter → amp).
|
||
- Mode, cutoff, Q, and mod-amt controls appear in a deck group labeled
|
||
**"Filter"**; the filter AHDSR gets the full item-1 treatment (curve inner
|
||
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
|
||
modes.
|
||
- Two simultaneously sounding voices at different envelope phases are filtered
|
||
independently (per-voice processing is audible, not a shared instance-wide
|
||
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 filter is off by default: a project saved before this change reopens
|
||
sounding identical, and a freshly loaded capture sounds unchanged until the
|
||
filter is engaged.
|
||
|
||
---
|
||
|
||
## 3 — Alternative Spline EGs: hard/smooth multi-segment monotonic splines
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> Alternative Spline EGs: Every processor which has an envelope will have the
|
||
> ability to change the Staged EG to a Spline EG, based on the monotonic
|
||
> splines for the velocity curve. HOWEVER, we will need to enhance the (singly
|
||
> implemented, multi referenced) spline algorithm to support multiple segments
|
||
> that DON'T minimally smooth the spline, so that hard points are possible. In
|
||
> other words, the contour of the EG will be defined by 1 or more monotonic
|
||
> spline functions which together form the full time function for that
|
||
> processor, such that the first three points could make a curved segment,
|
||
> which connects at a sharp angle to the next three points, finishing out the
|
||
> contour over the full sample length. Control-clicking a point makes it a
|
||
> "hard" or "smooth" point (toggled, smooth by default) which when hard does no
|
||
> curve smoothing on either side segment, forming the natural sharp angle
|
||
> instead of a continuous derivative. This enhanced spline drawing will be used
|
||
> for the velocity-amp transfer curve as well as the pitch, filter, and amp EGs
|
||
> (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.
|
||
|
||
**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.
|
||
|
||
**Daniel's third follow-up (verbatim, 2026-07-28).**
|
||
|
||
> oh, maybe 64? is that way too much? I don't want to limit from long rhythmic
|
||
> phrases, which require a high resolution to be interesting
|
||
>
|
||
> oh, do right click delete instead for the spline
|
||
> 128 then
|
||
|
||
**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
|
||
the monotonic-spline machinery already proven by the velocity curve — enhanced
|
||
so sharp corners are possible, not everything smoothed.
|
||
|
||
**Behavior.**
|
||
|
||
- **Mode toggle per EG.** Every processor that has an envelope (pitch, filter,
|
||
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.)*
|
||
- **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; right-click deletes a
|
||
point; control-click toggles a point hard/smooth.** *(Settled by third
|
||
follow-up; control-click hard/smooth confirms the original ask.)* Note for
|
||
readers of the prior revision: the second follow-up answered alt-click
|
||
delete; the third follow-up **supersedes that** with right-click delete —
|
||
which matches the velocity-curve popup's already-shipped right-click node
|
||
delete, giving one point-editing grammar across both spline consumers.
|
||
- **Point-count ceiling: 128.** A spline contour holds at most **128 points**
|
||
(floor: the two endpoints implied by full-length coverage). Daniel floated
|
||
64 and raised it to 128 explicitly so the cap does not limit **long rhythmic
|
||
phrases, which require high resolution to be interesting** — at roughly two
|
||
points per articulation event, 64 points is about two bars of 16ths and 128
|
||
about four. The ceiling is a musical bound, not a performance one (segment
|
||
lookup is logarithmic; on-screen the editor's 8 px minimum node separation
|
||
is the practical density limit anyway). **An engineer tempted to lower this
|
||
number should read that motivation first.** *(Settled by third follow-up.)*
|
||
- **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
|
||
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
|
||
for the velocity curve. The spline algorithm is singly implemented and
|
||
multi-referenced; the enhancement below applies to that one implementation
|
||
and flows to every consumer.
|
||
- **Hard points.** The algorithm is enhanced to support **multiple segments
|
||
that don't minimally smooth the spline**, so hard points are possible: the
|
||
EG contour is defined by **one or more monotonic spline functions** which
|
||
together form the full time function for that processor — e.g. the first
|
||
three points form a curved segment that connects **at a sharp angle** to the
|
||
next three points, finishing the contour over the **full sample length**.
|
||
- **Hard/smooth gesture.** **Control-clicking a point toggles it hard/smooth
|
||
(smooth by default).** A hard point does no curve smoothing on either
|
||
adjacent segment — the natural sharp angle stands instead of a continuous
|
||
derivative.
|
||
- **Shared across consumers.** The enhanced spline drawing serves the
|
||
**velocity→amp transfer curve** as well as the pitch, filter, and amp EGs
|
||
(when those are in spline mode). The velocity curve gains hard-point support
|
||
by the same enhancement.
|
||
|
||
**Open questions.**
|
||
|
||
- None remaining — both prior questions closed by the third follow-up round.
|
||
Point-count bounds: ceiling 128, floor two endpoints. Gesture convergence:
|
||
resolved by the delete-gesture reversal itself — the Spline EG's right-click
|
||
delete now matches the velocity-curve popup's shipped right-click node
|
||
delete, so **no migration is needed on either side**; one grammar serves
|
||
both consumers.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- 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
|
||
drawn contour, and played notes audibly follow it.
|
||
- Left-click on the contour adds a point at that position; right-click on a
|
||
point deletes it; control-click toggles it hard/smooth. Points are smooth by
|
||
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).
|
||
- A contour accepts points up to the **128-point ceiling**; attempting to add
|
||
beyond it is refused without disturbing the existing contour. The two
|
||
endpoints cannot be deleted (full-length coverage always holds).
|
||
- 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
|
||
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.
|
||
- 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,
|
||
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
|
||
hard/smooth toggle with identical rendering behavior, and its existing
|
||
right-click node delete matches the Spline EG's delete gesture unchanged —
|
||
one point-editing grammar across both consumers.
|
||
|
||
---
|
||
|
||
## 4 — Bug: end-of-sample click in Trigger mode under Preserve *(his 1)*
|
||
|
||
**Daniel's report (verbatim, 2026-07-28).**
|
||
|
||
> actual bug: in trigger mode, polyphonic or monophonic, in preserved pitch
|
||
> mode only, the end of the sample has an audible click.
|
||
|
||
**Symptom.** In Trigger mode — polyphonic or monophonic alike — with the pitch
|
||
engine in **Preserve mode only**, the end of the sample produces an audible
|
||
click. The scoping is the useful part of the report and is recorded as given:
|
||
Trigger × Preserve × end-of-sample; Varispeed is not implicated. No cause
|
||
speculation here.
|
||
|
||
**Expected behavior.** A Trigger one-shot in Preserve mode ends silently — no
|
||
click or discontinuity at the sample end, in either voice mode.
|
||
|
||
**Acceptance gate.** A Trigger-mode note played in Preserve, in both Poly and
|
||
Mono, ends with no audible click at the sample end (verified by ear and by
|
||
inspecting the rendered output for a terminal discontinuity). Varispeed
|
||
playback is unchanged.
|
||
|
||
---
|
||
|
||
## 5 — Bug: drag-out sometimes lands without audio (extension) *(his 2)*
|
||
|
||
**Daniel's report (verbatim, 2026-07-28).**
|
||
|
||
> other bug (extension, not VST): Dragging capture out of the pool or bank does
|
||
> sometimes doesn't actually contain the audio, and I hae to try dragging
|
||
> again.
|
||
|
||
**Symptom.** Extension side, not the VST. Dragging a capture out of the pool
|
||
or a named bank **sometimes** produces a drop that does not actually contain
|
||
the audio; retrying the drag works. Both details are load-bearing: the failure
|
||
is intermittent, and a retry succeeds.
|
||
|
||
**Expected behavior.** Every completed drag-out delivers the capture's audio
|
||
at the drop target — first try, every time.
|
||
|
||
**Acceptance gate.** Because the failure is intermittent, the gate is a soak:
|
||
across a sustained session of varied drag-outs (pool and bank sources,
|
||
including the first drag after other bank activity), every drop yields a
|
||
playable file containing the audio, with no retry ever needed.
|
||
|
||
---
|
||
|
||
## 6 — Bug: drop onto FX container loads instrument without the capture *(his 3, first)*
|
||
|
||
**Daniel's report (verbatim, 2026-07-28).**
|
||
|
||
> drop to FX container bug: the reasmpler 9000 loads, but not with the capture.
|
||
> drop to FX button works as expected with capture preloaded.
|
||
|
||
**Symptom.** Dropping a capture onto an **FX container** loads a ReaSampler
|
||
9000 instance, but **without the capture**. Dropping the same capture onto the
|
||
**FX button** works as expected — instrument loads with the capture preloaded.
|
||
|
||
**Expected behavior.** The FX-button path is the reference; the container path
|
||
must match it: instrument added *with* the dragged capture loaded.
|
||
|
||
**Acceptance gate.** A capture dropped onto an FX container yields an
|
||
instrument instance with that capture loaded and immediately playable,
|
||
indistinguishable (apart from where the FX sits) from the FX-button drop. The
|
||
FX-button path remains unregressed.
|
||
|
||
---
|
||
|
||
## 7 — Enhancement: stereo waveform shows both channels *(his 4, first)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> VST Waveform Visualizer: in stereo mode, both L and R channels should show
|
||
> in the waveform visual. left on top. mono mode still shows just one channel
|
||
> for unredundancy.
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||
|
||
> 7) One full height; stereo linked processing, one editor
|
||
|
||
**Behavior.**
|
||
|
||
- In **stereo mode**, the waveform visual shows **both L and R channels, left
|
||
on top** (two stacked lanes).
|
||
- In **mono mode**, a single channel shows — no redundant duplicate lane.
|
||
- The display keys off the active channel mode, per Daniel's phrasing.
|
||
- **Overlays draw once, at full height.** Overlays that ride the waveform
|
||
(the envelope overlay, markers, and item 9's loop region if it lands) draw
|
||
**once at full height across both stacked lanes** — not per lane.
|
||
*(Settled by follow-up.)*
|
||
- **Stereo processing is linked.** One editor, one set of controls governing
|
||
both channels — no per-channel parameter divergence, no per-channel editing
|
||
surface. *(Settled by follow-up.)*
|
||
|
||
**Open questions.**
|
||
|
||
- None remaining — the overlay-layout question closed by the second-batch
|
||
follow-up round.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- A stereo capture in stereo mode shows two stacked lanes, L above R, each a
|
||
true view of its channel's content (an asymmetric-channel capture visibly
|
||
differs between lanes).
|
||
- Mono mode shows exactly one lane. Switching modes updates the display
|
||
accordingly.
|
||
- In stereo mode, waveform-riding overlays (envelope, markers, loop region if
|
||
present) render once at full stacked height — no duplicated per-lane copies
|
||
— and stay legible across both lanes.
|
||
- No per-channel controls appear; every edit applies identically to both
|
||
channels (linked stereo processing, one editor).
|
||
|
||
---
|
||
|
||
## 8 — Enhancement: staged-overlay release anchoring; the Pitch AD becomes AHD *(his 3, second)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> AHDSR visual overlay looks odd, not taking up the whole range. with no
|
||
> release, the sustain portion only travels accross a small portion of the
|
||
> panel, making the thing look off center. to resolve, the release segment
|
||
> should be anchored to the right, and draggable from the top node (connecting
|
||
> to sustain segment) instead of the bottom corner, which will now be anchored.
|
||
> All staged envelope overlays should follow this policy.
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||
|
||
> 8) For the AD... make it AHD, and the combined A H and D segment lengths
|
||
> (time displacement) cannot exceed the full sample length. Hold goes from 0
|
||
> to 100%, and the visual overlay for the envelope is then 1:1 scale with the
|
||
> waveform time. D is not release, so it is not right anchored.
|
||
|
||
**Daniel's second follow-up (verbatim, 2026-07-28).**
|
||
|
||
> 1) 100% of the sample length - attack+decay times
|
||
> 2) for all envelopes that DON'T have a sustain stage. The 1:1 mapping only
|
||
> makes sense for trigger, not gated envelopes
|
||
|
||
**Intent.** A layout-policy change to the staged envelope overlay so it uses
|
||
the full panel width: today, with little or no release, the sustain portion
|
||
occupies only a small stretch and the whole figure reads off-center. The
|
||
follow-up round grew this item beyond layout: it now also carries **the spec
|
||
change that turns the pitch envelope from AD into AHD**.
|
||
|
||
**Behavior.**
|
||
|
||
- The **release segment anchors to the right edge** of the overlay.
|
||
- Release is dragged from its **top node** — the node joining sustain to
|
||
release — instead of the bottom corner. The bottom corner (the envelope's
|
||
end point) becomes **fixed/anchored**, not draggable.
|
||
- **The policy applies to the envelopes that have a release** — the amp AHDSR
|
||
today and the filter AHDSR when item 2 lands. **It does not apply to the
|
||
pitch envelope: D is not a release stage, so it is not right-anchored.**
|
||
*(Settled by follow-up — this closes the prior open question about mapping
|
||
the policy onto the pitch envelope: the answer is that the policy does not
|
||
apply there; the envelope gains a Hold stage instead.)*
|
||
- **Spec change: the pitch envelope becomes AHD.** The Pitch AD gains a
|
||
**Hold** stage: **Attack → Hold → Decay**. *(Settled by follow-up — a spec
|
||
change, not a clarification. The doc's own prose — here and item 1's
|
||
sloped-segment reading — is updated to match; Daniel's verbatim asks stay
|
||
as written.)*
|
||
- **Hold ranges 0 to 100% of the time remaining after Attack and Decay** —
|
||
i.e. 100% of (sample length − (attack time + decay time)). At 100%, Hold
|
||
fills all the remaining time; at 0% it takes none. *(Settled by second
|
||
follow-up.)*
|
||
- **The A + H + D ≤ sample-length bound holds by construction**, not by a
|
||
separate clamp: Hold is expressed as a fraction of what is left after
|
||
Attack and Decay, so the sum cannot overflow. Daniel's stated bound
|
||
("the combined A H and D segment lengths cannot exceed the full sample
|
||
length") is a *property* of the Hold definition, not a constraint to
|
||
enforce on top of it.
|
||
- **The overlay is therefore 1:1 scale with the waveform time axis** — the
|
||
drawn envelope maps directly onto the displayed sample's time.
|
||
- **Scope rule — split on the sustain stage.** The 1:1-overlay property and
|
||
the combined-time bound apply to **all envelopes that do NOT have a sustain
|
||
stage**; envelopes **with** a sustain stage (the amp and filter AHDSRs) get
|
||
the right-anchored-release policy instead. Daniel's rationale: the 1:1
|
||
mapping only makes sense for trigger, not gated envelopes — that is the
|
||
reasoning behind the stage-list rule, not a second competing rule. Today
|
||
the pitch AHD is the only sustain-less envelope, but the rule is general:
|
||
it governs any future sustain-less envelope too. The two policies
|
||
**coexist rather than merge**, split cleanly on whether the envelope has a
|
||
sustain stage — the prior revision's open reading, now confirmed. *(Settled
|
||
by second follow-up.)*
|
||
- **Cross-references.** Item 1 reworks this same overlay surface (radio
|
||
switch, mid-segment curve knots, recolor) — this item is cheapest folded
|
||
into or immediately after that work; item 1's sloped-segment rule reads
|
||
Attack and Decay for the pitch AHD (Hold is flat, no curve dial). Item 3's
|
||
Spline overlays are unaffected by construction: a spline always spans the
|
||
full sample width already. Item 14 extends the AHD to the amp and filter
|
||
envelopes' Trigger mode, so this scope rule selects by the envelope's
|
||
current shape under the active playback mode — see item 14.
|
||
|
||
**Open questions.**
|
||
|
||
- None remaining — both prior questions (Hold's 0–100% reference; the scope
|
||
of the 1:1/combined-bound policy) closed by the second-batch second
|
||
follow-up round. The coexist-vs-merge reading the prior revision flagged is
|
||
confirmed: the two policies coexist, split cleanly on whether the envelope
|
||
has a sustain stage.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- With release at zero or minimum, the sustain segment extends to (near) the
|
||
right edge — the overlay reads full-width, not bunched left.
|
||
- Dragging the sustain→release top node adjusts release; the bottom-right
|
||
corner is fixed and not draggable.
|
||
- The envelopes with a sustain stage (amp, and filter once present) follow
|
||
the same anchoring policy; the pitch envelope's Decay is **not**
|
||
right-anchored.
|
||
- The pitch envelope plays and displays three stages — Attack, Hold, Decay —
|
||
with Hold spanning 0–100% of the time remaining after Attack and Decay. By
|
||
construction, no combination of A, H, and D settings yields a combined time
|
||
displacement exceeding the sample length (at Hold = 100% the three stages
|
||
exactly fill it) — no separate clamp fires, because none is needed.
|
||
- The overlay of any sustain-less envelope (today: the pitch AHD) is 1:1 with
|
||
the waveform's time axis: a stage boundary at N seconds sits over the
|
||
waveform at N seconds.
|
||
|
||
---
|
||
|
||
## 9 — Bug + Enhancement: loop points — suspected regression, and the Gate-mode loop-sustain spec *(his 4, second)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> I think loop points got lost. ideally if in gate mode we have a loopable
|
||
> section with parameterized start end points and parameterized crossfade on
|
||
> reset, which will function as the sustain for indefinite playback until note
|
||
> off and release.
|
||
|
||
**This item is both** a regression report and a feature spec, and is recorded
|
||
as both.
|
||
|
||
**Regression half (Bug).** Daniel's observation: loop points appear to have
|
||
been lost. Whether they were genuinely removed from playback or are merely
|
||
unexposed in the current UI is a code question that **cannot be answered here**
|
||
under the no-code-reads constraint — it must be verified as the first act of
|
||
implementation, not guessed in this document.
|
||
|
||
**Feature half (Enhancement — spec as given).** In **Gate mode**: a loopable
|
||
section with **parameterized start and end points** and a **parameterized
|
||
crossfade on loop reset**. The loop functions as the sustain — indefinite
|
||
playback cycling the loop until note-off, then release.
|
||
|
||
- **Cross-reference item 3.** Gate mode is unavailable while a Spline EG is
|
||
active (settled), so loop-sustain is a **Staged/Gate-mode feature**; Spline
|
||
mode remains full-sample-length playback with no loop.
|
||
|
||
**Open questions.**
|
||
|
||
- The regression verification above (removed vs. unexposed).
|
||
- The crossfade parameter's units and range are unspecified — Daniel call, or
|
||
a proposed default surfaced at implementation review.
|
||
- Storage side: presumably per-zone alongside the other playback parameters
|
||
(Sample/Zone panel parity, with VOICE/MASTER the per-instance exceptions) —
|
||
confirm.
|
||
- Editing surface for loop start/end (waveform markers, knobs, or both) is
|
||
unspecified; the waveform display is the natural home for range markers, but
|
||
Daniel has not said.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- In Gate mode with a loop defined, a held note sustains indefinitely, audibly
|
||
cycling the loop section; note-off exits into the release stage.
|
||
- With a nonzero crossfade, the loop seam is smooth — no click at the loop
|
||
reset; crossfade length audibly follows its parameter.
|
||
- Loop start, end, and crossfade are user-parameterized, editable, and
|
||
persisted across save/reload.
|
||
- Whatever the regression finding, the end state is loop points exposed and
|
||
functional per this spec.
|
||
|
||
---
|
||
|
||
## 10 — Enhancement: knob and label sizing, ms units, double-click reset *(his 5)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> Radial knobs and text labels are too small. The labels for time constants
|
||
> should be in ms not seconds. double clicking any radial knob resets to
|
||
> default (applies to the dual-ring radial knobs as individual sections)
|
||
|
||
**Behavior.**
|
||
|
||
- Radial knobs and their text labels grow — both are currently too small. No
|
||
target size was given; this is a visual-judgment change accepted by eye.
|
||
- Time-constant labels display in **ms, not seconds**. (A display-unit change;
|
||
this spec makes no claim about internal representation.)
|
||
- **Double-click on any radial knob resets it to its default value.**
|
||
- On item 1's **dual-ring knobs, each ring is its own reset target**:
|
||
double-click on the outer ring resets the time/level value; double-click on
|
||
the inner curve dial resets the exponent to 1.0 (the settled linear
|
||
neutral) — each independently, without touching the other ring.
|
||
- **Cross-reference item 1** (introduces the dual-ring knobs this refines).
|
||
|
||
**Open questions.**
|
||
|
||
- None beyond the sizing being judged by eye (see acceptance).
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- Knobs and labels are legibly larger; Daniel signs off on the result by eye.
|
||
- Every time-constant label reads in ms.
|
||
- Double-click resets any radial knob to its default; on dual-ring knobs,
|
||
double-clicking the inner dial resets only the exponent (to 1.0) and
|
||
double-clicking the outer ring resets only the value.
|
||
|
||
---
|
||
|
||
## 11 — Enhancement: preview glyph; VELOCITY deck for velocity-curve buttons; bipolar pitch/filter curves *(his 6)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> Preview button inner text should go and be replaced with an appropriate
|
||
> glyph of your choosing (no dependencies just load a bitmap staticly or
|
||
> something, whatever plays nice with LICE. Amp velocity curve button moves
|
||
> to the master section. pitch velocity curve goes in the pitch section.
|
||
> filter velocity curve button goes in the filter section. filter and pitch
|
||
> velocity transfer functions default to y=0 and y range is [-1,1] (where as
|
||
> amp stays unipolar at [0,1]).
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||
|
||
> 11) actually, that is a real contention point... MASTER is for other things,
|
||
> post voice mixer (I will add to this later). The velocity popup buttons
|
||
> should all go together in a new control deck group labelled VELOCITY, to the
|
||
> left of VOICE
|
||
|
||
**Behavior.**
|
||
|
||
- **Preview glyph.** The preview button's inner text is replaced with a glyph.
|
||
Proposed (product level): a right-pointing **play triangle** — the universal
|
||
"audition" read. Daniel's constraint: **no new dependencies** — a statically
|
||
embedded bitmap or equivalent that plays nicely with the existing drawing
|
||
path is fine.
|
||
- **Velocity-curve button placement — the VELOCITY deck.** All three
|
||
velocity-curve popup buttons (amp, pitch, filter) live **together in a new
|
||
control deck group labelled "VELOCITY", placed to the left of the VOICE
|
||
group**. *(Settled by follow-up.)* Note for readers of the prior revision:
|
||
this **supersedes the original ask's per-section placement** (amp → MASTER,
|
||
pitch → PITCH, filter → Filter). Daniel confirmed the MASTER placement was
|
||
a real contention point — **MASTER is reserved for other, post-voice-mixer
|
||
concerns** (he will add to it later), so the velocity curves do not belong
|
||
there.
|
||
- **Storage stays per-zone.** The velocity transfer curves are stored
|
||
**per-zone**, with the other playback parameters — Sample/Zone panel parity
|
||
applies. *(Derived, not a Daniel quote: the storage doubt existed only
|
||
because the proposed MASTER placement implied per-instance storage; with
|
||
the buttons in their own VELOCITY group that doubt is gone, and the
|
||
project's settled convention — playback parameters are per-zone, VOICE and
|
||
MASTER the per-instance exceptions — decides it.)*
|
||
- **Bipolar pitch/filter transfer functions.** Pitch and filter velocity
|
||
transfer functions are **bipolar: y range [−1, 1], default y = 0** — flat at
|
||
zero, meaning velocity modulation of pitch and filter is **off until the
|
||
user draws a curve**. **Amp stays unipolar at [0, 1]**, and its existing
|
||
flat default (every velocity → unity) is unchanged.
|
||
- **Cross-references.** Item 2 introduces the filter's velocity modulation —
|
||
this item specifies that curve's domain and default, and homes its button
|
||
in the VELOCITY deck. Item 3's shared spline editor serves these curves, so
|
||
it must render and edit a **bipolar y-domain** for pitch and filter
|
||
alongside the amp curve's unipolar one.
|
||
|
||
**Open questions.**
|
||
|
||
- Whether a user-facing pitch velocity transfer curve already exists or is
|
||
introduced by this item — unverifiable here under the no-code-reads
|
||
constraint; if absent, this item introduces it. (The former second question
|
||
— amp-curve storage under the MASTER placement — dissolved with the
|
||
placement's supersession; storage is settled per-zone above.)
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- The preview button shows the glyph (no text) and stays legible in all
|
||
interaction states; no new build or runtime dependency is introduced.
|
||
- The three velocity-curve buttons sit together in a deck group labelled
|
||
**VELOCITY**, immediately to the left of the VOICE group; no velocity-curve
|
||
button appears in MASTER, PITCH, or Filter.
|
||
- The velocity curves follow Sample/Zone panel parity and persist per-zone
|
||
(two zones with different curves audibly differ).
|
||
- Opening the pitch or filter curve shows a bipolar editor ([−1, 1]) defaulted
|
||
flat at y = 0; played velocities produce no pitch/filter modulation until a
|
||
curve is drawn, then audibly follow it.
|
||
- The amp curve's domain ([0, 1]) and flat-unity default are unchanged.
|
||
|
||
---
|
||
|
||
## 12 — Enhancement: top toolbar cleanup; full-width piano strip; uniform keys; note-name tooltips *(his 7)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> top toolbar text font should be cleaned up to match, and the zone count
|
||
> label is not needed in the title. next to the browse and zoom buttons, we
|
||
> can move the preview and mono stereo controls, in order to allow the note
|
||
> range piano roll control to take up full width. also we need to clean up
|
||
> the piano key pattern, idk if it's pixel aliasing but it looks like some
|
||
> keys are skinnier than others. NOte value (C4, etc) should display in
|
||
> tooltip on hover over the piano notes.
|
||
|
||
**Behavior.**
|
||
|
||
- **Font cleanup.** One consistent font treatment across the top toolbar text.
|
||
- **Zone count label removed** from the title.
|
||
- **Preview and mono/stereo controls relocate** next to the browse and zoom
|
||
buttons, freeing the **note-range piano strip to take the full width**.
|
||
- **Uniform piano keys.** Some keys currently render skinnier than others —
|
||
Daniel suspects pixel aliasing, but the requirement stands regardless of
|
||
cause: keys of the same class render at uniform width. (No cause analysis
|
||
here.)
|
||
- **Note-name tooltips.** Hovering a piano key shows its note value (C4 etc.,
|
||
DAW convention), following the instrument's existing tooltip conventions
|
||
where they apply.
|
||
- **Cross-references.** Item 11 also changes the preview button (glyph); the
|
||
two compose — the glyph button in its new toolbar position. Item 13's
|
||
anti-aliasing audit covers the key-pattern rendering if aliasing turns out
|
||
to be the cause.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- Top toolbar text renders in one consistent font treatment; the title carries
|
||
no zone count.
|
||
- Preview and mono/stereo sit adjacent to browse/zoom; the piano strip spans
|
||
the full editor width.
|
||
- Same-class keys are equal pixel width at any window width and DPI scale.
|
||
- Hovering any piano key shows its note name in a tooltip.
|
||
|
||
---
|
||
|
||
## 13 — Enhancement (audit): antialiased rendering for high-DPI *(his 8)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> We should finally review to make sure we are rendering with some kind of
|
||
> antialiasing equivalent for high DPI high res clean rendering. It still
|
||
> looks pixely in places (radial arcs, waveform lines, env segment slopes)
|
||
|
||
**Intent.** A review pass, not a point fix: audit the editor's drawn surfaces
|
||
and confirm they render with antialiasing (or an equivalent) suitable for
|
||
high-DPI, high-resolution displays. Daniel named the visibly pixely surfaces:
|
||
**radial arcs, waveform lines, envelope segment slopes**.
|
||
|
||
**Behavior.**
|
||
|
||
- Audit each class of drawn surface; where one renders visibly aliased, bring
|
||
it to the smooth standard. The outcome is observable, not procedural: the
|
||
named surfaces (and any others the audit turns up) render without visible
|
||
stair-stepping.
|
||
- **Sequencing observation** (not a decision): this touches nearly every
|
||
surface items 1, 3, 7, 8, 10, 11, and 12 repaint — running it after the
|
||
layout/knob work likely avoids doing the polish twice.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- Radial arcs (including item 1's inner dials), waveform lines (including
|
||
item 7's stereo lanes), and envelope segment slopes (staged and spline)
|
||
render smooth — no visible jaggies at 100% scale or on a high-DPI display.
|
||
- The audit produces a short disposition list: surfaces checked, which needed
|
||
work, which were already clean.
|
||
- Daniel signs off by eye on the named surfaces.
|
||
|
||
---
|
||
|
||
## 14 — Enhancement: Trigger-mode amp envelope — fade-in/fade-out replaced by the AHD (with curves)
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> the amp env trigger mode fade in length fade out changes to the AHD envelope
|
||
> (with curves of course), to reduce code for the same thing, and consolidate
|
||
> under the new design.
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||
|
||
> sure, filter follows as well
|
||
|
||
**Intent.** Consolidation. In Trigger mode the amp envelope's fade-in-length /
|
||
fade-out-length pair is retired and replaced by the same three-stage
|
||
Attack → Hold → Decay envelope item 8 specifies for the pitch envelope — with
|
||
item 1's per-segment curves. Daniel's stated motive is reducing code for the
|
||
same job: one staged-envelope design covering what is currently two separate
|
||
mechanisms doing the same thing. The product consequence: **the amp envelope's
|
||
staged shape follows the playback mode** — Gate → AHDSR (sustain,
|
||
right-anchored release, per item 8); Trigger → AHD (sustain-less). The
|
||
follow-up round extends the same rule to item 2's filter envelope.
|
||
|
||
**Behavior.**
|
||
|
||
- **Trigger mode: fades out, AHD in.** In Trigger mode the amp envelope is an
|
||
AHD per item 8's definition: Hold spans 0–100% of the time remaining after
|
||
Attack and Decay, so A + H + D ≤ sample length holds by construction and the
|
||
overlay is 1:1 with the waveform's time axis. The fade-in-length and
|
||
fade-out-length controls go away in Trigger mode; Attack and Decay carry
|
||
those roles under the new design.
|
||
- **With curves.** The Trigger AHD's sloped segments — Attack and Decay; Hold
|
||
is flat, as everywhere — get item 1's full curve treatment: exponent 0.1–10,
|
||
inner dials, mid-segment overlay knots, tertiary-purple rendering.
|
||
- **Gate mode unchanged.** In Gate mode the amp envelope remains the AHDSR
|
||
with item 8's right-anchored release. Item 9's loop-sustain spec (a
|
||
Gate-mode feature) is untouched.
|
||
- **The filter envelope follows as well.** Item 2's filter envelope takes the
|
||
same mode-driven shape: **Gate → AHDSR, Trigger → AHD** — same staged
|
||
machinery, same consolidation. It necessarily lands with or after item 2
|
||
(the filter must exist first); item 2 carries a cross-reference. *(Settled
|
||
by follow-up.)*
|
||
- **Item 8's scope rule now governs all three envelopes uniformly.** Item 8
|
||
settled that the 1:1-overlay property and the by-construction combined-time
|
||
bound apply to envelopes **without a sustain stage**, and the
|
||
right-anchored-release policy to those **with** one — Daniel's rationale:
|
||
"the 1:1 mapping only makes sense for trigger, not gated envelopes." With
|
||
this item the amp — and, per the follow-up, the filter — envelope in
|
||
Trigger mode *is* sustain-less, so each takes the 1:1 time-mapped overlay
|
||
automatically; in Gate mode each keeps the right-anchored release. The
|
||
general policy, stated once: **pitch is always AHD (1:1 overlay); amp and
|
||
filter are AHDSR in Gate (right-anchored release) and AHD in Trigger (1:1
|
||
overlay)**. The rule selects by the envelope's **current shape under the
|
||
active playback mode**, not by which processor the envelope modulates. No
|
||
new rule is needed — item 8's rule already decides every case.
|
||
- **Pre-existing instances reopen sounding identical.** The doc's standing
|
||
migration framing (items 1, 2, 11) applies: a project saved before this
|
||
change reopens with unchanged audible behavior — in particular, a Trigger
|
||
instance's prior fade-in/fade-out contour is reproduced by the loaded AHD.
|
||
The evident mapping (Attack ← fade-in, Decay ← fade-out, Hold ← the full
|
||
remainder, curve exponents at whatever value reproduces the prior fade
|
||
shape) is a verify-at-implementation detail, not a Daniel call; the gate
|
||
below states the requirement. A prior zero fade-out is Decay = 0 — the
|
||
abrupt end stays representable, so nothing the old controls could express
|
||
is lost.
|
||
- **Cross-references.** Item 8 supplies the AHD definition and the scope rule
|
||
(this item is that rule's second consumer); item 1 supplies the curves —
|
||
sequencing: cheapest folded into or immediately after that combined work.
|
||
Item 3 is unaffected in Spline mode (a spline already plays as a
|
||
full-sample-length time function — the trigger model); its "save but
|
||
inactive" dual-state precedent bears on the second open question below.
|
||
Item 4's Trigger × Preserve end-of-sample click sits in the region the
|
||
fade-out currently governs — whichever of the two lands first, item 4's
|
||
gate must be re-verified under the surviving mechanism.
|
||
|
||
**Open questions.**
|
||
|
||
- **Stage-value state across the Gate/Trigger switch — shared or per-mode?**
|
||
The Gate AHDSR and Trigger AHD share stage names (A, H, D); whether they
|
||
share *values* (one envelope whose S and R fall away in Trigger) or keep
|
||
per-mode state (item 3's "save but inactive" dual-state precedent) is
|
||
unspecified — and with the follow-up the question covers the **filter
|
||
envelope too**, not just the amp. Migration leans per-mode for the amp: an
|
||
old instance carries both its AHDSR values and its Trigger fade values, and
|
||
a shared-value model cannot preserve both modes' prior sound at once. (The
|
||
filter is new in item 2, so it carries no migration weight either way;
|
||
matching the amp's answer is the natural default.) Resolve at
|
||
implementation review with a proposal — not Daniel-blocking, but the
|
||
sound-identical gate must hold for whichever mode a saved instance plays
|
||
in. (The filter question that previously led this list — does the filter
|
||
AHDSR follow the same mode-driven shape? — is settled by the follow-up:
|
||
yes; folded into Behavior above.)
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- In Trigger mode the amp deck shows Attack / Hold / Decay — no fade-in or
|
||
fade-out control anywhere in Trigger mode — with curve inner dials on
|
||
Attack and Decay and none on Hold; when the amp envelope is overlay-active
|
||
(item 1's radio), its overlay is 1:1 with the waveform time axis, and no
|
||
combination of A, H, D settings exceeds the sample length (Hold = 100%
|
||
exactly fills it — by construction, no clamp).
|
||
- In Gate mode the amp envelope is the unchanged AHDSR: sustain stage,
|
||
right-anchored release per item 8.
|
||
- Switching between Gate and Trigger playback switches the amp envelope
|
||
surface (deck and overlay) between AHDSR and AHD accordingly.
|
||
- Once item 2's filter lands, its envelope switches identically: AHDSR
|
||
(right-anchored release) in Gate, 1:1 AHD in Trigger — the mode switch
|
||
swaps the amp and filter envelope surfaces the same way.
|
||
- A project saved before this change reopens sounding identical: a Trigger
|
||
instance's prior fade-in/fade-out contour — including a zero fade-out's
|
||
abrupt end — is audibly reproduced by the loaded AHD.
|
||
- The Trigger amp AHD behaves stage-for-stage like item 8's pitch AHD — Hold
|
||
semantics, curve treatment, and overlay mapping match. (This is the
|
||
observable proxy for the consolidation motive: one staged-envelope design,
|
||
two consumers.)
|