save/restore plugin state with track-template

This commit is contained in:
Robin Gareus 2015-12-18 14:27:15 +01:00
parent 7b6ef41f0c
commit 3eb04c3c23
6 changed files with 64 additions and 3 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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)
{

View File

@ -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<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (*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<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (*i);
if (pi) {
pi->set_state_dir ();
}
}
}
XMLTree tree;
IO::set_name_in_state (*node.children().front(), name);