From 47aa48e7696912e2b3e5fb4d854cc3f4e3136733 Mon Sep 17 00:00:00 2001 From: Nikolaus Gullotta Date: Fri, 15 Mar 2019 15:19:39 -0500 Subject: [PATCH] add read and write functions to class --- gtk2_ardour/editor_route_groups.cc | 23 ++- gtk2_ardour/editor_route_groups.h | 2 + libs/ardour/ardour/mixer_snapshot.h | 10 +- libs/ardour/mixer_snapshot.cc | 223 +++++++++++++++++++++------- 4 files changed, 199 insertions(+), 59 deletions(-) diff --git a/gtk2_ardour/editor_route_groups.cc b/gtk2_ardour/editor_route_groups.cc index 02f043c18d..0597c7e93e 100644 --- a/gtk2_ardour/editor_route_groups.cc +++ b/gtk2_ardour/editor_route_groups.cc @@ -198,10 +198,16 @@ EditorRouteGroups::EditorRouteGroups (Editor* e) Button* custom1 = new Button("Mark"); Button* custom2 = new Button("Recall"); + Button* custom3 = new Button("Write"); + Button* custom4 = new Button("load"); button_box->pack_start(*custom1); button_box->pack_start(*custom2); + button_box->pack_start(*custom3); + button_box->pack_start(*custom4); custom1->signal_clicked().connect(sigc::mem_fun(*this, &EditorRouteGroups::snap)); custom2->signal_clicked().connect(sigc::mem_fun(*this, &EditorRouteGroups::recall)); + custom3->signal_clicked().connect(sigc::mem_fun(*this, &EditorRouteGroups::write)); + custom4->signal_clicked().connect(sigc::mem_fun(*this, &EditorRouteGroups::load)); _display_packer.pack_start (_scroller, true, true); _display_packer.pack_start (*button_box, false, false); @@ -211,19 +217,24 @@ void EditorRouteGroups::snap() { camera->clear(); RouteList rl = _editor->get_selection().tracks.routelist(); - if(rl.empty()) { + if(rl.empty()) camera->snap(); - } else { - for(RouteList::const_iterator i = rl.begin(); i != rl.end(); i++) { - camera->snap((*i)); - } - } + else + camera->snap(rl); } void EditorRouteGroups::recall() { camera->recall(); } +void EditorRouteGroups::write() { + camera->write(); +} + +void EditorRouteGroups::load() { + camera->load(); +} + void EditorRouteGroups::remove_selected () { diff --git a/gtk2_ardour/editor_route_groups.h b/gtk2_ardour/editor_route_groups.h index 2b8e97aa71..b192ed8ca1 100644 --- a/gtk2_ardour/editor_route_groups.h +++ b/gtk2_ardour/editor_route_groups.h @@ -48,6 +48,8 @@ private: MixerSnapshot* camera; void snap(); void recall(); + void write(); + void load(); struct Columns : public Gtk::TreeModel::ColumnRecord { diff --git a/libs/ardour/ardour/mixer_snapshot.h b/libs/ardour/ardour/mixer_snapshot.h index 1756204920..87ec608e56 100644 --- a/libs/ardour/ardour/mixer_snapshot.h +++ b/libs/ardour/ardour/mixer_snapshot.h @@ -37,20 +37,24 @@ class MixerSnapshot //: public PBD::Stateful MixerSnapshot(ARDOUR::Session*); ~MixerSnapshot(); - void snap(boost::shared_ptr); void snap(); + void snap(ARDOUR::RouteList); void recall(); void clear(); + void write(); + void load(); int id; - char label[255]; + std::string label; std::time_t timestamp; private: ARDOUR::Session* _session; + void snap(boost::shared_ptr); + struct State { - PBD::ID id; + std::string id; std::string name; XMLNode node; std::vector slaves; diff --git a/libs/ardour/mixer_snapshot.cc b/libs/ardour/mixer_snapshot.cc index 6e4d77ac1f..768efead71 100644 --- a/libs/ardour/mixer_snapshot.cc +++ b/libs/ardour/mixer_snapshot.cc @@ -6,17 +6,24 @@ #include "ardour/route_group.h" #include "ardour/vca_manager.h" #include "ardour/vca.h" +#include "ardour/session_directory.h" +#include "ardour/filesystem_paths.h" #include "pbd/stateful.h" #include "pbd/id.h" #include "pbd/i18n.h" +#include "pbd/xml++.h" + +#include +#include +#include using namespace std; using namespace ARDOUR; MixerSnapshot::MixerSnapshot(Session* s) : id(0) - , label("") + , label("snapshot") , timestamp(time(0)) { if(s) @@ -38,13 +45,11 @@ void MixerSnapshot::clear() void MixerSnapshot::snap(boost::shared_ptr route) { if(route) { - cout << route->name() << endl; - string name = route->name(); XMLNode node (route->get_state()); vector slaves; - State state {route->id(), (string) route->name(), node, slaves}; + State state {route->id().to_s(), (string) route->name(), node, slaves}; route_states.push_back(state); //is it in a group? @@ -55,18 +60,39 @@ void MixerSnapshot::snap(boost::shared_ptr route) if(group) { XMLNode node (group->get_state()); - State state {group->id(), group->name(), node, slaves}; + State state {group->id().to_s(), group->name(), node, slaves}; group_states.push_back(state); } //push back VCA's connected to this route VCAList vl = _session->vca_manager().vcas(); for(VCAList::const_iterator i = vl.begin(); i != vl.end(); i++) { + + //only store this particular VCA once + bool already_exists = false; + for(vector::iterator s = vca_states.begin(); s != vca_states.end(); s++) { + if((*s).name == (*i)->name()) { + already_exists = !already_exists; + break; + } + } + + if(already_exists) + continue; + if(route->slaved_to((*i))) { + XMLNode node ((*i)->get_state()); vector slaves; - slaves.push_back(route->name()); - State state {(*i)->id(), (*i)->name(), node, slaves}; + + RouteList rl = _session->get_routelist(); + for(RouteList::iterator r = rl.begin(); r != rl.end(); r++){ + if((*r)->slaved_to((*i))) { + slaves.push_back((*r)->name()); + } + } + + State state {(*i)->id().to_s(), (*i)->name(), node, slaves}; vca_states.push_back(state); } } @@ -81,52 +107,25 @@ void MixerSnapshot::snap() clear(); RouteList rl = _session->get_routelist(); + if(rl.empty()) + return; + + for(RouteList::const_iterator it = rl.begin(); it != rl.end(); it++) + snap((*it)); +} + +void MixerSnapshot::snap(RouteList rl) +{ + if(!_session) + return; + + clear(); if(rl.empty()) return; - for(RouteList::const_iterator i = rl.begin(); i != rl.end(); i++) { - //copy current state - XMLNode node ((*i)->get_state()); - - //placeholder - vector slaves; - - State state {(*i)->id(), (string) (*i)->name(), node, slaves}; - route_states.push_back(state); - } - - //push back groups - list gl = _session->route_groups(); - for(list::const_iterator i = gl.begin(); i != gl.end(); i++) { - //copy current state - XMLNode node ((*i)->get_state()); - - //placeholder - vector slaves; - - State state {(*i)->id(), (string) (*i)->name(), node, slaves}; - group_states.push_back(state); - } - - //push back VCA's - VCAList vl = _session->vca_manager().vcas(); - for(VCAList::const_iterator i = vl.begin(); i != vl.end(); i++) { - //copy current state - XMLNode node ((*i)->get_state()); - - boost::shared_ptr rl = _session->get_tracks(); - - vector slaves; - for(RouteList::const_iterator t = rl->begin(); t != rl->end(); t++) { - if((*t)->slaved_to((*i))) { - slaves.push_back((*t)->name()); - } - } - - State state {(*i)->id(), (string) (*i)->name(), node, slaves}; - vca_states.push_back(state); - } + for(RouteList::const_iterator it = rl.begin(); it != rl.end(); it++) + snap((*it)); } void MixerSnapshot::recall() { @@ -135,7 +134,7 @@ void MixerSnapshot::recall() { for(vector::const_iterator i = route_states.begin(); i != route_states.end(); i++) { State state = (*i); - boost::shared_ptr route = _session->route_by_id(state.id); + boost::shared_ptr route = _session->route_by_id(PBD::ID(state.id)); if(!route) route = _session->route_by_name(state.name); @@ -188,4 +187,128 @@ void MixerSnapshot::recall() { } } } +} + +void MixerSnapshot::write() +{ + XMLNode* node = new XMLNode("MixerSnapshot"); + XMLNode* child; + + child = node->add_child ("Routes"); + for(vector::iterator i = route_states.begin(); i != route_states.end(); i++) { + child->add_child_copy((*i).node); + } + + child = node->add_child("Groups"); + for(vector::iterator i = group_states.begin(); i != group_states.end(); i++) { + child->add_child_copy((*i).node); + } + + child = node->add_child("VCAS"); + for(vector::iterator i = vca_states.begin(); i != vca_states.end(); i++) { + XMLNode* ch; + ch = find_named_node((*i).node, "Slaves"); + + if(!ch) + ch = (*i).node.add_child_copy(XMLNode("Slaves")); + else + ch->remove_nodes("Slave"); + + for(vector::const_iterator sl = (*i).slaves.begin(); sl != (*i).slaves.end(); sl++) { + XMLNode n ("Slave"); + n.set_property(X_("name"), *(sl)); + ch->add_child_copy(n); + } + + child->add_child_copy((*i).node); + } + + string snap = Glib::build_filename(user_config_directory(-1), label + ".xml"); + XMLTree tree; + tree.set_root(node); + tree.write(snap.c_str()); +} + +void MixerSnapshot::load() +{ + clear(); + + string snap = Glib::build_filename(user_config_directory(-1), label + ".xml"); + XMLTree tree; + tree.read(snap); + + XMLNode* root = tree.root(); + if(!root) { + return; + } + + XMLNode* route_node = find_named_node(*root, "Routes"); + XMLNode* group_node = find_named_node(*root, "Groups"); + XMLNode* vca_node = find_named_node(*root, "VCAS"); + + if(route_node) { + XMLNodeList nlist; + XMLNodeConstIterator niter; + nlist = route_node->children(); + + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + + string name, id; + (*niter)->get_property(X_("name"), name); + (*niter)->get_property(X_("id"), id); + + vector slaves; + + State state {id, name, **niter, slaves}; + route_states.push_back(state); + } + } + + if(group_node) { + XMLNodeList nlist; + XMLNodeConstIterator niter; + nlist = group_node->children(); + + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + + string name, id; + (*niter)->get_property(X_("name"), name); + (*niter)->get_property(X_("id"), id); + + vector slaves; + + State state {id, name, **niter, slaves}; + group_states.push_back(state); + } + } + + if(vca_node) { + XMLNodeList nlist; + XMLNodeConstIterator niter; + nlist = vca_node->children(); + + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + + string name, id; + (*niter)->get_property(X_("name"), name); + (*niter)->get_property(X_("id"), id); + + vector slaves; + + XMLNodeList slist; + XMLNodeConstIterator siter; + XMLNode* slave_node = find_named_node((**niter), "Slaves"); + if(slave_node) { + slist = slave_node->children(); + for(siter = slist.begin(); siter != slist.end(); siter++) { + string sname; + (*siter)->get_property(X_("name"), sname); + slaves.push_back(sname); + } + } + + State state {id, name, **niter, slaves}; + vca_states.push_back(state); + } + } } \ No newline at end of file