summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2019-08-07 17:27:01 +0200
committerRobin Gareus <robin@gareus.org>2019-08-07 17:40:23 +0200
commit3243bf591cca8f31708412d7c4e89755af5204a4 (patch)
treeb47cd88bf8b3b852c9c91dd5e4c61f06dbe4c659 /libs/ardour
parent6bdf5cb0d7037ea38fb2b6ca15cfb47720d4917b (diff)
Add method to graphviz plot the process-graph
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/graph.h6
-rw-r--r--libs/ardour/ardour/session.h2
-rw-r--r--libs/ardour/graph.cc56
-rw-r--r--libs/ardour/luabindings.cc1
-rw-r--r--libs/ardour/session.cc5
5 files changed, 65 insertions, 5 deletions
diff --git a/libs/ardour/ardour/graph.h b/libs/ardour/ardour/graph.h
index 0515b335ce..2ba8ae921c 100644
--- a/libs/ardour/ardour/graph.h
+++ b/libs/ardour/ardour/graph.h
@@ -59,8 +59,9 @@ public:
void trigger (GraphNode* n);
void rechain (boost::shared_ptr<RouteList>, GraphEdges const&);
+ bool plot (std::string const& file_name) const;
- void dump (int chain);
+ void plot (int chain);
void reached_terminal_node ();
void helper_thread ();
@@ -84,6 +85,7 @@ private:
void run_one ();
void main_thread ();
void prep ();
+ void dump (int chain) const;
node_list_t _nodes_rt[2];
node_list_t _init_trigger_list[2];
@@ -115,8 +117,8 @@ private:
volatile gint _terminate;
/* chain swapping */
- Glib::Threads::Mutex _swap_mutex;
Glib::Threads::Cond _cleanup_cond;
+ mutable Glib::Threads::Mutex _swap_mutex;
volatile int _current_chain;
volatile int _pending_chain;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index cfab99bcf6..81c692580a 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -328,6 +328,8 @@ public:
uint32_t ntracks () const;
uint32_t nbusses () const;
+ bool plot_process_graph (std::string const& file_name) const;
+
boost::shared_ptr<BundleList> bundles () {
return _bundles.reader ();
}
diff --git a/libs/ardour/graph.cc b/libs/ardour/graph.cc
index ef7393e824..0cf3f79101 100644
--- a/libs/ardour/graph.cc
+++ b/libs/ardour/graph.cc
@@ -526,11 +526,11 @@ again:
}
void
-Graph::dump (int chain)
+Graph::dump (int chain) const
{
#ifndef NDEBUG
- node_list_t::iterator ni;
- node_set_t::iterator ai;
+ node_list_t::const_iterator ni;
+ node_set_t::const_iterator ai;
chain = _pending_chain;
@@ -552,6 +552,56 @@ Graph::dump (int chain)
#endif
}
+bool
+Graph::plot (std::string const& file_name) const
+{
+ Glib::Threads::Mutex::Lock ls (_swap_mutex);
+ int chain = _current_chain;
+
+ node_list_t::const_iterator ni;
+ node_set_t::const_iterator ai;
+ stringstream ss;
+
+ ss << "digraph {\n";
+ ss << " node [shape = ellipse];\n";
+
+ for (ni = _nodes_rt[chain].begin (); ni != _nodes_rt[chain].end (); ni++) {
+ boost::shared_ptr<Route> sr = boost::dynamic_pointer_cast<Route> (*ni);
+ std::string sn = string_compose ("%1 (%2)", sr->name (), (*ni)->_init_refcount[chain]);
+ if ((*ni)->_init_refcount[chain] == 0 && (*ni)->_activation_set[chain].size() == 0) {
+ ss << " \"" << sn << "\"[style=filled,fillcolor=gold1];\n";
+ } else if ((*ni)->_init_refcount[chain] == 0) {
+ ss << " \"" << sn << "\"[style=filled,fillcolor=lightskyblue1];\n";
+ } else if ((*ni)->_activation_set[chain].size() == 0) {
+ ss << " \"" << sn << "\"[style=filled,fillcolor=aquamarine2];\n";
+ }
+ for (ai = (*ni)->_activation_set[chain].begin (); ai != (*ni)->_activation_set[chain].end (); ai++) {
+ boost::shared_ptr<Route> dr = boost::dynamic_pointer_cast<Route> (*ai);
+ std::string dn = string_compose ("%1 (%2)", dr->name (), (*ai)->_init_refcount[chain]);
+ bool sends_only = false;
+ sr->feeds (dr, &sends_only);
+ if (sends_only) {
+ ss << " edge [style=dashed];\n";
+ }
+ ss << " \"" << sn << "\" -> \"" << dn << "\"\n";
+ if (sends_only) {
+ ss << " edge [style=solid];\n";
+ }
+ }
+ }
+ ss << "}\n";
+
+ GError *err = NULL;
+ if (!g_file_set_contents (file_name.c_str(), ss.str().c_str(), -1, &err)) {
+ if (err) {
+ error << string_compose (_("Could not graph to file (%1)"), err->message) << endmsg;
+ g_error_free (err);
+ }
+ return false;
+ }
+ return true;
+}
+
int
Graph::process_routes (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool& need_butler)
{
diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc
index 4e04cd59a7..6fb9411a1e 100644
--- a/libs/ardour/luabindings.cc
+++ b/libs/ardour/luabindings.cc
@@ -2279,6 +2279,7 @@ LuaBindings::common (lua_State* L)
.addFunction ("get_tracks", &Session::get_tracks)
.addFunction ("get_stripables", (StripableList (Session::*)() const)&Session::get_stripables)
.addFunction ("get_routelist", &Session::get_routelist)
+ .addFunction ("plot_process_graph", &Session::plot_process_graph)
.addFunction ("name", &Session::name)
.addFunction ("path", &Session::path)
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 584c5cfb4d..71468c2a10 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -6482,6 +6482,11 @@ Session::nstripables (bool with_monitor) const
return rv;
}
+bool
+Session::plot_process_graph (std::string const& file_name) const {
+ return _process_graph ? _process_graph->plot (file_name) : false;
+}
+
void
Session::add_automation_list(AutomationList *al)
{