This commit is contained in:
Jean Pierre Cimalando 2020-07-28 22:59:59 +02:00
parent 0e35f392a7
commit 6c870a53d3
3 changed files with 69 additions and 0 deletions

View file

@ -13,6 +13,7 @@
#include "SIMDHelpers.h"
#include "Debug.h"
#include <absl/container/flat_hash_map.h>
#include <absl/strings/string_view.h>
#include <vector>
#include <algorithm>
@ -382,4 +383,45 @@ bool ModMatrix::validSource(SourceId id) const
return static_cast<unsigned>(id.number()) < impl_->sources_.size();
}
std::string ModMatrix::toDotGraph() const
{
const Impl& impl = *impl_;
struct Edge {
std::string source;
std::string target;
};
// collect all connections as string pairs
std::vector<Edge> edges;
for (const Impl::Target& target : impl.targets_) {
for (const auto& cs : target.connectedSources) {
const Impl::Source& source = impl.sources_[cs.first];
Edge e;
e.source = source.key.toString();
e.target = target.key.toString();
edges.push_back(std::move(e));
}
}
// alphabetic sort, to produce stable output for unit testing
auto compare = [](const Edge& a, const Edge& b) -> bool {
std::pair<absl::string_view, absl::string_view> aa{a.source, a.target};
std::pair<absl::string_view, absl::string_view> bb{b.source, b.target};
return aa < bb;
};
std::sort(edges.begin(), edges.end(), compare);
// write dot graph
std::string dot;
dot.reserve(1024);
absl::StrAppend(&dot, "digraph {" "\n");
for (const Edge& e : edges) {
absl::StrAppend(&dot, "\t" "\"", e.source, "\""
" -> " "\"", e.target, "\"" "\n");
}
absl::StrAppend(&dot, "}" "\n");
return dot;
}
} // namespace sfz

View file

@ -167,6 +167,11 @@ public:
*/
bool validSource(SourceId id) const;
/**
* @brief Get a representation of the matrix written as a Dot graph.
*/
std::string toDotGraph() const;
private:
struct Impl;
std::unique_ptr<Impl> impl_;

View file

@ -6,6 +6,7 @@
#include "sfizz/modulations/ModId.h"
#include "sfizz/modulations/ModKey.h"
#include "sfizz/Synth.h"
#include "catch2/catch.hpp"
TEST_CASE("[Modulations] Identifiers")
@ -74,3 +75,24 @@ TEST_CASE("[Modulations] Display names")
REQUIRE(!sfz::ModKey(id).toString().empty());
});
}
TEST_CASE("[Modulations] Connection graph from SFZ")
{
sfz::Synth synth;
synth.loadSfzString("/modulation.sfz", R"(
<region>
sample=*sine
amplitude_oncc20=59 amplitude_curvecc20=3
pitch_oncc42=71 pitch_smoothcc42=32
pan_oncc36=14.5 pan_stepcc36=1.5
width_oncc425=29
)");
const std::string graph = synth.getResources().modMatrix.toDotGraph();
REQUIRE(graph == R"(digraph {
"Controller 20 {curve=3, smooth=0, value=59, step=0}" -> "Amplitude"
"Controller 36 {curve=0, smooth=0, value=14.5, step=1.5}" -> "Pan"
"Controller 42 {curve=0, smooth=32, value=71, step=0}" -> "Pitch"
"Controller 425 {curve=0, smooth=0, value=29, step=0}" -> "Width"
}
)");
}