Remove dsp_has_midi_*() in favor of dsp_ioconfig()
[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         if (!ioconfig.isFunction ()) {
333                 return false;
334         }
335
336         luabridge::LuaRef *_iotable = NULL; // can't use reference :(
337         try {
338                 luabridge::LuaRef iotable = ioconfig ();
339                 if (iotable.isTable ()) {
340                         _iotable = new luabridge::LuaRef (iotable);
341                 }
342         } catch (luabridge::LuaException const& e) {
343                 return false;
344         }
345
346         if (!_iotable) {
347                 return false;
348         }
349
350         // now we can reference it.
351         luabridge::LuaRef iotable (*_iotable);
352         delete _iotable;
353
354         if ((iotable).length () < 1) {
355                 return false;
356         }
357
358         const int audio_in = in.n_audio ();
359         const int midi_in = in.n_midi ();
360
361         // preferred setting (provided by plugin_insert)
362         const int preferred_out = out.n_audio ();
363         const int preferred_midiout = out.n_midi ();
364
365         int midi_out = -1;
366         int audio_out = -1;
367         float penalty = 9999;
368         bool found = false;
369
370 #define FOUNDCFG_PENALTY(in, out, p) {                              \
371   _output_configs.insert (out);                                     \
372   if (p < penalty) {                                                \
373     audio_out = (out);                                              \
374     midi_out = possible_midiout;                                    \
375     if (imprecise) {                                                \
376       imprecise->set (DataType::AUDIO, (in));                       \
377       imprecise->set (DataType::MIDI, possible_midiin);             \
378     }                                                               \
379     _has_midi_input = (possible_midiin > 0);                        \
380     _has_midi_output = (possible_midiout > 0);                      \
381     penalty = p;                                                    \
382     found = true;                                                   \
383   }                                                                 \
384 }
385
386 #define FOUNDCFG_IMPRECISE(in, out) {                               \
387   const float p = fabsf ((float)(out) - preferred_out) *            \
388                       (((out) > preferred_out) ? 1.1 : 1)           \
389                 + fabsf ((float)possible_midiout - preferred_midiout) *    \
390                       ((possible_midiout - preferred_midiout) ? 0.6 : 0.5) \
391                 + fabsf ((float)(in) - audio_in) *                  \
392                       (((in) > audio_in) ? 275 : 250)               \
393                 + fabsf ((float)possible_midiin - midi_in) *        \
394                       ((possible_midiin - midi_in) ? 100 : 110);    \
395   FOUNDCFG_PENALTY(in, out, p);                                     \
396 }
397
398 #define FOUNDCFG(out)                                               \
399   FOUNDCFG_IMPRECISE(audio_in, out)
400
401 #define ANYTHINGGOES                                                \
402   _output_configs.insert (0);
403
404 #define UPTO(nch) {                                                 \
405   for (int n = 1; n < nch; ++n) {                                   \
406     _output_configs.insert (n);                                     \
407   }                                                                 \
408 }
409
410         if (imprecise) {
411                 *imprecise = in;
412         }
413
414         for (luabridge::Iterator i (iotable); !i.isNil (); ++i) {
415                 luabridge::LuaRef io (i.value ());
416                 if (!io.isTable()) {
417                         continue;
418                 }
419
420                 int possible_in = io["audio_in"].isNumber() ? io["audio_in"] : -1;
421                 int possible_out = io["audio_out"].isNumber() ? io["audio_out"] : -1;
422                 int possible_midiin = io["midi_in"].isNumber() ? io["midi_in"] : 0;
423                 int possible_midiout = io["midi_out"].isNumber() ? io["midi_out"] : 0;
424
425                 if (midi_in != possible_midiin && !imprecise) {
426                         continue;
427                 }
428
429                 // exact match
430                 if ((possible_in == audio_in) && (possible_out == preferred_out)) {
431                         /* Set penalty so low that this output configuration
432                          * will trump any other one */
433                         FOUNDCFG_PENALTY(audio_in, preferred_out, -1);
434                 }
435
436                 if (possible_out == 0 && possible_midiout == 0) {
437                         /* skip configurations with no output at all */
438                         continue;
439                 }
440
441                 if (possible_in == -1 || possible_in == -2) {
442                         /* wildcard for input */
443                         if (possible_out == possible_in) {
444                                 /* either both -1 or both -2 (invalid and
445                                  * interpreted as both -1): out must match in */
446                                 FOUNDCFG (audio_in);
447                         } else if (possible_out == -3 - possible_in) {
448                                 /* one is -1, the other is -2: any output configuration
449                                  * possible, pick what the insert prefers */
450                                 FOUNDCFG (preferred_out);
451                                 ANYTHINGGOES;
452                         } else if (possible_out < -2) {
453                                 /* variable number of outputs up to -N,
454                                  * invalid if in == -2 but we accept it anyway */
455                                 FOUNDCFG (min (-possible_out, preferred_out));
456                                 UPTO (-possible_out)
457                         } else {
458                                 /* exact number of outputs */
459                                 FOUNDCFG (possible_out);
460                         }
461                 }
462
463                 if (possible_in < -2 || possible_in >= 0) {
464                         /* specified number, exact or up to */
465                         int desired_in;
466                         if (possible_in >= 0) {
467                                 /* configuration can only match possible_in */
468                                 desired_in = possible_in;
469                         } else {
470                                 /* configuration can match up to -possible_in */
471                                 desired_in = min (-possible_in, audio_in);
472                         }
473                         if (!imprecise && audio_in != desired_in) {
474                                 /* skip that configuration, it cannot match
475                                  * the required audio input count, and we
476                                  * cannot ask for change via \imprecise */
477                         } else if (possible_out == -1 || possible_out == -2) {
478                                 /* any output configuration possible
479                                  * out == -2 is invalid, interpreted as out == -1.
480                                  * Really imprecise only if desired_in != audio_in */
481                                 FOUNDCFG_IMPRECISE (desired_in, preferred_out);
482                                 ANYTHINGGOES;
483                         } else if (possible_out < -2) {
484                                 /* variable number of outputs up to -N
485                                  * not specified if in > 0, but we accept it anyway.
486                                  * Really imprecise only if desired_in != audio_in */
487                                 FOUNDCFG_IMPRECISE (desired_in, min (-possible_out, preferred_out));
488                                 UPTO (-possible_out)
489                         } else {
490                                 /* exact number of outputs
491                                  * Really imprecise only if desired_in != audio_in */
492                                 FOUNDCFG_IMPRECISE (desired_in, possible_out);
493                         }
494                         // ideally we'll also find the closest, best matching
495                         // input configuration with minimal output penalty...
496                 }
497
498         }
499
500         if (!found) {
501                 return false;
502         }
503
504         if (imprecise) {
505                 _selected_in = *imprecise;
506         } else {
507                 _selected_in = in;
508         }
509
510         out.set (DataType::MIDI, midi_out);
511         out.set (DataType::AUDIO, audio_out);
512         _selected_out = out;
513
514         return true;
515 }
516
517 bool
518 LuaProc::configure_io (ChanCount in, ChanCount out)
519 {
520         in.set (DataType::MIDI, _has_midi_input ? 1 : 0);
521         out.set (DataType::MIDI, _has_midi_output ? 1 : 0);
522
523         _info->n_inputs = _selected_in;
524         _info->n_outputs = _selected_out;
525
526         // configure the DSP if needed
527         if (in != _configured_in || out != _configured_out) {
528                 lua_State* L = lua.getState ();
529                 luabridge::LuaRef lua_dsp_configure = luabridge::getGlobal (L, "dsp_configure");
530                 if (lua_dsp_configure.type () == LUA_TFUNCTION) {
531                         try {
532                                 luabridge::LuaRef io = lua_dsp_configure (&in, &out);
533                                 if (io.isTable ()) {
534                                         ChanCount lin (_selected_in);
535                                         ChanCount lout (_selected_out);
536
537                                         if (io["audio_in"].type() == LUA_TNUMBER) {
538                                                 const int c = io["audio_in"].cast<int> ();
539                                                 if (c >= 0) {
540                                                         lin.set (DataType::AUDIO, c);
541                                                 }
542                                         }
543                                         if (io["audio_out"].type() == LUA_TNUMBER) {
544                                                 const int c = io["audio_out"].cast<int> ();
545                                                 if (c >= 0) {
546                                                         lout.set (DataType::AUDIO, c);
547                                                 }
548                                         }
549                                         if (io["midi_in"].type() == LUA_TNUMBER) {
550                                                 const int c = io["midi_in"].cast<int> ();
551                                                 if (c >= 0) {
552                                                         lin.set (DataType::MIDI, c);
553                                                 }
554                                         }
555                                         if (io["midi_out"].type() == LUA_TNUMBER) {
556                                                 const int c = io["midi_out"].cast<int> ();
557                                                 if (c >= 0) {
558                                                         lout.set (DataType::MIDI, c);
559                                                 }
560                                         }
561                                         _info->n_inputs = lin;
562                                         _info->n_outputs = lout;
563                                 }
564                         } catch (luabridge::LuaException const& e) {
565                                 PBD::error << "LuaException: " << e.what () << "\n";
566 #ifndef NDEBUG
567                                 std::cerr << "LuaException: " << e.what () << "\n";
568 #endif
569                                 return false;
570                         }
571                 }
572         }
573
574         _configured_in = in;
575         _configured_out = out;
576
577         return true;
578 }
579
580 int
581 LuaProc::connect_and_run (BufferSet& bufs,
582                 framepos_t start, framepos_t end, double speed,
583                 ChanMapping in, ChanMapping out,
584                 pframes_t nframes, framecnt_t offset)
585 {
586         if (!_lua_dsp) {
587                 return 0;
588         }
589
590         Plugin::connect_and_run (bufs, start, end, speed, in, out, nframes, offset);
591
592         // This is needed for ARDOUR::Session requests :(
593         if (! SessionEvent::has_per_thread_pool ()) {
594                 char name[64];
595                 snprintf (name, 64, "Proc-%p", this);
596                 pthread_set_name (name);
597                 SessionEvent::create_per_thread_pool (name, 64);
598                 PBD::notify_event_loops_about_thread_creation (pthread_self(), name, 64);
599         }
600
601         uint32_t const n = parameter_count ();
602         for (uint32_t i = 0; i < n; ++i) {
603                 if (parameter_is_control (i) && parameter_is_input (i)) {
604                         _control_data[i] = _shadow_data[i];
605                 }
606         }
607
608 #ifdef WITH_LUAPROC_STATS
609         int64_t t0 = g_get_monotonic_time ();
610 #endif
611
612         try {
613                 if (_lua_does_channelmapping) {
614                         // run the DSP function
615                         (*_lua_dsp)(&bufs, in, out, nframes, offset);
616                 } else {
617                         // map buffers
618                         BufferSet& silent_bufs  = _session.get_silent_buffers (ChanCount (DataType::AUDIO, 1));
619                         BufferSet& scratch_bufs = _session.get_scratch_buffers (ChanCount (DataType::AUDIO, 1));
620
621                         lua_State* L = lua.getState ();
622                         luabridge::LuaRef in_map (luabridge::newTable (L));
623                         luabridge::LuaRef out_map (luabridge::newTable (L));
624
625                         const uint32_t audio_in = _configured_in.n_audio ();
626                         const uint32_t audio_out = _configured_out.n_audio ();
627                         const uint32_t midi_in = _configured_in.n_midi ();
628
629                         for (uint32_t ap = 0; ap < audio_in; ++ap) {
630                                 bool valid;
631                                 const uint32_t buf_index = in.get(DataType::AUDIO, ap, &valid);
632                                 if (valid) {
633                                         in_map[ap + 1] = bufs.get_audio (buf_index).data (offset);
634                                 } else {
635                                         in_map[ap + 1] = silent_bufs.get_audio (0).data (offset);
636                                 }
637                         }
638                         for (uint32_t ap = 0; ap < audio_out; ++ap) {
639                                 bool valid;
640                                 const uint32_t buf_index = out.get(DataType::AUDIO, ap, &valid);
641                                 if (valid) {
642                                         out_map[ap + 1] = bufs.get_audio (buf_index).data (offset);
643                                 } else {
644                                         out_map[ap + 1] = scratch_bufs.get_audio (0).data (offset);
645                                 }
646                         }
647
648                         luabridge::LuaRef lua_midi_src_tbl (luabridge::newTable (L));
649                         int e = 1; // > 1 port, we merge events (unsorted)
650                         for (uint32_t mp = 0; mp < midi_in; ++mp) {
651                                 bool valid;
652                                 const uint32_t idx = in.get(DataType::MIDI, mp, &valid);
653                                 if (valid) {
654                                         for (MidiBuffer::iterator m = bufs.get_midi(idx).begin();
655                                                         m != bufs.get_midi(idx).end(); ++m, ++e) {
656                                                 const Evoral::MIDIEvent<framepos_t> ev(*m, false);
657                                                 luabridge::LuaRef lua_midi_data (luabridge::newTable (L));
658                                                 const uint8_t* data = ev.buffer();
659                                                 for (uint32_t i = 0; i < ev.size(); ++i) {
660                                                         lua_midi_data [i + 1] = data[i];
661                                                 }
662                                                 luabridge::LuaRef lua_midi_event (luabridge::newTable (L));
663                                                 lua_midi_event["time"] = 1 + (*m).time();
664                                                 lua_midi_event["data"] = lua_midi_data;
665                                                 lua_midi_src_tbl[e] = lua_midi_event;
666                                         }
667                                 }
668                         }
669
670                         if (_has_midi_input) {
671                                 // XXX TODO This needs a better solution than global namespace
672                                 luabridge::push (L, lua_midi_src_tbl);
673                                 lua_setglobal (L, "midiin");
674                         }
675
676                         luabridge::LuaRef lua_midi_sink_tbl (luabridge::newTable (L));
677                         if (_has_midi_output) {
678                                 luabridge::push (L, lua_midi_sink_tbl);
679                                 lua_setglobal (L, "midiout");
680                         }
681
682                         // run the DSP function
683                         (*_lua_dsp)(in_map, out_map, nframes);
684
685                         // copy back midi events
686                         if (_has_midi_output && lua_midi_sink_tbl.isTable ()) {
687                                 bool valid;
688                                 const uint32_t idx = out.get(DataType::MIDI, 0, &valid);
689                                 if (valid && bufs.count().n_midi() > idx) {
690                                         MidiBuffer& mbuf = bufs.get_midi(idx);
691                                         mbuf.silence(0, 0);
692                                         for (luabridge::Iterator i (lua_midi_sink_tbl); !i.isNil (); ++i) {
693                                                 if (!i.key ().isNumber ()) { continue; }
694                                                 if (!i.value ()["time"].isNumber ()) { continue; }
695                                                 if (!i.value ()["data"].isTable ()) { continue; }
696                                                 luabridge::LuaRef data_tbl (i.value ()["data"]);
697                                                 framepos_t tme = i.value ()["time"];
698                                                 if (tme < 1 || tme > nframes) { continue; }
699                                                 uint8_t data[64];
700                                                 size_t size = 0;
701                                                 for (luabridge::Iterator di (data_tbl); !di.isNil () && size < sizeof(data); ++di, ++size) {
702                                                         data[size] = di.value ();
703                                                 }
704                                                 if (size > 0 && size < 64) {
705                                                         mbuf.push_back(tme - 1, size, data);
706                                                 }
707                                         }
708
709                                 }
710                         }
711                 }
712         } catch (luabridge::LuaException const& e) {
713                 PBD::error << "LuaException: " << e.what () << "\n";
714 #ifndef NDEBUG
715                 std::cerr << "LuaException: " << e.what () << "\n";
716 #endif
717                 return -1;
718         }
719 #ifdef WITH_LUAPROC_STATS
720         int64_t t1 = g_get_monotonic_time ();
721 #endif
722
723         lua.collect_garbage_step ();
724 #ifdef WITH_LUAPROC_STATS
725         ++_stats_cnt;
726         int64_t t2 = g_get_monotonic_time ();
727         int64_t ela0 = t1 - t0;
728         int64_t ela1 = t2 - t1;
729         if (ela0 > _stats_max[0]) _stats_max[0] = ela0;
730         if (ela1 > _stats_max[1]) _stats_max[1] = ela1;
731         _stats_avg[0] += ela0;
732         _stats_avg[1] += ela1;
733 #endif
734         return 0;
735 }
736
737
738 void
739 LuaProc::add_state (XMLNode* root) const
740 {
741         XMLNode*    child;
742         char        buf[32];
743         LocaleGuard lg;
744
745         gchar* b64 = g_base64_encode ((const guchar*)_script.c_str (), _script.size ());
746         std::string b64s (b64);
747         g_free (b64);
748         XMLNode* script_node = new XMLNode (X_("script"));
749         script_node->add_property (X_("lua"), LUA_VERSION);
750         script_node->add_content (b64s);
751         root->add_child_nocopy (*script_node);
752
753         for (uint32_t i = 0; i < parameter_count(); ++i) {
754                 if (parameter_is_input(i) && parameter_is_control(i)) {
755                         child = new XMLNode("Port");
756                         snprintf(buf, sizeof(buf), "%u", i);
757                         child->add_property("id", std::string(buf));
758                         snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]);
759                         child->add_property("value", std::string(buf));
760                         root->add_child_nocopy(*child);
761                 }
762         }
763 }
764
765 int
766 LuaProc::set_script_from_state (const XMLNode& node)
767 {
768         XMLNode* child;
769         if (node.name () != state_node_name ()) {
770                 return -1;
771         }
772
773         if ((child = node.child (X_("script"))) != 0) {
774                 for (XMLNodeList::const_iterator n = child->children ().begin (); n != child->children ().end (); ++n) {
775                         if (!(*n)->is_content ()) { continue; }
776                         gsize size;
777                         guchar* buf = g_base64_decode ((*n)->content ().c_str (), &size);
778                         _script = std::string ((const char*)buf, size);
779                         g_free (buf);
780                         if (load_script ()) {
781                                 PBD::error << _("Failed to load Lua script from session state.") << endmsg;
782 #ifndef NDEBUG
783                                 std::cerr << "Failed Lua Script: " << _script << std::endl;
784 #endif
785                                 _script = "";
786                         }
787                         break;
788                 }
789         }
790         if (_script.empty ()) {
791                 PBD::error << _("Session State for LuaProcessor did not include a Lua script.") << endmsg;
792                 return -1;
793         }
794         if (!_lua_dsp) {
795                 PBD::error << _("Invalid/incompatible Lua script found for LuaProcessor.") << endmsg;
796                 return -1;
797         }
798         return 0;
799 }
800
801 int
802 LuaProc::set_state (const XMLNode& node, int version)
803 {
804 #ifndef NO_PLUGIN_STATE
805         XMLNodeList nodes;
806         XMLProperty const * prop;
807         XMLNodeConstIterator iter;
808         XMLNode *child;
809         const char *value;
810         const char *port;
811         uint32_t port_id;
812 #endif
813         LocaleGuard lg;
814
815         if (_script.empty ()) {
816                 if (set_script_from_state (node)) {
817                         return -1;
818                 }
819         }
820
821 #ifndef NO_PLUGIN_STATE
822         if (node.name() != state_node_name()) {
823                 error << _("Bad node sent to LuaProc::set_state") << endmsg;
824                 return -1;
825         }
826
827         nodes = node.children ("Port");
828         for (iter = nodes.begin(); iter != nodes.end(); ++iter) {
829                 child = *iter;
830                 if ((prop = child->property("id")) != 0) {
831                         port = prop->value().c_str();
832                 } else {
833                         warning << _("LuaProc: port has no symbol, ignored") << endmsg;
834                         continue;
835                 }
836                 if ((prop = child->property("value")) != 0) {
837                         value = prop->value().c_str();
838                 } else {
839                         warning << _("LuaProc: port has no value, ignored") << endmsg;
840                         continue;
841                 }
842                 sscanf (port, "%" PRIu32, &port_id);
843                 set_parameter (port_id, atof(value));
844         }
845 #endif
846
847         return Plugin::set_state (node, version);
848 }
849
850 uint32_t
851 LuaProc::parameter_count () const
852 {
853         return _ctrl_params.size ();
854 }
855
856 float
857 LuaProc::default_value (uint32_t port)
858 {
859         if (_ctrl_params[port].first) {
860                 assert (0);
861                 return 0;
862         }
863         int lp = _ctrl_params[port].second;
864         return _param_desc[lp].normal;
865 }
866
867 void
868 LuaProc::set_parameter (uint32_t port, float val)
869 {
870         assert (port < parameter_count ());
871         if (get_parameter (port) == val) {
872                 return;
873         }
874         _shadow_data[port] = val;
875         Plugin::set_parameter (port, val);
876 }
877
878 float
879 LuaProc::get_parameter (uint32_t port) const
880 {
881         if (parameter_is_input (port)) {
882                 return _shadow_data[port];
883         } else {
884                 return _control_data[port];
885         }
886 }
887
888 int
889 LuaProc::get_parameter_descriptor (uint32_t port, ParameterDescriptor& desc) const
890 {
891         assert (port <= parameter_count ());
892         int lp = _ctrl_params[port].second;
893         const ParameterDescriptor& d (_param_desc.find(lp)->second);
894
895         desc.lower        = d.lower;
896         desc.upper        = d.upper;
897         desc.normal       = d.normal;
898         desc.toggled      = d.toggled;
899         desc.logarithmic  = d.logarithmic;
900         desc.integer_step = d.integer_step;
901         desc.sr_dependent = d.sr_dependent;
902         desc.enumeration  = d.enumeration;
903         desc.unit         = d.unit;
904         desc.label        = d.label;
905         desc.scale_points = d.scale_points;
906
907         desc.update_steps ();
908         return 0;
909 }
910
911 std::string
912 LuaProc::get_parameter_docs (uint32_t port) const {
913         assert (port <= parameter_count ());
914         int lp = _ctrl_params[port].second;
915         return _param_doc.find(lp)->second;
916 }
917
918 uint32_t
919 LuaProc::nth_parameter (uint32_t port, bool& ok) const
920 {
921         if (port < _ctrl_params.size ()) {
922                 ok = true;
923                 return port;
924         }
925         ok = false;
926         return 0;
927 }
928
929 bool
930 LuaProc::parameter_is_input (uint32_t port) const
931 {
932         assert (port < _ctrl_params.size ());
933         return (!_ctrl_params[port].first);
934 }
935
936 bool
937 LuaProc::parameter_is_output (uint32_t port) const
938 {
939         assert (port < _ctrl_params.size ());
940         return (_ctrl_params[port].first);
941 }
942
943 std::set<Evoral::Parameter>
944 LuaProc::automatable () const
945 {
946         std::set<Evoral::Parameter> automatables;
947         for (uint32_t i = 0; i < _ctrl_params.size (); ++i) {
948                 if (parameter_is_input (i)) {
949                         automatables.insert (automatables.end (), Evoral::Parameter (PluginAutomation, 0, i));
950                 }
951         }
952         return automatables;
953 }
954
955 std::string
956 LuaProc::describe_parameter (Evoral::Parameter param)
957 {
958         if (param.type () == PluginAutomation && param.id () < parameter_count ()) {
959                 int lp = _ctrl_params[param.id ()].second;
960                 return _param_desc[lp].label;
961         }
962         return "??";
963 }
964
965 void
966 LuaProc::print_parameter (uint32_t param, char* buf, uint32_t len) const
967 {
968         if (buf && len) {
969                 if (param < parameter_count ()) {
970                         snprintf (buf, len, "%.3f", get_parameter (param));
971                 } else {
972                         strcat (buf, "0");
973                 }
974         }
975 }
976
977 boost::shared_ptr<ScalePoints>
978 LuaProc::parse_scale_points (luabridge::LuaRef* lr)
979 {
980         if (!(*lr)["scalepoints"].isTable()) {
981                 return boost::shared_ptr<ScalePoints> ();
982         }
983
984         int cnt = 0;
985         boost::shared_ptr<ScalePoints> rv = boost::shared_ptr<ScalePoints>(new ScalePoints());
986         luabridge::LuaRef scalepoints ((*lr)["scalepoints"]);
987
988         for (luabridge::Iterator i (scalepoints); !i.isNil (); ++i) {
989                 if (!i.key ().isString ())    { continue; }
990                 if (!i.value ().isNumber ())  { continue; }
991                 rv->insert(make_pair(i.key ().cast<std::string> (),
992                                         i.value ().cast<float> ()));
993                 ++cnt;
994         }
995
996         if (rv->size() > 0) {
997                 return rv;
998         }
999         return boost::shared_ptr<ScalePoints> ();
1000 }
1001
1002 boost::shared_ptr<ScalePoints>
1003 LuaProc::get_scale_points (uint32_t port) const
1004 {
1005         int lp = _ctrl_params[port].second;
1006         return _param_desc.find(lp)->second.scale_points;
1007 }
1008
1009 void
1010 LuaProc::setup_lua_inline_gui (LuaState *lua_gui)
1011 {
1012         lua_State* LG = lua_gui->getState ();
1013         LuaBindings::stddef (LG);
1014         LuaBindings::common (LG);
1015         LuaBindings::dsp (LG);
1016
1017         lua_gui->Print.connect (sigc::mem_fun (*this, &LuaProc::lua_print));
1018         lua_gui->do_command ("function ardour () end");
1019         lua_gui->do_command (_script);
1020
1021         // TODO think: use a weak-pointer here ?
1022         // (the GUI itself uses a shared ptr to this plugin, so we should be good)
1023         luabridge::getGlobalNamespace (LG)
1024                 .beginNamespace ("Ardour")
1025                 .beginClass <LuaProc> ("LuaProc")
1026                 .addFunction ("shmem", &LuaProc::instance_shm)
1027                 .addFunction ("table", &LuaProc::instance_ref)
1028                 .endClass ()
1029                 .endNamespace ();
1030
1031         luabridge::push <LuaProc *> (LG, this);
1032         lua_setglobal (LG, "self");
1033
1034         luabridge::push <float *> (LG, _shadow_data);
1035         lua_setglobal (LG, "CtrlPorts");
1036 }
1037 ////////////////////////////////////////////////////////////////////////////////
1038
1039 #include "ardour/search_paths.h"
1040 #include "sha1.c"
1041
1042 std::string
1043 LuaProc::preset_name_to_uri (const std::string& name) const
1044 {
1045         std::string uri ("urn:lua:");
1046         char hash[41];
1047         Sha1Digest s;
1048         sha1_init (&s);
1049         sha1_write (&s, (const uint8_t *) name.c_str(), name.size ());
1050         sha1_write (&s, (const uint8_t *) _script.c_str(), _script.size ());
1051         sha1_result_hash (&s, hash);
1052         return uri + hash;
1053 }
1054
1055 std::string
1056 LuaProc::presets_file () const
1057 {
1058         return string_compose ("lua-%1", _info->unique_id);
1059 }
1060
1061 XMLTree*
1062 LuaProc::presets_tree () const
1063 {
1064         XMLTree* t = new XMLTree;
1065         std::string p = Glib::build_filename (ARDOUR::user_config_directory (), "presets");
1066
1067         if (!Glib::file_test (p, Glib::FILE_TEST_IS_DIR)) {
1068                 if (g_mkdir_with_parents (p.c_str(), 0755) != 0) {
1069                         error << _("Unable to create LuaProc presets directory") << endmsg;
1070                 };
1071         }
1072
1073         p = Glib::build_filename (p, presets_file ());
1074
1075         if (!Glib::file_test (p, Glib::FILE_TEST_EXISTS)) {
1076                 t->set_root (new XMLNode (X_("LuaPresets")));
1077                 return t;
1078         }
1079
1080         t->set_filename (p);
1081         if (!t->read ()) {
1082                 delete t;
1083                 return 0;
1084         }
1085         return t;
1086 }
1087
1088 bool
1089 LuaProc::load_preset (PresetRecord r)
1090 {
1091         boost::shared_ptr<XMLTree> t (presets_tree ());
1092         if (t == 0) {
1093                 return false;
1094         }
1095
1096         XMLNode* root = t->root ();
1097         for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
1098                 XMLProperty const * label = (*i)->property (X_("label"));
1099                 assert (label);
1100                 if (label->value() != r.label) {
1101                         continue;
1102                 }
1103
1104                 for (XMLNodeList::const_iterator j = (*i)->children().begin(); j != (*i)->children().end(); ++j) {
1105                         if ((*j)->name() == X_("Parameter")) {
1106                                 XMLProperty const * index = (*j)->property (X_("index"));
1107                                 XMLProperty const * value = (*j)->property (X_("value"));
1108                                 assert (index);
1109                                 assert (value);
1110                                 LocaleGuard lg;
1111                                 set_parameter (atoi (index->value().c_str()), atof (value->value().c_str ()));
1112                         }
1113                 }
1114                 return Plugin::load_preset(r);
1115         }
1116         return false;
1117 }
1118
1119 std::string
1120 LuaProc::do_save_preset (std::string name) {
1121
1122         boost::shared_ptr<XMLTree> t (presets_tree ());
1123         if (t == 0) {
1124                 return "";
1125         }
1126
1127         std::string uri (preset_name_to_uri (name));
1128
1129         XMLNode* p = new XMLNode (X_("Preset"));
1130         p->add_property (X_("uri"), uri);
1131         p->add_property (X_("label"), name);
1132
1133         for (uint32_t i = 0; i < parameter_count(); ++i) {
1134                 if (parameter_is_input (i)) {
1135                         XMLNode* c = new XMLNode (X_("Parameter"));
1136                         c->add_property (X_("index"), string_compose ("%1", i));
1137                         c->add_property (X_("value"), string_compose ("%1", get_parameter (i)));
1138                         p->add_child_nocopy (*c);
1139                 }
1140         }
1141         t->root()->add_child_nocopy (*p);
1142
1143         std::string f = Glib::build_filename (ARDOUR::user_config_directory (), "presets");
1144         f = Glib::build_filename (f, presets_file ());
1145
1146         t->write (f);
1147         return uri;
1148 }
1149
1150 void
1151 LuaProc::do_remove_preset (std::string name)
1152 {
1153         boost::shared_ptr<XMLTree> t (presets_tree ());
1154         if (t == 0) {
1155                 return;
1156         }
1157         t->root()->remove_nodes_and_delete (X_("label"), name);
1158         std::string f = Glib::build_filename (ARDOUR::user_config_directory (), "presets");
1159         f = Glib::build_filename (f, presets_file ());
1160         t->write (f);
1161 }
1162
1163 void
1164 LuaProc::find_presets ()
1165 {
1166         boost::shared_ptr<XMLTree> t (presets_tree ());
1167         if (t) {
1168                 XMLNode* root = t->root ();
1169                 for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
1170
1171                         XMLProperty const * uri = (*i)->property (X_("uri"));
1172                         XMLProperty const * label = (*i)->property (X_("label"));
1173
1174                         assert (uri);
1175                         assert (label);
1176
1177                         PresetRecord r (uri->value(), label->value(), true);
1178                         _presets.insert (make_pair (r.uri, r));
1179                 }
1180         }
1181 }
1182
1183 ////////////////////////////////////////////////////////////////////////////////
1184
1185 LuaPluginInfo::LuaPluginInfo (LuaScriptInfoPtr lsi) {
1186         if (lsi->type != LuaScriptInfo::DSP) {
1187                 throw failed_constructor ();
1188         }
1189
1190         path = lsi->path;
1191         name = lsi->name;
1192         creator = lsi->author;
1193         category = lsi->category;
1194         unique_id = lsi->unique_id;
1195
1196         n_inputs.set (DataType::AUDIO, 1);
1197         n_outputs.set (DataType::AUDIO, 1);
1198         type = Lua;
1199
1200         _is_instrument = category == "Instrument";
1201 }
1202
1203 PluginPtr
1204 LuaPluginInfo::load (Session& session)
1205 {
1206         std::string script = "";
1207         if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
1208                 return PluginPtr ();
1209         }
1210
1211         try {
1212                 script = Glib::file_get_contents (path);
1213         } catch (Glib::FileError err) {
1214                 return PluginPtr ();
1215         }
1216
1217         if (script.empty ()) {
1218                 return PluginPtr ();
1219         }
1220
1221         try {
1222                 PluginPtr plugin (new LuaProc (session.engine (), session, script));
1223                 return plugin;
1224         } catch (failed_constructor& err) {
1225                 ;
1226         }
1227         return PluginPtr ();
1228 }
1229
1230 std::vector<Plugin::PresetRecord>
1231 LuaPluginInfo::get_presets (bool /*user_only*/) const
1232 {
1233         std::vector<Plugin::PresetRecord> p;
1234         XMLTree* t = new XMLTree;
1235         std::string pf = Glib::build_filename (ARDOUR::user_config_directory (), "presets", string_compose ("lua-%1", unique_id));
1236         if (Glib::file_test (pf, Glib::FILE_TEST_EXISTS)) {
1237                 t->set_filename (pf);
1238                 if (t->read ()) {
1239                         XMLNode* root = t->root ();
1240                         for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
1241                                 XMLProperty const * uri = (*i)->property (X_("uri"));
1242                                 XMLProperty const * label = (*i)->property (X_("label"));
1243                                 p.push_back (Plugin::PresetRecord (uri->value(), label->value(), true));
1244                         }
1245                 }
1246         }
1247         delete t;
1248         return p;
1249 }