# 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). 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 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 (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. --- ## 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 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.