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:
@@ -212,6 +212,16 @@ PlayParams resolvePlay(const PlaySeconds& stored, int sampleRate) {
|
||||
if (f < 0.0) f = 0.0;
|
||||
return static_cast<std::int64_t>(f + 0.5);
|
||||
};
|
||||
// The one seconds->frames fold for a stored AHD; the fraction and the curves are rate-free.
|
||||
const auto resolveAhd = [&secToFrames](const AhdSeconds& s) {
|
||||
AhdParams a;
|
||||
a.attackFrames = secToFrames(s.attackSeconds);
|
||||
a.decayFrames = secToFrames(s.decaySeconds);
|
||||
a.holdFraction = s.holdFraction;
|
||||
a.attackCurve = s.attackCurve;
|
||||
a.decayCurve = s.decayCurve;
|
||||
return a;
|
||||
};
|
||||
PlayParams out;
|
||||
out.playMode = stored.playMode;
|
||||
out.adsr.attackFrames = secToFrames(stored.adsr.attackSeconds);
|
||||
@@ -219,12 +229,15 @@ PlayParams resolvePlay(const PlaySeconds& stored, int sampleRate) {
|
||||
out.adsr.decayFrames = secToFrames(stored.adsr.decaySeconds);
|
||||
out.adsr.sustainLevel = stored.adsr.sustainLevel; // level, not a time
|
||||
out.adsr.releaseFrames = secToFrames(stored.adsr.releaseSeconds);
|
||||
out.trigger = stored.trigger; // source-frame / fraction, unchanged
|
||||
out.adsr.attackCurve = stored.adsr.attackCurve; // dimensionless
|
||||
out.adsr.decayCurve = stored.adsr.decayCurve;
|
||||
out.adsr.releaseCurve = stored.adsr.releaseCurve;
|
||||
out.trigger = stored.trigger; // fraction, unchanged
|
||||
out.trigAhd = resolveAhd(stored.trigAhd);
|
||||
out.pitchEngine = stored.pitchEngine;
|
||||
out.pitchEnv.enabled = stored.pitchEnv.enabled;
|
||||
out.pitchEnv.attackFrames = secToFrames(stored.pitchEnv.attackSeconds);
|
||||
out.pitchEnv.decayFrames = secToFrames(stored.pitchEnv.decaySeconds);
|
||||
out.pitchEnv.peakSemitones = stored.pitchEnv.peakSemitones; // depth, not a time
|
||||
out.pitchEnv.shape = resolveAhd(stored.pitchEnv.shape);
|
||||
// Filter: the control positions are already rate-free and carry through untouched; only
|
||||
// its envelope resolves to frames.
|
||||
out.filter.enabled = stored.filter.enabled;
|
||||
@@ -238,6 +251,10 @@ PlayParams resolvePlay(const PlaySeconds& stored, int sampleRate) {
|
||||
out.filter.env.decayFrames = secToFrames(stored.filter.env.decaySeconds);
|
||||
out.filter.env.sustainLevel = stored.filter.env.sustainLevel;
|
||||
out.filter.env.releaseFrames = secToFrames(stored.filter.env.releaseSeconds);
|
||||
out.filter.env.attackCurve = stored.filter.env.attackCurve;
|
||||
out.filter.env.decayCurve = stored.filter.env.decayCurve;
|
||||
out.filter.env.releaseCurve = stored.filter.env.releaseCurve;
|
||||
out.filter.trigEnv = resolveAhd(stored.filter.trigEnv);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user