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