diff --git a/include/sst/basic-blocks/mod-matrix/ModMatrix.h b/include/sst/basic-blocks/mod-matrix/ModMatrix.h index 0eaeb87..b43b38e 100644 --- a/include/sst/basic-blocks/mod-matrix/ModMatrix.h +++ b/include/sst/basic-blocks/mod-matrix/ModMatrix.h @@ -52,6 +52,13 @@ */ namespace sst::basic_blocks::mod_matrix { + +enum ApplicationMode +{ + ADDITIVE = 0, + MULTIPLICATIVE = 1 +}; + template struct RoutingTable : details::CheckModMatrixConstraints { @@ -69,6 +76,8 @@ struct RoutingTable : details::CheckModMatrixConstraints int16_t sourceLagMS{0}, sourceViaLagMS{0}; bool sourceLagExp{true}, sourceViaLagExp{true}; + int16_t applicationMode{ADDITIVE}; + float depth{0.f}; std::optional extraPayload{std::nullopt}; @@ -140,7 +149,6 @@ struct ModMatrix : details::CheckModMatrixConstraints } static constexpr bool supportsCurves{details::has_getCurveOperator::value}; - static constexpr bool supportsMultiplicative{details::has_getIsMultiplicative::value}; }; template struct FixedLengthRoutingTable : RoutingTable @@ -231,11 +239,8 @@ template struct FixedMatrix : ModMatrix curveFn; - enum ApplicationMode - { - ADDITIVE, - MULTIPLICATIVE - } applicationMode{ADDITIVE}; + + ApplicationMode applicationMode; // We can handle the 'first time' by setting in prepare dsp::OnePoleLag sourceLagExp, sourceViaLagExp; @@ -369,15 +374,7 @@ template struct FixedMatrix : ModMatrix::supportsMultiplicative) - { - if (TR::getIsMultiplicative(*(r.target))) - { - rv.applicationMode = RoutingValuePointers::MULTIPLICATIVE; - } - } - + rv.applicationMode = static_cast(r.applicationMode); rv.target = &matrixOutputs[targetToOutputIndex.at(*r.target)]; } @@ -467,10 +464,10 @@ template struct FixedMatrix : ModMatrix struct FixedMatrix : ModMatrix= 0 && mulfac <= 1.f); + *(r.target) *= mulfac; } break; diff --git a/include/sst/basic-blocks/mod-matrix/ModMatrixDetails.h b/include/sst/basic-blocks/mod-matrix/ModMatrixDetails.h index 34df51e..9ff1e6b 100644 --- a/include/sst/basic-blocks/mod-matrix/ModMatrixDetails.h +++ b/include/sst/basic-blocks/mod-matrix/ModMatrixDetails.h @@ -54,7 +54,6 @@ HAS_MEMBER(isTargetModMatrixDepth) HAS_MEMBER(supportsLag) HAS_MEMBER(getTargetModMatrixElement) HAS_MEMBER(getCurveOperator) -HAS_MEMBER(getIsMultiplicative) #undef HAS_MEMBER struct detailTypeNo diff --git a/tests/mod_matrix_tests.cpp b/tests/mod_matrix_tests.cpp index e905b8e..fd86161 100644 --- a/tests/mod_matrix_tests.cpp +++ b/tests/mod_matrix_tests.cpp @@ -390,6 +390,36 @@ TEST_CASE("Routing Via", "[mod-matrix]") REQUIRE(*t3P == Approx(t3V + 0.5 * barSVal * fooSVal).margin(1e-5)); } +TEST_CASE("Multiplicative vs Additive", "[mod-matrix]") +{ + FixedMatrix m; + FixedMatrix::RoutingTable rt; + + auto srcS = Config::SourceIdentifier{Config::SourceIdentifier::SI::BAR, 2, 3}; + + auto tg3T = Config::TargetIdentifier{3}; + + float srcSVal{0.2}; + m.bindSourceValue(srcS, srcSVal); + + float t3V{0.2}; + m.bindTargetBaseValue(tg3T, t3V); + + rt.updateRoutingAt(0, srcS, tg3T, 0.3); + + m.prepare(rt, 48000, 16); + m.process(); + auto t3P = m.getTargetValuePointer(tg3T); + REQUIRE(t3P); + REQUIRE(*t3P == Approx(t3V + 0.3 * srcSVal).margin(1e-5)); + + rt.routes[0].applicationMode = ApplicationMode::MULTIPLICATIVE; + m.prepare(rt, 48000, 16); + m.process(); + REQUIRE(t3P); + REQUIRE(*t3P == Approx(t3V * (0.3 * srcSVal + (1 - 0.3))).margin(1e-5)); +} + TEST_CASE("Source Lags", "[mod-matrix]") { FixedMatrix m;