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