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, 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 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 sr = boost::dynamic_pointer_cast (*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 dr = boost::dynamic_pointer_cast (*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) {