instrument: one staged-envelope system — per-segment curves, the sustain-less AHD, and a shared overlay for all three envelopes

Trigger's fade pair folds into the AHD (and goes live); the release anchors right;
Preserve rings its synthetic tail out instead of cutting it. Payload v10.
This commit is contained in:
2026-07-31 08:37:57 -04:00
parent 87d7ceb066
commit 13e8c5c4d9
51 changed files with 3406 additions and 1812 deletions
+21 -6
View File
@@ -27,7 +27,9 @@ static_assert(std::is_trivially_copyable_v<LiveValues>, "the live block must sta
static void testFoldCarriesEveryContinuousControl() {
PlayParams p;
p.adsr = AdsrParams{11, 22, 33, 0.44, 55};
p.adsr = AdsrParams{11, 22, 33, 0.44, 55, 2.0, 0.5, 3.0};
p.trigAhd = AhdParams{61, 62, 0.63, 4.0, 0.25};
p.filter.trigEnv = AhdParams{71, 72, 0.73, 5.0, 0.2};
p.filter.enabled = true;
p.filter.settings.cutoffNorm = 0.25f;
p.filter.settings.resonanceNorm = 0.5f;
@@ -36,8 +38,7 @@ static void testFoldCarriesEveryContinuousControl() {
p.filter.modAmount = -0.6;
p.filter.keyTrack = 1.5;
p.filter.env = AdsrParams{1, 2, 3, 0.4, 5};
p.pitchEnv.attackFrames = 7;
p.pitchEnv.decayFrames = 9;
p.pitchEnv.shape = AhdParams{7, 9, 0.4, 1.5, 0.75};
p.pitchEnv.peakSemitones = -3.5;
const LiveValues v = foldLive(p);
@@ -46,6 +47,17 @@ static void testFoldCarriesEveryContinuousControl() {
CHECK(v.adsr.decayFrames == 33);
CHECK(v.adsr.sustainLevel == 0.44);
CHECK(v.adsr.releaseFrames == 55);
CHECK(v.adsr.attackCurve == 2.0);
CHECK(v.adsr.decayCurve == 0.5);
CHECK(v.adsr.releaseCurve == 3.0);
CHECK(v.ampAhd.attackFrames == 61);
CHECK(v.ampAhd.decayFrames == 62);
CHECK(v.ampAhd.holdFraction == 0.63);
CHECK(v.ampAhd.attackCurve == 4.0);
CHECK(v.ampAhd.decayCurve == 0.25);
CHECK(v.filterAhd.attackFrames == 71);
CHECK(v.filterAhd.holdFraction == 0.73);
CHECK(v.filterAhd.decayCurve == 0.2);
CHECK(v.filterSettings.cutoffNorm == 0.25f);
CHECK(v.filterSettings.resonanceNorm == 0.5f);
CHECK(v.filterSettings.morphNorm == 0.75f);
@@ -54,9 +66,12 @@ static void testFoldCarriesEveryContinuousControl() {
CHECK(v.filterKeyTrack == 1.5);
CHECK(v.filterEnv.decayFrames == 3);
CHECK(v.filterEnv.sustainLevel == 0.4);
CHECK(v.pitchEnvAttackFrames == 7);
CHECK(v.pitchEnvDecayFrames == 9);
CHECK(v.pitchEnvPeakSemitones == -3.5);
CHECK(v.pitchEnv.shape.attackFrames == 7);
CHECK(v.pitchEnv.shape.decayFrames == 9);
CHECK(v.pitchEnv.shape.holdFraction == 0.4);
CHECK(v.pitchEnv.shape.attackCurve == 1.5);
CHECK(v.pitchEnv.shape.decayCurve == 0.75);
CHECK(v.pitchEnv.peakSemitones == -3.5);
}
static void testUnpublishedBlockReadsAsNothing() {