Add option to limit automatable control parmaters
[ardour.git] / libs / ardour / luaproc.cc
index 09be770b0a9bd2b4719acfdfffe68d58832d124e..bf93e1df676adfe690d31b3590a2b6e1679c1579 100644 (file)
@@ -22,7 +22,6 @@
 #include <glibmm/fileutils.h>
 
 #include "pbd/gstdio_compat.h"
-#include "pbd/locale_guard.h"
 #include "pbd/pthread_utils.h"
 
 #include "ardour/audio_buffer.h"
@@ -46,7 +45,7 @@ LuaProc::LuaProc (AudioEngine& engine,
                   Session& session,
                   const std::string &script)
        : Plugin (engine, session)
-       , _mempool ("LuaProc", 2097152)
+       , _mempool ("LuaProc", 3145728)
 #ifdef USE_TLSF
        , lua (lua_newstate (&PBD::TLSF::lalloc, &_mempool))
 #elif defined USE_MALLOC
@@ -55,12 +54,15 @@ LuaProc::LuaProc (AudioEngine& engine,
        , lua (lua_newstate (&PBD::ReallocPool::lalloc, &_mempool))
 #endif
        , _lua_dsp (0)
+       , _lua_latency (0)
        , _script (script)
        , _lua_does_channelmapping (false)
        , _lua_has_inline_display (false)
        , _designated_bypass_port (UINT32_MAX)
+       , _signal_latency (0)
        , _control_data (0)
        , _shadow_data (0)
+       , _configured (false)
        , _has_midi_input (false)
        , _has_midi_output (false)
 {
@@ -76,7 +78,7 @@ LuaProc::LuaProc (AudioEngine& engine,
 
 LuaProc::LuaProc (const LuaProc &other)
        : Plugin (other)
-       , _mempool ("LuaProc", 2097152)
+       , _mempool ("LuaProc", 3145728)
 #ifdef USE_TLSF
        , lua (lua_newstate (&PBD::TLSF::lalloc, &_mempool))
 #elif defined USE_MALLOC
@@ -85,12 +87,16 @@ LuaProc::LuaProc (const LuaProc &other)
        , lua (lua_newstate (&PBD::ReallocPool::lalloc, &_mempool))
 #endif
        , _lua_dsp (0)
+       , _lua_latency (0)
        , _script (other.script ())
+       , _origin (other._origin)
        , _lua_does_channelmapping (false)
        , _lua_has_inline_display (false)
        , _designated_bypass_port (UINT32_MAX)
+       , _signal_latency (0)
        , _control_data (0)
        , _shadow_data (0)
+       , _configured (false)
        , _has_midi_input (false)
        , _has_midi_output (false)
 {
@@ -109,18 +115,21 @@ LuaProc::LuaProc (const LuaProc &other)
 LuaProc::~LuaProc () {
 #ifdef WITH_LUAPROC_STATS
        if (_info && _stats_cnt > 0) {
-               printf ("LuaProc: '%s' run()  avg: %.3f  max: %.3f [ms]\n",
+               printf ("LuaProc: '%s' run()  avg: %.3f  max: %.3f [ms] p: %.1f\n",
                                _info->name.c_str (),
                                0.0001f * _stats_avg[0] / (float) _stats_cnt,
-                               0.0001f * _stats_max[0]);
-               printf ("LuaProc: '%s' gc()   avg: %.3f  max: %.3f [ms]\n",
+                               0.0001f * _stats_max[0],
+                               _stats_max[0] * (float)_stats_cnt / _stats_avg[0]);
+               printf ("LuaProc: '%s' gc()   avg: %.3f  max: %.3f [ms] p: %.1f\n",
                                _info->name.c_str (),
                                0.0001f * _stats_avg[1] / (float) _stats_cnt,
-                               0.0001f * _stats_max[1]);
+                               0.0001f * _stats_max[1],
+                               _stats_max[1] * (float)_stats_cnt / _stats_avg[1]);
        }
 #endif
        lua.do_command ("collectgarbage();");
        delete (_lua_dsp);
+       delete (_lua_latency);
        delete [] _control_data;
        delete [] _shadow_data;
 }
@@ -129,25 +138,30 @@ void
 LuaProc::init ()
 {
 #ifdef WITH_LUAPROC_STATS
-       _stats_avg[0] = _stats_avg[1] = _stats_max[0] = _stats_max[1] = _stats_cnt = 0;
+       _stats_avg[0] = _stats_avg[1] = _stats_max[0] = _stats_max[1] = 0;
+       _stats_cnt = -25;
 #endif
 
-       lua.tweak_rt_gc ();
        lua.Print.connect (sigc::mem_fun (*this, &LuaProc::lua_print));
        // register session object
        lua_State* L = lua.getState ();
+       lua_mlock (L, 1);
        LuaBindings::stddef (L);
        LuaBindings::common (L);
        LuaBindings::dsp (L);
 
        luabridge::getGlobalNamespace (L)
                .beginNamespace ("Ardour")
-               .beginClass <LuaProc> ("LuaProc")
+               .deriveClass <LuaProc, PBD::StatefulDestructible> ("LuaProc")
                .addFunction ("queue_draw", &LuaProc::queue_draw)
                .addFunction ("shmem", &LuaProc::instance_shm)
                .addFunction ("table", &LuaProc::instance_ref)
+               .addFunction ("route", &LuaProc::route)
+               .addFunction ("unique_id", &LuaProc::unique_id)
+               .addFunction ("name", &LuaProc::name)
                .endClass ()
                .endNamespace ();
+       lua_mlock (L, 0);
 
        // add session to global lua namespace
        luabridge::push <Session *> (L, &_session);
@@ -158,13 +172,22 @@ LuaProc::init ()
        lua_setglobal (L, "self");
 
        // sandbox
-       lua.do_command ("io = nil os = nil loadfile = nil require = nil dofile = nil package = nil debug = nil");
+       lua.sandbox (true);
 #if 0
        lua.do_command ("for n in pairs(_G) do print(n) end print ('----')"); // print global env
 #endif
        lua.do_command ("function ardour () end");
 }
 
+boost::weak_ptr<Route>
+LuaProc::route () const
+{
+       if (!_owner) {
+               return boost::weak_ptr<Route>();
+       }
+       return static_cast<Route*>(_owner)->weakroute ();
+}
+
 void
 LuaProc::lua_print (std::string s) {
        std::cout <<"LuaProc: " << s << "\n";
@@ -218,33 +241,18 @@ LuaProc::load_script ()
                assert (0);
        }
 
+       luabridge::LuaRef lua_dsp_latency = luabridge::getGlobal (L, "dsp_latency");
+       if (lua_dsp_latency.type () == LUA_TFUNCTION) {
+               _lua_latency = new luabridge::LuaRef (lua_dsp_latency);
+       }
+
        // initialize the DSP if needed
        luabridge::LuaRef lua_dsp_init = luabridge::getGlobal (L, "dsp_init");
        if (lua_dsp_init.type () == LUA_TFUNCTION) {
                try {
-                       lua_dsp_init (_session.nominal_frame_rate ());
+                       lua_dsp_init (_session.nominal_sample_rate ());
                } catch (luabridge::LuaException const& e) {
-                       ;
-               }
-       }
-
-       // query midi i/o
-       luabridge::LuaRef lua_dsp_has_midi_in = luabridge::getGlobal (L, "dsp_has_midi_input");
-       if (lua_dsp_has_midi_in.type () == LUA_TFUNCTION) {
-               try {
-                       _has_midi_input = lua_dsp_has_midi_in ();
-               } catch (luabridge::LuaException const& e) {
-                       ;
-               }
-       }
-
-       luabridge::LuaRef lua_dsp_has_midi_out = luabridge::getGlobal (L, "dsp_has_midi_output");
-       if (lua_dsp_has_midi_out.type () == LUA_TFUNCTION) {
-               try {
-                       _has_midi_output = lua_dsp_has_midi_out ();
-               } catch (luabridge::LuaException const& e) {
-                       ;
-               }
+               } catch (...) { }
        }
 
        _ctrl_params.clear ();
@@ -348,22 +356,26 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
 
        lua_State* L = lua.getState ();
        luabridge::LuaRef ioconfig = luabridge::getGlobal (L, "dsp_ioconfig");
-       if (!ioconfig.isFunction ()) {
-               return false;
-       }
 
        luabridge::LuaRef *_iotable = NULL; // can't use reference :(
-       try {
-               luabridge::LuaRef iotable = ioconfig ();
-               if (iotable.isTable ()) {
-                       _iotable = new luabridge::LuaRef (iotable);
+
+       if (ioconfig.isFunction ()) {
+               try {
+                       luabridge::LuaRef iotable = ioconfig ();
+                       if (iotable.isTable ()) {
+                               _iotable = new luabridge::LuaRef (iotable);
+                       }
+               } catch (luabridge::LuaException const& e) {
+                       _iotable = NULL;
+               } catch (...) {
+                       _iotable = NULL;
                }
-       } catch (luabridge::LuaException const& e) {
-               return false;
        }
 
        if (!_iotable) {
-               return false;
+               /* empty table as default */
+               luabridge::LuaRef iotable = luabridge::newTable(L);
+               _iotable = new luabridge::LuaRef (iotable);
        }
 
        // now we can reference it.
@@ -371,7 +383,9 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
        delete _iotable;
 
        if ((iotable).length () < 1) {
-               return false;
+               /* empty table as only config, to get default values */
+               luabridge::LuaRef ioconf = luabridge::newTable(L);
+               iotable[1] = ioconf;
        }
 
        const int audio_in = in.n_audio ();
@@ -379,6 +393,7 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
 
        // preferred setting (provided by plugin_insert)
        const int preferred_out = out.n_audio ();
+       const int preferred_midiout = out.n_midi ();
 
        int midi_out = -1;
        int audio_out = -1;
@@ -394,6 +409,8 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
       imprecise->set (DataType::AUDIO, (in));                       \
       imprecise->set (DataType::MIDI, possible_midiin);             \
     }                                                               \
+    _has_midi_input = (possible_midiin > 0);                        \
+    _has_midi_output = (possible_midiout > 0);                      \
     penalty = p;                                                    \
     found = true;                                                   \
   }                                                                 \
@@ -402,8 +419,12 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
 #define FOUNDCFG_IMPRECISE(in, out) {                               \
   const float p = fabsf ((float)(out) - preferred_out) *            \
                       (((out) > preferred_out) ? 1.1 : 1)           \
+                + fabsf ((float)possible_midiout - preferred_midiout) *    \
+                      ((possible_midiout - preferred_midiout) ? 0.6 : 0.5) \
                 + fabsf ((float)(in) - audio_in) *                  \
-                      (((in) > audio_in) ? 275 : 250);              \
+                      (((in) > audio_in) ? 275 : 250)               \
+                + fabsf ((float)possible_midiin - midi_in) *        \
+                      ((possible_midiin - midi_in) ? 100 : 110);    \
   FOUNDCFG_PENALTY(in, out, p);                                     \
 }
 
@@ -431,10 +452,10 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
 
                int possible_in = io["audio_in"].isNumber() ? io["audio_in"] : -1;
                int possible_out = io["audio_out"].isNumber() ? io["audio_out"] : -1;
-               int possible_midiin = _has_midi_input ? 1 : 0;
-               int possible_midiout = _has_midi_output ? 1 : 0;
+               int possible_midiin = io["midi_in"].isNumber() ? io["midi_in"] : 0;
+               int possible_midiout = io["midi_out"].isNumber() ? io["midi_out"] : 0;
 
-               if (midi_in > 0 && possible_midiin == 0 && !imprecise) {
+               if (midi_in != possible_midiin && !imprecise) {
                        continue;
                }
 
@@ -445,19 +466,8 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
                        FOUNDCFG_PENALTY(audio_in, preferred_out, -1);
                }
 
-               // "imprecise" matches
-               if (possible_out == 0) {
-                       /* skip configurations with no audio output, unless
-                        * the plugin is a midi filter or generator */
-                       if (possible_in == 0 && _has_midi_output) {
-                               if (audio_in == 0) {
-                                       FOUNDCFG(possible_out);
-                                       break;
-                               } else if (imprecise) {
-                                       // TODO hide audio input from plugin
-                                       FOUNDCFG_IMPRECISE (possible_in, possible_out);
-                               }
-                       }
+               if (possible_out == 0 && possible_midiout == 0) {
+                       /* skip configurations with no output at all */
                        continue;
                }
 
@@ -514,8 +524,6 @@ LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, Chan
                                 * Really imprecise only if desired_in != audio_in */
                                FOUNDCFG_IMPRECISE (desired_in, possible_out);
                        }
-                       // ideally we'll also find the closest, best matching
-                       // input configuration with minimal output penalty...
                }
 
        }
