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