#include <glibmm/fileutils.h>
#include "pbd/gstdio_compat.h"
-#include "pbd/locale_guard.h"
#include "pbd/pthread_utils.h"
#include "ardour/audio_buffer.h"
, 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)
, 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)
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;
}
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);
.addFunction ("name", &LuaProc::name)
.endClass ()
.endNamespace ();
+ lua_mlock (L, 0);
// add session to global lua namespace
luabridge::push <Session *> (L, &_session);
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
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) {
- ;
- }
+ } catch (...) { }
}
_ctrl_params.clear ();
}
} catch (luabridge::LuaException const& e) {
_iotable = NULL;
+ } catch (...) {
+ _iotable = NULL;
}
}
std::cerr << "LuaException: " << e.what () << "\n";
#endif
return false;
+ } catch (...) {
+ return false;
}
}
}
int
LuaProc::connect_and_run (BufferSet& bufs,
- framepos_t start, framepos_t end, double speed,
- ChanMapping in, ChanMapping out,
- pframes_t nframes, framecnt_t offset)
+ samplepos_t start, samplepos_t end, double speed,
+ ChanMapping const& in, ChanMapping const& out,
+ pframes_t nframes, samplecnt_t offset)
{
if (!_lua_dsp) {
return 0;
if (valid) {
for (MidiBuffer::iterator m = bufs.get_midi(idx).begin();
m != bufs.get_midi(idx).end(); ++m, ++e) {
- const Evoral::Event<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) {
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;
}
}
}
+
+ 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 ();
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;
}
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->add_property (X_("origin"), _origin);
+ 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);
}
}
{
#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)) {
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
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;
- const uint32_t p = atoi (index->value().c_str());
- const float v = atof (value->value().c_str ());
- set_parameter (p, v);
- PresetPortSetValue (p, v); /* EMIT SIGNAL */
+ 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);
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);
}
}
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));
}
}
n_outputs.set (DataType::AUDIO, 1);
type = Lua;
- _is_instrument = category == "Instrument";
}
PluginPtr
try {
script = Glib::file_get_contents (path);
- } catch (Glib::FileError err) {
+ } catch (Glib::FileError const& err) {
return PluginPtr ();
}