#include "ModulationMatrix.h" namespace serum { bool ModulationMatrix::addConnection (ModSource source, ModTarget target, float depth, bool bipolar) { if ((int) source < 0 || (int) source >= kNumModSources || (int) target < 0 || (int) target >= kNumModTargets || ! std::isfinite (depth) || (int) connections.size() >= kMaxConnections) return false; connections.push_back ({ source, target, juce::jlimit (-1.0f, 1.0f, depth), bipolar }); return true; } void ModulationMatrix::removeConnection (int index) { if (index >= 0 && index < (int) connections.size()) connections.erase (connections.begin() + index); } void ModulationMatrix::removeAllWithTarget (ModTarget target) { connections.erase (std::remove_if (connections.begin(), connections.end(), [target] (const ModConnection& c) { return c.target == target; }), connections.end()); } juce::ValueTree ModulationMatrix::toValueTree() const { ModulationMatrix validated; for (const auto& c : connections) { if (validated.size() >= kMaxConnections) break; if (! validated.addConnection (c.source, c.target, c.depth, c.bipolar)) continue; } juce::ValueTree tree ("MODMATRIX"); for (const auto& c : validated.connections) { juce::ValueTree con ("CONNECTION"); con.setProperty ("source", modSourceToString (c.source), nullptr); con.setProperty ("target", modTargetToString (c.target), nullptr); con.setProperty ("depth", c.depth, nullptr); con.setProperty ("bipolar", c.bipolar, nullptr); tree.appendChild (con, nullptr); } return tree; } void ModulationMatrix::fromValueTree (const juce::ValueTree& tree) { connections.clear(); if (! tree.hasType ("MODMATRIX")) return; for (const auto& con : tree) { if ((int) connections.size() >= kMaxConnections) break; if (! con.hasType ("CONNECTION")) continue; const auto sourceName = con.getProperty ("source").toString(); const auto source = modSourceFromString (sourceName); if (sourceName.isEmpty() || modSourceToString (source) != sourceName) continue; if (! addConnection (source, modTargetFromString (con.getProperty ("target").toString()), (float) con.getProperty ("depth", 0.0), (bool) con.getProperty ("bipolar", false))) continue; } } } // namespace serum