fix configurable IO MIDI FX w/strict-i/o
[ardour.git] / libs / ardour / luaproc.cc
1 /*
2     Copyright (C) 2016 Robin Gareus <robin@gareus.org>
3     Copyright (C) 2006 Paul Davis
4
5     This program is free software; you can redistribute it and/or modify it
6     under the terms of the GNU General Public License as published by the Free
7     Software Foundation; either version 2 of the License, or (at your option)
8     any later version.
9
10     This program is distributed in the hope that it will be useful, but WITHOUT
11     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13     for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <glib.h>
21 #include "pbd/gstdio_compat.h"
22
23 #include "pbd/pthread_utils.h"
24
25 #include "ardour/audio_buffer.h"
26 #include "ardour/buffer_set.h"
27 #include "ardour/luabindings.h"
28 #include "ardour/luaproc.h"
29 #include "ardour/luascripting.h"
30 #include "ardour/midi_buffer.h"
31 #include "ardour/plugin.h"
32 #include "ardour/session.h"
33
34 #include "LuaBridge/LuaBridge.h"
35
36 #include "i18n.h"
37
38 using namespace ARDOUR;
39 using namespace PBD;
40
41 LuaProc::LuaProc (AudioEngine& engine,
42                   Session& session,
43                   const std::string &script)
44         : Plugin (engine, session)
45         , _mempool ("LuaProc", 1048576) // 1 MB is plenty. (64K would be enough)
46         , lua (lua_newstate (&PBD::ReallocPool::lalloc, &_mempool))
47         , _lua_dsp (0)
48         , _script (script)
49         , _lua_does_channelmapping (false)
50         , _lua_has_inline_display (false)
51         , _control_data (0)
52         , _shadow_data (0)
53         , _has_midi_input (false)
54         , _has_midi_output (false)
55 {
56         init ();
57
58         /* when loading a session, or pasing a processor,
59          * the script is set during set_state();
60          */
61         if (!_script.empty () && load_script ()) {
62                 throw failed_constructor ();
63         }
64 }
65
66 LuaProc::LuaProc (const LuaProc &other)
67         : Plugin (other)
68         , _mempool ("LuaProc", 1048576) // 1 MB is plenty. (64K would be enough)
69         , lua (lua_newstate (&PBD::ReallocPool::lalloc, &_mempool))
70         , _lua_dsp (0)
71         , _script (other.script ())
72         , _lua_does_channelmapping (false)
73         , _lua_has_inline_display (false)
74         , _control_data (0)
75         , _shadow_data (0)
76         , _has_midi_input (false)
77         , _has_midi_output (false)
78 {
79         init ();
80
81         if (load_script ()) {
82                 throw failed_constructor ();
83         }
84
85         for (uint32_t i = 0; i < parameter_count (); ++i) {
86                 _control_data[i] = other._shadow_data[i];
87                 _shadow_data[i]  = other._shadow_data[i];
88         }
89 }
90
91 LuaProc::~LuaProc () {
92 #ifdef WITH_LUAPROC_STATS
93         if (_info && _stats_cnt > 0) {
94                 printf ("LuaProc: '%s' run()  avg: %.3f  max: %.3f [ms]\n",
95                                 _info->name.c_str (),
96                                 0.0001f * _stats_avg[0] / (float) _stats_cnt,
97                                 0.0001f * _stats_max[0]);
98                 printf ("LuaProc: '%s' gc()   avg: %.3f  max: %.3f [ms]\n",
99                                 _info->name.c_str (),
100                                 0.0001f * _stats_avg[1] / (float) _stats_cnt,
101                                 0.0001f * _stats_max[1]);
102         }
103 #endif
104         lua.do_command ("collectgarbage();");
105         delete (_lua_dsp);
106         delete [] _control_data;
107         delete [] _shadow_data;
108 }
109
110 void
111 LuaProc::init ()
112 {
113 #ifdef WITH_LUAPROC_STATS
114         _stats_avg[0] = _stats_avg[1] = _stats_max[0] = _stats_max[1] = _stats_cnt = 0;
115 #endif
116
117 #ifndef NDEBUG
118         lua.Print.connect (sigc::mem_fun (*this, &LuaProc::lua_print));
119 #endif
120         // register session object
121         lua_State* L = lua.getState ();
122         LuaBindings::stddef (L);
123         LuaBindings::common (L);
124         LuaBindings::dsp (L);
125
126         luabridge::getGlobalNamespace (L)
127                 .beginNamespace ("Ardour")
128                 .beginClass <LuaProc> ("LuaProc")
129                 .addFunction ("queue_draw", &LuaProc::queue_draw)
130                 .addFunction ("shmem", &LuaProc::instance_shm)
131                 .endClass ()
132                 .endNamespace ();
133
134         // add session to global lua namespace
135         luabridge::push <Session *> (L, &_session);
136         lua_setglobal (L, "Session");
137
138         // instance
139         luabridge::push <LuaProc *> (L, this);
140         lua_setglobal (L, "self");
141
142         // sandbox
143         lua.do_command ("io = nil os = nil loadfile = nil require = nil dofile = nil package = nil debug = nil");
144 #if 0
145         lua.do_command ("for n in pairs(_G) do print(n) end print ('----')"); // print global env
146 #endif
147         lua.do_command ("function ardour () end");
148 }
149
150 void
151 LuaProc::lua_print (std::string s) {
152         std::cout <<"LuaProc: " << s << "\n";
153 }
154
155 bool
156 LuaProc::load_script ()
157 {
158         assert (!_lua_dsp); // don't allow to re-initialize
159         LuaPluginInfoPtr lpi;
160
161         // TODO: refine APIs; function arguments..
162         // - perform channel-map in ardour (silent/scratch buffers) ?
163         // - control-port API (explicit get/set functions ??)
164         // - latency reporting (global var? ctrl-port? set-function ?)
165         // - MIDI -> sparse table of events
166         //     { [sample] => { Event }, .. }
167         //   or  { { sample, Event }, .. }
168
169         try {
170                 LuaScriptInfoPtr lsi = LuaScripting::script_info (_script);
171                 lpi = LuaPluginInfoPtr (new LuaPluginInfo (lsi));
172                 assert (lpi);
173                 set_info (lpi);
174                 _mempool.set_name ("LuaProc: " + lsi->name);
175                 _docs = lsi->description;
176         } catch (failed_constructor& err) {
177                 return true;
178         }
179
180         lua_State* L = lua.getState ();
181         lua.do_command (_script);
182
183         // check if script has a DSP callback
184         luabridge::LuaRef lua_dsp_run = luabridge::getGlobal (L, "dsp_run");
185         luabridge::LuaRef lua_dsp_map = luabridge::getGlobal (L, "dsp_runmap");
186
187         if ((lua_dsp_run.type () != LUA_TFUNCTION) == (lua_dsp_map.type () != LUA_TFUNCTION)) {
188                 return true;
189         }
190
191         if (lua_dsp_run.type () == LUA_TFUNCTION) {
192                 _lua_dsp = new luabridge::LuaRef (lua_dsp_run);
193         }
194         else if (lua_dsp_map.type () == LUA_TFUNCTION) {
195                 _lua_dsp = new luabridge::LuaRef (lua_dsp_map);
196                 _lua_does_channelmapping = true;
197         }
198         else {
199                 assert (0);
200         }
201
202         // initialize the DSP if needed
203         luabridge::LuaRef lua_dsp_init = luabridge::getGlobal (L, "dsp_init");
204         if (lua_dsp_init.type () == LUA_TFUNCTION) {
205                 try {
206                         lua_dsp_init (_session.nominal_frame_rate ());
207                 } catch (luabridge::LuaException const& e) {
208                         ;
209                 }
210         }
211
212         luabridge::LuaRef lua_dsp_midi_in = luabridge::getGlobal (L, "dsp_midi_input");
213         if (lua_dsp_midi_in.type () == LUA_TFUNCTION) {
214                 try {
215                         _has_midi_input = lua_dsp_midi_in ();
216                 } catch (luabridge::LuaException const& e) {
217                         ;
218                 }
219         }
220         lpi->_is_instrument = _has_midi_input;
221
222         _ctrl_params.clear ();
223
224         luabridge::LuaRef lua_render = luabridge::getGlobal (L, "render_inline");
225         if (lua_render.isFunction ()) {
226                 _lua_has_inline_display = true;
227         }
228
229         luabridge::LuaRef lua_params = luabridge::getGlobal (L, "dsp_params");
230         if (lua_params.isFunction ()) {
231
232                 // call function // add try {} catch (luabridge::LuaException const& e)
233                 luabridge::LuaRef params = lua_params ();
234
235                 if (params.isTable ()) {
236
237                         for (luabridge::Iterator i (params); !i.isNil (); ++i) {
238                                 // required fields
239                                 if (!i.key ().isNumber ())           { return false; }
240                                 if (!i.value ().isTable ())          { return false; }
241                                 if (!i.value ()["type"].isString ()) { return false; }
242                                 if (!i.value ()["name"].isString ()) { return false; }
243                                 if (!i.value ()["min"].isNumber ())  { return false; }
244                                 if (!i.value ()["max"].isNumber ())  { return false; }
245
246                                 int pn = i.key ().cast<int> ();
247                                 std::string type = i.value ()["type"].cast<std::string> ();
248                                 if (type == "input") {
249                                         if (!i.value ()["default"].isNumber ()) { return false; }
250                                         _ctrl_params.push_back (std::make_pair (false, pn));
251                                 }
252                                 else if (type == "output") {
253                                         _ctrl_params.push_back (std::make_pair (true, pn));
254                                 } else {
255                                         return false;
256                                 }
257                                 assert (pn == (int) _ctrl_params.size ());
258
259                                 //_param_desc[pn] = boost::shared_ptr<ParameterDescriptor> (new ParameterDescriptor());
260                                 luabridge::LuaRef lr = i.value ();
261
262                                 if (type == "input") {
263                                         _param_desc[pn].normal     = lr["default"].cast<float> ();
264                                 } else {
265                                         _param_desc[pn].normal     = lr["min"].cast<float> (); // output-port, no default
266                                 }
267                                 _param_desc[pn].lower        = lr["min"].cast<float> ();
268                                 _param_desc[pn].upper        = lr["max"].cast<float> ();
269                                 _param_desc[pn].toggled      = lr["toggled"].isBoolean () && (lr["toggled"]).cast<bool> ();
270                                 _param_desc[pn].logarithmic  = lr["logarithmic"].isBoolean () && (lr["logarithmic"]).cast<bool> ();
271                                 _param_desc[pn].integer_step = lr["integer"].isBoolean () && (lr["integer"]).cast<bool> ();
272                                 _param_desc[pn].sr_dependent = lr["ratemult"].isBoolean () && (lr["ratemult"]).cast<bool> ();
273                                 _param_desc[pn].enumeration  = lr["enum"].isBoolean () && (lr["enum"]).cast<bool> ();
274
275                                 if (lr["unit"].isString ()) {
276                                         std::string unit = lr["unit"].cast<std::string> ();
277                                         if (unit == "dB")             { _param_desc[pn].unit = ParameterDescriptor::DB; }
278                                         else if (unit == "Hz")        { _param_desc[pn].unit = ParameterDescriptor::HZ; }
279                                         else if (unit == "Midi Note") { _param_desc[pn].unit = ParameterDescriptor::MIDI_NOTE; }
280                                 }
281                                 _param_desc[pn].label        = (lr["name"]).cast<std::string> ();
282                                 _param_desc[pn].scale_points = parse_scale_points (&lr);
283
284                                 luabridge::LuaRef doc = lr["doc"];
285                                 if (doc.isString ()) {
286                                         _param_doc[pn] = doc.cast<std::string> ();
287                                 } else {
288                                         _param_doc[pn] = "";
289                                 }
290                                 assert (!(_param_desc[pn].toggled && _param_desc[pn].logarithmic));
291                         }
292                 }
293         }
294
295         _control_data = new float[parameter_count ()];
296         _shadow_data  = new float[parameter_count ()];
297
298         for (uint32_t i = 0; i < parameter_count (); ++i) {
299                 if (parameter_is_input (i)) {
300                         _control_data[i] = _shadow_data[i] = default_value (i);
301                 }
302         }
303
304         // expose ctrl-ports to global lua namespace
305         luabridge::push <float *> (L, _control_data);
306         lua_setglobal (L, "CtrlPorts");
307
308         return false; // no error
309 }
310
311 bool
312 LuaProc::can_support_io_configuration (const ChanCount& in, ChanCount& out, ChanCount* imprecise)
313 {
314         // caller must hold process lock (no concurrent calls to interpreter
315
316         if (in.n_midi() > 0 && !_has_midi_input && !imprecise) {
317                 return false;
318         }
319
320         lua_State* L = lua.getState ();
321         luabridge::LuaRef ioconfig = luabridge::getGlobal (L, "dsp_ioconfig");
322         if (!ioconfig.isFunction ()) {
323                 return false;
324         }
325
326         luabridge::LuaRef table = luabridge::getGlobal (L, "table"); //lua std lib
327         luabridge::LuaRef tablesort = table["sort"];
328         assert (tablesort.isFunction ());
329
330         luabridge::LuaRef *_iotable = NULL; // can't use reference :(
331         try {
332                 luabridge::LuaRef iotable = ioconfig ();
333                 tablesort (iotable);
334                 if (iotable.isTable ()) {
335                         _iotable = new luabridge::LuaRef (iotable);
336                 }
337         } catch (luabridge::LuaException const& e) {
338                 return false;
339         }
340
341         if (!_iotable) {
342                 return false;
343         }
344
345         // now we can reference it.
346         luabridge::LuaRef iotable (*_iotable);
347         delete _iotable;
348
349         if ((iotable).length () < 1) {
350                 return false;
351         }
352
353         const int32_t audio_in = in.n_audio ();
354         int32_t audio_out;
355         int32_t midi_out = 0; // TODO handle  _has_midi_output
356
357         if (in.n_midi() > 0 && audio_in == 0) {
358                 audio_out = 2; // prefer stereo version if available.
359         } else {
360                 audio_out = audio_in;
361         }
362
363
364         for (luabridge::Iterator i (iotable); !i.isNil (); ++i) {
365                 assert (i.value ().type () == LUA_TTABLE);
366                 luabridge::LuaRef io (i.value ());
367
368                 int possible_in = io["audio_in"];
369                 int possible_out = io["audio_out"];
370
371                 // exact match
372                 if ((possible_in == audio_in) && (possible_out == audio_out)) {
373                         out.set (DataType::MIDI, 0);
374                         out.set (DataType::AUDIO, audio_out);
375                         return true;
376                 }
377         }
378
379         /* now allow potentially "imprecise" matches */
380         audio_out = -1;
381         bool found = false;
382
383         for (luabridge::Iterator i (iotable); !i.isNil (); ++i) {
384                 assert (i.value ().type () == LUA_TTABLE);
385                 luabridge::LuaRef io (i.value ());
386
387                 int possible_in = io["audio_in"];
388                 int possible_out = io["audio_out"];
389
390                 if (possible_out == 0) {
391                         continue;
392                 }
393                 if (possible_in == 0) {
394                         /* no inputs, generators & instruments */
395                         if (possible_out == -1) {
396                                 /* any configuration possible, provide stereo output */
397                                 audio_out = 2;
398                                 found = true;
399                         } else if (possible_out == -2) {
400                                 /* invalid, should be (0, -1) */
401                                 audio_out = 2;
402                                 found = true;
403                         } else if (possible_out < -2) {
404                                 /* variable number of outputs. -> whatever */
405                                 audio_out = 2;
406                                 found = true;
407                         } else {
408                                 /* exact number of outputs */
409                                 audio_out = possible_out;
410                                 found = true;
411                         }
412                 }
413
414                 if (possible_in == -1) {
415                         /* wildcard for input */
416                         if (possible_out == -1) {
417                                 /* out must match in */
418                                 audio_out = audio_in;
419                                 found = true;
420                         } else if (possible_out == -2) {
421                                 /* any configuration possible, pick matching */
422                                 audio_out = audio_in;
423                                 found = true;
424                         } else if (possible_out < -2) {
425                                 /* explicitly variable number of outputs, pick maximum */
426                                 audio_out = -possible_out;
427                                 found = true;
428                         } else {
429                                 /* exact number of outputs */
430                                 audio_out = possible_out;
431                                 found = true;
432                         }
433                 }
434
435                 if (possible_in == -2) {
436
437                         if (possible_out == -1) {
438                                 /* any configuration possible, pick matching */
439                                 audio_out = audio_in;
440                                 found = true;
441                         } else if (possible_out == -2) {
442                                 /* invalid. interpret as (-1, -1) */
443                                 audio_out = audio_in;
444                                 found = true;
445                         } else if (possible_out < -2) {
446                                 /* explicitly variable number of outputs, pick maximum */
447                                 audio_out = -possible_out;
448                                 found = true;
449                         } else {
450                                 /* exact number of outputs */
451                                 audio_out = possible_out;
452                                 found = true;
453                         }
454                 }
455
456                 if (possible_in < -2) {
457                         /* explicit variable number of inputs */
458                         if (audio_in > -possible_in && imprecise != NULL) {
459                                 // hide inputs ports
460                                 imprecise->set (DataType::AUDIO, -possible_in);
461                         }
462
463                         if (audio_in > -possible_in && imprecise == NULL) {
464                                 /* request is too large */
465                         } else if (possible_out == -1) {
466                                 /* any output configuration possible, provide stereo out */
467                                 audio_out = 2;
468                                 found = true;
469                         } else if (possible_out == -2) {
470                                 /* invalid. interpret as (<-2, -1) */
471                                 audio_out = 2;
472                                 found = true;
473                         } else if (possible_out < -2) {
474                                 /* explicitly variable number of outputs, pick stereo */
475                                 audio_out = 2;
476                                 found = true;
477                         } else {
478                                 /* exact number of outputs */
479                                 audio_out = possible_out;
480                                 found = true;
481                         }
482                 }
483
484                 if (possible_in && (possible_in == audio_in)) {
485                         /* exact number of inputs ... must match obviously */
486                         if (possible_out == -1) {
487                                 /* any output configuration possible, provide stereo output */
488                                 audio_out = 2;
489                                 found = true;
490                         } else if (possible_out == -2) {
491                                 /* invalid. interpret as (>0, -1) */
492                                 audio_out = 2;
493                                 found = true;
494                         } else if (possible_out < -2) {
495                                 /* explicitly variable number of outputs, pick maximum */
496                                 audio_out = -possible_out;
497                                 found = true;
498                         } else {
499                                 /* exact number of outputs */
500                                 audio_out = possible_out;
501                                 found = true;
502                         }
503                 }
504
505                 if (found) {
506                         break;
507                 }
508         }
509
510         if (!found && imprecise) {
511                 /* try harder */
512                 for (luabridge::Iterator i (iotable); !i.isNil (); ++i) {
513                         assert (i.value ().type () == LUA_TTABLE);
514                         luabridge::LuaRef io (i.value ());
515
516                         int possible_in = io["audio_in"];
517                         int possible_out = io["audio_out"];
518
519                         assert (possible_in > 0); // all other cases will have been matched above
520                         assert (possible_out !=0 || possible_in !=0); // already handled above
521
522                         imprecise->set (DataType::AUDIO, possible_in);
523                         if (possible_out == -1 || possible_out == -2) {
524                                 audio_out = 2;
525                                 found = true;
526                         } else if (possible_out < -2) {
527                                 /* explicitly variable number of outputs, pick maximum */
528                                 audio_out = -possible_out;
529                                 found = true;
530                         } else {
531                                 /* exact number of outputs */
532                                 audio_out = possible_out;
533                                 found = true;
534                         }
535
536                         if (found) {
537                                 // ideally we'll keep iterating and take the "best match"
538                                 // whatever "best" means:
539                                 // least unconnected inputs, least silenced inputs,
540                                 // closest match of inputs == outputs
541                                 break;
542                         }
543                 }
544         }
545
546
547         if (!found) {
548                 return false;
549         }
550
551         out.set (DataType::MIDI, midi_out); // currently always zero
552         out.set (DataType::AUDIO, audio_out);
553         return true;
554 }
555
556 bool
557 LuaProc::configure_io (ChanCount in, ChanCount out)
558 {
559         _configured_in = in;
560         _configured_out = out;
561
562         _configured_in.set (DataType::MIDI, _has_midi_input ? 1 : 0);
563         _configured_out.set (DataType::MIDI, _has_midi_output ? 1 : 0);
564
565         // configure the DSP if needed
566         lua_State* L = lua.getState ();
567         luabridge::LuaRef lua_dsp_configure = luabridge::getGlobal (L, "dsp_configure");
568         if (lua_dsp_configure.type () == LUA_TFUNCTION) {
569                 try {
570                         lua_dsp_configure (&in, &out);
571                 } catch (luabridge::LuaException const& e) {
572                         return false;
573                 }
574         }
575
576         _info->n_inputs = _configured_in;
577         _info->n_outputs = _configured_out;
578         return true;
579 }
580
581 int
582 LuaProc::connect_and_run (BufferSet& bufs,
583                 ChanMapping in, ChanMapping out,
584                 pframes_t nframes, framecnt_t offset)
585 {
586         if (!_lua_dsp) {
587                 return 0;
588         }
589
590         Plugin::connect_and_run (bufs, in, out, nframes, offset);
591
592         // This is needed for ARDOUR::Session requests :(
593         if (! SessionEvent::has_per_thread_pool ()) {
594                 char name[64];
595                 snprintf (name, 64, "Proc-%p", this);
596                 pthread_set_name (name);
597                 SessionEvent::create_per_thread_pool (name, 64);
598                 PBD::notify_event_loops_about_thread_creation (pthread_self(), name, 64);
599         }
600
601         uint32_t const n = parameter_count ();
602         for (uint32_t i = 0; i < n; ++i) {
603                 if (parameter_is_control (i) && parameter_is_input (i)) {
604                         _control_data[i] = _shadow_data[i];
605                 }
606         }
607
608 #ifdef WITH_LUAPROC_STATS
609         int64_t t0 = g_get_monotonic_time ();
610 #endif
611
612         try {
613                 if (_lua_does_channelmapping) {
614                         // run the DSP function
615                         (*_lua_dsp)(&bufs, in, out, nframes, offset);
616                 } else {
617                         // map buffers
618                         BufferSet& silent_bufs  = _session.get_silent_buffers (ChanCount (DataType::AUDIO, 1));
619                         BufferSet& scratch_bufs = _session.get_scratch_buffers (ChanCount (DataType::AUDIO, 1));
620
621                         lua_State* L = lua.getState ();
622                         luabridge::LuaRef in_map (luabridge::newTable (L));
623                         luabridge::LuaRef out_map (luabridge::newTable (L));
624
625                         const uint32_t audio_in = _configured_in.n_audio ();
626                         const uint32_t audio_out = _configured_out.n_audio ();
627                         const uint32_t midi_in = _configured_in.n_midi ();
628
629                         for (uint32_t ap = 0; ap < audio_in; ++ap) {
630                                 bool valid;
631                                 const uint32_t buf_index = in.get(DataType::AUDIO, ap, &valid);
632                                 if (valid) {
633                                         in_map[ap + 1] = bufs.get_audio (buf_index).data (offset);
634                                 } else {
635                                         in_map[ap + 1] = silent_bufs.get_audio (0).data (offset);
636                                 }
637                         }
638                         for (uint32_t ap = 0; ap < audio_out; ++ap) {
639                                 bool valid;
640                                 const uint32_t buf_index = out.get(DataType::AUDIO, ap, &valid);
641                                 if (valid) {
642                                         out_map[ap + 1] = bufs.get_audio (buf_index).data (offset);
643                                 } else {
644                                         out_map[ap + 1] = scratch_bufs.get_audio (0).data (offset);
645                                 }
646                         }
647
648                         luabridge::LuaRef lua_midi_tbl (luabridge::newTable (L));
649                         int e = 1; // > 1 port, we merge events (unsorted)
650                         for (uint32_t mp = 0; mp < midi_in; ++mp) {
651                                 bool valid;
652                                 const uint32_t idx = in.get(DataType::MIDI, mp, &valid);
653                                 if (valid) {
654                                         for (MidiBuffer::iterator m = bufs.get_midi(idx).begin();
655                                                         m != bufs.get_midi(idx).end(); ++m, ++e) {
656                                                 const Evoral::MIDIEvent<framepos_t> ev(*m, false);
657                                                 luabridge::LuaRef lua_midi_data (luabridge::newTable (L));
658                                                 const uint8_t* data = ev.buffer();
659                                                 for (uint32_t i = 0; i < ev.size(); ++i) {
660                                                         lua_midi_data [i + 1] = data[i];
661                                                 }
662                                                 luabridge::LuaRef lua_midi_event (luabridge::newTable (L));
663                                                 lua_midi_event["time"] = 1 + (*m).time();
664                                                 lua_midi_event["data"] = lua_midi_data;
665                                                 lua_midi_tbl[e] = lua_midi_event;
666                                         }
667                                 }
668                         }
669
670                         if (_has_midi_input) {
671                                 // XXX TODO This needs a better solution than global namespace
672                                 luabridge::push (L, lua_midi_tbl);
673                                 lua_setglobal (L, "mididata");
674                         }
675
676
677                         // run the DSP function
678                         (*_lua_dsp)(in_map, out_map, nframes);
679                 }
680         } catch (luabridge::LuaException const& e) {
681 #ifndef NDEBUG
682                 printf ("LuaException: %s\n", e.what ());
683 #endif
684                 return -1;
685         }
686 #ifdef WITH_LUAPROC_STATS
687         int64_t t1 = g_get_monotonic_time ();
688 #endif
689         lua.collect_garbage (); // rt-safe, slight *regular* performance overhead
690 #ifdef WITH_LUAPROC_STATS
691         ++_stats_cnt;
692         int64_t t2 = g_get_monotonic_time ();
693         int64_t ela0 = t1 - t0;
694         int64_t ela1 = t2 - t1;
695         if (ela0 > _stats_max[0]) _stats_max[0] = ela0;
696         if (ela1 > _stats_max[1]) _stats_max[1] = ela1;
697         _stats_avg[0] += ela0;
698         _stats_avg[1] += ela1;
699 #endif
700         return 0;
701 }
702
703
704 void
705 LuaProc::add_state (XMLNode* root) const
706 {
707         XMLNode*    child;
708         char        buf[32];
709         LocaleGuard lg(X_("C"));
710
711         gchar* b64 = g_base64_encode ((const guchar*)_script.c_str (), _script.size ());
712         std::string b64s (b64);
713         g_free (b64);
714         XMLNode* script_node = new XMLNode (X_("script"));
715         script_node->add_property (X_("lua"), LUA_VERSION);
716         script_node->add_content (b64s);
717         root->add_child_nocopy (*script_node);
718
719         for (uint32_t i = 0; i < parameter_count(); ++i) {
720                 if (parameter_is_input(i) && parameter_is_control(i)) {
721                         child = new XMLNode("Port");
722                         snprintf(buf, sizeof(buf), "%u", i);
723                         child->add_property("id", std::string(buf));
724                         snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]);
725                         child->add_property("value", std::string(buf));
726                         root->add_child_nocopy(*child);
727                 }
728         }
729 }
730
731 int
732 LuaProc::set_script_from_state (const XMLNode& node)
733 {
734         XMLNode* child;
735         if (node.name () != state_node_name ()) {
736                 return -1;
737         }
738
739         if ((child = node.child (X_("script"))) != 0) {
740                 for (XMLNodeList::const_iterator n = child->children ().begin (); n != child->children ().end (); ++n) {
741                         if (!(*n)->is_content ()) { continue; }
742                         gsize size;
743                         guchar* buf = g_base64_decode ((*n)->content ().c_str (), &size);
744                         _script = std::string ((const char*)buf, size);
745                         g_free (buf);
746                         if (load_script ()) {
747                                 PBD::error << _("Failed to load Lua script from session state.") << endmsg;
748 #ifndef NDEBUG
749                                 std::cerr << "Failed Lua Script: " << _script << std::endl;
750 #endif
751                                 _script = "";
752                         }
753                         break;
754                 }
755         }
756         if (_script.empty ()) {
757                 PBD::error << _("Session State for LuaProcessor did not include a Lua script.") << endmsg;
758                 return -1;
759         }
760         if (!_lua_dsp) {
761                 PBD::error << _("Invalid/incompatible Lua script found for LuaProcessor.") << endmsg;
762                 return -1;
763         }
764         return 0;
765 }
766
767 int
768 LuaProc::set_state (const XMLNode& node, int version)
769 {
770 #ifndef NO_PLUGIN_STATE
771         XMLNodeList nodes;
772         XMLProperty *prop;
773         XMLNodeConstIterator iter;
774         XMLNode *child;
775         const char *value;
776         const char *port;
777         uint32_t port_id;
778 #endif
779         LocaleGuard lg (X_("C"));
780
781         if (_script.empty ()) {
782                 if (set_script_from_state (node)) {
783                         return -1;
784                 }
785         }
786
787 #ifndef NO_PLUGIN_STATE
788         if (node.name() != state_node_name()) {
789                 error << _("Bad node sent to LuaProc::set_state") << endmsg;
790                 return -1;
791         }
792
793         nodes = node.children ("Port");
794         for (iter = nodes.begin(); iter != nodes.end(); ++iter) {
795                 child = *iter;
796                 if ((prop = child->property("id")) != 0) {
797                         port = prop->value().c_str();
798                 } else {
799                         warning << _("LuaProc: port has no symbol, ignored") << endmsg;
800                         continue;
801                 }
802                 if ((prop = child->property("value")) != 0) {
803                         value = prop->value().c_str();
804                 } else {
805                         warning << _("LuaProc: port has no value, ignored") << endmsg;
806                         continue;
807                 }
808                 sscanf (port, "%" PRIu32, &port_id);
809                 set_parameter (port_id, atof(value));
810         }
811 #endif
812
813         return Plugin::set_state (node, version);
814 }
815
816 uint32_t
817 LuaProc::parameter_count () const
818 {
819         return _ctrl_params.size ();
820 }
821
822 float
823 LuaProc::default_value (uint32_t port)
824 {
825         if (_ctrl_params[port].first) {
826                 assert (0);
827                 return 0;
828         }
829         int lp = _ctrl_params[port].second;
830         return _param_desc[lp].normal;
831 }
832
833 void
834 LuaProc::set_parameter (uint32_t port, float val)
835 {
836         assert (port < parameter_count ());
837         if (get_parameter (port) == val) {
838                 return;
839         }
840         _shadow_data[port] = val;
841         Plugin::set_parameter (port, val);
842 }
843
844 float
845 LuaProc::get_parameter (uint32_t port) const
846 {
847         if (parameter_is_input (port)) {
848                 return _shadow_data[port];
849         } else {
850                 return _control_data[port];
851         }
852 }
853
854 int
855 LuaProc::get_parameter_descriptor (uint32_t port, ParameterDescriptor& desc) const
856 {
857         assert (port <= parameter_count ());
858         int lp = _ctrl_params[port].second;
859         const ParameterDescriptor& d (_param_desc.find(lp)->second);
860
861         desc.lower        = d.lower;
862         desc.upper        = d.upper;
863         desc.normal       = d.normal;
864         desc.toggled      = d.toggled;
865         desc.logarithmic  = d.logarithmic;
866         desc.integer_step = d.integer_step;
867         desc.sr_dependent = d.sr_dependent;
868         desc.enumeration  = d.enumeration;
869         desc.unit         = d.unit;
870         desc.label        = d.label;
871         desc.scale_points = d.scale_points;
872
873         desc.update_steps ();
874         return 0;
875 }
876
877 std::string
878 LuaProc::get_parameter_docs (uint32_t port) const {
879         assert (port <= parameter_count ());
880         int lp = _ctrl_params[port].second;
881         return _param_doc.find(lp)->second;
882 }
883
884 uint32_t
885 LuaProc::nth_parameter (uint32_t port, bool& ok) const
886 {
887         if (port < _ctrl_params.size ()) {
888                 ok = true;
889                 return port;
890         }
891         ok = false;
892         return 0;
893 }
894
895 bool
896 LuaProc::parameter_is_input (uint32_t port) const
897 {
898         assert (port < _ctrl_params.size ());
899         return (!_ctrl_params[port].first);
900 }
901
902 bool
903 LuaProc::parameter_is_output (uint32_t port) const
904 {
905         assert (port < _ctrl_params.size ());
906         return (_ctrl_params[port].first);
907 }
908
909 std::set<Evoral::Parameter>
910 LuaProc::automatable () const
911 {
912         std::set<Evoral::Parameter> automatables;
913         for (uint32_t i = 0; i < _ctrl_params.size (); ++i) {
914                 if (parameter_is_input (i)) {
915                         automatables.insert (automatables.end (), Evoral::Parameter (PluginAutomation, 0, i));
916                 }
917         }
918         return automatables;
919 }
920
921 std::string
922 LuaProc::describe_parameter (Evoral::Parameter param)
923 {
924         if (param.type () == PluginAutomation && param.id () < parameter_count ()) {
925                 int lp = _ctrl_params[param.id ()].second;
926                 return _param_desc[lp].label;
927         }
928         return "??";
929 }
930
931 void
932 LuaProc::print_parameter (uint32_t param, char* buf, uint32_t len) const
933 {
934         if (buf && len) {
935                 if (param < parameter_count ()) {
936                         snprintf (buf, len, "%.3f", get_parameter (param));
937                 } else {
938                         strcat (buf, "0");
939                 }
940         }
941 }
942
943 boost::shared_ptr<ScalePoints>
944 LuaProc::parse_scale_points (luabridge::LuaRef* lr)
945 {
946         if (!(*lr)["scalepoints"].isTable()) {
947                 return boost::shared_ptr<ScalePoints> ();
948         }
949
950         int cnt = 0;
951         boost::shared_ptr<ScalePoints> rv = boost::shared_ptr<ScalePoints>(new ScalePoints());
952         luabridge::LuaRef scalepoints ((*lr)["scalepoints"]);
953
954         for (luabridge::Iterator i (scalepoints); !i.isNil (); ++i) {
955                 if (!i.key ().isString ())    { continue; }
956                 if (!i.value ().isNumber ())  { continue; }
957                 rv->insert(make_pair(i.key ().cast<std::string> (),
958                                         i.value ().cast<float> ()));
959                 ++cnt;
960         }
961
962         if (rv->size() > 0) {
963                 return rv;
964         }
965         return boost::shared_ptr<ScalePoints> ();
966 }
967
968 boost::shared_ptr<ScalePoints>
969 LuaProc::get_scale_points (uint32_t port) const
970 {
971         int lp = _ctrl_params[port].second;
972         return _param_desc.find(lp)->second.scale_points;
973 }
974
975 void
976 LuaProc::setup_lua_inline_gui (LuaState *lua_gui)
977 {
978         lua_State* LG = lua_gui->getState ();
979         LuaBindings::stddef (LG);
980         LuaBindings::common (LG);
981         LuaBindings::dsp (LG);
982
983 #ifndef NDEBUG
984         lua_gui->Print.connect (sigc::mem_fun (*this, &LuaProc::lua_print));
985 #endif
986
987         lua_gui->do_command ("function ardour () end");
988         lua_gui->do_command (_script);
989
990         // TODO think: use a weak-pointer here ?
991         // (the GUI itself uses a shared ptr to this plugin, so we should be good)
992         luabridge::getGlobalNamespace (LG)
993                 .beginNamespace ("Ardour")
994                 .beginClass <LuaProc> ("LuaProc")
995                 .addFunction ("shmem", &LuaProc::instance_shm)
996                 .endClass ()
997                 .endNamespace ();
998
999         luabridge::push <LuaProc *> (LG, this);
1000         lua_setglobal (LG, "self");
1001
1002         luabridge::push <float *> (LG, _shadow_data);
1003         lua_setglobal (LG, "CtrlPorts");
1004 }
1005
1006 ////////////////////////////////////////////////////////////////////////////////
1007 #include <glibmm/miscutils.h>
1008 #include <glibmm/fileutils.h>
1009
1010 LuaPluginInfo::LuaPluginInfo (LuaScriptInfoPtr lsi) {
1011         if (lsi->type != LuaScriptInfo::DSP) {
1012                 throw failed_constructor ();
1013         }
1014
1015         path = lsi->path;
1016         name = lsi->name;
1017         creator = lsi->author;
1018         category = lsi->category;
1019         unique_id = "luascript"; // the interpreter is not unique.
1020
1021         n_inputs.set (DataType::AUDIO, 1);
1022         n_outputs.set (DataType::AUDIO, 1);
1023         type = Lua;
1024 }
1025
1026 PluginPtr
1027 LuaPluginInfo::load (Session& session)
1028 {
1029         std::string script = "";
1030         if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
1031                 return PluginPtr ();
1032         }
1033
1034         try {
1035                 script = Glib::file_get_contents (path);
1036         } catch (Glib::FileError err) {
1037                 return PluginPtr ();
1038         }
1039
1040         if (script.empty ()) {
1041                 return PluginPtr ();
1042         }
1043
1044         try {
1045                 PluginPtr plugin (new LuaProc (session.engine (), session, script));
1046                 return plugin;
1047         } catch (failed_constructor& err) {
1048                 ;
1049         }
1050         return PluginPtr ();
1051 }
1052
1053 std::vector<Plugin::PresetRecord>
1054 LuaPluginInfo::get_presets (bool /*user_only*/) const
1055 {
1056         std::vector<Plugin::PresetRecord> p;
1057         return p;
1058 }