Skip to content

Commit

Permalink
Mod Matrix Smoothing in place (still defaults to off)
Browse files Browse the repository at this point in the history
This commit implements smoothing, both linear and exponential,
in the mod matrix. It exposes this in the UI as a sub-menu for
a source and it is available for every source (except of course
for "No Source").

Currently there's no per-source defaults for the matrix.
I'll add that as a separate issue but lets use this commit to
close #1343
  • Loading branch information
baconpaul committed Sep 20, 2024
1 parent 82d9791 commit a9e762e
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 6 deletions.
80 changes: 80 additions & 0 deletions src-ui/app/edit-screen/components/ModPane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ template <typename GZTrait> struct ModRow : juce::Component, HasEditor
p.addSeparator();

auto sub = juce::PopupMenu();
std::string sourceName{""};
auto subTicked{false};
std::string lastCat{};
for (const auto &[si, sn] : srcs)
Expand Down Expand Up @@ -539,13 +540,92 @@ template <typename GZTrait> struct ModRow : juce::Component, HasEditor
}
}
sub.addItem(nm, true, selected, mkCallback(si));
if (selected)
sourceName = nm;
}

if (sub.getNumItems() > 0)
{
p.addSubMenu(lastCat, sub, true, nullptr, subTicked);
}

const auto &row = parent->routingTable.routes[index];

bool smoothingAvailable = true;
if (isVia)
smoothingAvailable = row.sourceVia.has_value();
else
smoothingAvailable = row.source.has_value();

if (smoothingAvailable)
{
p.addSeparator();
std::string lab = "Smoothing ";
auto st = row.sourceLagMS;
auto se = row.sourceLagExp;

if (isVia)
{
st = row.sourceViaLagMS;
se = row.sourceViaLagExp;
}

if (st == 0)
{
lab += "(Off)";
}
else
{
lab += "(" + std::to_string(st) + "ms, " + (se ? "Exp" : "Lin") + ")";
}

auto smoothSubMenu = juce::PopupMenu();
smoothSubMenu.addSectionHeader(sourceName + " Smoothing");
smoothSubMenu.addSeparator();
for (auto vals : {0, 10, 25, 50, 100, 250, 500})
{
smoothSubMenu.addItem(vals == 0 ? "No Smoothing" : (std::to_string(vals) + "ms"),
true, vals == st,
[isVia, w = juce::Component::SafePointer(this), vals]() {
if (!w)
return;
auto &row = w->parent->routingTable.routes[w->index];
if (isVia)
row.sourceViaLagMS = vals;
else
row.sourceLagMS = vals;
w->pushRowUpdate();
w->refreshRow();
});
}
smoothSubMenu.addSeparator();
smoothSubMenu.addItem("Exponential", true, se,
[isVia, w = juce::Component::SafePointer(this)]() {
if (!w)
return;
auto &row = w->parent->routingTable.routes[w->index];
if (isVia)
row.sourceViaLagExp = true;
else
row.sourceLagExp = true;
w->pushRowUpdate();
w->refreshRow();
});
smoothSubMenu.addItem("Linear", true, !se,
[isVia, w = juce::Component::SafePointer(this)]() {
if (!w)
return;
auto &row = w->parent->routingTable.routes[w->index];
if (isVia)
row.sourceViaLagExp = false;
else
row.sourceLagExp = false;
w->pushRowUpdate();
w->refreshRow();
});

p.addSubMenu(lab, smoothSubMenu);
}
p.showMenuAsync(editor->defaultPopupMenuOptions());
}

Expand Down
2 changes: 1 addition & 1 deletion src/engine/group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Group::Group()
void Group::rePrepareAndBindGroupMatrix()
{
endpoints.sources.bind(modMatrix, *this);
modMatrix.prepare(routingTable);
modMatrix.prepare(routingTable, getSampleRate(), blockSize);
endpoints.bindTargetBaseValues(modMatrix, *this);
modMatrix.process();

Expand Down
11 changes: 9 additions & 2 deletions src/json/modulation_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,11 @@ SC_STREAMDEF(scxt::voice::modulation::Matrix::RoutingTable::Routing, SC_FROM({
}
else
{
v = {{"active", t.active}, {"source", t.source}, {"sourceVia", t.sourceVia},
{"target", t.target}, {"curve", t.curve}, {"depth", t.depth}};
v = {{"active", t.active}, {"source", t.source},
{"sourceVia", t.sourceVia}, {"target", t.target},
{"curve", t.curve}, {"depth", t.depth},
{"srcLMS", t.sourceLagMS}, {"srVLMS", t.sourceViaLagMS},
{"srcLE", t.sourceLagExp}, {"srVLE", t.sourceViaLagExp}};
if (SC_STREAMING_FOR_IN_PROCESS)
addToObject<val_t>(v, "extraPayload", t.extraPayload);
}
Expand All @@ -204,6 +207,10 @@ SC_STREAMDEF(scxt::voice::modulation::Matrix::RoutingTable::Routing, SC_FROM({
findIf(v, "curve", result.curve);
findIf(v, "depth", result.depth);
findIf(v, "extraPayload", result.extraPayload);
findOrSet(v, "srcLMS", 0, result.sourceLagMS);
findOrSet(v, "srVLMS", 0, result.sourceViaLagMS);
findOrSet(v, "srcLE", true, result.sourceLagExp);
findOrSet(v, "srVLE", true, result.sourceViaLagExp);
}));

SC_STREAMDEF(scxt::voice::modulation::Matrix::RoutingTable, SC_FROM({
Expand Down
5 changes: 5 additions & 0 deletions src/modulation/group_matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ struct GroupMatrixConfig
auto res = multiplicativeTargets.find(ti) != multiplicativeTargets.end();
return res;
}
static bool supportsLag(const SourceIdentifier &s)
{
SCLOG_ONCE("Supports Lag says 'yes' for all voice matrix values currently");
return true;
}

static constexpr bool IsFixedMatrix{true};
static constexpr size_t FixedMatrixSize{12};
Expand Down
6 changes: 6 additions & 0 deletions src/modulation/voice_matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ struct MatrixConfig
return res;
}

static bool supportsLag(const SourceIdentifier &s)
{
SCLOG_ONCE("Supports Lag says 'yes' for all voice matrix values currently");
return true;
}

static constexpr bool IsFixedMatrix{true};
static constexpr size_t FixedMatrixSize{12};

Expand Down
2 changes: 1 addition & 1 deletion src/selection/selection_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ void SelectionManager::configureAndSendZoneModMatrixMetadata(int p, int g, int z
// routing table. Or maybe even make it a function on zone (that's probably better).
scxt::voice::modulation::Matrix mat;
mat.forUIMode = true;
mat.prepare(zp->routingTable);
mat.prepare(zp->routingTable, engine.getSampleRate(), blockSize);
scxt::voice::modulation::MatrixEndpoints ep{nullptr};
ep.bindTargetBaseValues(mat, *zp);
for (auto &r : zp->routingTable.routes)
Expand Down
2 changes: 1 addition & 1 deletion src/voice/voice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ void Voice::voiceStarted()

// This order matters
endpoints->sources.bind(modMatrix, *zone, *this);
modMatrix.prepare(zone->routingTable);
modMatrix.prepare(zone->routingTable, getSampleRate(), blockSize);
endpoints->bindTargetBaseValues(modMatrix, *zone);
modMatrix.process();

Expand Down

0 comments on commit a9e762e

Please sign in to comment.