From 4de9b42427ee2c8ca8c6ff1304621f575644f388 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Sat, 26 Jun 2021 21:09:36 +0200 Subject: [PATCH] Add tests --- src/sfizz/FlexEGDescription.cpp | 18 +++++++++++++++ src/sfizz/FlexEGDescription.h | 4 ++++ src/sfizz/FlexEnvelope.cpp | 8 ++----- tests/FlexEGT.cpp | 40 +++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/sfizz/FlexEGDescription.cpp b/src/sfizz/FlexEGDescription.cpp index 18ea92e3..f92e20eb 100644 --- a/src/sfizz/FlexEGDescription.cpp +++ b/src/sfizz/FlexEGDescription.cpp @@ -6,6 +6,7 @@ #include "FlexEGDescription.h" #include "Curve.h" +#include "MidiState.h" #include #include @@ -84,4 +85,21 @@ void FlexEGs::clearUnusedCurves() } } +/// +float FlexEGPoint::getTime(const MidiState& state) const noexcept +{ + float returnedValue { time }; + for (const CCData& mod : ccTime) + returnedValue += state.getCCValue(mod.cc) * mod.data; + return returnedValue; +} + +float FlexEGPoint::getLevel(const MidiState& state) const noexcept +{ + float returnedValue { level }; + for (const CCData& mod : ccLevel) + returnedValue += state.getCCValue(mod.cc) * mod.data; + return returnedValue; +} + } // namespace sfz diff --git a/src/sfizz/FlexEGDescription.h b/src/sfizz/FlexEGDescription.h index 16a7e566..4c816bef 100644 --- a/src/sfizz/FlexEGDescription.h +++ b/src/sfizz/FlexEGDescription.h @@ -12,6 +12,7 @@ namespace sfz { class Curve; +class MidiState; namespace FlexEGs { std::shared_ptr getShapeCurve(float shape); @@ -25,6 +26,9 @@ struct FlexEGPoint { CCMap ccTime; CCMap ccLevel; + float getTime(const MidiState& state) const noexcept; + float getLevel(const MidiState& state) const noexcept; + void setShape(float shape); float shape() const noexcept { return shape_; } const Curve& curve() const; diff --git a/src/sfizz/FlexEnvelope.cpp b/src/sfizz/FlexEnvelope.cpp index 90273547..ae06c022 100644 --- a/src/sfizz/FlexEnvelope.cpp +++ b/src/sfizz/FlexEnvelope.cpp @@ -266,12 +266,8 @@ bool FlexEnvelope::Impl::advanceToStage(unsigned stageNumber) const FlexEGPoint& point = desc.points[stageNumber]; stageSourceLevel_ = currentLevel_; - stageTargetLevel_ = point.level; - for (const CCData& mod : point.ccLevel) - stageTargetLevel_ += midiState.getCCValue(mod.cc) * mod.data; - stageTime_ = point.time; - for (const CCData& mod : point.ccTime) - stageTime_ += midiState.getCCValue(mod.cc) * mod.data; + stageTargetLevel_ = point.getLevel(midiState); + stageTime_ = point.getTime(midiState); stageSustained_ = int(stageNumber) == desc.sustain; stageCurve_ = &point.curve(); diff --git a/tests/FlexEGT.cpp b/tests/FlexEGT.cpp index d4e671c6..a35711e6 100644 --- a/tests/FlexEGT.cpp +++ b/tests/FlexEGT.cpp @@ -417,3 +417,43 @@ TEST_CASE("[FlexEG] Free-running flex AmpEG (no sustain)") synth.renderBlock(buffer); REQUIRE( synth.getNumActiveVoices() == 0 ); } + +TEST_CASE("[FlexEG] Modulation of time and level") +{ + sfz::Synth synth; + + synth.loadSfzString(fs::current_path(), R"( + sample=*noise + eg1_time1=0 eg1_level1=1 + eg1_time2=0.7 eg1_level2=0.5 + eg1_time2_oncc1=-0.7 eg1_level2_oncc2=0.5 + eg1_time3=0.3 eg1_level3=0.0 + )"); + + REQUIRE( synth.getNumRegions() == 1 ); + const sfz::Region* region = synth.getRegionView(0); + REQUIRE( region->flexEGs.size() == 1 ); + const sfz::FlexEGDescription& desc = synth.getRegionView(0)->flexEGs[0]; + REQUIRE( desc.points.size() == 4 ); + + REQUIRE( desc.points[2].time == Approx(0.7f) ); + REQUIRE( desc.points[2].level == Approx(0.5f) ); + + sfz::MidiState state; + + REQUIRE( desc.points[2].getTime(state) == Approx(0.7f) ); + state.ccEvent(0, 1, 0.0f); + REQUIRE( desc.points[2].getTime(state) == Approx(0.7f) ); + state.ccEvent(0, 1, 0.5f); + REQUIRE( desc.points[2].getTime(state) == Approx(0.35f) ); + state.ccEvent(0, 1, 1.0f); + REQUIRE( desc.points[2].getTime(state) == Approx(0.0f) ); + + REQUIRE( desc.points[2].getLevel(state) == Approx(0.5f) ); + state.ccEvent(0, 2, 0.0f); + REQUIRE( desc.points[2].getLevel(state) == Approx(0.5f) ); + state.ccEvent(0, 2, 0.5f); + REQUIRE( desc.points[2].getLevel(state) == Approx(0.75f) ); + state.ccEvent(0, 2, 1.0f); + REQUIRE( desc.points[2].getLevel(state) == Approx(1.0f) ); +}