summaryrefslogtreecommitdiff
path: root/libs/ardour/redirect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/redirect.cc')
-rw-r--r--libs/ardour/redirect.cc300
1 files changed, 153 insertions, 147 deletions
diff --git a/libs/ardour/redirect.cc b/libs/ardour/redirect.cc
index 09d650b069..adad79e2a3 100644
--- a/libs/ardour/redirect.cc
+++ b/libs/ardour/redirect.cc
@@ -108,101 +108,77 @@ Redirect::set_placement (const string& str, void *src)
}
}
+/* NODE STRUCTURE
+
+ <Automation [optionally with visible="...." ]>
+ <parameter-N>
+ <AutomationList id=N>
+ <events>
+ X1 Y1
+ X2 Y2
+ ....
+ </events>
+ </parameter-N>
+ <Automation>
+*/
+
int
-Redirect::load_automation (string path)
-{
- string fullpath;
+Redirect::set_automation_state (const XMLNode& node)
+{
+ Glib::Mutex::Lock lm (_automation_lock);
- if (path[0] == '/') { // legacy
- fullpath = path;
- } else {
- fullpath = _session.automation_dir();
- fullpath += path;
- }
- ifstream in (fullpath.c_str());
+ parameter_automation.clear ();
- if (!in) {
- warning << string_compose(_("%1: cannot open %2 to load automation data (%3)"), _name, fullpath, strerror (errno)) << endmsg;
- return 1;
- }
+ XMLNodeList nlist = node.children();
+ XMLNodeIterator niter;
- Glib::Mutex::Lock lm (_automation_lock);
- set<uint32_t> tosave;
- parameter_automation.clear ();
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+ uint32_t param;
- while (in) {
- double when;
- double value;
- uint32_t port;
+ if (sscanf ((*niter)->name().c_str(), "parameter-%" PRIu32, &param) != 1) {
+ error << string_compose (_("%2: badly formatted node name in XML automation state, ignored"), _name) << endmsg;
+ continue;
+ }
- in >> port; if (!in) break;
- in >> when; if (!in) goto bad;
- in >> value; if (!in) goto bad;
-
- AutomationList& al = automation_list (port);
- al.add (when, value);
- tosave.insert (port);
- }
-
- for (set<uint32_t>::iterator i = tosave.begin(); i != tosave.end(); ++i) {
- automation_list (*i).save_state (_("loaded from disk"));
+ AutomationList& al = automation_list (param);
+ if (al.set_state (*(*niter)->children().front())) {
+ goto bad;
+ }
}
-
+
return 0;
bad:
- error << string_compose(_("%1: cannot load automation data from %2"), _name, fullpath) << endmsg;
+ error << string_compose(_("%1: cannot load automation data from XML"), _name) << endmsg;
parameter_automation.clear ();
return -1;
}
-int
-Redirect::save_automation (string path)
+XMLNode&
+Redirect::get_automation_state ()
{
Glib::Mutex::Lock lm (_automation_lock);
+ XMLNode* node = new XMLNode (X_("Automation"));
string fullpath;
if (parameter_automation.empty()) {
- return 1;
- }
-
- fullpath = _session.automation_dir();
- fullpath += path;
-
- ofstream out (fullpath.c_str());
-
- if (!out) {
- error << string_compose(_("%1: cannot open %2 to store automation data (%3)"), _name, fullpath, strerror (errno)) << endmsg;
- return -1;
+ return *node;
}
- AutomationList::const_iterator i;
map<uint32_t,AutomationList*>::iterator li;
for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
- for (i = (*li).second->begin(); i != (*li).second->end(); ++i) {
-
- out << (*li).first << ' ' << (*i)->when << ' ' << (*i)->value << endl;
-
- if (!out) {
- break;
- }
- }
+
+ XMLNode* child;
- if (i != (*li).second->end()) {
- unlink (fullpath.c_str());
- error << string_compose(_("%1: could not save automation state to %2"), _name, fullpath) << endmsg;
- return -1;
- }
- }
-
- if (li != parameter_automation.end()) {
- unlink (fullpath.c_str());
- error << string_compose(_("%1: could not save automation state to %2"), _name, fullpath) << endmsg;
- return -1;
+ char buf[64];
+ stringstream str;
+ snprintf (buf, sizeof (buf), "parameter-%" PRIu32, li->first);
+ child = new XMLNode (buf);
+ child->add_child_nocopy (li->second->get_state ());
}
- return 0;
+ return *node;
}
XMLNode&
@@ -214,7 +190,6 @@ Redirect::get_state (void)
XMLNode&
Redirect::state (bool full_state)
{
- char buf[64];
XMLNode* node = new XMLNode (state_node_name);
stringstream sstr;
@@ -228,65 +203,24 @@ Redirect::state (bool full_state)
if (full_state) {
- string path;
- string legal_name;
+ XMLNode& automation = get_automation_state();
- path = _session.snap_name();
- path += "-redirect-";
- id().print (buf, sizeof (buf));
- path += buf;
- path += ".automation";
-
- /* XXX we didn't ask for a state save, we asked for the current state.
- FIX ME!
- */
-
- switch (save_automation (path)) {
- case -1:
- error << string_compose(_("Could not get state from Redirect (%1). Problem with save_automation"), _name) << endmsg;
- break;
-
- case 0:
- XMLNode *aevents = node->add_child("Automation");
-
- for (set<uint32_t>::iterator x = visible_parameter_automation.begin(); x != visible_parameter_automation.end(); ++x) {
- if (x != visible_parameter_automation.begin()) {
- sstr << ' ';
- }
- sstr << *x;
+ for (set<uint32_t>::iterator x = visible_parameter_automation.begin(); x != visible_parameter_automation.end(); ++x) {
+ if (x != visible_parameter_automation.begin()) {
+ sstr << ' ';
}
-
- aevents->add_property ("path", path);
- aevents->add_property ("visible", sstr.str());
- break;
+ sstr << *x;
}
- }
- return *node;
-}
+ automation.add_property ("visible", sstr.str());
-void
-Redirect::what_has_automation (set<uint32_t>& s) const
-{
- Glib::Mutex::Lock lm (_automation_lock);
- map<uint32_t,AutomationList*>::const_iterator li;
-
- for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
- s.insert ((*li).first);
+ node->add_child_nocopy (automation);
}
-}
-void
-Redirect::what_has_visible_automation (set<uint32_t>& s) const
-{
- Glib::Mutex::Lock lm (_automation_lock);
- set<uint32_t>::const_iterator li;
-
- for (li = visible_parameter_automation.begin(); li != visible_parameter_automation.end(); ++li) {
- s.insert (*li);
- }
+ return *node;
}
+
int
Redirect::set_state (const XMLNode& node)
{
@@ -308,14 +242,15 @@ Redirect::set_state (const XMLNode& node)
IO::set_state (**niter);
have_io = true;
- } else if ((*niter)->name() == "Automation") {
+ } else if ((*niter)->name() == X_("Automation")) {
+
XMLProperty *prop;
if ((prop = (*niter)->property ("path")) != 0) {
- load_automation (prop->value());
+ old_set_automation_state (*(*niter));
} else {
- warning << string_compose(_("%1: Automation node has no path property"), _name) << endmsg;
+ set_automation_state (*(*niter));
}
if ((prop = (*niter)->property ("visible")) != 0) {
@@ -364,6 +299,102 @@ Redirect::set_state (const XMLNode& node)
return 0;
}
+int
+Redirect::old_set_automation_state (const XMLNode& node)
+{
+ const XMLProperty *prop;
+
+ if ((prop = node.property ("path")) != 0) {
+ load_automation (prop->value());
+ } else {
+ warning << string_compose(_("%1: Automation node has no path property"), _name) << endmsg;
+ }
+
+ if ((prop = node.property ("visible")) != 0) {
+ uint32_t what;
+ stringstream sstr;
+
+ visible_parameter_automation.clear ();
+
+ sstr << prop->value();
+ while (1) {
+ sstr >> what;
+ if (sstr.fail()) {
+ break;
+ }
+ mark_automation_visible (what, true);
+ }
+ }
+
+ return 0;
+}
+
+int
+Redirect::load_automation (string path)
+{
+ string fullpath;
+
+ if (path[0] == '/') { // legacy
+ fullpath = path;
+ } else {
+ fullpath = _session.automation_dir();
+ fullpath += path;
+ }
+ ifstream in (fullpath.c_str());
+
+ if (!in) {
+ warning << string_compose(_("%1: cannot open %2 to load automation data (%3)"), _name, fullpath, strerror (errno)) << endmsg;
+ return 1;
+ }
+
+ Glib::Mutex::Lock lm (_automation_lock);
+ set<uint32_t> tosave;
+ parameter_automation.clear ();
+
+ while (in) {
+ double when;
+ double value;
+ uint32_t port;
+
+ in >> port; if (!in) break;
+ in >> when; if (!in) goto bad;
+ in >> value; if (!in) goto bad;
+
+ AutomationList& al = automation_list (port);
+ al.add (when, value);
+ tosave.insert (port);
+ }
+
+ return 0;
+
+ bad:
+ error << string_compose(_("%1: cannot load automation data from %2"), _name, fullpath) << endmsg;
+ parameter_automation.clear ();
+ return -1;
+}
+
+
+void
+Redirect::what_has_automation (set<uint32_t>& s) const
+{
+ Glib::Mutex::Lock lm (_automation_lock);
+ map<uint32_t,AutomationList*>::const_iterator li;
+
+ for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
+ s.insert ((*li).first);
+ }
+}
+
+void
+Redirect::what_has_visible_automation (set<uint32_t>& s) const
+{
+ Glib::Mutex::Lock lm (_automation_lock);
+ set<uint32_t>::const_iterator li;
+
+ for (li = visible_parameter_automation.begin(); li != visible_parameter_automation.end(); ++li) {
+ s.insert (*li);
+ }
+}
AutomationList&
Redirect::automation_list (uint32_t parameter)
{
@@ -437,34 +468,9 @@ Redirect::find_next_event (nframes_t now, nframes_t end, ControlEvent& next_even
}
void
-Redirect::store_state (RedirectState& state) const
-{
- state.active = _active;
-}
-
-Change
-Redirect::restore_state (StateManager::State& state)
-{
- RedirectState* rstate = dynamic_cast<RedirectState*> (&state);
- set_active (rstate->active, this);
- return Change (0);
-}
-
-StateManager::State*
-Redirect::state_factory (std::string why) const
-{
- RedirectState* state = new RedirectState (why);
-
- store_state (*state);
-
- return state;
-}
-
-void
Redirect::set_active (bool yn, void* src)
{
_active = yn;
- save_state (_("active_changed"));
active_changed (this, src);
_session.set_dirty ();
}