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:
@@ -52,6 +52,19 @@ struct LiveValues {
|
||||
// ordinarily live.
|
||||
double playRate = 1.0;
|
||||
double pitchOffsetSemitones = 0.0;
|
||||
// Two more members of playRate's note-on-latched class, here for the same reason it is:
|
||||
// both resolve a fact the voice fixes at note-on (the pitch ratio, and playEnd_), so live
|
||||
// delivery would retune or re-span a note already struck. Voice::start receives them as
|
||||
// arguments; applyLive never touches either.
|
||||
double keyTrack = kKeyTrackDefault;
|
||||
// ALREADY spline-folded (effectiveLengthFraction) — a drawn contour is a pure time function
|
||||
// over the whole sample, so the stored knob is inert while one is active and the block must
|
||||
// carry what the voice will actually play, not the stored value.
|
||||
double lengthFraction = 1.0;
|
||||
// The drawn-EG state the fold above reads. A mode flip travels by reload like the contours
|
||||
// themselves, so this is not a control; it rides here only so a block-boundary write of
|
||||
// Trigger length (a host automation point) can apply the SAME fold rather than un-doing it.
|
||||
bool splineActive = false;
|
||||
};
|
||||
|
||||
// The seqlock copies the block as raw bytes, which is only defensible for a plain value type.
|
||||
@@ -59,8 +72,10 @@ static_assert(std::is_trivially_copyable_v<LiveValues>,
|
||||
"the live block is copied under a seqlock — it must stay a plain value");
|
||||
|
||||
// The ONE derivation of the live block from the parameter set. Every publisher goes through
|
||||
// here so there is a single site to keep in step with PlayParams.
|
||||
LiveValues foldLive(const PlayParams& params);
|
||||
// here so there is a single site to keep in step with PlayParams. `keyTrack` is passed in
|
||||
// because it belongs to the capture/instrument scalar beside the play bundle, not to
|
||||
// PlayParams — SampleData::keyTrack at the reload, InstrumentParams::keyTrack at a live commit.
|
||||
LiveValues foldLive(const PlayParams& params, double keyTrack);
|
||||
|
||||
// Single-writer / single-reader seqlock. The writer publishes a whole block between an odd
|
||||
// and an even generation; the reader copies the block and re-checks the generation, retrying
|
||||
@@ -96,6 +111,10 @@ public:
|
||||
seq_.store(next, std::memory_order_release); // even: complete and coherent
|
||||
}
|
||||
|
||||
// The last generation published, without copying the block — one relaxed load, so a reader
|
||||
// that only needs "has anything moved" pays nothing for asking on a block where nothing has.
|
||||
std::uint32_t generation() const { return seq_.load(std::memory_order_relaxed); }
|
||||
|
||||
// Copies the block into `out` and returns the generation actually observed, or 0 when
|
||||
// nothing has been published yet or the retry budget ran out (in which case `out` may hold
|
||||
// a torn copy and MUST be discarded — compare the return against 0 before using it).
|
||||
|
||||
Reference in New Issue
Block a user