@@ -547,7 +555,7 @@ LuaProc::configure_io (ChanCount in, ChanCount out)
        _info->n_outputs = _selected_out;
 
        // configure the DSP if needed
-       if (in != _configured_in || out != _configured_out) {
+       if (in != _configured_in || out != _configured_out || !_configured) {
                lua_State* L = lua.getState ();
                luabridge::LuaRef lua_dsp_configure = luabridge::getGlobal (L, "dsp_configure");
                if (lua_dsp_configure.type () == LUA_TFUNCTION) {
@@ -584,12 +592,15 @@ LuaProc::configure_io (ChanCount in, ChanCount out)
                                        _info->n_inputs = lin;
                                        _info->n_outputs = lout;
                                }
+                               _configured = true;
                        } catch (luabridge::LuaException const& e) {
                                PBD::error << "LuaException: " << e.what () << "\n";
 #ifndef NDEBUG
                                std::cerr << "LuaException: " << e.what () << "\n";
 #endif
                                return false;
+                       } catch (...) {
+                               return false;
                        }
                }
        }
@@ -602,9 +613,9 @@ LuaProc::configure_io (ChanCount in, ChanCount out)
 
 int
 LuaProc::connect_and_run (BufferSet& bufs,
-               framepos_t start, framepos_t end, double speed,
+               samplepos_t start, samplepos_t end, double speed,
                ChanMapping in, ChanMapping out,
-               pframes_t nframes, framecnt_t offset)
+               pframes_t nframes, samplecnt_t offset)
 {
        if (!_lua_dsp) {
                return 0;
@@ -676,7 +687,7 @@ LuaProc::connect_and_run (BufferSet& bufs,
                                if (valid) {
                                        for (MidiBuffer::iterator m = bufs.get_midi(idx).begin();
                                                        m != bufs.get_midi(idx).end(); ++m, ++e) {
-                                               const Evoral::MIDIEvent<framepos_t> ev(*m, false);
+                                               const Evoral::Event<samplepos_t> ev(*m, false);
                                                luabridge::LuaRef lua_midi_data (luabridge::newTable (L));
                                                const uint8_t* data = ev.buffer();
                                                for (uint32_t i = 0; i < ev.size(); ++i) {
@@ -685,6 +696,8 @@ LuaProc::connect_and_run (BufferSet& bufs,
                                                luabridge::LuaRef lua_midi_event (luabridge::newTable (L));
                                                lua_midi_event["time"] = 1 + (*m).time();
                                                lua_midi_event["data"] = lua_midi_data;
+                                               lua_midi_event["bytes"] = data;
+                                               lua_midi_event["size"] = ev.size();
                                                lua_midi_src_tbl[e] = lua_midi_event;
                                        }
                                }
@@ -717,7 +730,7 @@ LuaProc::connect_and_run (BufferSet& bufs,
                                                if (!i.value ()["time"].isNumber ()) { continue; }
                                                if (!i.value ()["data"].isTable ()) { continue; }
                                                luabridge::LuaRef data_tbl (i.value ()["data"]);
-                                               framepos_t tme = i.value ()["time"];
+                                               samplepos_t tme = i.value ()["time"];
                                                if (tme < 1 || tme > nframes) { continue; }
                                                uint8_t data[64];
                                                size_t size = 0;
@@ -732,12 +745,19 @@ LuaProc::connect_and_run (BufferSet& bufs,
                                }
                        }
                }
+
+               if (_lua_latency) {
+                       _signal_latency = (*_lua_latency)();
+               }
+
        } catch (luabridge::LuaException const& e) {
                PBD::error << "LuaException: " << e.what () << "\n";
 #ifndef NDEBUG
                std::cerr << "LuaException: " << e.what () << "\n";
 #endif
                return -1;
+       } catch (...) {
+               return -1;
        }
 #ifdef WITH_LUAPROC_STATS
        int64_t t1 = g_get_monotonic_time ();
@@ -745,14 +765,15 @@ LuaProc::connect_and_run (BufferSet& bufs,
 
        lua.collect_garbage_step ();
 #ifdef WITH_LUAPROC_STATS
-       ++_stats_cnt;
-       int64_t t2 = g_get_monotonic_time ();
-       int64_t ela0 = t1 - t0;
-       int64_t ela1 = t2 - t1;
-       if (ela0 > _stats_max[0]) _stats_max[0] = ela0;
-       if (ela1 > _stats_max[1]) _stats_max[1] = ela1;
-       _stats_avg[0] += ela0;
-       _stats_avg[1] += ela1;
+       if (++_stats_cnt > 0) {
+               int64_t t2 = g_get_monotonic_time ();
+               int64_t ela0 = t1 - t0;
+               int64_t ela1 = t2 - t1;
+               if (ela0 > _stats_max[0]) _stats_max[0] = ela0;
+               if (ela1 > _stats_max[1]) _stats_max[1] = ela1;
+               _stats_avg[0] += ela0;
+               _stats_avg[1] += ela1;
+       }
 #endif
        return 0;
 }
@@ -762,24 +783,21 @@ void
 LuaProc::add_state (XMLNode* root) const
 {
        XMLNode*    child;
-       char        buf[32];
-       LocaleGuard lg;
 
        gchar* b64 = g_base64_encode ((const guchar*)_script.c_str (), _script.size ());
        std::string b64s (b64);
        g_free (b64);
        XMLNode* script_node = new XMLNode (X_("script"));
-       script_node->add_property (X_("lua"), LUA_VERSION);
+       script_node->set_property (X_("lua"), LUA_VERSION);
+       script_node->set_property (X_("origin"), _origin);
        script_node->add_content (b64s);
        root->add_child_nocopy (*script_node);
 
        for (uint32_t i = 0; i < parameter_count(); ++i) {
                if (parameter_is_input(i) && parameter_is_control(i)) {
                        child = new XMLNode("Port");
-                       snprintf(buf, sizeof(buf), "%u", i);
-                       child->add_property("id", std::string(buf));
-                       snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]);
-                       child->add_property("value", std::string(buf));
+                       child->set_property("id", i);
+                       child->set_property("value", _shadow_data[i]);
                        root->add_child_nocopy(*child);
                }
        }
@@ -794,6 +812,10 @@ LuaProc::set_script_from_state (const XMLNode& node)
        }
 
        if ((child = node.child (X_("script"))) != 0) {
+               XMLProperty const* prop;
+               if ((prop = node.property ("origin")) != 0) {
+                       _origin = prop->value();
+               }
                for (XMLNodeList::const_iterator n = child->children ().begin (); n != child->children ().end (); ++n) {
                        if (!(*n)->is_content ()) { continue; }
                        gsize size;
@@ -826,14 +848,9 @@ LuaProc::set_state (const XMLNode& node, int version)
 {
 #ifndef NO_PLUGIN_STATE
        XMLNodeList nodes;
-       XMLProperty const * prop;
        XMLNodeConstIterator iter;
        XMLNode *child;
-       const char *value;
-       const char *port;
-       uint32_t port_id;
 #endif
-       LocaleGuard lg;
 
        if (_script.empty ()) {
                if (set_script_from_state (node)) {
@@ -850,20 +867,21 @@ LuaProc::set_state (const XMLNode& node, int version)
        nodes = node.children ("Port");
        for (iter = nodes.begin(); iter != nodes.end(); ++iter) {
                child = *iter;
-               if ((prop = child->property("id")) != 0) {
-                       port = prop->value().c_str();
-               } else {
+
+               uint32_t port_id;
+               float value;
+
+               if (!child->get_property("id", port_id)) {
                        warning << _("LuaProc: port has no symbol, ignored") << endmsg;
                        continue;
                }
-               if ((prop = child->property("value")) != 0) {
-                       value = prop->value().c_str();
-               } else {
+
+               if (!child->get_property("value", value)) {
                        warning << _("LuaProc: port has no value, ignored") << endmsg;
                        continue;
                }
-               sscanf (port, "%" PRIu32, &port_id);
-               set_parameter (port_id, atof(value));
+
+               set_parameter (port_id, value);
        }
 #endif
 
@@ -1036,6 +1054,7 @@ LuaProc::setup_lua_inline_gui (LuaState *lua_gui)
        LuaBindings::stddef (LG);
        LuaBindings::common (LG);
        LuaBindings::dsp (LG);
+       LuaBindings::osc (LG);
 
        lua_gui->Print.connect (sigc::mem_fun (*this, &LuaProc::lua_print));
        lua_gui->do_command ("function ardour () end");
@@ -1054,7 +1073,7 @@ LuaProc::setup_lua_inline_gui (LuaState *lua_gui)
        luabridge::push <LuaProc *> (LG, this);
        lua_setglobal (LG, "self");
 
-       luabridge::push <float *> (LG, _shadow_data);
+       luabridge::push <float *> (LG, _control_data);
        lua_setglobal (LG, "CtrlPorts");
 }
 ////////////////////////////////////////////////////////////////////////////////
@@ -1118,20 +1137,24 @@ LuaProc::load_preset (PresetRecord r)
 
        XMLNode* root = t->root ();
        for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
-               XMLProperty const * label = (*i)->property (X_("label"));
-               assert (label);
-               if (label->value() != r.label) {
+               std::string str;
+               if (!(*i)->get_property (X_("label"), str)) {
+                       assert (false);
+               }
+               if (str != r.label) {
                        continue;
                }
 
                for (XMLNodeList::const_iterator j = (*i)->children().begin(); j != (*i)->children().end(); ++j) {
                        if ((*j)->name() == X_("Parameter")) {
-                               XMLProperty const * index = (*j)->property (X_("index"));
-                               XMLProperty const * value = (*j)->property (X_("value"));
-                               assert (index);
-                               assert (value);
-                               LocaleGuard lg;
-                               set_parameter (atoi (index->value().c_str()), atof (value->value().c_str ()));
+                               uint32_t index;
+                               float value;
+                               if (!(*j)->get_property (X_("index"), index) ||
+                                   !(*j)->get_property (X_("value"), value)) {
+                                       assert (false);
+                               }
+                               set_parameter (index, value);
+                               PresetPortSetValue (index, value); /* EMIT SIGNAL */
                        }
                }
                return Plugin::load_preset(r);
@@ -1147,17 +1170,20 @@ LuaProc::do_save_preset (std::string name) {
                return "";
        }
 
+       // prevent dups -- just in case
+       t->root()->remove_nodes_and_delete (X_("label"), name);
+
        std::string uri (preset_name_to_uri (name));
 
        XMLNode* p = new XMLNode (X_("Preset"));
-       p->add_property (X_("uri"), uri);
-       p->add_property (X_("label"), name);
+       p->set_property (X_("uri"), uri);
+       p->set_property (X_("label"), name);
 
        for (uint32_t i = 0; i < parameter_count(); ++i) {
                if (parameter_is_input (i)) {
                        XMLNode* c = new XMLNode (X_("Parameter"));
-                       c->add_property (X_("index"), string_compose ("%1", i));
-                       c->add_property (X_("value"), string_compose ("%1", get_parameter (i)));
+                       c->set_property (X_("index"), i);
+                       c->set_property (X_("value"), get_parameter (i));
                        p->add_child_nocopy (*c);
                }
        }
@@ -1190,14 +1216,14 @@ LuaProc::find_presets ()
        if (t) {
                XMLNode* root = t->root ();
                for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
+                       std::string uri;
+                       std::string label;
 
-                       XMLProperty const * uri = (*i)->property (X_("uri"));
-                       XMLProperty const * label = (*i)->property (X_("label"));
-
-                       assert (uri);
-                       assert (label);
+                       if (!(*i)->get_property (X_("uri"), uri) || !(*i)->get_property (X_("label"), label)) {
+                               assert (false);
+                       }
 
-                       PresetRecord r (uri->value(), label->value(), true);
+                       PresetRecord r (uri, label, true);
                        _presets.insert (make_pair (r.uri, r));
                }
        }
@@ -1220,7 +1246,6 @@ LuaPluginInfo::LuaPluginInfo (LuaScriptInfoPtr lsi) {
        n_outputs.set (DataType::AUDIO, 1);
        type = Lua;
 
-       _is_instrument = category == "Instrument";
 }
 
 PluginPtr
@@ -1233,7 +1258,7 @@ LuaPluginInfo::load (Session& session)
 
        try {
                script = Glib::file_get_contents (path);
-       } catch (Glib::FileError err) {
+       } catch (Glib::FileError const& err) {
                return PluginPtr ();
        }
 
@@ -1242,7 +1267,9 @@ LuaPluginInfo::load (Session& session)
        }
 
        try {
-               PluginPtr plugin (new LuaProc (session.engine (), session, script));
+               LuaProc* lp = new LuaProc (session.engine (), session, script);
+               lp->set_origin (path);
+               PluginPtr plugin (lp);
                return plugin;
        } catch (failed_constructor& err) {
                ;