diff --git a/TODO-1.0.md b/TODO-1.0.md index 863b2b7..d34ce8a 100644 --- a/TODO-1.0.md +++ b/TODO-1.0.md @@ -1,7 +1,9 @@ # TODO-1.0 -Post-1.0 enhancement queue for the ReaSampler 9000 instrument. Three items, in -Daniel's ordering (2026-07-28). Deliberately specified at the level of product +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 @@ -21,12 +23,32 @@ 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 items now have no open -questions; the document is fully settled at the product level.** +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. 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 placement presupposes item 2's 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. --- @@ -402,3 +424,369 @@ so sharp corners are possible, not everything smoothed. 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. + +**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. + +**Open questions.** + +- How overlays that ride the waveform (the envelope overlay, markers, and + item 9's loop region if it lands) render across the stereo split — spanning + the full stacked height once, or drawn per lane. A layout call to make at + implementation with Daniel's eye; the product intent is only that overlays + stay legible and unambiguous in both modes. + +**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. + +--- + +## 8 — Enhancement: staged-envelope overlay — release anchored right, dragged from its top node *(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. + +**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. + +**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 **all staged envelope overlays** — amp AHDSR today, + Pitch AD, and the filter AHDSR when item 2 lands. +- **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 3's Spline overlays are unaffected + by construction: a spline always spans the full sample width already. + +**Open questions.** + +- How the policy maps onto the two-stage Pitch AD, which has no sustain or + release: presumably its final (decay) segment's endpoint anchors right and + drags from its top node, but Daniel stated the policy in AHDSR terms — + confirm the AD reading at implementation. + +**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. +- Every staged envelope overlay (amp, pitch, and filter once present) follows + the same anchoring policy. + +--- + +## 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-curve buttons per section; 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]). + +**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.** Amp velocity curve button → **MASTER** + section; pitch velocity curve → **PITCH** section; filter velocity curve → + **Filter** section (the deck item 2 creates). +- **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 and + the Filter deck — this item specifies that curve's domain, default, and + button placement. 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 amp velocity curve's *button* moves to MASTER, but MASTER is settled as + a per-instance group while the velocity curve is a playback parameter. Does + the move imply the amp velocity curve becomes per-instance, or is it a + purely spatial relocation with storage unchanged? This also touches + Sample/Zone panel parity (which surfaces show the button). Needs a Daniel + call before implementation. + +**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 in their named sections: amp in MASTER, + pitch in PITCH, filter in Filter. +- 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.