a689fb75eb
Two Greek-lettered phases (Θ instrument overhaul, Ξ resample loop): sequenced waves, parallel tracks on disjoint surfaces, per-track acceptance criteria, carried-forward open questions, traceability table. TODO-1.0.md retained as verbatim-provenance appendix.
1683 lines
94 KiB
Markdown
1683 lines
94 KiB
Markdown
# TODO-1.0
|
||
|
||
> **`docs/PLAN.md` is now the roadmap.** All seventeen items below have been
|
||
> consolidated into areas and sequenced into the Phase → Wave → Track hierarchy in
|
||
> `docs/PLAN.md`; that file is what implementation specialists are dispatched against,
|
||
> and each of its tracks is self-sufficient for a brief. **This file is retained as the
|
||
> verbatim-provenance spec appendix** — Daniel's raw asks and every answer round,
|
||
> unedited, are the source of truth behind PLAN.md's compressed behavior bullets. Its
|
||
> traceability table maps each item number below onto the track that owns it. Nothing in
|
||
> this file changes as work lands; PLAN.md points move to `docs/COMPLETED.md`.
|
||
|
||
Post-1.0 queue for ReaSampler — chiefly the 9000 instrument, plus two
|
||
extension-side bugs. Items 1–3 are the first batch, in Daniel's ordering
|
||
(2026-07-28); items 4–13 are a second batch (2026-07-28, later the same day);
|
||
item 14 is a third, single-item batch (2026-07-28, later again); item 15 is
|
||
a fourth, single-item batch (2026-07-29); item 16 (2026-07-29) is not a new
|
||
ask batch — it records the system change mandated by answer 1 of item 15's
|
||
answer round (the zone mapping system is retired); item 17 (2026-07-29) is
|
||
likewise not a new ask batch — it records the requirement mandated by
|
||
answer 1 of the second fourth-batch answer round (the provenance/usage
|
||
tracking consolidated and made 100% robust).
|
||
Deliberately specified at the level of product
|
||
intent, user-visible behavior, and acceptance criteria — **no implementation
|
||
design, no file/module references**. These were authored while Phase Q was
|
||
restructuring the tree; the implementing engineer maps each spec onto the
|
||
post-Q layout at execution time. Each item preserves Daniel's raw ask verbatim
|
||
as the source of truth, then breaks it into behavior, open questions, and an
|
||
observable acceptance gate.
|
||
|
||
A follow-up answer round from Daniel (2026-07-28) settled most of the open
|
||
questions. Each item now carries his follow-up verbatim alongside the original
|
||
ask; settled answers are folded into **Behavior** (marked *settled by
|
||
follow-up*), and only the genuinely unresolved remainder stays under **Open
|
||
questions**.
|
||
|
||
A **second follow-up round** (2026-07-28, same day) settled nearly all of the
|
||
remainder. Each item carries that round's verbatim as a third provenance block;
|
||
answers are folded the same way (marked *settled by second follow-up*).
|
||
|
||
A **third follow-up round** (2026-07-28, same day) settled item 3's last two
|
||
questions (point-count ceiling; delete gesture — reversing the second round's
|
||
alt-click answer back to right-click). **All three first-batch items now have
|
||
no open questions; the first batch is fully settled at the product level.**
|
||
|
||
A **second batch** from Daniel (2026-07-28) appends items 4–13 — a mix of bug
|
||
reports and enhancements. His message numbered them 1, 2, 3, 4, 3, 4, 5, 6, 7,
|
||
8 (two items labelled 3 and two labelled 4). His *sequence* is preserved
|
||
exactly; each item carries an unambiguous doc number continuing from 3, with
|
||
his original label recorded in the heading (e.g. *his 3, second*) so his
|
||
message maps onto the doc. Each item is marked **Bug** or **Enhancement**;
|
||
item 9 is explicitly both — a suspected regression plus a feature spec. Bugs
|
||
are recorded compactly (symptom, expected behavior, acceptance gate) with **no
|
||
root-cause analysis** — same no-code-reads constraint as the first batch.
|
||
|
||
A **second-batch follow-up round** (2026-07-28, same day) answered items 7, 8,
|
||
and 11. Item 7 closes clean. Item 11's answer **supersedes the original ask's
|
||
button placement** — a new VELOCITY deck group replaces the per-section
|
||
placement, MASTER being reserved for later post-voice-mixer concerns. Item 8's
|
||
answer is a **spec change, not a clarification**: the pitch envelope's AD
|
||
becomes an **AHD** (a Hold stage is added), and the doc's own prose (items 1
|
||
and 8) is updated to match — Daniel's verbatim asks stay exactly as originally
|
||
written.
|
||
|
||
A **second-batch second follow-up round** (2026-07-28, same day) closed item
|
||
8's last two questions — Hold's 0–100% reference, and the scope of the
|
||
1:1-overlay/combined-bound policy. **With that, no open question then in the
|
||
doc awaited a Daniel decision.** Everything still marked open in items 1–13 is
|
||
verify-or-propose-at-implementation, not a blocker: item 9's loop-point
|
||
regression verification and its spec details (crossfade units, storage
|
||
confirmation, editing surface — each carries its own resolve-at-review path in
|
||
the item), and item 11's does-a-user-facing-pitch-velocity-curve-already-exist
|
||
check. Nothing in items 1–13 is blocked on Daniel.
|
||
|
||
A **third batch** (2026-07-28, later again) appends item 14 — a single
|
||
consolidation enhancement: in Trigger mode the amp envelope's
|
||
fade-in-length/fade-out-length pair is replaced by item 8's AHD (with item 1's
|
||
curves), so the amp envelope's staged shape follows the playback mode —
|
||
Gate → AHDSR, Trigger → AHD. Item 8's sustain-stage scope rule then covers the
|
||
amp envelope literally, not just by analogy (a one-line cross-reference is
|
||
added there). Item 14 arrived carrying one question awaiting a Daniel
|
||
decision — whether item 2's filter AHDSR follows the same mode-driven shape —
|
||
answered by the round below. Its other open question (stage-value state across
|
||
the Gate/Trigger switch) is propose-at-implementation-review, not
|
||
Daniel-blocking.
|
||
|
||
A **third-batch follow-up round** (2026-07-28, same day) answered item 14's
|
||
filter question: **the filter envelope follows the same mode-driven shape** —
|
||
Gate → AHDSR, Trigger → AHD. Item 8's scope rule now governs all three
|
||
envelopes uniformly (the general statement lives in item 14; item 2 carries a
|
||
cross-reference), and item 14's remaining stage-value question now covers the
|
||
filter envelope too. **With that, no open question in items 1–14 awaits a
|
||
Daniel decision.** Everything still open across all 14 items is
|
||
verify-or-propose-at-implementation: item 9's loop-point regression
|
||
verification and its spec details, item 11's
|
||
does-a-pitch-velocity-curve-already-exist check, and item 14's
|
||
shared-vs-per-mode stage-value question. Nothing in items 1–14 is blocked on
|
||
Daniel.
|
||
|
||
A **fourth batch** (2026-07-29) appends item 15 — a single enhancement Daniel
|
||
himself frames as "a pretty radical feature idea": one-click resampling from
|
||
inside the ReaSampler 9000. An offline pass through the instrument's own
|
||
processing is captured back into the bank, the source capture is replaced (or
|
||
a distinct capture added when other references exist), the instance re-points
|
||
at the recapture, and the audio parameters reset to default — the
|
||
dial → bake → dial-again iteration loop, run without leaving the sampler.
|
||
**Item 15 reopened the Daniel-blocked state: five of its open questions
|
||
awaited a Daniel decision** — the multi-zone scope of "the sound," what the
|
||
offline pass plays (note, velocity, and the Gate-mode hold/tail policy), the
|
||
parameter-reset scope, what counts as "other references," and the
|
||
undo/recovery expectation. Its remaining questions are
|
||
propose-at-implementation-review; items 1–14 stay fully unblocked.
|
||
|
||
A **fourth-batch answer round** (2026-07-29) answered all five. The answers
|
||
are folded into item 15's Behavior (marked *settled by answer round*).
|
||
Answer 1 is a **system change, not a scoping rule**: the zone mapping system
|
||
is retired — ReaSampler 9000 becomes **one capture = one parameter set** —
|
||
recorded in full as **item 16**, which supersedes the doc's per-zone-storage
|
||
and Sample/Zone-panel-parity language throughout (items 2, 9, 11, and 12
|
||
carry marked superseded-by/cross-reference notes; Daniel's verbatim asks
|
||
stand exactly as written). Answer 2 spawns a new sub-feature inside item 15:
|
||
a **capture-signal popup** (note length, start/end offsets in ms and in
|
||
beats, velocity, and a preview trigger). **Daniel-blocked state after that
|
||
round: exactly one question awaited a Daniel decision — item 16's migration
|
||
of saved multi-zone instances** (since settled; next paragraph).
|
||
|
||
A **second fourth-batch answer round** (2026-07-29) — one message — settled
|
||
that migration question and answered the doc's three under-specification
|
||
flags. The unnumbered opening line rules the migration: **adopt the first
|
||
zone's capture and parameters** — a lossy rule Daniel accepts because he has
|
||
**no projects with zones in use**; for a genuinely multi-zone instance the
|
||
doc's standing sounds-identical migration bar is **deliberately relaxed**
|
||
(recorded in item 16). Answer 1 converts the doc's provenance-consolidation
|
||
flag into a requirement — **the provenance/usage tracking is to be
|
||
consolidated and made 100% robust** — recorded in full as **item 17**, on
|
||
which item 15's replace-vs-add rule now explicitly depends. Answer 2
|
||
("that's good") ratifies item 15's derived reset-scope classification —
|
||
promoted from derived to confirmed by Daniel. Answer 3 settles the
|
||
capture-window semantics: the start/end offsets anchor to **note-on and
|
||
note-off** of the programmed note; note length is a **musical division**
|
||
(1/64th through 64/1, with dotted and triplet multipliers), not a free
|
||
duration; beats resolve against **the project tempo under the cursor**.
|
||
**Current Daniel-blocked state: no open question anywhere in items 1–17
|
||
awaits a Daniel decision.** Everything still open is
|
||
verify-or-propose-at-implementation.
|
||
|
||
Ordering note: item 1's curve/overlay treatment explicitly anticipates item 2's
|
||
filter envelope ("filter to be added"), and item 3 layers on both. They can land
|
||
in sequence or together, but 1 and 2 are prerequisites for 3's full surface.
|
||
Second-batch interactions: the three bugs (4–6) are independent of the
|
||
enhancement chain and can land at any time. Item 8 edits the same overlay
|
||
surface as item 1 and is cheapest folded into or immediately after that work;
|
||
item 10's per-ring reset presupposes item 1's inner dials; item 11's filter
|
||
velocity curve presupposes item 2's filter (though its button now homes in
|
||
item 11's own VELOCITY deck, not the Filter deck); item 9's
|
||
loop-sustain is a Gate-mode (Staged) feature and composes with item 3's
|
||
Gate-unavailable-in-Spline rule. Item 13 (anti-aliasing audit) touches nearly
|
||
every surface the other items repaint — sequencing it after the layout/knob
|
||
work (1, 8, 10, 11, 12) likely avoids doing the polish twice; that is an
|
||
observation, not a decision. Item 14 (third batch) rides directly on item 8's
|
||
AHD definition and item 1's curve treatment — cheapest folded into or
|
||
immediately after that combined work — and repaints amp-deck/overlay surface
|
||
that items 10 and 13 later polish; its filter half (the filter envelope
|
||
following the same mode-driven shape) necessarily lands with or after item 2.
|
||
Item 15 (fourth batch) presupposes the processing surface it bakes —
|
||
"filtering, pitching, amp all set up nice" is the instrument items 1, 2, 3,
|
||
and 14 build — so its spec only becomes fully meaningful once those have
|
||
landed, and its Gate-mode render policy touches item 9's loop-sustain; that
|
||
is a statement of what the feature operates on, not a schedule decision. Its
|
||
bank-side half rides the already-settled capture and prune safety model, not
|
||
any queued item. Item 16 (zone retirement) is a **prerequisite of meaning**
|
||
for item 15 — it is what makes "the sound" singular and dissolves the
|
||
multi-zone question — and it touches the surfaces other queued items work
|
||
on: items 2, 9, and 11 now store their parameters into the one parameter
|
||
set rather than per-zone, and item 12's full-width piano strip is
|
||
re-grounded by what the strip means with zones retired. That too is
|
||
dependency-of-meaning, not a schedule: the affected items' work is
|
||
unchanged in substance; only its storage/parity framing simplifies.
|
||
Item 17 (provenance/usage consolidation) is likewise a **prerequisite of
|
||
meaning** for item 15's bank-side half — the replace-vs-add rule is
|
||
computable only once the consolidated lineage records exist — and is
|
||
independent of the editor chain (items 1–14); it reworks tracking machinery
|
||
today's prune protections ride, so those guarantees must hold undiminished
|
||
through the consolidation. Landing it with or before item 15's bank-side
|
||
half is the natural order.
|
||
|
||
---
|
||
|
||
## 1 — Envelope editor: per-deck radio switch, segment curve dials, overlay recolor
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> The VST envelope editor visual is a great start but we need to add some
|
||
> features. The Amp AHDSR is currently always displayed. We need to add a radio
|
||
> switch to the corner of each env knob deck which makes THAT envelope editable
|
||
> via the graphic waveform overlay. This is currently the amp and pitch
|
||
> envelopes, with filter to be added (see below). All envelopes (amp AHDSR,
|
||
> Pitch AD, Filter AHDSR) should be enhanced to have editable segment curve
|
||
> values. This should be an exponential function with the exponent scalar
|
||
> parameter for each sloped segment having possible values from 0.1 to 10. The
|
||
> knob deck radial knobs for the sloped curvable segments will have an INNER
|
||
> dial, with its own inner arc, hover accent (tertiary purple), needle, and
|
||
> numerical label which controls the curve for that sloped segment. Also the
|
||
> graphical envelope editor draws its segments in secondary blue, which
|
||
> contrasts poorly against the primary green waveform display. Change those to
|
||
> tertiary purple.
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||
|
||
> yes, one overlay (or none). Everything besides Hold and Sustain, right? "is
|
||
> 1.0 the linear neutral" CLAUDE, y=x^1.0 is linear!! of course! yes dragging
|
||
> on the segment (add a round knot midsegment) adjusts the curve.
|
||
|
||
**Daniel's second follow-up (verbatim, 2026-07-28).**
|
||
|
||
> default overlay none
|
||
> what about the curves?
|
||
|
||
("what about the curves?" is Daniel turning the pre-existing-instances
|
||
question back — the answer recorded below is derived from this doc's own
|
||
acceptance criterion, not a Daniel quote.)
|
||
|
||
**Intent.** Grow the envelope-overlay editor from an amp-only fixture into the
|
||
shared graphical surface for every envelope in the instrument, and give every
|
||
envelope shapeable (non-linear) segments — while fixing the blue-on-green
|
||
contrast failure.
|
||
|
||
**Behavior.**
|
||
|
||
- **Radio switch per envelope deck.** Each envelope knob-deck group (currently
|
||
AMP ENVELOPE and PITCH ENV; the filter envelope joins when item 2 lands)
|
||
gains a radio switch in the corner of its deck. Selecting a deck's radio
|
||
makes *that* envelope the one displayed and editable in the graphic waveform
|
||
overlay — replacing today's behavior where the Amp AHDSR is always the
|
||
displayed envelope. The switch is exclusive: **one overlay-active envelope at
|
||
a time, or none** — no-envelope-shown is a valid state, not an error.
|
||
*(Settled by follow-up.)*
|
||
- **Default overlay: none.** The editor opens with **no envelope selected** —
|
||
the none-state is the default, replacing today's always-on Amp AHDSR.
|
||
*(Settled by second follow-up.)*
|
||
- **Pre-existing instances load at exponent 1.0.** Saved instances from before
|
||
this change load **every curve at exponent 1.0** — the linear neutral — so
|
||
their audible envelope behavior is unchanged. *(Derived, not a Daniel quote:
|
||
1.0 is the settled linear neutral, and the acceptance criterion "a project
|
||
saved before this change reopens with unchanged audible envelope behavior"
|
||
admits no other default. Daniel prompted the question; this is the only
|
||
answer consistent with what he has already settled.)*
|
||
- **Segment curve values on all envelopes.** Amp AHDSR, Pitch AHD (AD in the
|
||
original ask; item 8's follow-up adds the Hold stage), and Filter AHDSR all
|
||
gain an editable curve value per *sloped* segment. The curve is an
|
||
exponential function; the per-segment parameter is the exponent scalar,
|
||
range **0.1 to 10**.
|
||
- **Which segments are sloped.** **Every stage except Hold and Sustain** — for
|
||
an AHDSR that is Attack, Decay, and Release; for the Pitch AHD (A→H→D since
|
||
item 8's spec change), Attack and Decay — its Hold, like every Hold, is flat
|
||
and carries no curve dial. *(Settled by follow-up; the pitch reading updated
|
||
for item 8's AD→AHD change.)*
|
||
- **Linear neutral.** Exponent **1.0 is the linear neutral** (y = x^1.0 is
|
||
linear). *(Settled by follow-up — emphatically.)*
|
||
- **Curve editing in the overlay.** Dragging on a segment in the overlay
|
||
**adds a round mid-segment knot** whose drag adjusts that segment's curve —
|
||
the overlay is a curve-edit surface in its own right, alongside (not instead
|
||
of) the inner dial. *(Settled by follow-up.)*
|
||
- **Inner dial on curvable-segment knobs.** Every knob-deck radial knob that
|
||
controls a sloped, curvable segment gains an **inner dial**: its own inner
|
||
arc, its own hover accent (tertiary purple), its own needle, and its own
|
||
numerical label. The inner dial controls the curve exponent for that
|
||
segment; the outer knob keeps controlling the segment's time/level value as
|
||
today.
|
||
- **Overlay recolor.** The graphical envelope editor's segments change from
|
||
secondary blue to **tertiary purple** (secondary blue contrasts poorly
|
||
against the primary green waveform behind it).
|
||
|
||
**Open questions.**
|
||
|
||
- None remaining — both prior questions (default overlay selection,
|
||
pre-existing-instance curve loading) closed by the second follow-up round.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- Each envelope deck shows a corner radio switch; activating one puts that
|
||
envelope in the overlay, editable there, and the overlay tracks the switch
|
||
immediately. At most one envelope is overlay-active; with none active, the
|
||
overlay draws no envelope.
|
||
- The editor opens with no envelope overlay-active (default is none, not the
|
||
Amp AHDSR).
|
||
- Every curvable-segment knob shows the inner dial (inner arc, tertiary-purple
|
||
hover accent, needle, numeric label); sweeping it through 0.1 → 10 visibly
|
||
reshapes the overlay segment and audibly reshapes the envelope on played
|
||
notes. Hold and Sustain knobs carry no inner dial.
|
||
- Dragging on an overlay segment adds a round mid-segment knot; dragging the
|
||
knot adjusts that segment's curve, and the segment's inner dial reflects the
|
||
same value.
|
||
- Overlay envelope segments render in tertiary purple and are clearly legible
|
||
against the primary green waveform.
|
||
- A project saved before this change reopens with unchanged audible envelope
|
||
behavior: every curve loads at exponent 1.0.
|
||
|
||
---
|
||
|
||
## 2 — MM preamp Filter: resonant HP/LP stage in the voice pipeline
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> MM preamp Filter: We must implement a new processing point in the sampler
|
||
> audio pipeline, after pitch env, before amp, for filtering. The processor for
|
||
> this will be based on code I wrote for the cortex M4 for resonant high and
|
||
> lowpass filtering. The filter will have parameters for mode, cutoff, Q, and
|
||
> mod amt, then the AHDSR controls as described above. The knob deck row will
|
||
> then be relaid out in signal flow order: pitch -> filter -> amp
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||
|
||
> modes beyond the pass filters will be added later. cutoff range full audio
|
||
> spectrum, log scaled, fully open to fully closed, Q should go from 0.1 to 10
|
||
> again, scaled around root 2 at the center. mod amt targets cutoff, -100% -
|
||
> +100% to cover full range from either end. per-voice. label it "Filter"
|
||
|
||
**Daniel's second follow-up (verbatim, 2026-07-28).**
|
||
|
||
> oh, zone.
|
||
> yes, filter is off by default
|
||
> velocity and keytracking with the rest, not deffered. Same idea as the amp
|
||
> velocity transfer curve and pitch key tracking
|
||
|
||
**Intent.** Add the instrument's first filter stage — resonant high-pass and
|
||
low-pass — as a new fixed point in the per-voice signal path, with its own
|
||
AHDSR envelope, and make the knob-deck row read in signal-flow order.
|
||
|
||
**Behavior.**
|
||
|
||
- **Pipeline position.** A new processing point in the sampler audio pipeline:
|
||
**after the pitch envelope, before the amp stage.**
|
||
- **DSP source.** The filter processor is based on Daniel's own Cortex-M4
|
||
resonant high/lowpass filter code. **That code is an input Daniel supplies at
|
||
implementation time** — it is not in this repo and this spec does not
|
||
characterize it beyond "resonant high and lowpass."
|
||
- **Parameters.** Mode, cutoff, Q, and mod amt — then the AHDSR controls,
|
||
treated exactly as item 1 specifies (curvable sloped segments with inner
|
||
dials, overlay editability via the filter deck's radio switch).
|
||
*(Ranges settled by follow-up:)*
|
||
- **Mode:** high-pass and low-pass now; **modes beyond the pass filters are
|
||
explicitly deferred to later.**
|
||
- **Cutoff:** the **full audio spectrum, log scaled**, from fully open to
|
||
fully closed.
|
||
- **Q:** **0.1 to 10** (the curve-exponent range again), scaled so **√2 sits
|
||
at the center** of the control.
|
||
- **Mod amt:** **bipolar, −100% to +100%**, targeting **cutoff** — covering
|
||
the full range from either end.
|
||
- **Mode-driven envelope shape.** The filter envelope follows the playback
|
||
mode exactly as the amp does: **Gate → AHDSR, Trigger → AHD** — see item 14,
|
||
where the policy is stated in full. *(Settled by item 14's follow-up.)*
|
||
- **Per-voice.** The filter processes **per voice** — each sounding voice runs
|
||
its own filter with its own envelope state. *(Settled by follow-up.)*
|
||
- **Per-zone storage.** The filter's parameters are **stored per-zone**,
|
||
alongside the other playback parameters — Sample/Zone panel parity applies,
|
||
same as the existing per-zone controls (VOICE and MASTER remain the
|
||
per-instance exceptions). *(Settled by second follow-up.)* **Superseded by
|
||
item 16** (zone retirement): the filter's parameters join the instrument's
|
||
**one parameter set** — no per-zone storage, no Sample/Zone parity, no
|
||
per-instance exception structure to be an exception to. The follow-up's
|
||
substance carries over unchanged: the filter's parameters live with the
|
||
other playback parameters.
|
||
- **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 live in the instrument's one parameter set: they edit in
|
||
one place and govern the instrument as a whole. (Original per-zone/parity
|
||
form — two surfaces in parity, per-zone divergence — superseded by item 16;
|
||
neither is expressible after the zone retirement.)
|
||
- Velocity and key-tracking modulation of the filter ship with this item and
|
||
are audible — velocity following the amp-velocity-transfer-curve pattern,
|
||
key-tracking following the pitch-key-tracking pattern.
|
||
- The deck row reads pitch → filter → amp left-to-right.
|
||
- The filter is off by default: a project saved before this change reopens
|
||
sounding identical, and a freshly loaded capture sounds unchanged until the
|
||
filter is engaged.
|
||
|
||
---
|
||
|
||
## 3 — Alternative Spline EGs: hard/smooth multi-segment monotonic splines
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> Alternative Spline EGs: Every processor which has an envelope will have the
|
||
> ability to change the Staged EG to a Spline EG, based on the monotonic
|
||
> splines for the velocity curve. HOWEVER, we will need to enhance the (singly
|
||
> implemented, multi referenced) spline algorithm to support multiple segments
|
||
> that DON'T minimally smooth the spline, so that hard points are possible. In
|
||
> other words, the contour of the EG will be defined by 1 or more monotonic
|
||
> spline functions which together form the full time function for that
|
||
> processor, such that the first three points could make a curved segment,
|
||
> which connects at a sharp angle to the next three points, finishing out the
|
||
> contour over the full sample length. Control-clicking a point makes it a
|
||
> "hard" or "smooth" point (toggled, smooth by default) which when hard does no
|
||
> curve smoothing on either side segment, forming the natural sharp angle
|
||
> instead of a continuous derivative. This enhanced spline drawing will be used
|
||
> for the velocity-amp transfer curve as well as the pitch, filter, and amp EGs
|
||
> (if they are in spline mode).
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||
|
||
> dual state, save but inactive. Default Curve Spline is a smooth y=1-x. Gate
|
||
> mode is not available when the Spline is used, spline always covers the full
|
||
> sample length. The spline curves don't have to rise AND fall, they also
|
||
> aren't globally monotone, the default curve is a smooth downward slope over
|
||
> the length. all the soft points between any hard points will be
|
||
> smooth/monotone.
|
||
|
||
**Daniel's second follow-up (verbatim, 2026-07-28).**
|
||
|
||
> normalize the spline eg length to the full width, it should represent the
|
||
> time axis of the actual sample visually 1:1
|
||
> left click add, alt-click delete, cntrl-click toggles point hard or soft.
|
||
> spline active -> stage knobs disabled.
|
||
|
||
**Daniel's third follow-up (verbatim, 2026-07-28).**
|
||
|
||
> oh, maybe 64? is that way too much? I don't want to limit from long rhythmic
|
||
> phrases, which require a high resolution to be interesting
|
||
>
|
||
> oh, do right click delete instead for the spline
|
||
> 128 then
|
||
|
||
**Intent.** Offer a free-drawn alternative to every staged envelope: the user
|
||
switches any EG from Staged to Spline mode and draws the contour directly, with
|
||
the monotonic-spline machinery already proven by the velocity curve — enhanced
|
||
so sharp corners are possible, not everything smoothed.
|
||
|
||
**Behavior.**
|
||
|
||
- **Mode toggle per EG.** Every processor that has an envelope (pitch, filter,
|
||
amp) can switch its Staged EG to a **Spline EG**.
|
||
- **Dual state — save but inactive.** Both the Staged and the Spline state are
|
||
persisted; switching modes keeps the inactive one **saved but inactive**. No
|
||
conversion, no discard — round-tripping Staged↔Spline restores the other
|
||
mode's shape untouched. *(Settled by follow-up.)*
|
||
- **Gate unavailable in Spline mode.** Gate mode is **not available while a
|
||
Spline EG is active**; the spline **always covers the full sample length** —
|
||
a pure time function over the sample, i.e. the Trigger/one-shot playback
|
||
model. *(Settled by follow-up.)*
|
||
- **Time axis: normalized, visually 1:1.** The spline contour is **normalized
|
||
to the full sample length**, and the overlay represents **the time axis of
|
||
the actual sample visually 1:1** — the contour's full width maps directly
|
||
onto the displayed sample. Consequently a different-length capture rescales
|
||
the stored contour to its own length. *(Settled by second follow-up.)*
|
||
- **Point-editing grammar.** **Left-click adds a point; right-click deletes a
|
||
point; control-click toggles a point hard/smooth.** *(Settled by third
|
||
follow-up; control-click hard/smooth confirms the original ask.)* Note for
|
||
readers of the prior revision: the second follow-up answered alt-click
|
||
delete; the third follow-up **supersedes that** with right-click delete —
|
||
which matches the velocity-curve popup's already-shipped right-click node
|
||
delete, giving one point-editing grammar across both spline consumers.
|
||
- **Point-count ceiling: 128.** A spline contour holds at most **128 points**
|
||
(floor: the two endpoints implied by full-length coverage). Daniel floated
|
||
64 and raised it to 128 explicitly so the cap does not limit **long rhythmic
|
||
phrases, which require high resolution to be interesting** — at roughly two
|
||
points per articulation event, 64 points is about two bars of 16ths and 128
|
||
about four. The ceiling is a musical bound, not a performance one (segment
|
||
lookup is logarithmic; on-screen the editor's 8 px minimum node separation
|
||
is the practical density limit anyway). **An engineer tempted to lower this
|
||
number should read that motivation first.** *(Settled by third follow-up.)*
|
||
- **Staged controls disabled while Spline is active.** While a Spline EG is
|
||
active, that envelope's **staged segment knobs are disabled** — inert, not
|
||
merely inaudible — including their item-1 inner curve dials (the dial is
|
||
part of the knob). The dormant staged state is edited only by switching back
|
||
to Staged mode. *(Settled by second follow-up.)*
|
||
- **Not globally monotone.** Spline contours **don't have to rise and fall and
|
||
are not globally monotone**; the monotone guarantee is per-segment — **all
|
||
soft points between any hard points are smooth/monotone** (no overshoot
|
||
between adjacent points). *(Settled by follow-up.)*
|
||
- **Default contour.** A new Spline EG defaults to a **smooth y = 1 − x** — a
|
||
smooth downward slope over the full sample length. (Read as the Spline-EG
|
||
default contour; not a change to the velocity→amp transfer curve's existing
|
||
default.) *(Settled by follow-up.)*
|
||
- **Spline foundation.** The Spline EG is based on the monotonic splines used
|
||
for the velocity curve. The spline algorithm is singly implemented and
|
||
multi-referenced; the enhancement below applies to that one implementation
|
||
and flows to every consumer.
|
||
- **Hard points.** The algorithm is enhanced to support **multiple segments
|
||
that don't minimally smooth the spline**, so hard points are possible: the
|
||
EG contour is defined by **one or more monotonic spline functions** which
|
||
together form the full time function for that processor — e.g. the first
|
||
three points form a curved segment that connects **at a sharp angle** to the
|
||
next three points, finishing the contour over the **full sample length**.
|
||
- **Hard/smooth gesture.** **Control-clicking a point toggles it hard/smooth
|
||
(smooth by default).** A hard point does no curve smoothing on either
|
||
adjacent segment — the natural sharp angle stands instead of a continuous
|
||
derivative.
|
||
- **Shared across consumers.** The enhanced spline drawing serves the
|
||
**velocity→amp transfer curve** as well as the pitch, filter, and amp EGs
|
||
(when those are in spline mode). The velocity curve gains hard-point support
|
||
by the same enhancement.
|
||
|
||
**Open questions.**
|
||
|
||
- None remaining — both prior questions closed by the third follow-up round.
|
||
Point-count bounds: ceiling 128, floor two endpoints. Gesture convergence:
|
||
resolved by the delete-gesture reversal itself — the Spline EG's right-click
|
||
delete now matches the velocity-curve popup's shipped right-click node
|
||
delete, so **no migration is needed on either side**; one grammar serves
|
||
both consumers.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- Each of the pitch, filter, and amp EGs offers a Staged/Spline mode switch;
|
||
in Spline mode the overlay (via the item-1 radio switch) shows and edits the
|
||
drawn contour, and played notes audibly follow it.
|
||
- Left-click on the contour adds a point at that position; right-click on a
|
||
point deletes it; control-click toggles it hard/smooth. Points are smooth by
|
||
default; a hard point renders a visible sharp angle with no smoothing on
|
||
either adjacent segment, and the discontinuous slope is audible where the
|
||
modulation target makes it so (e.g. a pitch EG corner).
|
||
- A contour accepts points up to the **128-point ceiling**; attempting to add
|
||
beyond it is refused without disturbing the existing contour. The two
|
||
endpoints cannot be deleted (full-length coverage always holds).
|
||
- A contour of several segments joined at hard points plays back over the full
|
||
sample length exactly as drawn — including contours that rise and fall
|
||
freely (no globally-monotone restriction), with no overshoot between any
|
||
adjacent pair of points.
|
||
- A freshly created Spline EG shows the smooth y = 1 − x default contour.
|
||
- While a Spline EG is active, Gate mode is not selectable; the spline plays
|
||
as a pure time function over the full sample length.
|
||
- The overlay contour spans the full displayed sample width, 1:1 with the
|
||
sample's time axis; loading a different-length capture rescales the contour
|
||
to the new sample length (normalized storage), with the drawn shape
|
||
preserved proportionally.
|
||
- While a Spline EG is active, that envelope's staged segment knobs and their
|
||
inner curve dials render disabled and reject edits; switching back to Staged
|
||
re-enables them with values exactly as left.
|
||
- Staged↔Spline round-trip preserves both states: switch to Spline, draw,
|
||
switch back — the staged values are exactly as left; switch forward again —
|
||
the spline contour is exactly as drawn. Both survive save/reload.
|
||
- The velocity→amp transfer-curve editor supports the same control-click
|
||
hard/smooth toggle with identical rendering behavior, and its existing
|
||
right-click node delete matches the Spline EG's delete gesture unchanged —
|
||
one point-editing grammar across both consumers.
|
||
|
||
---
|
||
|
||
## 4 — Bug: end-of-sample click in Trigger mode under Preserve *(his 1)*
|
||
|
||
**Daniel's report (verbatim, 2026-07-28).**
|
||
|
||
> actual bug: in trigger mode, polyphonic or monophonic, in preserved pitch
|
||
> mode only, the end of the sample has an audible click.
|
||
|
||
**Symptom.** In Trigger mode — polyphonic or monophonic alike — with the pitch
|
||
engine in **Preserve mode only**, the end of the sample produces an audible
|
||
click. The scoping is the useful part of the report and is recorded as given:
|
||
Trigger × Preserve × end-of-sample; Varispeed is not implicated. No cause
|
||
speculation here.
|
||
|
||
**Expected behavior.** A Trigger one-shot in Preserve mode ends silently — no
|
||
click or discontinuity at the sample end, in either voice mode.
|
||
|
||
**Acceptance gate.** A Trigger-mode note played in Preserve, in both Poly and
|
||
Mono, ends with no audible click at the sample end (verified by ear and by
|
||
inspecting the rendered output for a terminal discontinuity). Varispeed
|
||
playback is unchanged.
|
||
|
||
---
|
||
|
||
## 5 — Bug: drag-out sometimes lands without audio (extension) *(his 2)*
|
||
|
||
**Daniel's report (verbatim, 2026-07-28).**
|
||
|
||
> other bug (extension, not VST): Dragging capture out of the pool or bank does
|
||
> sometimes doesn't actually contain the audio, and I hae to try dragging
|
||
> again.
|
||
|
||
**Symptom.** Extension side, not the VST. Dragging a capture out of the pool
|
||
or a named bank **sometimes** produces a drop that does not actually contain
|
||
the audio; retrying the drag works. Both details are load-bearing: the failure
|
||
is intermittent, and a retry succeeds.
|
||
|
||
**Expected behavior.** Every completed drag-out delivers the capture's audio
|
||
at the drop target — first try, every time.
|
||
|
||
**Acceptance gate.** Because the failure is intermittent, the gate is a soak:
|
||
across a sustained session of varied drag-outs (pool and bank sources,
|
||
including the first drag after other bank activity), every drop yields a
|
||
playable file containing the audio, with no retry ever needed.
|
||
|
||
---
|
||
|
||
## 6 — Bug: drop onto FX container loads instrument without the capture *(his 3, first)*
|
||
|
||
**Daniel's report (verbatim, 2026-07-28).**
|
||
|
||
> drop to FX container bug: the reasmpler 9000 loads, but not with the capture.
|
||
> drop to FX button works as expected with capture preloaded.
|
||
|
||
**Symptom.** Dropping a capture onto an **FX container** loads a ReaSampler
|
||
9000 instance, but **without the capture**. Dropping the same capture onto the
|
||
**FX button** works as expected — instrument loads with the capture preloaded.
|
||
|
||
**Expected behavior.** The FX-button path is the reference; the container path
|
||
must match it: instrument added *with* the dragged capture loaded.
|
||
|
||
**Acceptance gate.** A capture dropped onto an FX container yields an
|
||
instrument instance with that capture loaded and immediately playable,
|
||
indistinguishable (apart from where the FX sits) from the FX-button drop. The
|
||
FX-button path remains unregressed.
|
||
|
||
---
|
||
|
||
## 7 — Enhancement: stereo waveform shows both channels *(his 4, first)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> VST Waveform Visualizer: in stereo mode, both L and R channels should show
|
||
> in the waveform visual. left on top. mono mode still shows just one channel
|
||
> for unredundancy.
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||
|
||
> 7) One full height; stereo linked processing, one editor
|
||
|
||
**Behavior.**
|
||
|
||
- In **stereo mode**, the waveform visual shows **both L and R channels, left
|
||
on top** (two stacked lanes).
|
||
- In **mono mode**, a single channel shows — no redundant duplicate lane.
|
||
- The display keys off the active channel mode, per Daniel's phrasing.
|
||
- **Overlays draw once, at full height.** Overlays that ride the waveform
|
||
(the envelope overlay, markers, and item 9's loop region if it lands) draw
|
||
**once at full height across both stacked lanes** — not per lane.
|
||
*(Settled by follow-up.)*
|
||
- **Stereo processing is linked.** One editor, one set of controls governing
|
||
both channels — no per-channel parameter divergence, no per-channel editing
|
||
surface. *(Settled by follow-up.)*
|
||
|
||
**Open questions.**
|
||
|
||
- None remaining — the overlay-layout question closed by the second-batch
|
||
follow-up round.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- A stereo capture in stereo mode shows two stacked lanes, L above R, each a
|
||
true view of its channel's content (an asymmetric-channel capture visibly
|
||
differs between lanes).
|
||
- Mono mode shows exactly one lane. Switching modes updates the display
|
||
accordingly.
|
||
- In stereo mode, waveform-riding overlays (envelope, markers, loop region if
|
||
present) render once at full stacked height — no duplicated per-lane copies
|
||
— and stay legible across both lanes.
|
||
- No per-channel controls appear; every edit applies identically to both
|
||
channels (linked stereo processing, one editor).
|
||
|
||
---
|
||
|
||
## 8 — Enhancement: staged-overlay release anchoring; the Pitch AD becomes AHD *(his 3, second)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> AHDSR visual overlay looks odd, not taking up the whole range. with no
|
||
> release, the sustain portion only travels accross a small portion of the
|
||
> panel, making the thing look off center. to resolve, the release segment
|
||
> should be anchored to the right, and draggable from the top node (connecting
|
||
> to sustain segment) instead of the bottom corner, which will now be anchored.
|
||
> All staged envelope overlays should follow this policy.
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||
|
||
> 8) For the AD... make it AHD, and the combined A H and D segment lengths
|
||
> (time displacement) cannot exceed the full sample length. Hold goes from 0
|
||
> to 100%, and the visual overlay for the envelope is then 1:1 scale with the
|
||
> waveform time. D is not release, so it is not right anchored.
|
||
|
||
**Daniel's second follow-up (verbatim, 2026-07-28).**
|
||
|
||
> 1) 100% of the sample length - attack+decay times
|
||
> 2) for all envelopes that DON'T have a sustain stage. The 1:1 mapping only
|
||
> makes sense for trigger, not gated envelopes
|
||
|
||
**Intent.** A layout-policy change to the staged envelope overlay so it uses
|
||
the full panel width: today, with little or no release, the sustain portion
|
||
occupies only a small stretch and the whole figure reads off-center. The
|
||
follow-up round grew this item beyond layout: it now also carries **the spec
|
||
change that turns the pitch envelope from AD into AHD**.
|
||
|
||
**Behavior.**
|
||
|
||
- The **release segment anchors to the right edge** of the overlay.
|
||
- Release is dragged from its **top node** — the node joining sustain to
|
||
release — instead of the bottom corner. The bottom corner (the envelope's
|
||
end point) becomes **fixed/anchored**, not draggable.
|
||
- **The policy applies to the envelopes that have a release** — the amp AHDSR
|
||
today and the filter AHDSR when item 2 lands. **It does not apply to the
|
||
pitch envelope: D is not a release stage, so it is not right-anchored.**
|
||
*(Settled by follow-up — this closes the prior open question about mapping
|
||
the policy onto the pitch envelope: the answer is that the policy does not
|
||
apply there; the envelope gains a Hold stage instead.)*
|
||
- **Spec change: the pitch envelope becomes AHD.** The Pitch AD gains a
|
||
**Hold** stage: **Attack → Hold → Decay**. *(Settled by follow-up — a spec
|
||
change, not a clarification. The doc's own prose — here and item 1's
|
||
sloped-segment reading — is updated to match; Daniel's verbatim asks stay
|
||
as written.)*
|
||
- **Hold ranges 0 to 100% of the time remaining after Attack and Decay** —
|
||
i.e. 100% of (sample length − (attack time + decay time)). At 100%, Hold
|
||
fills all the remaining time; at 0% it takes none. *(Settled by second
|
||
follow-up.)*
|
||
- **The A + H + D ≤ sample-length bound holds by construction**, not by a
|
||
separate clamp: Hold is expressed as a fraction of what is left after
|
||
Attack and Decay, so the sum cannot overflow. Daniel's stated bound
|
||
("the combined A H and D segment lengths cannot exceed the full sample
|
||
length") is a *property* of the Hold definition, not a constraint to
|
||
enforce on top of it.
|
||
- **The overlay is therefore 1:1 scale with the waveform time axis** — the
|
||
drawn envelope maps directly onto the displayed sample's time.
|
||
- **Scope rule — split on the sustain stage.** The 1:1-overlay property and
|
||
the combined-time bound apply to **all envelopes that do NOT have a sustain
|
||
stage**; envelopes **with** a sustain stage (the amp and filter AHDSRs) get
|
||
the right-anchored-release policy instead. Daniel's rationale: the 1:1
|
||
mapping only makes sense for trigger, not gated envelopes — that is the
|
||
reasoning behind the stage-list rule, not a second competing rule. Today
|
||
the pitch AHD is the only sustain-less envelope, but the rule is general:
|
||
it governs any future sustain-less envelope too. The two policies
|
||
**coexist rather than merge**, split cleanly on whether the envelope has a
|
||
sustain stage — the prior revision's open reading, now confirmed. *(Settled
|
||
by second follow-up.)*
|
||
- **Cross-references.** Item 1 reworks this same overlay surface (radio
|
||
switch, mid-segment curve knots, recolor) — this item is cheapest folded
|
||
into or immediately after that work; item 1's sloped-segment rule reads
|
||
Attack and Decay for the pitch AHD (Hold is flat, no curve dial). Item 3's
|
||
Spline overlays are unaffected by construction: a spline always spans the
|
||
full sample width already. Item 14 extends the AHD to the amp and filter
|
||
envelopes' Trigger mode, so this scope rule selects by the envelope's
|
||
current shape under the active playback mode — see item 14.
|
||
|
||
**Open questions.**
|
||
|
||
- None remaining — both prior questions (Hold's 0–100% reference; the scope
|
||
of the 1:1/combined-bound policy) closed by the second-batch second
|
||
follow-up round. The coexist-vs-merge reading the prior revision flagged is
|
||
confirmed: the two policies coexist, split cleanly on whether the envelope
|
||
has a sustain stage.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- With release at zero or minimum, the sustain segment extends to (near) the
|
||
right edge — the overlay reads full-width, not bunched left.
|
||
- Dragging the sustain→release top node adjusts release; the bottom-right
|
||
corner is fixed and not draggable.
|
||
- The envelopes with a sustain stage (amp, and filter once present) follow
|
||
the same anchoring policy; the pitch envelope's Decay is **not**
|
||
right-anchored.
|
||
- The pitch envelope plays and displays three stages — Attack, Hold, Decay —
|
||
with Hold spanning 0–100% of the time remaining after Attack and Decay. By
|
||
construction, no combination of A, H, and D settings yields a combined time
|
||
displacement exceeding the sample length (at Hold = 100% the three stages
|
||
exactly fill it) — no separate clamp fires, because none is needed.
|
||
- The overlay of any sustain-less envelope (today: the pitch AHD) is 1:1 with
|
||
the waveform's time axis: a stage boundary at N seconds sits over the
|
||
waveform at N seconds.
|
||
|
||
---
|
||
|
||
## 9 — Bug + Enhancement: loop points — suspected regression, and the Gate-mode loop-sustain spec *(his 4, second)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> I think loop points got lost. ideally if in gate mode we have a loopable
|
||
> section with parameterized start end points and parameterized crossfade on
|
||
> reset, which will function as the sustain for indefinite playback until note
|
||
> off and release.
|
||
|
||
**This item is both** a regression report and a feature spec, and is recorded
|
||
as both.
|
||
|
||
**Regression half (Bug).** Daniel's observation: loop points appear to have
|
||
been lost. Whether they were genuinely removed from playback or are merely
|
||
unexposed in the current UI is a code question that **cannot be answered here**
|
||
under the no-code-reads constraint — it must be verified as the first act of
|
||
implementation, not guessed in this document.
|
||
|
||
**Feature half (Enhancement — spec as given).** In **Gate mode**: a loopable
|
||
section with **parameterized start and end points** and a **parameterized
|
||
crossfade on loop reset**. The loop functions as the sustain — indefinite
|
||
playback cycling the loop until note-off, then release.
|
||
|
||
- **Cross-reference item 3.** Gate mode is unavailable while a Spline EG is
|
||
active (settled), so loop-sustain is a **Staged/Gate-mode feature**; Spline
|
||
mode remains full-sample-length playback with no loop.
|
||
|
||
**Open questions.**
|
||
|
||
- The regression verification above (removed vs. unexposed).
|
||
- The crossfade parameter's units and range are unspecified — Daniel call, or
|
||
a proposed default surfaced at implementation review.
|
||
- Storage side: closed by **item 16** (zone retirement) — the loop
|
||
parameters belong to the instrument's one parameter set; there is no
|
||
per-zone side left to confirm. (Cross-reference: item 15's settled reset
|
||
scope classifies loop points as baked-in, so they reset on a resample.)
|
||
- 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.)* **Superseded by item
|
||
16** (zone retirement): the curves live in the instrument's **one
|
||
parameter set**. The bullet's point survives in simplified form — the
|
||
curves store with the other playback parameters; the per-zone framing and
|
||
the parity convention it leaned on are gone.
|
||
- **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 above — per-zone at the time
|
||
of that round, now the one parameter set per item 16.)
|
||
|
||
**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 persist in the instrument's one parameter set and
|
||
round-trip save/reload. (Original per-zone/parity form superseded by
|
||
item 16; per-zone divergence is no longer expressible.)
|
||
- 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. **Item 16** (zone retirement) removes the zone count
|
||
label's referent entirely — this item's removal of the label is doubly
|
||
settled — and re-grounds what the full-width strip displays: with no zone
|
||
bars, its surviving jobs are the root affordance (item 15's answer round
|
||
makes root explicitly resample-stable) and these note-name tooltips;
|
||
whether any key-range display remains follows item 16's key-range
|
||
question.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- Top toolbar text renders in one consistent font treatment; the title carries
|
||
no zone count.
|
||
- Preview and mono/stereo sit adjacent to browse/zoom; the piano strip spans
|
||
the full editor width.
|
||
- Same-class keys are equal pixel width at any window width and DPI scale.
|
||
- Hovering any piano key shows its note name in a tooltip.
|
||
|
||
---
|
||
|
||
## 13 — Enhancement (audit): antialiased rendering for high-DPI *(his 8)*
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> We should finally review to make sure we are rendering with some kind of
|
||
> antialiasing equivalent for high DPI high res clean rendering. It still
|
||
> looks pixely in places (radial arcs, waveform lines, env segment slopes)
|
||
|
||
**Intent.** A review pass, not a point fix: audit the editor's drawn surfaces
|
||
and confirm they render with antialiasing (or an equivalent) suitable for
|
||
high-DPI, high-resolution displays. Daniel named the visibly pixely surfaces:
|
||
**radial arcs, waveform lines, envelope segment slopes**.
|
||
|
||
**Behavior.**
|
||
|
||
- Audit each class of drawn surface; where one renders visibly aliased, bring
|
||
it to the smooth standard. The outcome is observable, not procedural: the
|
||
named surfaces (and any others the audit turns up) render without visible
|
||
stair-stepping.
|
||
- **Sequencing observation** (not a decision): this touches nearly every
|
||
surface items 1, 3, 7, 8, 10, 11, and 12 repaint — running it after the
|
||
layout/knob work likely avoids doing the polish twice.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- Radial arcs (including item 1's inner dials), waveform lines (including
|
||
item 7's stereo lanes), and envelope segment slopes (staged and spline)
|
||
render smooth — no visible jaggies at 100% scale or on a high-DPI display.
|
||
- The audit produces a short disposition list: surfaces checked, which needed
|
||
work, which were already clean.
|
||
- Daniel signs off by eye on the named surfaces.
|
||
|
||
---
|
||
|
||
## 14 — Enhancement: Trigger-mode amp envelope — fade-in/fade-out replaced by the AHD (with curves)
|
||
|
||
**Daniel's ask (verbatim, 2026-07-28).**
|
||
|
||
> the amp env trigger mode fade in length fade out changes to the AHD envelope
|
||
> (with curves of course), to reduce code for the same thing, and consolidate
|
||
> under the new design.
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-28).**
|
||
|
||
> sure, filter follows as well
|
||
|
||
**Intent.** Consolidation. In Trigger mode the amp envelope's fade-in-length /
|
||
fade-out-length pair is retired and replaced by the same three-stage
|
||
Attack → Hold → Decay envelope item 8 specifies for the pitch envelope — with
|
||
item 1's per-segment curves. Daniel's stated motive is reducing code for the
|
||
same job: one staged-envelope design covering what is currently two separate
|
||
mechanisms doing the same thing. The product consequence: **the amp envelope's
|
||
staged shape follows the playback mode** — Gate → AHDSR (sustain,
|
||
right-anchored release, per item 8); Trigger → AHD (sustain-less). The
|
||
follow-up round extends the same rule to item 2's filter envelope.
|
||
|
||
**Behavior.**
|
||
|
||
- **Trigger mode: fades out, AHD in.** In Trigger mode the amp envelope is an
|
||
AHD per item 8's definition: Hold spans 0–100% of the time remaining after
|
||
Attack and Decay, so A + H + D ≤ sample length holds by construction and the
|
||
overlay is 1:1 with the waveform's time axis. The fade-in-length and
|
||
fade-out-length controls go away in Trigger mode; Attack and Decay carry
|
||
those roles under the new design.
|
||
- **With curves.** The Trigger AHD's sloped segments — Attack and Decay; Hold
|
||
is flat, as everywhere — get item 1's full curve treatment: exponent 0.1–10,
|
||
inner dials, mid-segment overlay knots, tertiary-purple rendering.
|
||
- **Gate mode unchanged.** In Gate mode the amp envelope remains the AHDSR
|
||
with item 8's right-anchored release. Item 9's loop-sustain spec (a
|
||
Gate-mode feature) is untouched.
|
||
- **The filter envelope follows as well.** Item 2's filter envelope takes the
|
||
same mode-driven shape: **Gate → AHDSR, Trigger → AHD** — same staged
|
||
machinery, same consolidation. It necessarily lands with or after item 2
|
||
(the filter must exist first); item 2 carries a cross-reference. *(Settled
|
||
by follow-up.)*
|
||
- **Item 8's scope rule now governs all three envelopes uniformly.** Item 8
|
||
settled that the 1:1-overlay property and the by-construction combined-time
|
||
bound apply to envelopes **without a sustain stage**, and the
|
||
right-anchored-release policy to those **with** one — Daniel's rationale:
|
||
"the 1:1 mapping only makes sense for trigger, not gated envelopes." With
|
||
this item the amp — and, per the follow-up, the filter — envelope in
|
||
Trigger mode *is* sustain-less, so each takes the 1:1 time-mapped overlay
|
||
automatically; in Gate mode each keeps the right-anchored release. The
|
||
general policy, stated once: **pitch is always AHD (1:1 overlay); amp and
|
||
filter are AHDSR in Gate (right-anchored release) and AHD in Trigger (1:1
|
||
overlay)**. The rule selects by the envelope's **current shape under the
|
||
active playback mode**, not by which processor the envelope modulates. No
|
||
new rule is needed — item 8's rule already decides every case.
|
||
- **Pre-existing instances reopen sounding identical.** The doc's standing
|
||
migration framing (items 1, 2, 11) applies: a project saved before this
|
||
change reopens with unchanged audible behavior — in particular, a Trigger
|
||
instance's prior fade-in/fade-out contour is reproduced by the loaded AHD.
|
||
The evident mapping (Attack ← fade-in, Decay ← fade-out, Hold ← the full
|
||
remainder, curve exponents at whatever value reproduces the prior fade
|
||
shape) is a verify-at-implementation detail, not a Daniel call; the gate
|
||
below states the requirement. A prior zero fade-out is Decay = 0 — the
|
||
abrupt end stays representable, so nothing the old controls could express
|
||
is lost.
|
||
- **Cross-references.** Item 8 supplies the AHD definition and the scope rule
|
||
(this item is that rule's second consumer); item 1 supplies the curves —
|
||
sequencing: cheapest folded into or immediately after that combined work.
|
||
Item 3 is unaffected in Spline mode (a spline already plays as a
|
||
full-sample-length time function — the trigger model); its "save but
|
||
inactive" dual-state precedent bears on the second open question below.
|
||
Item 4's Trigger × Preserve end-of-sample click sits in the region the
|
||
fade-out currently governs — whichever of the two lands first, item 4's
|
||
gate must be re-verified under the surviving mechanism.
|
||
|
||
**Open questions.**
|
||
|
||
- **Stage-value state across the Gate/Trigger switch — shared or per-mode?**
|
||
The Gate AHDSR and Trigger AHD share stage names (A, H, D); whether they
|
||
share *values* (one envelope whose S and R fall away in Trigger) or keep
|
||
per-mode state (item 3's "save but inactive" dual-state precedent) is
|
||
unspecified — and with the follow-up the question covers the **filter
|
||
envelope too**, not just the amp. Migration leans per-mode for the amp: an
|
||
old instance carries both its AHDSR values and its Trigger fade values, and
|
||
a shared-value model cannot preserve both modes' prior sound at once. (The
|
||
filter is new in item 2, so it carries no migration weight either way;
|
||
matching the amp's answer is the natural default.) Resolve at
|
||
implementation review with a proposal — not Daniel-blocking, but the
|
||
sound-identical gate must hold for whichever mode a saved instance plays
|
||
in. (The filter question that previously led this list — does the filter
|
||
AHDSR follow the same mode-driven shape? — is settled by the follow-up:
|
||
yes; folded into Behavior above.)
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- In Trigger mode the amp deck shows Attack / Hold / Decay — no fade-in or
|
||
fade-out control anywhere in Trigger mode — with curve inner dials on
|
||
Attack and Decay and none on Hold; when the amp envelope is overlay-active
|
||
(item 1's radio), its overlay is 1:1 with the waveform time axis, and no
|
||
combination of A, H, D settings exceeds the sample length (Hold = 100%
|
||
exactly fills it — by construction, no clamp).
|
||
- In Gate mode the amp envelope is the unchanged AHDSR: sustain stage,
|
||
right-anchored release per item 8.
|
||
- Switching between Gate and Trigger playback switches the amp envelope
|
||
surface (deck and overlay) between AHDSR and AHD accordingly.
|
||
- Once item 2's filter lands, its envelope switches identically: AHDSR
|
||
(right-anchored release) in Gate, 1:1 AHD in Trigger — the mode switch
|
||
swaps the amp and filter envelope surfaces the same way.
|
||
- A project saved before this change reopens sounding identical: a Trigger
|
||
instance's prior fade-in/fade-out contour — including a zero fade-out's
|
||
abrupt end — is audibly reproduced by the loaded AHD.
|
||
- The Trigger amp AHD behaves stage-for-stage like item 8's pitch AHD — Hold
|
||
semantics, curve treatment, and overlay mapping match. (This is the
|
||
observable proxy for the consolidation motive: one staged-envelope design,
|
||
two consumers.)
|
||
|
||
---
|
||
|
||
## 15 — Enhancement: one-click in-sampler resample — bake the dialed sound into the bank and iterate
|
||
|
||
**Daniel's ask (verbatim, 2026-07-29).**
|
||
|
||
> I would like the ability to somehow resample from directly inside the
|
||
> ReaSampler 9000 VST. Once I have the filtering, pitching, amp all set up
|
||
> nice, one click should:
|
||
> send a trigger or gate through the sampler offline, capture the audio,
|
||
> replace the bank source capture with the recapture (or add a new distinct
|
||
> one if there are other references), replace that sampler capture with the
|
||
> new/corrected bank capture, and reinitialize the reasampler 9000 audio
|
||
> parameters to default, effectively allow reiteration over sounds from
|
||
> within the sampler.
|
||
|
||
**Daniel's answer round (verbatim, 2026-07-29)** — answering, in order, the
|
||
five questions this item carried as awaiting a Daniel decision:
|
||
|
||
> 1. I don't actually care, or even really understand, our zones. Retire
|
||
> the zone mapping system, simplify. I don't expect to use it,
|
||
> reasampler 9000 becomes 1 capture = one parameter set
|
||
> 2. capture root (so that parameter is not reset by resampling), for the
|
||
> gate and velocity questions, we need a popup menu to program note
|
||
> length, start/end offsets in ms AND in beats, and velocity for the
|
||
> capture signal. The popup shoulud have a preview trigger button to
|
||
> allow previewing the note capture as currently programed.
|
||
> 3. only what is baked into the sample recapture (contours, filter, master
|
||
> gain, etc)
|
||
> 4. any usage of that capture that is tied by the provenance/recaptureing
|
||
> system
|
||
> 5. Undo/Recovery is a plus
|
||
|
||
**Daniel's second answer round (verbatim, 2026-07-29)** — the fourth
|
||
batch's second answer round. The unnumbered opening line answers item 16's
|
||
migration question (carried there); the numbered answers map, in order,
|
||
onto the doc's three under-specification flags: the
|
||
provenance-consolidation flag (→ item 17), this item's derived reset-scope
|
||
classification, and this item's capture-window semantics:
|
||
|
||
> adopt the first zone's capture and parameters, I don't have any projects
|
||
> with zones used
|
||
>
|
||
> 1. the provenance/usage tracking will need to be consolidated and made
|
||
> 100% robust
|
||
> 2. that's good
|
||
> 3. yeah relative to note-on and note-off of the programed note length
|
||
> (1/8., 1/4t, 1/16, 4/1 etc (1/64th to 64/1 with dotted and triplet
|
||
> multipliers)). the project tempo under the item cursor.
|
||
|
||
**Intent.** Close the sound-design loop from inside the instrument: once the
|
||
filtering, pitching, and amp are set up nice, one click bakes that processing
|
||
into the audio itself — a new bank capture — and hands the instrument back at
|
||
neutral, ready to be dialed again. Daniel frames it as a radical feature, and
|
||
it is: it turns the sampler from a player of captures into an iterative
|
||
resampling instrument, with the bank as the medium each iteration passes
|
||
through.
|
||
|
||
**Behavior.**
|
||
|
||
- **One gesture, whole chain.** A single click performs the full sequence:
|
||
offline pass → capture → bank update (replace or add-distinct) → instance
|
||
re-point → parameter reset. The steps are one action from the user's side,
|
||
not a wizard.
|
||
- **Offline pass through the instrument's own processing.** The audio is
|
||
produced by sending a trigger or gate through the sampler **offline** — the
|
||
instrument's own voice path, with the filtering, pitching, and amp exactly
|
||
as dialed, renders the result. The recapture is of that processed output,
|
||
not of the raw source.
|
||
- **The recapture is a bank capture like any other.** It lands in the bank —
|
||
project-relative, indexed, browsable from any surface that browses the
|
||
bank — and is governed by the same safety rules as every file the system
|
||
itself creates.
|
||
- **Replace, or add distinct.** When nothing else references the source
|
||
capture, the recapture **replaces** it as the bank entry; when other
|
||
references exist, the original entry stays and the recapture is **added as
|
||
a new distinct capture**. (What counts as an "other reference" is settled
|
||
by the answer round — usage tied by the provenance/recapture system; see
|
||
the settled bullet below.)
|
||
- **Replacement never destroys audio bytes.** "Replace" means the bank entry
|
||
now denotes the recapture; the superseded file itself is not deleted by
|
||
this action. *(Derived, not a Daniel quote: the settled rule that the
|
||
prune action is the system's only file-deletion authority admits no other
|
||
reading — resample writes a new file and retires the old one to
|
||
reclaimable-by-prune status; it never overwrites or deletes it.)* Until a
|
||
prune reclaims it, the pre-bake audio therefore survives on disk — the
|
||
iterate loop's built-in recovery floor, whatever the undo question below
|
||
settles.
|
||
- **The instance re-points.** The sampler's loaded capture is replaced with
|
||
the new/corrected bank capture — the instrument now plays the baked sound.
|
||
- **Parameters reinitialize to default.** After the swap, the instrument's
|
||
audio parameters return to default — destructive to the dialed settings
|
||
**by design**: the processing now lives in the recaptured audio, and the
|
||
neutral controls are the starting point for the next iteration. Which
|
||
parameters "audio parameters" covers is settled by the answer round — see
|
||
the reset-scope bullet below.
|
||
- **No timeline item, ever.** Resampling is a capture act: it writes a file
|
||
to the bank and updates the index; nothing is placed in the arrange view.
|
||
*(Derived, not a Daniel quote: the tool's load-bearing capture/placement
|
||
separation forces this — any framing of the feature that auto-inserts the
|
||
recapture into the timeline is invalid.)*
|
||
- **Single capture, single parameter set — "the sound" is unambiguous.**
|
||
Answer 1 dissolves the multi-zone question by **system change, not scoping
|
||
rule**: the zone mapping system is retired outright — recorded in full as
|
||
**item 16**. With one capture = one parameter set, one click resamples the
|
||
instrument's one capture through its one parameter set; no multi-zone rule
|
||
is needed because no multi-zone state exists. *(Settled by answer round —
|
||
by reference to item 16.)*
|
||
- **The capture-signal popup.** A **popup menu programs the capture
|
||
signal**: **note length**, **start and end offsets — in ms AND in
|
||
beats**, and **velocity**. The popup carries a **preview trigger button**
|
||
that auditions the capture note exactly as currently programmed — the
|
||
user hears the bake before committing it — and the offline pass renders
|
||
that same programmed performance. *(Settled by answer round — a new
|
||
sub-feature, specced here with its own acceptance criteria below.)*
|
||
- **The note is the capture's root.** The rendered note is the capture's
|
||
root note — and, as Daniel states as a consequence, **the root-note
|
||
parameter is therefore not reset by resampling** (capturing at root is
|
||
what makes the root parameter survivable: it composes with the
|
||
reset-scope rule below, and resetting it would detune every subsequent
|
||
iteration). *(Settled by answer round.)*
|
||
- **Note length is a musical division, not a free duration.** The
|
||
programmed note length is chosen from musical divisions spanning
|
||
**1/64th through 64/1, with dotted and triplet multipliers** (Daniel's
|
||
examples: `1/8.`, `1/4t`, `1/16`, `4/1`). *(Settled by second answer
|
||
round.)*
|
||
- **Offsets anchor to note-on and note-off.** The start offset is
|
||
relative to the programmed note's **note-on**; the end offset is
|
||
relative to its **note-off**. *(Settled by second answer round.)*
|
||
- **Beats resolve against the project tempo under the cursor.** A
|
||
beat-denominated value — the note-length division always, the offsets
|
||
when expressed in beats — resolves to time against **"the project
|
||
tempo under the item cursor"** (Daniel's phrase; read plainly: the
|
||
tempo in effect at the project's cursor position when the preview or
|
||
bake runs). *(Settled by second answer round.)*
|
||
- **Gate's hold and tail are answered by the programmed window.** The
|
||
programmed **note length is the Gate hold bound** — the gate holds for
|
||
the note length, then releases; item 9's loop-sustain cycles within the
|
||
held span and the render still terminates. The **end offset** is the
|
||
natural home of the tail policy: captured time past the note's end is
|
||
where the release rings. *(The hold reading is settled by the answer
|
||
round; the anchors are settled by the second answer round — with the
|
||
end offset anchored to note-off, the tail reading is direct, no longer
|
||
a derivation.)*
|
||
- **Velocity is explicit.** The programmed velocity is the render
|
||
velocity — material because the velocity transfer curves modulate amp
|
||
(and, with items 2 and 11, pitch and filter) at that velocity.
|
||
*(Settled by answer round.)*
|
||
- **Reset scope: only what the bake baked in.** *(Settled by answer round.)*
|
||
"Reinitialize the audio parameters to default" covers **only the
|
||
parameters whose effect is baked into the recaptured audio** — Daniel
|
||
names contours, filter, and master gain, with an explicit "etc". The
|
||
per-parameter classification follows — it began as this doc's derivation
|
||
and is now **confirmed by Daniel** ("that's good," second answer round);
|
||
the record that it originated as a reading-off is preserved, but the
|
||
reset/survive lists below are ratified, not derived:
|
||
- **Reset** (their effect is in the audio): the envelope contours — staged
|
||
and spline alike — the filter parameters, master gain, the pitch
|
||
envelope/engine settings, the velocity transfer curves (their effect at
|
||
the programmed velocity is in the audio), and the loop points (they
|
||
shaped the render, and old loop positions are meaningless against new
|
||
audio).
|
||
- **Survive** (mapping facts, not present in the audio): the **root
|
||
note** (explicit in answer 2), and — post-item-16 — whatever remains of
|
||
key mapping (key-tracking; any key-range concept item 16's open
|
||
question settles), plus the VOICE group (polyphony behavior leaves no
|
||
trace in a single rendered note).
|
||
- Edge classifications are verified at implementation review **against
|
||
the rule** — not new Daniel calls (open question below).
|
||
- **"Other references" = usage tied by the provenance/recapture system.**
|
||
*(Settled by answer round.)* Replace-vs-add is decided by whether **any
|
||
usage of the source capture is tied to it by the provenance/recapture
|
||
system**: tied usage exists → the original entry stays and the recapture
|
||
is added distinct; none → replace. Read plainly: the reference universe
|
||
is the resample system's own lineage records — **not** the
|
||
prune-protection universe. The answer does not appear to cover bank
|
||
multi-membership, items placed in the arrange, or a plain hold by another
|
||
instance outside any recapture lineage — those do not force add-distinct,
|
||
and need not for safety: the superseded file survives until prune, and
|
||
prune's protection universe is unchanged and broader than this one. How
|
||
the provenance/recapture system represents a "usage tie" is part of the
|
||
lineage question below — answer 4 makes that question load-bearing, and
|
||
the second answer round's answer 1 converts the dependency into a
|
||
requirement in its own right: **item 17** (the provenance/usage tracking
|
||
consolidated and made 100% robust), on which this rule now explicitly
|
||
depends.
|
||
- **Undo/recovery: a plus, not a requirement.** *(Settled by answer round —
|
||
at exactly that strength.)* Undo of the bake chain is **desirable but not
|
||
required**: welcome if it falls out cheaply, and the feature ships
|
||
without it. The guaranteed recovery path remains the floor already stated
|
||
above — the superseded file survives on disk until a prune reclaims it.
|
||
This is a nice-to-have note, not a spec.
|
||
|
||
**Open questions.**
|
||
|
||
- The five awaiting-a-Daniel-decision questions the fourth batch opened
|
||
(multi-zone scope; what the offline pass plays; reset scope; "other
|
||
references"; undo/recovery) are **all settled by the answer round** and
|
||
folded into Behavior above. What remains:
|
||
- **Capture-window residuals — propose at implementation review.** The
|
||
second answer round settles the anchors (note-on / note-off), the tempo
|
||
source (the project tempo under the cursor), and note length as a
|
||
musical division (1/64th–64/1, dotted/triplet). Two residuals remain:
|
||
whether negative offsets are meaningful (unchanged from before); and a
|
||
denomination seam — the first answer round expressed the offsets "in ms
|
||
AND in beats" while note length is now musical-division-only. The plain
|
||
reading is that the ms/beats duality applies to the offsets only; if an
|
||
ms display or entry for note length seems wanted at implementation,
|
||
propose it at review rather than assuming either way.
|
||
- **Reset-scope edge cases — verify at implementation review.** The rule is
|
||
settled and the per-parameter classification above is now ratified by
|
||
the second answer round ("that's good"). Only a genuinely new parameter —
|
||
one arriving with a queued item and absent from the ratified lists — is
|
||
classified against the rule and surfaced at review; not a new Daniel
|
||
call.
|
||
- **Extension presence — propose at implementation review.** The instrument
|
||
plays self-contained with the extension absent, but the bank is the
|
||
extension's surface, and resampling mutates the bank. The natural answer
|
||
is that resample requires the extension present and is cleanly
|
||
unavailable — not silently lossy — without it; propose the exact behavior
|
||
at review.
|
||
- **Provenance of the recapture — homed in item 17.** Captures carry a
|
||
reproducibility fingerprint of their capture recipe; a resample's recipe
|
||
is the instrument's own settings, not a track's chain. The answer round
|
||
made this load-bearing (replace-vs-add is decided by usage ties, so the
|
||
settled record-nothing conservative default is no longer available for
|
||
the lineage half — the recapture must carry whatever record makes
|
||
answer 4's decision computable), and the second answer round's answer 1
|
||
converts it into **item 17**, where the consolidation requirement and
|
||
its open questions now live. This item's dependency stands: its
|
||
replace-vs-add half is meaningful only once item 17's consolidated
|
||
lineage exists.
|
||
- **Naming and lineage — propose at implementation review, jointly with
|
||
item 17.** When add-distinct fires, the new capture needs a display name
|
||
(derived from the original?), and the bank some way to read iteration
|
||
lineage across repeated bakes; propose at review as one proposal with
|
||
item 17's lineage-record question, on which answer 4 leans.
|
||
- (The multi-zone migration question this list previously carried is
|
||
settled in item 16 by the second answer round — adopt the first zone's
|
||
capture and parameters; a pre-existing multi-zone instance's resample
|
||
therefore bakes its first zone's sound.)
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- On a dialed-in instrument (one capture, one parameter set — item 16), one
|
||
click yields all of: a recapture in the bank, the instance holding that
|
||
recapture, and the baked-in audio parameters at their defaults — with the
|
||
root note and the other surviving mapping parameters untouched (the
|
||
settled reset scope).
|
||
- The bake is audible and faithful: after the click, playing what the
|
||
offline pass played (the programmed capture note: root, at the programmed
|
||
length, offsets, and velocity, in the active mode) through the
|
||
now-neutral controls sounds as the dialed instrument sounded just before
|
||
the click — the processing has moved from the controls into the audio.
|
||
- The capture-signal popup exposes: note length as a musical-division
|
||
picker spanning 1/64th to 64/1 with dotted and triplet multipliers;
|
||
start and end offsets, each readable and editable in both ms and beats,
|
||
anchored to note-on and note-off respectively; and velocity. Its preview
|
||
trigger auditions the capture note exactly as programmed, and the bake
|
||
renders that same programmed performance (preview and bake cannot
|
||
diverge).
|
||
- Beat-denominated values resolve against the project tempo under the
|
||
cursor: the same programmed division yields a correspondingly different
|
||
rendered duration when the tempo at the cursor differs.
|
||
- A Gate-mode bake terminates on its own: the gate holds for the programmed
|
||
note length, then releases — even with item 9's loop-sustain active, the
|
||
render ends (no indefinite capture).
|
||
- After the bake the root note is unchanged — iteration never detunes: the
|
||
next bake plays the same root.
|
||
- Sole-reference case: the bank afterwards shows the recapture where the
|
||
source capture's entry was; no other bank entry is disturbed.
|
||
Other-references case (provenance-tied usage of the original exists —
|
||
the tie computed by item 17's consolidated tracking): the original entry
|
||
is untouched, a distinct new entry appears, and every other holder of
|
||
the original sounds exactly as before.
|
||
- The click deletes no file: the superseded audio file still exists on disk
|
||
afterwards, and only a later prune — under the settled orphan rules, only
|
||
when nothing references it — can reclaim it.
|
||
- The arrange timeline is untouched: no item appears anywhere, on any track.
|
||
- Iteration composes: dial → click → dial → click bakes the second pass onto
|
||
the first's result, repeatable indefinitely.
|
||
- Save/reload: an instance holding a recapture reloads and plays it exactly
|
||
like any other loaded capture.
|
||
|
||
---
|
||
|
||
## 16 — Enhancement (simplification): retire the zone mapping system — one capture = one parameter set
|
||
|
||
**Daniel's ask (verbatim, 2026-07-29 — answer 1 of item 15's answer round).**
|
||
|
||
> I don't actually care, or even really understand, our zones. Retire the
|
||
> zone mapping system, simplify. I don't expect to use it, reasampler 9000
|
||
> becomes 1 capture = one parameter set
|
||
|
||
**Daniel's follow-up (verbatim, 2026-07-29 — the second answer round's
|
||
unnumbered opening line, answering this item's migration question).**
|
||
|
||
> adopt the first zone's capture and parameters, I don't have any projects
|
||
> with zones used
|
||
|
||
**Intent.** Simplification by deletion, not a feature: the multi-zone
|
||
keymap — zones with note ranges, per-zone parameters, and the dedicated
|
||
zone-editing surface — comes out of ReaSampler 9000 entirely. Daniel's
|
||
motive is stated plainly: he does not use it, does not care to understand
|
||
it, and wants the instrument simpler. The instrument becomes what its
|
||
common case already is: **one loaded capture played through one set of
|
||
parameters.** This arrived as answer 1 of item 15's answer round — it is a
|
||
far larger change than the question it answers (item 15's multi-zone
|
||
scope), which it dissolves rather than resolves; hence its own item.
|
||
|
||
**Behavior.**
|
||
|
||
- **One capture = one parameter set.** (Daniel's words.) The instrument
|
||
holds one loaded capture and one set of playback parameters governing it.
|
||
No zones, no per-zone divergence, no keymap of captures.
|
||
- **The zone-mapping surface goes away.** Forced by the decision, not
|
||
separately decided: the dedicated zone-editing surface and its authoring
|
||
affordances — add/delete zone, the per-zone parameter panel, and the
|
||
Low/High/Root zone legend — exist only to author zones and retire with
|
||
them. (The root note itself survives as a first-class parameter of the
|
||
one set — item 15's answer round makes it explicitly resample-stable;
|
||
only its zone-legend housing goes.)
|
||
- **The per-zone/per-instance storage distinction collapses.** Forced:
|
||
today playback parameters store per-zone, with VOICE and MASTER the
|
||
per-instance exceptions, and panel parity keeps the two editing surfaces
|
||
in step. With one parameter set there is nothing to be an exception to
|
||
and no second surface to keep in parity — every parameter simply belongs
|
||
to the instrument. Items 2, 9, and 11 carry superseded-by notes where
|
||
they asserted the per-zone convention.
|
||
- **Migration: adopt the first zone's capture and parameters.** *(Settled
|
||
by the second answer round.)* A saved multi-zone instance lifts to the
|
||
one-capture model by adopting its **first zone's** capture and that
|
||
zone's parameters; the remaining zones' captures and parameters drop
|
||
from the instance. Dropping a zone touches no file and no bank entry —
|
||
the instance simply no longer holds those captures; bank and prune
|
||
behavior are unchanged, per the bullet below. Daniel's stated rationale
|
||
is what makes a lossy rule acceptable here: **he has no projects with
|
||
zones in use**, so the migration path carries essentially no real-world
|
||
risk — no actual project sounds different under it. Consequently, for a
|
||
genuinely multi-zone instance the doc's standing sounds-identical
|
||
migration bar is **deliberately relaxed**: such an instance reopens
|
||
playing its first zone's sound only, and that is the accepted outcome —
|
||
accepted for that reason. Single-zone instances — the actual universe —
|
||
lift losslessly and reopen sounding identical, so the bar holds
|
||
everywhere it has real referents. (Which zone is "first" — the
|
||
instance's existing zone ordering — is a verify-at-implementation
|
||
detail with no real-world stakes, given the rationale.)
|
||
- **The single-capture experience is unchanged.** *(Derived, not a Daniel
|
||
quote: the retirement removes the multi-zone superstructure, not the way
|
||
a single capture plays — today's single-capture instrument already
|
||
behaves as one capture with one parameter set.)* A loaded capture still
|
||
plays across the keyboard repitched from its root, key-tracking still
|
||
applies, and every queued enhancement (items 1–15) lands on the one
|
||
parameter set unchanged in substance.
|
||
- **No effect on the bank or the extension.** The zone system is an
|
||
instrument-side mapping concept; captures, banks, the capture/placement
|
||
separation, and the prune safety model are untouched.
|
||
|
||
**Open questions.**
|
||
|
||
- The migration question this item carried as awaiting a Daniel decision
|
||
is **settled by the second answer round** — adopt the first zone's
|
||
capture and parameters — and folded into Behavior above, with his
|
||
rationale (no projects with zones in use) recorded there. **Nothing in
|
||
this item awaits a Daniel decision.** What remains is
|
||
propose-at-implementation-review:
|
||
- **Does any key-range concept survive? — propose at implementation
|
||
review.** With zones gone, does the capture respond across the entire
|
||
keyboard (repitched from root), or does a user-settable low/high playable
|
||
range survive as a plain parameter of the one set? Lean, consistent with
|
||
the simplification motive: no range concept — full-keyboard response —
|
||
with a low/high pair re-addable later as ordinary parameters if missed.
|
||
Not Daniel-blocking because the lean is cheap to reverse.
|
||
- **What the piano strip means with no zones — propose at implementation
|
||
review, jointly with item 12.** Item 12 keeps the full-width note-range
|
||
piano strip and adds note-name tooltips; item 15 needs the root
|
||
affordance. With no zone bars to draw, the strip's surviving jobs are the
|
||
root display/affordance and the tooltips — plus a range display only if
|
||
the key-range question keeps one. Propose the strip's exact contents at
|
||
review alongside item 12's work.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- The editor exposes no zone-mapping surface anywhere: no zone view or
|
||
button, no add/delete-zone affordance, no per-zone parameter panel, no
|
||
Low/High zone legend. The root-note control survives as a first-class
|
||
parameter.
|
||
- Every playback parameter edits in exactly one place and governs the
|
||
instrument as a whole; no gesture can express per-zone divergence.
|
||
- A single-capture instance saved before this change reopens sounding
|
||
identical — same keyboard response, same parameters, same root.
|
||
- A multi-zone instance saved before this change reopens holding its first
|
||
zone's capture with that zone's parameters — no error, no file touched,
|
||
no bank entry disturbed. (The sounds-identical bar deliberately does not
|
||
apply to this case: the instance reopens playing the first zone's sound
|
||
only — the settled, accepted outcome.)
|
||
- The one parameter set round-trips save/reload intact.
|
||
- Bank, capture, placement, and prune behavior are unchanged.
|
||
|
||
---
|
||
|
||
## 17 — Enhancement (requirement): consolidate provenance/usage tracking — one system, 100% robust
|
||
|
||
**Daniel's ask (verbatim, 2026-07-29 — answer 1 of the second fourth-batch
|
||
answer round).**
|
||
|
||
> the provenance/usage tracking will need to be consolidated and made 100%
|
||
> robust
|
||
|
||
**Intent.** A requirement, not a feature: the tracking machinery in the
|
||
provenance/usage territory becomes one coherent, fully robust system. This
|
||
began as a doc flag — item 15's answer 4 made recapture lineage
|
||
load-bearing while the territory's mechanisms were separate and ad-hoc —
|
||
and Daniel's answer converts the flag into a standing requirement. Today
|
||
the territory holds two separately-grown mechanisms plus one new demand:
|
||
(1) the **capture-recipe fingerprint** — a thin reproducibility record of
|
||
how a capture was made, deliberately not a restorable chain, conservatively
|
||
recording nothing when the situation is ambiguous; (2) the **instance-usage
|
||
tracking** — each live instrument instance declares the captures it holds,
|
||
so the prune can never delete a capture a live instance is using, with a
|
||
fail-safe stance that unreadable usage state halts the prune entirely; and
|
||
(3) item 15's demand for **recapture lineage** — records tying usages of a
|
||
capture to it "by the provenance/recaptureing system," deciding
|
||
replace-vs-add at bake time. "Consolidated" plainly means these stop being
|
||
separate ad-hoc mechanisms: one tracking system in which recipe provenance,
|
||
live usage, and recapture lineage are facets of the same record-keeping.
|
||
"100% robust" is a strength statement Daniel chose deliberately: this
|
||
territory gates the system's only file-deletion authority (prune) and its
|
||
only capture-replacement act (item 15's resample) — the two places where a
|
||
tracking error loses a user's audio or sound.
|
||
|
||
**Behavior.**
|
||
|
||
- **One system, not three mechanisms.** Recipe provenance, live-instance
|
||
usage, and recapture lineage are kept by one consolidated tracking
|
||
system, and every consumer — the prune's protection decision, the
|
||
resample's replace-vs-add decision, and any future lineage reader — is
|
||
answered from it.
|
||
- **What "100% robust" observably means.** Daniel stated the strength, not
|
||
the mechanics; the territory's stakes force three observable
|
||
implications, recorded without inventing further specifics:
|
||
- **No silent gaps.** Every capture the system itself creates is tracked
|
||
from the moment of its creation; a recapture carries its lineage from
|
||
birth, never backfilled. There is no window in which a
|
||
system-created file exists untracked.
|
||
- **Fail-safe on unreadable or ambiguous state.** Tracking state that
|
||
cannot be read never yields the destructive answer: the prune deletes
|
||
nothing (today's settled stance — preserved and generalized, not
|
||
relaxed), and the resample never takes the replace branch on
|
||
unreadable lineage (whether the safe branch is add-distinct or a halt
|
||
with a clear message is propose-at-review).
|
||
- **Consumers cannot disagree.** The prune's protection answer and the
|
||
resample's tied-usage answer are different questions with different
|
||
universes — item 15 settles that the replace-vs-add universe is
|
||
narrower than the prune-protection universe — but both are computed
|
||
from the same consolidated records, so they cannot drift apart or
|
||
contradict.
|
||
- **Existing guarantees are the floor.** Consolidation must not weaken
|
||
anything now settled: the prune still deletes only the system's own
|
||
orphans and never a referenced or live-held capture; the fail-safe abort
|
||
on unreadable usage state survives; the recipe fingerprint's
|
||
record-nothing-when-ambiguous conservatism survives for the recipe half.
|
||
The lineage half is the one place that conservatism is foreclosed —
|
||
item 15's answer 4 makes the lineage record mandatory for a recapture,
|
||
since replace-vs-add must be computable.
|
||
- **Dependency of meaning for item 15.** Item 15's replace-vs-add rule is
|
||
computable only once this item's consolidated lineage exists; item 15's
|
||
provenance-of-the-recapture question is homed here, and its
|
||
naming-and-lineage question is proposed jointly with this item's
|
||
lineage-record question. This is dependency of meaning, not merely
|
||
sequencing: without this item, "usage tied by the provenance/recapture
|
||
system" denotes nothing.
|
||
|
||
**Open questions.**
|
||
|
||
- None awaiting a Daniel decision — the requirement and its strength are
|
||
his; the shape is review work:
|
||
- **The consolidated shape — propose at implementation review.** What "one
|
||
system" concretely is (one record family, one authority, how the three
|
||
facets relate) is design work proposed at review, not a Daniel call.
|
||
- **The lineage record — propose at implementation review, jointly with
|
||
item 15's naming-and-lineage question.** What constitutes a "usage tie,"
|
||
when it is written, whether it is ever severed, and whether iteration
|
||
lineage is user-readable from the bank.
|
||
- **The recipe-fingerprint half of a recapture — propose at implementation
|
||
review.** A resample's recipe is the instrument's own settings, not a
|
||
track chain; whether the fingerprint records a resample-shaped recipe —
|
||
and what its conservatism means there — is proposed at review. (The
|
||
lineage half has no record-nothing option; the recipe half may keep
|
||
one.)
|
||
- **Never-recorded vs. unreadable — propose at implementation review.**
|
||
Pre-existing captures predate lineage records, and the two absences
|
||
demand opposite treatment: never-recorded means no tied usage exists
|
||
(replace is legitimate, per item 15's settled rule); unreadable means
|
||
fail-safe. How the consolidated system distinguishes them — and how
|
||
pre-existing banks lift in without weakening any protection they enjoy
|
||
today — is proposed at review.
|
||
|
||
**Acceptance criteria.**
|
||
|
||
- One consolidated tracking system answers both safety-critical consumers:
|
||
the prune's protected set and the resample's replace-vs-add decision are
|
||
each computed from it, per their own settled rules; no separate ad-hoc
|
||
tracking mechanism remains in the territory.
|
||
- No silent gaps: a recapture created by item 15's bake is tracked from
|
||
the instant it exists — a bake followed immediately by a prune, or by a
|
||
second bake, behaves correctly with no window in which the recapture is
|
||
untracked or its lineage absent.
|
||
- Fail-safe throughout: with tracking state made unreadable, the prune
|
||
deletes nothing (and reports what blocked it, per today's behavior) and
|
||
the resample never takes the replace branch; no destructive act follows
|
||
from ambiguity, anywhere in the territory.
|
||
- Every protection settled today holds undiminished after consolidation: a
|
||
capture held by a live instance cannot be pruned; files the system did
|
||
not create are untouchable; unreadable usage state still halts the
|
||
prune.
|
||
- A pre-existing bank lifts into the consolidated system with no loss of
|
||
protection and no spurious lineage, and never-recorded remains
|
||
distinguishable from unreadable.
|
||
- Item 15's other-references case is decidable: for any capture, "does
|
||
provenance-tied usage exist" has a definite yes/no answer.
|