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:
2026-08-02 16:22:17 -04:00
parent bfaa0f2614
commit de5654fb6f
44 changed files with 1205 additions and 302 deletions
+19 -1
View File
@@ -41,7 +41,9 @@ static void testFoldCarriesEveryContinuousControl() {
p.pitchEnv.shape = AhdParams{7, 9, 0.4, 1.5, 0.75};
p.pitchEnv.peakSemitones = -3.5;
const LiveValues v = foldLive(p);
// Distinct from filter.keyTrack below on purpose: the two are different controls and a fold
// that crossed them would pass under a shared value.
const LiveValues v = foldLive(p, /*keyTrack=*/0.8);
CHECK(v.adsr.attackFrames == 11);
CHECK(v.adsr.holdFrames == 22);
CHECK(v.adsr.decayFrames == 33);
@@ -72,6 +74,21 @@ static void testFoldCarriesEveryContinuousControl() {
CHECK(v.pitchEnv.shape.attackCurve == 1.5);
CHECK(v.pitchEnv.shape.decayCurve == 0.75);
CHECK(v.pitchEnv.peakSemitones == -3.5);
CHECK(v.keyTrack == 0.8);
// Spline-folded on the way in, so the block carries what the voice will actually play.
CHECK(!v.splineActive);
CHECK(v.lengthFraction == p.trigger.lengthFraction);
}
// The fold, not the voice, is where a drawn contour pins the Trigger span — so the block a
// note-on latches already carries the folded value.
static void testADrawnEnvelopePinsTheFoldedTriggerLength() {
PlayParams p;
p.trigger.lengthFraction = 0.25;
p.ampSpline.mode = EnvMode::Spline;
const LiveValues v = foldLive(p, kKeyTrackDefault);
CHECK(v.splineActive);
CHECK(v.lengthFraction == 1.0);
}
static void testUnpublishedBlockReadsAsNothing() {
@@ -170,6 +187,7 @@ static void testRampStepIsRateDerived() {
int main() {
testFoldCarriesEveryContinuousControl();
testADrawnEnvelopePinsTheFoldedTriggerLength();
testUnpublishedBlockReadsAsNothing();
testConcurrentReaderNeverSeesAHalfAppliedEdit();
testRampTerminatesExactlyOnTheTarget();