diff options
Diffstat (limited to 'libs/ardour/redirect.cc')
-rw-r--r-- | libs/ardour/redirect.cc | 300 |
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, ¶m) != 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 (); } |