remove StateManager code entirely and more debugging output cruft
[ardour.git] / libs / ardour / ladspa_plugin.cc
1 /*
2     Copyright (C) 2000-2006 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include <vector>
22 #include <string>
23
24 #include <cstdlib>
25 #include <cstdio> // so libraptor doesn't complain
26 #include <cmath>
27 #include <dirent.h>
28 #include <sys/stat.h>
29 #include <cerrno>
30
31 #include <lrdf.h>
32
33 #include <pbd/compose.h>
34 #include <pbd/error.h>
35 #include <pbd/pathscanner.h>
36 #include <pbd/xml++.h>
37
38 #include <midi++/manager.h>
39
40 #include <ardour/ardour.h>
41 #include <ardour/session.h>
42 #include <ardour/audioengine.h>
43 #include <ardour/ladspa_plugin.h>
44
45 #include <pbd/stl_delete.h>
46
47 #include "i18n.h"
48 #include <locale.h>
49
50 using namespace std;
51 using namespace ARDOUR;
52 using namespace PBD;
53
54 LadspaPlugin::LadspaPlugin (void *mod, AudioEngine& e, Session& session, uint32_t index, nframes_t rate)
55         : Plugin (e, session)
56 {
57         init (mod, index, rate);
58 }
59
60 LadspaPlugin::LadspaPlugin (const LadspaPlugin &other)
61         : Plugin (other)
62 {
63         init (other.module, other._index, other.sample_rate);
64
65         for (uint32_t i = 0; i < parameter_count(); ++i) {
66                 control_data[i] = other.shadow_data[i];
67                 shadow_data[i] = other.shadow_data[i];
68         }
69 }
70
71 void
72 LadspaPlugin::init (void *mod, uint32_t index, nframes_t rate)
73 {
74         LADSPA_Descriptor_Function dfunc;
75         uint32_t i, port_cnt;
76         const char *errstr;
77
78         module = mod;
79         control_data = 0;
80         shadow_data = 0;
81         latency_control_port = 0;
82         was_activated = false;
83
84         dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor");
85
86         if ((errstr = dlerror()) != NULL) {
87                 error << _("LADSPA: module has no descriptor function.") << endmsg;
88                 throw failed_constructor();
89         }
90
91         if ((descriptor = dfunc (index)) == 0) {
92                 error << _("LADSPA: plugin has gone away since discovery!") << endmsg;
93                 throw failed_constructor();
94         }
95
96         _index = index;
97
98         if (LADSPA_IS_INPLACE_BROKEN(descriptor->Properties)) {
99                 error << string_compose(_("LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"), descriptor->Name) << endmsg;
100                 throw failed_constructor();
101         }
102         
103         sample_rate = rate;
104
105         if (descriptor->instantiate == 0) {
106                 throw failed_constructor();
107         }
108
109         if ((handle = descriptor->instantiate (descriptor, rate)) == 0) {
110                 throw failed_constructor();
111         }
112
113         port_cnt = parameter_count();
114
115         control_data = new LADSPA_Data[port_cnt];
116         shadow_data = new LADSPA_Data[port_cnt];
117
118         for (i = 0; i < port_cnt; ++i) {
119                 if (LADSPA_IS_PORT_CONTROL(port_descriptor (i))) {
120                         connect_port (i, &control_data[i]);
121                         
122                         if (LADSPA_IS_PORT_OUTPUT(port_descriptor (i)) &&
123                             strcmp (port_names()[i], X_("latency")) == 0) {
124                                 latency_control_port = &control_data[i];
125                                 *latency_control_port = 0;
126                         }
127
128                         if (!LADSPA_IS_PORT_INPUT(port_descriptor (i))) {
129                                 continue;
130                         }
131                 
132                         shadow_data[i] = default_value (i);
133                 }
134         }
135
136         Plugin::setup_controls ();
137
138         latency_compute_run ();
139 }
140
141 LadspaPlugin::~LadspaPlugin ()
142 {
143         deactivate ();
144         cleanup ();
145
146         GoingAway (); /* EMIT SIGNAL */
147         
148         /* XXX who should close a plugin? */
149
150         // dlclose (module);
151
152         if (control_data) {
153                 delete [] control_data;
154         }
155
156         if (shadow_data) {
157                 delete [] shadow_data;
158         }
159 }
160
161 float
162 LadspaPlugin::default_value (uint32_t port)
163 {
164         const LADSPA_PortRangeHint *prh = port_range_hints();
165         float ret = 0.0f;
166         bool bounds_given = false;
167         bool sr_scaling = false;
168
169         /* defaults - case 1 */
170         
171         if (LADSPA_IS_HINT_HAS_DEFAULT(prh[port].HintDescriptor)) {
172                 if (LADSPA_IS_HINT_DEFAULT_MINIMUM(prh[port].HintDescriptor)) {
173                         ret = prh[port].LowerBound;
174                         bounds_given = true;
175                         sr_scaling = true;
176                 }
177                 
178                 /* FIXME: add support for logarithmic defaults */
179                 
180                 else if (LADSPA_IS_HINT_DEFAULT_LOW(prh[port].HintDescriptor)) {
181                         ret = prh[port].LowerBound * 0.75f + prh[port].UpperBound * 0.25f;
182                         bounds_given = true;
183                         sr_scaling = true;
184                 }
185                 else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(prh[port].HintDescriptor)) {
186                         ret = prh[port].LowerBound * 0.50f + prh[port].UpperBound * 0.50f;
187                         bounds_given = true;
188                         sr_scaling = true;
189                 }
190                 else if (LADSPA_IS_HINT_DEFAULT_HIGH(prh[port].HintDescriptor)) {
191                         ret = prh[port].LowerBound * 0.25f + prh[port].UpperBound * 0.75f;
192                         bounds_given = true;
193                         sr_scaling = true;
194                 }
195                 else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(prh[port].HintDescriptor)) {
196                         ret = prh[port].UpperBound;
197                         bounds_given = true;
198                         sr_scaling = true;
199                 }
200                 else if (LADSPA_IS_HINT_DEFAULT_0(prh[port].HintDescriptor)) {
201                         ret = 0.0f;
202                 }
203                 else if (LADSPA_IS_HINT_DEFAULT_1(prh[port].HintDescriptor)) {
204                         ret = 1.0f;
205                 }
206                 else if (LADSPA_IS_HINT_DEFAULT_100(prh[port].HintDescriptor)) {
207                         ret = 100.0f;
208                 }
209                 else if (LADSPA_IS_HINT_DEFAULT_440(prh[port].HintDescriptor)) {
210                         ret = 440.0f;
211                 }
212                 else {
213                         /* no hint found */
214                         ret = 0.0f;
215                 }
216         }
217         
218         /* defaults - case 2 */
219         else if (LADSPA_IS_HINT_BOUNDED_BELOW(prh[port].HintDescriptor) &&
220                  !LADSPA_IS_HINT_BOUNDED_ABOVE(prh[port].HintDescriptor)) {
221                 
222                 if (prh[port].LowerBound < 0) {
223                         ret = 0.0f;
224                 } else {
225                         ret = prh[port].LowerBound;
226                 }
227
228                 bounds_given = true;
229                 sr_scaling = true;
230         }
231         
232         /* defaults - case 3 */
233         else if (!LADSPA_IS_HINT_BOUNDED_BELOW(prh[port].HintDescriptor) &&
234                  LADSPA_IS_HINT_BOUNDED_ABOVE(prh[port].HintDescriptor)) {
235                 
236                 if (prh[port].UpperBound > 0) {
237                         ret = 0.0f;
238                 } else {
239                         ret = prh[port].UpperBound;
240                 }
241
242                 bounds_given = true;
243                 sr_scaling = true;
244         }
245         
246         /* defaults - case 4 */
247         else if (LADSPA_IS_HINT_BOUNDED_BELOW(prh[port].HintDescriptor) &&
248                  LADSPA_IS_HINT_BOUNDED_ABOVE(prh[port].HintDescriptor)) {
249                 
250                 if (prh[port].LowerBound < 0 && prh[port].UpperBound > 0) {
251                         ret = 0.0f;
252                 } else if (prh[port].LowerBound < 0 && prh[port].UpperBound < 0) {
253                         ret = prh[port].UpperBound;
254                 } else {
255                         ret = prh[port].LowerBound;
256                 }
257                 bounds_given = true;    
258                 sr_scaling = true;
259         }
260         
261         /* defaults - case 5 */
262                 
263         if (LADSPA_IS_HINT_SAMPLE_RATE(prh[port].HintDescriptor)) {
264                 if (bounds_given) {
265                         if (sr_scaling) {
266                                 ret *= sample_rate;
267                         }
268                 } else {
269                         ret = sample_rate;
270                 }
271         }
272
273         return ret;
274 }       
275
276 void
277 LadspaPlugin::set_parameter (uint32_t which, float val)
278 {
279         if (which < descriptor->PortCount) {
280                 shadow_data[which] = (LADSPA_Data) val;
281                 ParameterChanged (which, val); /* EMIT SIGNAL */
282
283                 if (which < parameter_count() && controls[which]) {
284                         controls[which]->Changed ();
285                 }
286                 
287         } else {
288                 warning << string_compose (_("illegal parameter number used with plugin \"%1\". This may"
289                                              "indicate a change in the plugin design, and presets may be"
290                                              "invalid"), name())
291                         << endmsg;
292         }
293 }
294
295 float
296 LadspaPlugin::get_parameter (uint32_t which) const
297 {
298         if (LADSPA_IS_PORT_INPUT(port_descriptor (which))) {
299                 return (float) shadow_data[which];
300         } else {
301                 return (float) control_data[which];
302         }
303 }
304
305 uint32_t
306 LadspaPlugin::nth_parameter (uint32_t n, bool& ok) const
307 {
308         uint32_t x, c;
309
310         ok = false;
311
312         for (c = 0, x = 0; x < descriptor->PortCount; ++x) {
313                 if (LADSPA_IS_PORT_CONTROL (port_descriptor (x))) {
314                         if (c++ == n) {
315                                 ok = true;
316                                 return x;
317                         }
318                 }
319         }
320         return 0;
321 }
322
323 XMLNode&
324 LadspaPlugin::get_state()
325 {
326         XMLNode *root = new XMLNode(state_node_name());
327         XMLNode *child;
328         char buf[16];
329         LocaleGuard lg (X_("POSIX"));
330
331         for (uint32_t i = 0; i < parameter_count(); ++i){
332
333                 if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && 
334                     LADSPA_IS_PORT_CONTROL(port_descriptor (i))){
335
336                         child = new XMLNode("port");
337                         snprintf(buf, sizeof(buf), "%u", i);
338                         child->add_property("number", string(buf));
339                         snprintf(buf, sizeof(buf), "%+f", shadow_data[i]);
340                         child->add_property("value", string(buf));
341                         root->add_child_nocopy (*child);
342                 }
343         }
344
345         return *root;
346 }
347
348 bool
349 LadspaPlugin::save_preset (string name)
350 {
351         return Plugin::save_preset (name, "ladspa");
352 }
353
354 int
355 LadspaPlugin::set_state(const XMLNode& node)
356 {
357         XMLNodeList nodes;
358         XMLProperty *prop;
359         XMLNodeConstIterator iter;
360         XMLNode *child;
361         const char *port;
362         const char *data;
363         uint32_t port_id;
364         LocaleGuard lg (X_("POSIX"));
365
366         if (node.name() != state_node_name()) {
367                 error << _("Bad node sent to LadspaPlugin::set_state") << endmsg;
368                 return -1;
369         }
370
371         nodes = node.children ("port");
372
373         for(iter = nodes.begin(); iter != nodes.end(); ++iter){
374
375                 child = *iter;
376
377                 if ((prop = child->property("number")) != 0) {
378                         port = prop->value().c_str();
379                 } else {
380                         warning << _("LADSPA: no ladspa port number") << endmsg;
381                         continue;
382                 }
383                 if ((prop = child->property("value")) != 0) {
384                         data = prop->value().c_str();
385                 } else {
386                         warning << _("LADSPA: no ladspa port data") << endmsg;
387                         continue;
388                 }
389
390                 sscanf (port, "%" PRIu32, &port_id);
391                 set_parameter (port_id, atof(data));
392         }
393
394         latency_compute_run ();
395
396         return 0;
397 }
398
399 int
400 LadspaPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) const
401 {
402         LADSPA_PortRangeHint prh;
403
404         prh  = port_range_hints()[which];
405         
406
407         if (LADSPA_IS_HINT_BOUNDED_BELOW(prh.HintDescriptor)) {
408                 desc.min_unbound = false;
409                 if (LADSPA_IS_HINT_SAMPLE_RATE(prh.HintDescriptor)) {
410                         desc.lower = prh.LowerBound * _session.frame_rate();
411                 } else {
412                         desc.lower = prh.LowerBound;
413                 }
414         } else {
415                 desc.min_unbound = true;
416                 desc.lower = 0;
417         }
418         
419
420         if (LADSPA_IS_HINT_BOUNDED_ABOVE(prh.HintDescriptor)) {
421                 desc.max_unbound = false;
422                 if (LADSPA_IS_HINT_SAMPLE_RATE(prh.HintDescriptor)) {
423                         desc.upper = prh.UpperBound * _session.frame_rate();
424                 } else {
425                         desc.upper = prh.UpperBound;
426                 }
427         } else {
428                 desc.max_unbound = true;
429                 desc.upper = 4; /* completely arbitrary */
430         }
431         
432         if (LADSPA_IS_HINT_INTEGER (prh.HintDescriptor)) {
433                 desc.step = 1.0;
434                 desc.smallstep = 0.1;
435                 desc.largestep = 10.0;
436         } else {
437                 float delta = desc.upper - desc.lower;
438                 desc.step = delta / 1000.0f;
439                 desc.smallstep = delta / 10000.0f;
440                 desc.largestep = delta/10.0f;
441         }
442         
443         desc.toggled = LADSPA_IS_HINT_TOGGLED (prh.HintDescriptor);
444         desc.logarithmic = LADSPA_IS_HINT_LOGARITHMIC (prh.HintDescriptor);
445         desc.sr_dependent = LADSPA_IS_HINT_SAMPLE_RATE (prh.HintDescriptor);
446         desc.integer_step = LADSPA_IS_HINT_INTEGER (prh.HintDescriptor);
447
448         desc.label = port_names()[which];
449
450
451         return 0;
452 }
453
454
455 string
456 LadspaPlugin::describe_parameter (uint32_t which)
457 {
458         if (which < parameter_count()) {
459                 return port_names()[which];
460         } else {
461                 return "??";
462         }
463 }
464
465 nframes_t
466 LadspaPlugin::latency () const
467 {
468         if (latency_control_port) {
469                 return (nframes_t) floor (*latency_control_port);
470         } else {
471                 return 0;
472         }
473 }
474
475 set<uint32_t>
476 LadspaPlugin::automatable () const
477 {
478         set<uint32_t> ret;
479
480         for (uint32_t i = 0; i < parameter_count(); ++i){
481                 if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && 
482                     LADSPA_IS_PORT_CONTROL(port_descriptor (i))){
483                         
484                         ret.insert (ret.end(), i);
485                 }
486         }
487
488         return ret;
489 }
490
491 int
492 LadspaPlugin::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, int32_t& in_index, int32_t& out_index, nframes_t nframes, nframes_t offset)
493 {
494         uint32_t port_index;
495         cycles_t then, now;
496
497         port_index = 0;
498
499         then = get_cycles ();
500
501         while (port_index < parameter_count()) {
502                 if (LADSPA_IS_PORT_AUDIO (port_descriptor(port_index))) {
503                         if (LADSPA_IS_PORT_INPUT (port_descriptor(port_index))) {
504                                 connect_port (port_index, bufs[min((uint32_t) in_index,nbufs - 1)] + offset);
505                                 //cerr << this << ' ' << name() << " @ " << offset << " inport " << in_index << " = buf " 
506                                 //     << min((uint32_t)in_index,nbufs) << " = " << &bufs[min((uint32_t)in_index,nbufs)][offset] << endl;
507                                 in_index++;
508
509
510                         } else if (LADSPA_IS_PORT_OUTPUT (port_descriptor (port_index))) {
511                                 connect_port (port_index, bufs[min((uint32_t) out_index,nbufs - 1)] + offset);
512                                 // cerr << this << ' ' << name() << " @ " << offset << " outport " << out_index << " = buf " 
513                                 //     << min((uint32_t)out_index,nbufs) << " = " << &bufs[min((uint32_t)out_index,nbufs)][offset] << endl;
514                                 out_index++;
515                         }
516                 }
517                 port_index++;
518         }
519         
520         run (nframes);
521         now = get_cycles ();
522         set_cycles ((uint32_t) (now - then));
523
524         return 0;
525 }
526
527 bool
528 LadspaPlugin::parameter_is_control (uint32_t param) const
529 {
530         return LADSPA_IS_PORT_CONTROL(port_descriptor (param));
531 }
532
533 bool
534 LadspaPlugin::parameter_is_audio (uint32_t param) const
535 {
536         return LADSPA_IS_PORT_AUDIO(port_descriptor (param));
537 }
538
539 bool
540 LadspaPlugin::parameter_is_output (uint32_t param) const
541 {
542         return LADSPA_IS_PORT_OUTPUT(port_descriptor (param));
543 }
544
545 bool
546 LadspaPlugin::parameter_is_input (uint32_t param) const
547 {
548         return LADSPA_IS_PORT_INPUT(port_descriptor (param));
549 }
550
551 void
552 LadspaPlugin::print_parameter (uint32_t param, char *buf, uint32_t len) const
553 {
554         if (buf && len) {
555                 if (param < parameter_count()) {
556                         snprintf (buf, len, "%.3f", get_parameter (param));
557                 } else {
558                         strcat (buf, "0");
559                 }
560         }
561 }
562
563 void
564 LadspaPlugin::run (nframes_t nframes)
565 {
566         for (uint32_t i = 0; i < parameter_count(); ++i) {
567                 if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && LADSPA_IS_PORT_CONTROL(port_descriptor (i))) {
568                         control_data[i] = shadow_data[i];
569                 }
570         }
571         descriptor->run (handle, nframes);
572 }
573
574 void
575 LadspaPlugin::latency_compute_run ()
576 {
577         if (!latency_control_port) {
578                 return;
579         }
580
581         /* we need to run the plugin so that it can set its latency
582            parameter.
583         */
584         
585         activate ();
586         
587         uint32_t port_index = 0;
588         uint32_t in_index = 0;
589         uint32_t out_index = 0;
590         const nframes_t bufsize = 1024;
591         LADSPA_Data buffer[bufsize];
592
593         memset(buffer,0,sizeof(LADSPA_Data)*bufsize);
594                 
595         /* Note that we've already required that plugins
596            be able to handle in-place processing.
597         */
598         
599         port_index = 0;
600         
601         while (port_index < parameter_count()) {
602                 if (LADSPA_IS_PORT_AUDIO (port_descriptor (port_index))) {
603                         if (LADSPA_IS_PORT_INPUT (port_descriptor (port_index))) {
604                                 connect_port (port_index, buffer);
605                                 in_index++;
606                         } else if (LADSPA_IS_PORT_OUTPUT (port_descriptor (port_index))) {
607                                 connect_port (port_index, buffer);
608                                 out_index++;
609                         }
610                 }
611                 port_index++;
612         }
613         
614         run (bufsize);
615         deactivate ();
616 }
617
618 PluginPtr
619 LadspaPluginInfo::load (Session& session)
620 {
621         try {
622                 PluginPtr plugin;
623                 void *module;
624
625                 if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
626                         error << string_compose(_("LADSPA: cannot load module from \"%1\""), path) << endmsg;
627                         error << dlerror() << endmsg;
628                 } else {
629                         plugin.reset (new LadspaPlugin (module, session.engine(), session, index, session.frame_rate()));
630                 }
631
632                 plugin->set_info(PluginInfoPtr(new LadspaPluginInfo(*this)));
633                 return plugin;
634         }
635
636         catch (failed_constructor &err) {
637                 return PluginPtr ((Plugin*) 0);
638         }       
639 }