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:
+28
-12
@@ -566,8 +566,8 @@ static void testLegacyLiftDecision() {
|
||||
// --- resolvePlay: stored SECONDS -> engine FRAMES at the live rate --------------
|
||||
|
||||
static void testResolvePlayConvertsWallClockAtTheRate() {
|
||||
// Wall-clock times convert at the LIVE rate; source-timeline quantities (the Trigger
|
||||
// %-length and its fades) carry through untouched, and levels/depths are not times.
|
||||
// Wall-clock times convert at the LIVE rate; the Trigger %-length, every hold FRACTION and
|
||||
// every curve exponent are rate-free and carry through untouched, as do levels and depths.
|
||||
PlaySeconds st;
|
||||
st.playMode = PlayMode::Trigger;
|
||||
st.adsr.attackSeconds = 0.01;
|
||||
@@ -575,13 +575,20 @@ static void testResolvePlayConvertsWallClockAtTheRate() {
|
||||
st.adsr.decaySeconds = 0.02;
|
||||
st.adsr.sustainLevel = 0.8;
|
||||
st.adsr.releaseSeconds = 0.15;
|
||||
st.adsr.attackCurve = 2.5;
|
||||
st.adsr.decayCurve = 0.4;
|
||||
st.adsr.releaseCurve = 3.5;
|
||||
st.trigger.lengthFraction = 0.75;
|
||||
st.trigger.fadeInFrames = 441;
|
||||
st.trigger.fadeOutFrames = 882;
|
||||
st.trigAhd.attackSeconds = 0.01;
|
||||
st.trigAhd.decaySeconds = 0.02;
|
||||
st.trigAhd.holdFraction = 0.6;
|
||||
st.trigAhd.attackCurve = 1.75;
|
||||
st.trigAhd.decayCurve = 0.8;
|
||||
st.pitchEngine = PitchEngine::Preserve;
|
||||
st.pitchEnv.enabled = true;
|
||||
st.pitchEnv.attackSeconds = 0.02;
|
||||
st.pitchEnv.decaySeconds = 0.03;
|
||||
st.pitchEnv.shape.attackSeconds = 0.02;
|
||||
st.pitchEnv.shape.decaySeconds = 0.03;
|
||||
st.pitchEnv.shape.holdFraction = 0.25;
|
||||
st.pitchEnv.peakSemitones = 5.0;
|
||||
|
||||
const PlayParams at48 = resolvePlay(st, 48000);
|
||||
@@ -591,13 +598,20 @@ static void testResolvePlayConvertsWallClockAtTheRate() {
|
||||
CHECK(at48.adsr.decayFrames == 960);
|
||||
CHECK(at48.adsr.sustainLevel == 0.8); // a level, not a time
|
||||
CHECK(at48.adsr.releaseFrames == 7200);
|
||||
CHECK(at48.adsr.attackCurve == 2.5); // dimensionless
|
||||
CHECK(at48.adsr.decayCurve == 0.4);
|
||||
CHECK(at48.adsr.releaseCurve == 3.5);
|
||||
CHECK(at48.trigger.lengthFraction == 0.75); // source-timeline, unconverted
|
||||
CHECK(at48.trigger.fadeInFrames == 441);
|
||||
CHECK(at48.trigger.fadeOutFrames == 882);
|
||||
CHECK(at48.trigAhd.attackFrames == 480);
|
||||
CHECK(at48.trigAhd.decayFrames == 960);
|
||||
CHECK(at48.trigAhd.holdFraction == 0.6); // a fraction, not a time
|
||||
CHECK(at48.trigAhd.attackCurve == 1.75);
|
||||
CHECK(at48.trigAhd.decayCurve == 0.8);
|
||||
CHECK(at48.pitchEngine == PitchEngine::Preserve);
|
||||
CHECK(at48.pitchEnv.enabled);
|
||||
CHECK(at48.pitchEnv.attackFrames == 960);
|
||||
CHECK(at48.pitchEnv.decayFrames == 1440);
|
||||
CHECK(at48.pitchEnv.shape.attackFrames == 960);
|
||||
CHECK(at48.pitchEnv.shape.decayFrames == 1440);
|
||||
CHECK(at48.pitchEnv.shape.holdFraction == 0.25);
|
||||
CHECK(at48.pitchEnv.peakSemitones == 5.0); // a depth, not a time
|
||||
|
||||
// THE no-hardcoded-rate contract: the SAME stored seconds yield different frame counts
|
||||
@@ -606,8 +620,10 @@ static void testResolvePlayConvertsWallClockAtTheRate() {
|
||||
CHECK(at96.adsr.attackFrames == 960);
|
||||
CHECK(at96.adsr.holdFrames == 4800);
|
||||
CHECK(at96.adsr.releaseFrames == 14400);
|
||||
CHECK(at96.pitchEnv.attackFrames == 1920);
|
||||
CHECK(at96.trigger.fadeInFrames == 441); // still unconverted
|
||||
CHECK(at96.pitchEnv.shape.attackFrames == 1920);
|
||||
CHECK(at96.trigAhd.attackFrames == 960);
|
||||
CHECK(at96.trigAhd.holdFraction == 0.6); // still unconverted
|
||||
CHECK(at96.adsr.attackCurve == 2.5);
|
||||
}
|
||||
|
||||
static void testResolvePlayCarriesTheFilterAndResolvesOnlyItsEnvelope() {
|
||||
|
||||
Reference in New Issue
Block a user