From 6c870a53d3ee1937217e93692b3455978fb1cf19 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Tue, 28 Jul 2020 22:59:59 +0200 Subject: [PATCH] Add test --- src/sfizz/modulations/ModMatrix.cpp | 42 +++++++++++++++++++++++++++++ src/sfizz/modulations/ModMatrix.h | 5 ++++ tests/ModulationsT.cpp | 22 +++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/src/sfizz/modulations/ModMatrix.cpp b/src/sfizz/modulations/ModMatrix.cpp index b3f5fe13..48b61f25 100644 --- a/src/sfizz/modulations/ModMatrix.cpp +++ b/src/sfizz/modulations/ModMatrix.cpp @@ -13,6 +13,7 @@ #include "SIMDHelpers.h" #include "Debug.h" #include +#include #include #include @@ -382,4 +383,45 @@ bool ModMatrix::validSource(SourceId id) const return static_cast(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 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 aa{a.source, a.target}; + std::pair 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 diff --git a/src/sfizz/modulations/ModMatrix.h b/src/sfizz/modulations/ModMatrix.h index f9338d68..516052ae 100644 --- a/src/sfizz/modulations/ModMatrix.h +++ b/src/sfizz/modulations/ModMatrix.h @@ -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_; diff --git a/tests/ModulationsT.cpp b/tests/ModulationsT.cpp index 3db0a96a..b3f6776c 100644 --- a/tests/ModulationsT.cpp +++ b/tests/ModulationsT.cpp @@ -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"( + +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" +} +)"); +}