Service both VST3 parameter channels, and promote pitch key-track and Trigger length so all 44 ids issue
The SDK's own single-component sample drains inputParameterChanges in process() and implements setParamNormalized; automation was reading the GUI channel alone. The audio thread now patches a block it solely owns.
This commit is contained in:
+27
-16
@@ -1277,7 +1277,12 @@ value semantics, any deck geometry, or the bake's reset *membership* (W3-T2's).
|
||||
sound intact; and a project with automation drawn, saved and reopened, replays against the
|
||||
same plain values.
|
||||
- **`process()` takes no new indirection and no new per-sample work** — the parameter read is
|
||||
a block-boundary act, on the existing live-publish path.
|
||||
a block-boundary act. **Correction to the original wording ("on the existing live-publish
|
||||
path"):** it cannot be, and the SDK is what decides that. `IParameterChanges` is delivered ON
|
||||
the audio thread, and the model's publish path allocates (`resolvePlay` copies velocity curves
|
||||
and spline contours), so the drain lands in `process()` and patches the live block in place.
|
||||
The block-boundary rule is unchanged and the per-sample path is untouched; what moved is which
|
||||
thread performs the fold.
|
||||
- **The bake's reset notifies the host**, verified by the host's displayed value following it
|
||||
rather than snapping back on next touch.
|
||||
- **The double-processing limitation is documented, not discovered** — a bake whose
|
||||
@@ -1297,11 +1302,17 @@ value semantics, any deck geometry, or the bake's reset *membership* (W3-T2's).
|
||||
- **No [Daniel] questions. Γ-F7 is RULED — signal flow** (2026-08-01, *"signal flow order."*),
|
||||
and Ruling 3 (real units) arrived specified rather than forked. **There is no unanswered
|
||||
[Daniel]-class question in this track or anywhere in this plan.**
|
||||
- **[verify, FIRST]** that REAPER calls `setState` (not `setComponentState`) on a
|
||||
single-component plug-in, and the ordering of `setState` against the first
|
||||
`IParameterChanges` block after a project load. §6.1 is built on the SDK's own
|
||||
name-collapse; **verify it in the DAW before wiring, and do not build on the paragraph
|
||||
alone.**
|
||||
- **CLOSED from the SDK, not the DAW.** Two things were bundled here and they separate.
|
||||
(a) The DELIVERY CHANNEL: `ivsteditcontroller.h` documents `setParamNormalized` as the
|
||||
GUI-update channel ("should update the according GUI element(s) only"), and the SDK's own
|
||||
`SingleComponentEffect` sample (`public.sdk/samples/vst/again/source/againsimple.cpp`) drains
|
||||
`ProcessData::inputParameterChanges` in `process()` while also implementing
|
||||
`setParamNormalized`. **Both are serviced.** This was never a DAW question — the headers
|
||||
answer it, and building on the paragraph alone is exactly what the first pass did.
|
||||
(b) The ORDERING of `setState` against the first parameter block: no longer a question. An
|
||||
automation point held by the audio thread is re-applied over every merge, so a written lane
|
||||
outranks the restore whichever way round the two arrive — VST3's own rule. What survives as
|
||||
DAW work is recorded in `docs/TODO.md`, and none of it can change the frozen contract.
|
||||
- **[verify]** whether REAPER renders `ParameterInfo::units` beside the string
|
||||
`getParamStringByValue` returns, or shows the string alone. **We ship the SDK's own
|
||||
convention** — digits in the string, unit carried separately, which is what
|
||||
@@ -1309,16 +1320,16 @@ value semantics, any deck geometry, or the bake's reset *membership* (W3-T2's).
|
||||
REAPER shows no unit at all, the fallback is to append the unit **inside the one formatter**:
|
||||
a one-line change in one place, touching neither the frozen id table nor the editor, because
|
||||
display strings are explicitly not frozen (§6.7.1). Do not discover this after shipping.
|
||||
- **[propose at review]** promoting **key-track** and **Trigger length** from `Reload` to
|
||||
`NoteOnLatched` (§7.4). Both are excluded from the live set *for the note-on-latch reason*
|
||||
in the predicate's own words, so the promotion aligns routing with documented semantics —
|
||||
and it is what makes them automatable at all. **If either promotion is refused, that
|
||||
control simply drops out of the parameter list.** The list follows the predicate; the
|
||||
predicate is never bent to fill the list. **Consequence for the frozen table:** a refusal
|
||||
drops ids 1000 and 1260 (key-track) or 1450 (Trigger length) and the count falls below 44.
|
||||
Those slots are then simply **never issued** — not retired, since nothing shipped under
|
||||
them — and remain available to the same control if it is promoted later. No other id moves;
|
||||
that is what the block-and-step scheme buys.
|
||||
- **RULED (Daniel, 2026-08-02): promote both.** **Key-track** and **Trigger length** move from
|
||||
`Reload` to `NoteOnLatched` (§7.4) and are exposed; ids **1000** and **1450** issue and the
|
||||
count is **44 of 44**. **The promotion is NOT the predicate-only change this bullet originally
|
||||
advertised** — the predicate flip is the smallest part of it. Key-track lives on
|
||||
`InstrumentParams`, not `PlaySeconds`, so the host's write path (`setDeckParam`/`deckParamNorm`)
|
||||
structurally could not see it and id 1000 would have no-oped in both directions with no
|
||||
compile-time guard; both controls also had to reach the engine, which meant widening
|
||||
`LiveValues` and `foldLive`'s input and handing `Voice::start` the two latched values as
|
||||
arguments beside the rate. The guard that closes the class is `param::valueHomeFor`, asserted
|
||||
over the exposed set.
|
||||
- **[propose at review]** whether to ship a default `IMidiMapping` CC table here or leave MIDI
|
||||
control to REAPER's host-side learn. Either is defensible; **skipping it silently is not.**
|
||||
- **[propose at review]** whether this track spends the reserved payload rung. §6.1 says
|
||||
|
||||
Reference in New Issue
Block a user