Skip to content

Commit

Permalink
Multiplicative/Additive goes from a structural to a data feature
Browse files Browse the repository at this point in the history
so you can toggle it per row from an external client. Defaults to
additive if you don't set anything. Part of

surge-synthesizer/shortcircuit-xt#1057
  • Loading branch information
baconpaul committed Sep 20, 2024
1 parent f9a4df4 commit 6decc71
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 18 deletions.
32 changes: 15 additions & 17 deletions include/sst/basic-blocks/mod-matrix/ModMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@
*/
namespace sst::basic_blocks::mod_matrix
{

enum ApplicationMode
{
ADDITIVE = 0,
MULTIPLICATIVE = 1
};

template <typename ModMatrixTraits>
struct RoutingTable : details::CheckModMatrixConstraints<ModMatrixTraits>
{
Expand All @@ -69,6 +76,8 @@ struct RoutingTable : details::CheckModMatrixConstraints<ModMatrixTraits>
int16_t sourceLagMS{0}, sourceViaLagMS{0};
bool sourceLagExp{true}, sourceViaLagExp{true};

int16_t applicationMode{ADDITIVE};

float depth{0.f};

std::optional<typename TR::RoutingExtraPayload> extraPayload{std::nullopt};
Expand Down Expand Up @@ -140,7 +149,6 @@ struct ModMatrix : details::CheckModMatrixConstraints<ModMatrixTraits>
}

static constexpr bool supportsCurves{details::has_getCurveOperator<TR>::value};
static constexpr bool supportsMultiplicative{details::has_getIsMultiplicative<TR>::value};
};

template <typename ModMatrixTraits> struct FixedLengthRoutingTable : RoutingTable<ModMatrixTraits>
Expand Down Expand Up @@ -231,11 +239,8 @@ template <typename ModMatrixTraits> struct FixedMatrix : ModMatrix<ModMatrixTrai
float *source{nullptr}, *sourceVia{nullptr}, *depth{nullptr}, *target{nullptr};
float depthScale{1.f};
std::function<float(float)> curveFn;
enum ApplicationMode
{
ADDITIVE,
MULTIPLICATIVE
} applicationMode{ADDITIVE};

ApplicationMode applicationMode;

// We can handle the 'first time' by setting in prepare
dsp::OnePoleLag<float, false> sourceLagExp, sourceViaLagExp;
Expand Down Expand Up @@ -369,15 +374,7 @@ template <typename ModMatrixTraits> struct FixedMatrix : ModMatrix<ModMatrixTrai
rv.curveFn = nullptr;
}

rv.applicationMode = RoutingValuePointers::ADDITIVE;
if constexpr (ModMatrix<TR>::supportsMultiplicative)
{
if (TR::getIsMultiplicative(*(r.target)))
{
rv.applicationMode = RoutingValuePointers::MULTIPLICATIVE;
}
}

rv.applicationMode = static_cast<ApplicationMode>(r.applicationMode);
rv.target = &matrixOutputs[targetToOutputIndex.at(*r.target)];
}

Expand Down Expand Up @@ -467,10 +464,10 @@ template <typename ModMatrixTraits> struct FixedMatrix : ModMatrix<ModMatrixTrai
}
switch (r.applicationMode)
{
case RoutingValuePointers::ApplicationMode::ADDITIVE:
case ApplicationMode::ADDITIVE:
*(r.target) += *(r.depth) * r.depthScale * offs;
break;
case RoutingValuePointers::ApplicationMode::MULTIPLICATIVE:
case ApplicationMode::MULTIPLICATIVE:
{
// TODO - a bit more thoughtful about this clamp I bet
offs = std::clamp(std::fabs(offs), 0.f, 1.f);
Expand All @@ -485,6 +482,7 @@ template <typename ModMatrixTraits> struct FixedMatrix : ModMatrix<ModMatrixTrai
mulfac = 1 + dep * offs;
}
assert(mulfac >= 0 && mulfac <= 1.f);

*(r.target) *= mulfac;
}
break;
Expand Down
1 change: 0 additions & 1 deletion include/sst/basic-blocks/mod-matrix/ModMatrixDetails.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ HAS_MEMBER(isTargetModMatrixDepth)
HAS_MEMBER(supportsLag)
HAS_MEMBER(getTargetModMatrixElement)
HAS_MEMBER(getCurveOperator)
HAS_MEMBER(getIsMultiplicative)
#undef HAS_MEMBER

struct detailTypeNo
Expand Down
30 changes: 30 additions & 0 deletions tests/mod_matrix_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Config> m;
FixedMatrix<Config>::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<Config> m;
Expand Down

0 comments on commit 6decc71

Please sign in to comment.