diff --git a/TODO-1.0.md b/TODO-1.0.md index 906b04c..45410ed 100644 --- a/TODO-1.0.md +++ b/TODO-1.0.md @@ -62,12 +62,25 @@ 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 carries **one question awaiting a Daniel decision** — -whether item 2's filter AHDSR follows the same mode-driven shape — so the doc -is no longer decision-clean. Its other open question (stage-value state across +added there). Item 14 arrived carrying one question awaiting a Daniel +decision — whether item 2's filter AHDSR follows the same mode-driven shape — +answered by the round below. Its other open question (stage-value state across the Gate/Trigger switch) is propose-at-implementation-review, not Daniel-blocking. +A **third-batch follow-up round** (2026-07-28, same day) answered item 14's +filter question: **the filter envelope follows the same mode-driven shape** — +Gate → AHDSR, Trigger → AHD. Item 8's scope rule now governs all three +envelopes uniformly (the general statement lives in item 14; item 2 carries a +cross-reference), and item 14's remaining stage-value question now covers the +filter envelope too. **With that, no open question anywhere in the doc awaits +a Daniel decision.** Everything still open across all 14 items is +verify-or-propose-at-implementation: item 9's loop-point regression +verification and its spec details, item 11's +does-a-pitch-velocity-curve-already-exist check, and item 14's +shared-vs-per-mode stage-value question. Nothing in items 1–14 is blocked on +Daniel. + Ordering note: item 1's curve/overlay treatment explicitly anticipates item 2's filter envelope ("filter to be added"), and item 3 layers on both. They can land in sequence or together, but 1 and 2 are prerequisites for 3's full surface. @@ -84,7 +97,8 @@ 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. +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. --- @@ -249,6 +263,9 @@ AHDSR envelope, and make the knob-deck row read in signal-flow order. 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**, @@ -654,9 +671,9 @@ change that turns the pitch envelope from AD into AHD**. 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 envelope's - Trigger mode, so this scope rule selects by the envelope's current shape - under the active playback mode — see item 14. + 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.** @@ -933,6 +950,10 @@ high-DPI, high-resolution displays. Daniel named the visibly pixely surfaces: > (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 @@ -940,7 +961,8 @@ 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). +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.** @@ -956,17 +978,24 @@ right-anchored release, per item 8); Trigger → AHD (sustain-less). - **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. -- **Item 8's scope rule now covers the amp envelope literally.** Item 8 +- **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 envelope in Trigger mode *is* sustain-less, so it takes - the 1:1 time-mapped overlay automatically; in Gate mode it keeps the - right-anchored release. The rationale now describes the amp envelope - directly, not just by analogy: 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 both cases. + 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 @@ -989,20 +1018,21 @@ right-anchored release, per item 8); Trigger → AHD (sustain-less). **Open questions.** -- **Does the filter AHDSR follow the same mode-driven shape?** Item 2's - filter envelope is the same staged machinery, so Gate → AHDSR / - Trigger → AHD would extend naturally — but Daniel said this only for the - amp envelope, and it is not asserted here. **Awaits a Daniel decision** — - currently the doc's only Daniel-pending question. - **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. Migration leans per-mode: 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. 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. + 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.** @@ -1016,6 +1046,9 @@ right-anchored release, per item 8); Trigger → AHD (sustain-less). 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.