Files
reasampler/TODO-1.0.md
T

907 lines
47 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TODO-1.0
Post-1.0 queue for ReaSampler — chiefly the 9000 instrument, plus two
extension-side bugs. Items 13 are the first batch, in Daniel's ordering
(2026-07-28); items 413 are a second batch (2026-07-28, later the same day).
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 413 — 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 0100% reference, and the scope of the
1:1-overlay/combined-bound policy. **With that, no open question anywhere in
this doc awaits a Daniel decision.** Everything still marked open 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 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 (46) 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.
---
## 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.
- **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.
**Open questions.**
- None remaining — both prior questions (Hold's 0100% 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 0100% 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.