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