docs: schedule VST3 parameters into Phase Γ
Automation ships as Γ-W4; the stage ceiling goes to 10 s in W1-T1 ahead of the one-way door; a new Γ-W3-T2 corrects Ξ's bake reset list. Four waves, ten tracks. Opens Γ-F7 on parameter order.
This commit is contained in:
@@ -57,6 +57,16 @@ own width formula, not carried over from a prior measurement. The stale geometry
|
||||
sits under it. The core finding behind the re-approach: three identical bars draw a
|
||||
*point* and the two ends of a *span* in the same ink, and the crossfade is painted where
|
||||
its *ingredient* lives rather than where the *event* is heard. §6.
|
||||
- **VST3 automation parameters SHIP IN THIS PHASE, as its last track** (Ruling 1, Daniel
|
||||
2026-08-01). The specification is `docs/product/parameter-automation.md` §§6–10: 44
|
||||
exposed parameters derived from the three-state commit predicate, a hand-assigned
|
||||
FOREVER-FROZEN id table in blocks of 100 with steps of 10, and the blob left
|
||||
authoritative with parameters as a third surface onto the one model.
|
||||
- **The stage-time ceiling moves 2 s → 10 s, in wave 1** (Daniel, reversing Γ-F3),
|
||||
*because* parameters now ship in-phase — a range endpoint is host-facing normalization,
|
||||
free to move now and permanently expensive afterwards. Its real cost is not the constant
|
||||
but keeping the AHDSR overlay legible when a 30 ms attack is 0.3 % of the schematic
|
||||
domain; the answer is to make the schematic axis *be* the taper. §4.3.1.
|
||||
|
||||
---
|
||||
|
||||
@@ -668,10 +678,24 @@ reduction is applied.**
|
||||
### 3.4 Where the master controls sit in the reset scope
|
||||
|
||||
Phase Ξ-W2's resample reset scope is settled by rule ("reset what the bake baked in").
|
||||
Derived against that rule, surfaced for Ξ-W2's review rather than as a Daniel call:
|
||||
**rate → reset**, **pitch offset → reset**, **limiter enabled → reset** (master gain is
|
||||
already on the reset list, so the bake includes the master stage, so the limiter's effect
|
||||
is in the audio).
|
||||
Derived against that rule — **no new Daniel call**: **rate → reset**, **pitch offset →
|
||||
reset**, **limiter enabled → reset** (master gain is already on the reset list, so the bake
|
||||
includes the master stage, so the limiter's effect is in the audio).
|
||||
|
||||
**This is now a CORRECTION, not a sequencing note.** The original plan required Phase Γ to
|
||||
land before Ξ-W2 so the bake's reset list would be complete on the day it shipped. **That
|
||||
ordering was never Daniel's choice and it is already violated** — Ξ-W2-T1 was underway
|
||||
before this phase was scoped (Daniel: *"xi was started before I spun you up, we'll have to
|
||||
correct phase xi inside gamma. wasn't a choice."*). So the three classifications above are
|
||||
an amendment Phase Γ **owes** to a shipped bake, and Γ-W3-T2 is the track that pays it. The
|
||||
amendment is verified **against what Ξ-W2-T1 actually shipped**, never against what this
|
||||
document predicted it would ship.
|
||||
|
||||
**A second correction of the same shape arrives with Ruling 1**, and it is Γ-W4-T1's, not
|
||||
this one's: once these values are exposed as VST3 parameters, the bake's reset must notify
|
||||
the host, and a host automation lane on a reset-class parameter re-imposes its curve onto
|
||||
already-baked audio. Full analysis and the disposition:
|
||||
`docs/product/parameter-automation.md` §9.
|
||||
|
||||
### 3.5 Assessment: the `temp_cortex/` limiter reference
|
||||
|
||||
@@ -775,16 +799,87 @@ shape):
|
||||
- Exactly **0 s at norm 0** and exactly `kEnvTimeMaxSeconds` at norm 1. Monotone and
|
||||
continuous throughout.
|
||||
- **10 ms lands within 0.12 … 0.20 of travel; 100 ms within 0.42 … 0.52.**
|
||||
- `kEnvTimeMaxSeconds` is **2.0 s** (`deck_values.h:22`, reading `kGateStageMaxSeconds` at
|
||||
`envelope_overlay.h:85`) and **does not move in this phase** — settled, Γ-F3. The AHDSR
|
||||
overlay's schematic scale is derived from it and the two must agree so a maxed knob lands
|
||||
exactly at the canvas edge; the agreement requirement is documented at
|
||||
`deck_values.h:19-22`. **Daniel foresees wanting a 10 s ceiling** for sound-design cases
|
||||
— his example, *"a horrifically long decay with tight exp"* — and that ambition is
|
||||
carried as a `docs/TODO.md` entry rather than dropped. Two things make it cheap later and
|
||||
both land in this phase: the log taper is precisely what makes a higher ceiling *usable*
|
||||
rather than unusable at the low end, and the reset-bypasses-the-taper change below
|
||||
removes the power-of-two dependency that would otherwise block a 10.0 s ceiling outright.
|
||||
- `kEnvTimeMaxSeconds` **moves 2.0 s → 10.0 s IN THIS PHASE, in this track**
|
||||
(`deck_values.h:22`, which reads `kGateStageMaxSeconds` at `envelope_overlay.h:85` — the
|
||||
two move together or not at all). **This reverses Γ-F3** (Daniel, 2026-08-01:
|
||||
*"extend the stage lengths to 10s"*), and §4.3.1 below is the design work it pulls in.
|
||||
|
||||
#### 4.3.1 The 10 s ceiling — why it moved, and what it costs
|
||||
|
||||
**Γ-F3 was ruled "not in this phase" and is now reversed.** The reversal is not a change of
|
||||
mind about the musical range; it is a consequence of Ruling 1 — VST3 parameters now ship at
|
||||
the end of this same phase (§4.4, `docs/product/parameter-automation.md` §8). The moment
|
||||
parameters exist, a range endpoint is part of the host-facing normalization exactly as much
|
||||
as the curve between the endpoints is: re-ceiling re-interprets every recorded automation
|
||||
point in project files we do not own and cannot migrate. **Raising the ceiling is free this
|
||||
wave and permanently expensive four waves later.** The `docs/TODO.md` entry that carried the
|
||||
ambition is discharged here rather than deferred again.
|
||||
|
||||
**Three constraints carry forward unchanged.**
|
||||
|
||||
1. **`kEnvTimeMaxSeconds` and `kGateStageMaxSeconds` move together.** `deck_values.h` reads
|
||||
the overlay's constant rather than restating it precisely so the two cannot drift, and the
|
||||
agreement requirement is documented at `deck_values.h:19-22`.
|
||||
2. **The reset bypass is now MANDATORY, not merely required-anyway.** `resetDeckParam`'s
|
||||
exact-default recovery depends on the ceiling being a power of two
|
||||
(`deck_values.h:42-46`); **2.0 is, 10.0 is not**, and the log taper compounds it. The
|
||||
bypass below was already required by this track — it is now also the only thing that
|
||||
makes the new ceiling correct, so it is not a candidate for "simplification" back into a
|
||||
norm round-trip under any circumstance.
|
||||
3. **A new, harder correctness case arrives with the parameters, and it is NOT solved by the
|
||||
bypass.** `ParameterInfo::defaultNormalizedValue` is normalized; a host's reset-to-default
|
||||
arrives back as `toPlain(defaultNorm)`, and **the host has no bypass to offer**. The taper
|
||||
must therefore be designed so **every default has an exact normalized preimage** — see
|
||||
`docs/product/parameter-automation.md` §8 door 3. This binds the taper's *shape*, so it
|
||||
belongs to this track and cannot be handed forward.
|
||||
|
||||
**The real design problem is legibility, and it is in scope here.** The AHDSR overlay's
|
||||
schematic gives each of the four timed stages an equal slot and maps seconds across it
|
||||
linearly (`gatePxPerSecond`, `envelope_overlay.cpp:33-34`). At a 2 s ceiling a 30 ms attack
|
||||
occupies 1.5 % of its stage's domain — small but drawn. **At 10 s it occupies 0.3 %, under a
|
||||
pixel at the floor width, and becomes visually indistinguishable from zero.** A 5× ceiling
|
||||
that makes the default attack invisible is not a feature.
|
||||
|
||||
**Three directions were considered.**
|
||||
|
||||
1. **Content-fit auto-scale** — the schematic's domain follows the largest current stage, so
|
||||
short envelopes draw large. Rejected: the axis moves under the hand while you drag, every
|
||||
node shifts when any node moves, and it breaks the documented anchor that a maxed knob
|
||||
lands exactly at the canvas edge.
|
||||
2. **A minimum drawn stage width** — every stage gets at least *n* px regardless of value.
|
||||
Rejected: it decouples the drawn position from the value, so `envelope_edit`'s drag
|
||||
inverse can no longer be the exact inverse of the draw — which is the one property the
|
||||
node/knot/knob "surfaces onto ONE model" invariant rests on.
|
||||
3. **The schematic axis BECOMES the taper — recommended.** A stage's slot width is
|
||||
`slotPx × taperNorm(seconds)` instead of `slotPx × seconds / ceiling`. The node's position
|
||||
within its slot then *is* its knob's needle position, drawn a second way.
|
||||
|
||||
**Recommended: direction 3.** It is the smallest change that is also the most principled one:
|
||||
|
||||
- **Legibility becomes ceiling-independent by construction.** The taper's own landmarks
|
||||
(10 ms within 0.12–0.20 of travel, 100 ms within 0.42–0.52) are landmarks on the overlay
|
||||
too, at any ceiling this or a future phase picks.
|
||||
- **It strengthens the one-model invariant rather than straining it.** A node and its knob
|
||||
become the same normalized quantity; today they are two maps that happen to agree.
|
||||
- **It costs the drawn curve nothing.** The taper decides only *where a stage's end node
|
||||
lands*. Within a stage, φ still runs linearly across the stage's pixel span, so a φ^p
|
||||
segment draws as φ^p exactly as Γ-W1-T3 specifies — the two tracks compose rather than
|
||||
fight.
|
||||
- **The AHD policy is untouched.** An AHD maps 1:1 onto the waveform's own time axis and is
|
||||
PCM-aligned; it must stay linear in seconds, and nothing here changes it. **Only the AHDSR
|
||||
schematic is tapered**, and it was already documented as schematic-not-time-aligned.
|
||||
|
||||
**The cost, named:** within-stage horizontal extent stops being proportional to time, so two
|
||||
stages can no longer be compared by eye at a 10× ratio the way they can at 2×. The ms labels
|
||||
Θ-W6-T1 landed carry the actual number, which is what that comparison is actually made
|
||||
against; and the alternative — a 30 ms attack drawn as zero — loses the comparison entirely.
|
||||
|
||||
**The structural consequence, and it is the important one.** The taper is now read by three
|
||||
consumers: the knob (`deck_values`), the overlay (`envelope_overlay` + `envelope_edit`), and
|
||||
— from Γ-W4-T1 — the host (`normalizedParamToPlain`). **It must be extracted into one pure
|
||||
module** rather than living inside `deck_values`, which sits above `envelope_overlay` in the
|
||||
dependency order. That extraction is what makes "the taper IS the host-facing normalization"
|
||||
structurally true instead of a comment somebody has to remember.
|
||||
|
||||
**Semitone knobs become log2-scaled.** More resolution across −7 … +7 st while still
|
||||
allowing the extremes:
|
||||
@@ -818,11 +913,17 @@ allowing the extremes:
|
||||
### 4.4 Sequencing — why item D goes first
|
||||
|
||||
Item D lands **before** the two new PITCH/RATE knobs, so Rate and Pitch are authored into
|
||||
the finished law rather than retro-fitted into it. It lands **well before** any VST3
|
||||
parameter work, for a much sharper reason: once parameters are exposed, the taper *is* the
|
||||
host-facing normalization, and re-tapering silently re-interprets every recorded automation
|
||||
point in every saved project. **Taper changes are free now and permanently expensive
|
||||
later.** See `docs/product/parameter-automation.md` §4.
|
||||
the finished law rather than retro-fitted into it. It lands **three waves before Γ-W4-T1's
|
||||
VST3 parameter work**, for a much sharper reason: once parameters are exposed, the taper
|
||||
*is* the host-facing normalization, and re-tapering silently re-interprets every recorded
|
||||
automation point in every saved project. **Taper changes are free now and permanently
|
||||
expensive later.** See `docs/product/parameter-automation.md` §4.
|
||||
|
||||
That argument used to justify Γ running ahead of a future phase; since Ruling 1 it governs
|
||||
**wave order inside this one**, which is strictly better — the taper and the parameters that
|
||||
freeze it are now reviewed against each other rather than across a phase boundary. It is
|
||||
also why the ceiling moved (§4.3.1) and why §8's one-way-door sweep in the automation doc is
|
||||
a deliverable rather than a caution.
|
||||
|
||||
---
|
||||
|
||||
@@ -1251,18 +1352,20 @@ shape is deliberate and its reasoning is documented at the call site.
|
||||
|
||||
---
|
||||
|
||||
## 8. Forks — all six ruled, none open
|
||||
## 8. Forks — six ruled (one later reversed), one open
|
||||
|
||||
### 8.1 Ruled by Daniel, 2026-08-01
|
||||
|
||||
Every fork this doc opened is closed. The rulings are folded into the sections that
|
||||
depend on them; this table is the index, not a second copy of the reasoning.
|
||||
The rulings are folded into the sections that depend on them; this table is the index, not a
|
||||
second copy of the reasoning. **Γ-F3 was ruled and then REVERSED the same day** — the row
|
||||
below carries both, because a reader who acts on the first ruling would ship the wrong
|
||||
ceiling.
|
||||
|
||||
| Fork | Question | Ruling | Where it landed |
|
||||
|---|---|---|---|
|
||||
| **Γ-F1** | Does `kEditorMinHeight` move 680 → 720? | **No — stays 680.** The reflow's 112 px goes entirely to the waveform. | §1.2 / §1.5, unchanged |
|
||||
| **Γ-F2** | Limiter lookahead, or zero-latency? | **Lookahead with DYNAMIC reported latency** — zero when off, the lookahead when on, reported to the host's PDC. *Overrides this doc's zero-lookahead recommendation.* | **§3.1.1** (new), §7.10 |
|
||||
| **Γ-F3** | Does the log taper raise the 2 s stage-time ceiling? | **Not in this phase — stays 2.0 s.** The 10 s ambition is preserved as a `docs/TODO.md` entry with its rationale. | §4.3, `docs/TODO.md` |
|
||||
| **Γ-F3** | Does the log taper raise the 2 s stage-time ceiling? | **REVERSED, same day. Ruled first "not in this phase — stays 2.0 s"; then Daniel: _"extend the stage lengths to 10s."_ The ceiling moves 2.0 → 10.0 in Γ-W1-T1.** The reversal's cause is Ruling 1: parameters now ship in-phase, so the ceiling is a one-way door that has to be walked through *before* them. | **§4.3.1** (new), §4.3; `docs/TODO.md` entry discharged |
|
||||
| **Γ-F4** | Explicit loop enable? | **Yes — on the CHROME ROW.** Not a deck cell; loop is a waveform-overlay concept and has no deck. | **§6.4** (new), §6.5, §7.9 |
|
||||
| **Γ-F5** | MASTER's reserved slot: one cell or two? | **One cell.** Two would spend 60 of the 90 px headroom on an unnamed control and freeze row 1 forever. | **§1.6** (new), §1.4 |
|
||||
| **Γ-F6** | Is the `kLatencyChanged` deactivate/reactivate acceptable as the cost of the toggle? | **Yes — ship dynamic latency as ruled.** No constant-latency fallback, no measurement gate. *Corrected this doc's analysis: the cost is self-inflicted, not SDK-imposed.* | **§3.1.1** (rewritten), §7.10, §7.11, `docs/TODO.md` |
|
||||
@@ -1322,18 +1425,39 @@ than just counting:
|
||||
`restartComponent`), not about this flag.
|
||||
5. **The reduction is filed**, with a trigger condition, in `docs/TODO.md`.
|
||||
|
||||
*No fork in this phase is open. Nothing in §§1–7 awaits a Daniel answer.*
|
||||
### 8.3 Γ-F7 — OPEN. The parameter order
|
||||
|
||||
**Opened 2026-08-01 by Ruling 1** (*"Make the parameter order logical"*), because "logical"
|
||||
resolves two ways and the choice is frozen forever the day parameters ship.
|
||||
|
||||
> **Signal-flow order** — PITCH/RATE → PITCH ENV → FILTER → FILTER ENV → AMP → VELOCITY →
|
||||
> VOICE → MASTER, the deck's own documented ordering rule, layout-independent.
|
||||
> **OR the editor's visual row order** after the Γ-W3 reflow — row 1 then row 2 then MASTER,
|
||||
> matching what the user's eye scans.
|
||||
|
||||
Same membership, different sequence; the recommendation, both arguments, and why the
|
||||
grouping (`IUnitInfo`, one unit per deck group) is settled either way are in
|
||||
`docs/product/parameter-automation.md` §6.4. **Recommendation: signal flow**, because the
|
||||
visual layout has moved twice already and this phase moves it again, and freezing a forever
|
||||
identity to a thing that moves is the wrong coupling.
|
||||
|
||||
**Urgency: low, but not zero.** Three waves sit in front of Γ-W4-T1 and nothing before it
|
||||
depends on the answer. It must close **before Γ-W4 dispatches**, and it cannot be closed by
|
||||
proposal at review — a forever commitment is a Daniel call.
|
||||
|
||||
*Every other fork in this phase is ruled. Nothing in §§1–7 awaits a Daniel answer.*
|
||||
|
||||
---
|
||||
|
||||
## 9. Build shape
|
||||
|
||||
Sequenced into `docs/PLAN.md` as **Phase Γ** (worktree slug prefix `pg-`), **three waves**
|
||||
(resequenced by Daniel, 2026-08-01 — see below):
|
||||
Sequenced into `docs/PLAN.md` as **Phase Γ** (worktree slug prefix `pg-`), **four waves**
|
||||
(resequenced by Daniel twice on 2026-08-01 — see below):
|
||||
|
||||
```
|
||||
Γ-W1 Foundations [5 tracks, disjoint by surface]
|
||||
T1 knob-interaction-law ............ item D (editor input + deck_values tapers)
|
||||
T1 knob-interaction-law ............ item D (editor input + the ONE taper module +
|
||||
10 s ceiling + AHDSR schematic scale)
|
||||
T2 master-bus-audio ................ item C (pure limiter + meter ballistics +
|
||||
processor + LATENCY REPORTING)
|
||||
T3 contour-trace-curves ............ item E (waveform painter)
|
||||
@@ -1344,11 +1468,17 @@ Sequenced into `docs/PLAN.md` as **Phase Γ** (worktree slug prefix `pg-`), **th
|
||||
T1 pitch-rate-deck ................. item A (params + engine + deck descriptor)
|
||||
T2 loop-crossfade-ux ............... item F (waveform painter + pure marker geometry
|
||||
+ the chrome-row loop enable)
|
||||
Γ-W3 The reflow [1 track]
|
||||
Γ-W3 The reflow, and the bake correction [2 tracks]
|
||||
T1 deck-reflow ..................... item B's ARRANGEMENT half + C's UI half
|
||||
T2 bake-reset-amendment ............ the Phase Ξ correction Γ owns (§3.4)
|
||||
Γ-W4 VST3 parameters [1 track]
|
||||
T1 vst3-parameter-set .............. Ruling 1 (parameter-automation.md §§6-10)
|
||||
```
|
||||
|
||||
**Two resequencing decisions, both Daniel's (2026-08-01).**
|
||||
**Three resequencing decisions, all Daniel's (2026-08-01).** The third is Ruling 1: the
|
||||
parameter system moves from "a future phase" into **Γ-W4**, which is what put the 10 s
|
||||
ceiling into W1 (§4.3.1) and turned the Ξ ordering constraint into an owned correction
|
||||
(§3.4). The first two:
|
||||
|
||||
1. **Item B splits: canvas early, arrangement late.** The window floor, the width budget it
|
||||
derives from, and each group's row membership land in W1-T4 so every other UI track is
|
||||
|
||||
Reference in New Issue
Block a user