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