From a20a4c0029506763f9dbfcc7cdd5e860b99dcafd Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Sun, 27 Sep 2020 11:25:43 +0200 Subject: [PATCH 1/2] flexEG: If stage is of zero duration, immediate transition to level --- src/sfizz/FlexEnvelope.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sfizz/FlexEnvelope.cpp b/src/sfizz/FlexEnvelope.cpp index 70dc0948..c58d3ae5 100644 --- a/src/sfizz/FlexEnvelope.cpp +++ b/src/sfizz/FlexEnvelope.cpp @@ -144,6 +144,9 @@ void FlexEnvelope::Impl::process(absl::Span out) const bool isReleased = isReleased_; while ((!stageSustained_ && currentTime_ >= stageTime_) || (stageSustained_ && isReleased)) { + // If stage is of zero duration, immediate transition to level + if (!stageSustained_ && stageTime_ == 0) + currentLevel_ = stageTargetLevel_; if (!advanceToNextStage()) { out.remove_prefix(frameIndex); fill(out, 0.0f); From 6694e8b85e45ff9cdc4a8639990f6e27b1d3d38e Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Mon, 28 Sep 2020 14:43:58 +0200 Subject: [PATCH 2/2] Add test --- tests/FlexEGT.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/FlexEGT.cpp b/tests/FlexEGT.cpp index db16f93c..229bee47 100644 --- a/tests/FlexEGT.cpp +++ b/tests/FlexEGT.cpp @@ -9,6 +9,7 @@ #include "sfizz/FlexEnvelope.h" #include "catch2/catch.hpp" #include "TestHelpers.h" +#include using namespace Catch::literals; using namespace sfz::literals; @@ -261,3 +262,29 @@ TEST_CASE("[FlexEG] Detailed numerical envelope test (with shapes)") envelope.process(absl::MakeSpan(output)); REQUIRE( approxEqual(output, expected, 0.01f) ); } + +TEST_CASE("[FlexEG] Zero delay transitions") +{ + sfz::Synth synth; + + synth.loadSfzString(fs::current_path(), R"( + sample=*sine + eg1_time1=0 eg1_level1=1 + eg1_time2=1 eg1_level2=0 + eg1_time3=1 eg1_level3=.5 eg1_sustain=3 + eg1_time4=1 eg1_level4=1 + )"); + sfz::FlexEnvelope envelope; + REQUIRE(synth.getNumRegions() == 1); + REQUIRE(synth.getRegionView(0)->flexEGs.size() == 1); + envelope.configure(&synth.getRegionView(0)->flexEGs[0]); + envelope.setSampleRate(10); + envelope.start(1); + + std::array output; + envelope.process(absl::MakeSpan(output)); + REQUIRE(output[0] == 0.0f); + REQUIRE(output[1] == Approx(0.9f).margin(0.01f)); + // Note(jpc): 0.9 is because EG pre-increments the time counter, slope is + // 1 frame off into the future +}