From: Robin Gareus Date: Fri, 18 Dec 2015 13:27:15 +0000 (+0100) Subject: save/restore plugin state with track-template X-Git-Tag: 4.5~163 X-Git-Url: https://main.carlh.net/gitweb/?p=ardour.git;a=commitdiff_plain;h=3eb04c3c2320ba60185e6efde170b562c3518e50 save/restore plugin state with track-template --- diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index 145b48a24b..4cb23719ae 100644 --- a/libs/ardour/ardour/lv2_plugin.h +++ b/libs/ardour/ardour/lv2_plugin.h @@ -121,6 +121,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee get_scale_points(uint32_t port_index) const; void set_insert_id(PBD::ID id); + void set_state_dir (const std::string& d = ""); int set_state (const XMLNode& node, int version); bool save_preset (std::string uri); @@ -176,6 +177,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee framepos_t _next_cycle_start; ///< Expected start frame of next run cycle double _next_cycle_speed; ///< Expected start frame of next run cycle PBD::ID _insert_id; + std::string _plugin_state_dir; uint32_t _patch_port_in_index; uint32_t _patch_port_out_index; URIMap& _uri_map; diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index 063335ccc3..37079751a9 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -101,6 +101,7 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent virtual int set_state (const XMLNode &, int version); virtual void set_insert_id (PBD::ID id) {} + virtual void set_state_dir (const std::string& d = "") {} virtual std::string unique_id() const = 0; virtual const char * label() const = 0; diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index a37c9cae68..0873825c02 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -54,6 +54,7 @@ class LIBARDOUR_API PluginInsert : public Processor XMLNode& get_state(void); int set_state(const XMLNode&, int version); void update_id (PBD::ID); + void set_state_dir (const std::string& d = ""); void run (BufferSet& in, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool); void silence (framecnt_t nframes); diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index 9cac6492b4..3753bd8066 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -44,6 +44,7 @@ #include "ardour/debug.h" #include "ardour/lv2_plugin.h" #include "ardour/session.h" +#include "ardour/template_utils.h" #include "ardour/tempo.h" #include "ardour/types.h" #include "ardour/utils.h" @@ -968,7 +969,11 @@ LV2Plugin::c_ui_type() const std::string LV2Plugin::plugin_dir() const { - return Glib::build_filename(_session.plugins_dir(), _insert_id.to_s()); + if (!_plugin_state_dir.empty ()){ + return Glib::build_filename(_plugin_state_dir, _insert_id.to_s()); + } else { + return Glib::build_filename(_session.plugins_dir(), _insert_id.to_s()); + } } /** Directory for files created by the plugin (except during save). */ @@ -1036,6 +1041,10 @@ LV2Plugin::add_state(XMLNode* root) const } } + if (!_plugin_state_dir.empty()) { + root->add_property("template-dir", _plugin_state_dir); + } + if (_has_state_interface) { // Provisionally increment state version and create directory const std::string new_dir = state_dir(++_state_version); @@ -1673,6 +1682,12 @@ LV2Plugin::set_insert_id(PBD::ID id) } } +void +LV2Plugin::set_state_dir (const std::string& d) +{ + _plugin_state_dir = d; +} + int LV2Plugin::set_state(const XMLNode& node, int version) { @@ -1728,6 +1743,13 @@ LV2Plugin::set_state(const XMLNode& node, int version) set_parameter(port_id, atof(value)); } + if ((prop = node.property("template-dir")) != 0) { + // portable templates, strip absolute path + set_state_dir (Glib::build_filename ( + ARDOUR::user_route_template_directory (), + Glib::path_get_basename (prop->value ()))); + } + _state_version = 0; if ((prop = node.property("state-dir")) != 0) { if (sscanf(prop->value().c_str(), "state%u", &_state_version) != 1) { @@ -1736,8 +1758,6 @@ LV2Plugin::set_state(const XMLNode& node, int version) prop->value()) << endmsg; } - // TODO: special case track-templates - // (state must be saved with the template) std::string state_file = Glib::build_filename( plugin_dir(), Glib::build_filename(prop->value(), "state.ttl")); @@ -1750,6 +1770,13 @@ LV2Plugin::set_state(const XMLNode& node, int version) _impl->state = state; } + if (!_plugin_state_dir.empty ()) { + // force save with session, next time (increment counter) + lilv_state_free (_impl->state); + _impl->state = NULL; + set_state_dir (""); + } + latency_compute_run(); #endif diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index b56419096e..1c9c573e42 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -1190,6 +1190,13 @@ PluginInsert::update_id (PBD::ID id) } } +void +PluginInsert::set_state_dir (const std::string& d) +{ + // state() only saves the state of the first plugin + _plugins[0]->set_state_dir (d); +} + void PluginInsert::set_parameter_state_2X (const XMLNode& node, int version) { diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 78eca17397..e24919a3b3 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -4158,7 +4158,30 @@ Route::shift (framepos_t pos, framecnt_t frames) int Route::save_as_template (const string& path, const string& name) { + { + // would be nice to use foreach_processor() + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); + std::string state_dir = path.substr (0, path.find_last_of ('.')); // strip template_suffix + for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { + boost::shared_ptr pi = boost::dynamic_pointer_cast (*i); + if (pi) { + pi->set_state_dir (state_dir); + } + } + } + XMLNode& node (state (false)); + + { + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); + for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { + boost::shared_ptr pi = boost::dynamic_pointer_cast (*i); + if (pi) { + pi->set_state_dir (); + } + } + } + XMLTree tree; IO::set_name_in_state (*node.children().front(), name);