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
+7 -3
View File
@@ -27,15 +27,19 @@ inline constexpr double kLiveRampSeconds = 0.020;
// morphLaw rides inside filterSettings only because it is cheaper to carry the whole struct to
// the filter's prepare() than to splice it back; it changes only across a reload, which
// republishes this block, so the two can never disagree.
// Each envelope carries BOTH mode shapes: which one a voice applies is fixed at note-on by
// its play mode, so publishing both keeps the block one shape regardless of mode. The pitch
// envelope's `enabled` rides along inside its params only because the struct is carried whole;
// PitchEnvelope ignores it, since a toggle travels by reload.
struct LiveValues {
filter::FilterSettings filterSettings{};
double filterModAmount = 0.0;
double filterKeyTrack = 0.0;
AdsrParams filterEnv{};
AhdParams filterAhd{};
AdsrParams adsr{};
std::int64_t pitchEnvAttackFrames = 0;
std::int64_t pitchEnvDecayFrames = 0;
double pitchEnvPeakSemitones = 0.0;
AhdParams ampAhd{};
PitchEnvParams pitchEnv{};
};
// The seqlock copies the block as raw bytes, which is only defensible for a plain value type.