work-around case where metric is NULL in split cycles.
[ardour.git] / libs / ardour / lv2_plugin.cc
index 3753bd80661453ee8e95f47f66654b12175837a5..7791c0b7dd7ec75cea17f4cd14052a3813c22d8e 100644 (file)
@@ -44,7 +44,6 @@
 #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"
@@ -1063,7 +1062,9 @@ LV2Plugin::add_state(XMLNode* root) const
                        0,
                        NULL);
 
-               if (!_impl->state || !lilv_state_equals(state, _impl->state)) {
+               if (!_plugin_state_dir.empty()
+                   || !_impl->state
+                   || !lilv_state_equals(state, _impl->state)) {
                        lilv_state_save(_world.world,
                                        _uri_map.urid_map(),
                                        _uri_map.urid_unmap(),
@@ -1072,8 +1073,14 @@ LV2Plugin::add_state(XMLNode* root) const
                                        new_dir.c_str(),
                                        "state.ttl");
 
-                       lilv_state_free(_impl->state);
-                       _impl->state = state;
+                       if (_plugin_state_dir.empty()) {
+                               // normal session save
+                               lilv_state_free(_impl->state);
+                               _impl->state = state;
+                       } else {
+                               // template save (dedicated state-dir)
+                               lilv_state_free(state);
+                       }
                } else {
                        // State is identical, decrement version and nuke directory
                        lilv_state_free(state);
@@ -1110,11 +1117,13 @@ LV2Plugin::find_presets()
                const LilvNode* preset = lilv_nodes_get(presets, i);
                lilv_world_load_resource(_world.world, preset);
                LilvNode* name = get_value(_world.world, preset, rdfs_label);
+               bool userpreset = true; // TODO
                if (name) {
                        _presets.insert(std::make_pair(lilv_node_as_string(preset),
                                                       Plugin::PresetRecord(
                                                               lilv_node_as_string(preset),
-                                                              lilv_node_as_string(name))));
+                                                              lilv_node_as_string(name),
+                                                              userpreset)));
                        lilv_node_free(name);
                } else {
                        warning << string_compose(
@@ -1744,10 +1753,7 @@ LV2Plugin::set_state(const XMLNode& node, int version)
        }
 
        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 ())));
+               set_state_dir (prop->value ());
        }
 
        _state_version = 0;
@@ -1917,7 +1923,6 @@ LV2Plugin::cleanup()
 {
        DEBUG_TRACE(DEBUG::LV2, string_compose("%1 cleanup\n", name()));
 
-       activate();
        deactivate();
        lilv_instance_free(_impl->instance);
        _impl->instance = NULL;
@@ -2150,8 +2155,10 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
                                                ? *metric_i : NULL;
                                        if (m != m_end && (!metric || metric->frame() > (*m).time())) {
                                                const Evoral::MIDIEvent<framepos_t> ev(*m, false);
-                                               LV2_Evbuf_Iterator eend = lv2_evbuf_end(_ev_buffers[port_index]);
-                                               lv2_evbuf_write(&eend, ev.time(), 0, type, ev.size(), ev.buffer());
+                                               if (ev.time() < nframes) {
+                                                       LV2_Evbuf_Iterator eend = lv2_evbuf_end(_ev_buffers[port_index]);
+                                                       lv2_evbuf_write(&eend, ev.time(), 0, type, ev.size(), ev.buffer());
+                                               }
                                                ++m;
                                        } else {
                                                tmetric.set_metric(metric);
@@ -2522,6 +2529,9 @@ LV2World::LV2World()
 
 LV2World::~LV2World()
 {
+       if (!world) {
+               return;
+       }
 #ifdef HAVE_LV2_1_2_0
        lilv_node_free(bufz_nominalBlockLength);
        lilv_node_free(bufz_fixedBlockLength);
@@ -2565,6 +2575,7 @@ LV2World::~LV2World()
        lilv_node_free(atom_Chunk);
        lilv_node_free(atom_AtomPort);
        lilv_world_free(world);
+       world = NULL;
 }
 
 void
@@ -2626,6 +2637,48 @@ LV2PluginInfo::load(Session& session)
        return PluginPtr();
 }
 
+std::vector<Plugin::PresetRecord>
+LV2PluginInfo::get_presets (bool /*user_only*/) const
+{
+       std::vector<Plugin::PresetRecord> p;
+#ifndef NO_PLUGIN_STATE
+       const LilvPlugin* lp = NULL;
+       try {
+               PluginPtr plugin;
+               const LilvPlugins* plugins = lilv_world_get_all_plugins(_world.world);
+               LilvNode* uri = lilv_new_uri(_world.world, _plugin_uri);
+               if (!uri) { throw failed_constructor(); }
+               lp = lilv_plugins_get_by_uri(plugins, uri);
+               if (!lp) { throw failed_constructor(); }
+               lilv_node_free(uri);
+       } catch (failed_constructor& err) {
+               return p;
+       }
+       assert (lp);
+       // see LV2Plugin::find_presets
+       LilvNode* lv2_appliesTo = lilv_new_uri(_world.world, LV2_CORE__appliesTo);
+       LilvNode* pset_Preset   = lilv_new_uri(_world.world, LV2_PRESETS__Preset);
+       LilvNode* rdfs_label    = lilv_new_uri(_world.world, LILV_NS_RDFS "label");
+
+       LilvNodes* presets = lilv_plugin_get_related(lp, pset_Preset);
+       LILV_FOREACH(nodes, i, presets) {
+               const LilvNode* preset = lilv_nodes_get(presets, i);
+               lilv_world_load_resource(_world.world, preset);
+               LilvNode* name = get_value(_world.world, preset, rdfs_label);
+               bool userpreset = true; // TODO
+               if (name) {
+                       p.push_back (Plugin::PresetRecord (lilv_node_as_string(preset), lilv_node_as_string(name), userpreset));
+                       lilv_node_free(name);
+               }
+       }
+       lilv_nodes_free(presets);
+       lilv_node_free(rdfs_label);
+       lilv_node_free(pset_Preset);
+       lilv_node_free(lv2_appliesTo);
+#endif
+       return p;
+}
+
 bool
 LV2PluginInfo::in_category (const std::string &c) const
 {