b5106cb4ca9b4b0b21915c6081fe1df796bc202d
[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 */
19
20 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23
24 #include <inttypes.h>
25
26 #include <vector>
27 #include <string>
28
29 #include <cstdlib>
30 #include <cstdio> // so libraptor doesn't complain
31 #include <cmath>
32 #ifndef COMPILER_MSVC
33 #include <dirent.h>
34 #endif
35 #include <sys/stat.h>
36 #include <cerrno>
37
38 #ifdef HAVE_LRDF
39 #include <lrdf.h>
40 #endif
41
42 #include "pbd/compose.h"
43 #include "pbd/error.h"
44 #include "pbd/xml++.h"
45 #include "pbd/stacktrace.h"
46
47 #include "ardour/session.h"
48 #include "ardour/ladspa_plugin.h"
49 #include "ardour/buffer_set.h"
50 #include "ardour/audio_buffer.h"
51
52 #include "pbd/stl_delete.h"
53
54 #include "pbd/i18n.h"
55 #include <locale.h>
56
57 using namespace std;
58 using namespace ARDOUR;
59 using namespace PBD;
60
61 LadspaPlugin::LadspaPlugin (string module_path, AudioEngine& e, Session& session, uint32_t index, framecnt_t rate)
62         : Plugin (e, session)
63 {
64         init (module_path, index, rate);
65 }
66
67 LadspaPlugin::LadspaPlugin (const LadspaPlugin &other)
68         : Plugin (other)
69 {
70         init (other._module_path, other._index, other._sample_rate);
71
72         for (uint32_t i = 0; i < parameter_count(); ++i) {
73                 _control_data[i] = other._shadow_data[i];
74                 _shadow_data[i] = other._shadow_data[i];
75         }
76 }
77
78 void
79 LadspaPlugin::init (string module_path, uint32_t index, framecnt_t rate)
80 {
81         void* func;
82         LADSPA_Descriptor_Function dfunc;
83         uint32_t i, port_cnt;
84
85         _module_path = module_path;
86         _module = new Glib::Module(_module_path);
87         _control_data = 0;
88         _shadow_data = 0;
89         _latency_control_port = 0;
90         _was_activated = false;
91
92         if (!(*_module)) {
93                 error << _("LADSPA: Unable to open module: ") << Glib::Module::get_last_error() << endmsg;
94                 delete _module;
95                 throw failed_constructor();
96         }
97
98         if (!_module->get_symbol("ladspa_descriptor", func)) {
99                 error << _("LADSPA: module has no descriptor function.") << endmsg;
100                 throw failed_constructor();
101         }
102
103         dfunc = (LADSPA_Descriptor_Function)func;
104
105         if ((_descriptor = dfunc (index)) == 0) {
106                 error << _("LADSPA: plugin has gone away since discovery!") << endmsg;
107                 throw failed_constructor();
108         }
109
110         _index = index;
111
112         if (LADSPA_IS_INPLACE_BROKEN(_descriptor->Properties)) {
113                 error << string_compose(_("LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"), _descriptor->Name) << endmsg;
114                 throw failed_constructor();
115         }
116
117         _sample_rate = rate;
118
119         if (_descriptor->instantiate == 0) {
120                 throw failed_constructor();
121         }
122
123         if ((_handle = _descriptor->instantiate (_descriptor, rate)) == 0) {
124                 throw failed_constructor();
125         }
126
127         port_cnt = parameter_count();
128
129         _control_data = new LADSPA_Data[port_cnt];
130         memset (_control_data, 0, sizeof (LADSPA_Data) * port_cnt);
131         _shadow_data = new LADSPA_Data[port_cnt];
132         memset (_shadow_data, 0, sizeof (LADSPA_Data) * port_cnt);
133
134         for (i = 0; i < port_cnt; ++i) {
135                 if (LADSPA_IS_PORT_CONTROL(port_descriptor (i))) {
136                         connect_port (i, &_control_data[i]);
137
138                         if (LADSPA_IS_PORT_OUTPUT(port_descriptor (i)) &&
139                             strcmp (port_names()[i], X_("latency")) == 0) {
140                                 _latency_control_port = &_control_data[i];
141                                 *_latency_control_port = 0;
142                         }
143
144                         _shadow_data[i] = _default_value (i);
145                         _control_data[i] = _shadow_data[i];
146                 }
147         }
148
149         latency_compute_run ();
150 }
151
152 LadspaPlugin::~LadspaPlugin ()
153 {
154         deactivate ();
155         cleanup ();
156
157         // glib has internal reference counting on modules so this is ok
158         delete _module;
159
160         delete [] _control_data;
161         delete [] _shadow_data;
162 }
163
164 string
165 LadspaPlugin::unique_id() const
166 {
167         char buf[32];
168         snprintf (buf, sizeof (buf), "%lu", _descriptor->UniqueID);
169         return string (buf);
170 }
171
172 float
173 LadspaPlugin::_default_value (uint32_t port) const
174 {
175         const LADSPA_PortRangeHint *prh = port_range_hints();
176         float ret = 0.0f;
177         bool bounds_given = false;
178         bool sr_scaling = false;
179         bool earlier_hint = false;
180
181         /* defaults - case 1 */
182
183         if (LADSPA_IS_HINT_HAS_DEFAULT(prh[port].HintDescriptor)) {
184                 if (LADSPA_IS_HINT_DEFAULT_MINIMUM(prh[port].HintDescriptor)) {
185                         ret = prh[port].LowerBound;
186                         bounds_given = true;
187                         sr_scaling = true;
188                 }
189
190                 else if (LADSPA_IS_HINT_DEFAULT_LOW(prh[port].HintDescriptor)) {
191                         ret = prh[port].LowerBound * 0.75f + prh[port].UpperBound * 0.25f;
192                         bounds_given = true;
193                         sr_scaling = true;
194                 }
195                 else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(prh[port].HintDescriptor)) {
196                         ret = prh[port].LowerBound * 0.5f + prh[port].UpperBound * 0.5f;
197                         bounds_given = true;
198                         sr_scaling = true;
199                 }
200                 else if (LADSPA_IS_HINT_DEFAULT_HIGH(prh[port].HintDescriptor)) {
201                         ret = prh[port].LowerBound * 0.25f + prh[port].UpperBound * 0.75f;
202                         bounds_given = true;
203                         sr_scaling = true;
204                 }
205                 else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(prh[port].HintDescriptor)) {
206                         ret = prh[port].UpperBound;
207                         bounds_given = true;
208                         sr_scaling = true;
209                 }
210                 else if (LADSPA_IS_HINT_DEFAULT_0(prh[port].HintDescriptor)) {
211                         ret = 0.0f;
212                         earlier_hint = true;
213                 }
214                 else if (LADSPA_IS_HINT_DEFAULT_1(prh[port].HintDescriptor)) {
215                         ret = 1.0f;
216                         earlier_hint = true;
217                 }
218                 else if (LADSPA_IS_HINT_DEFAULT_100(prh[port].HintDescriptor)) {
219                         ret = 100.0f;
220                         earlier_hint = true;
221                 }
222                 else if (LADSPA_IS_HINT_DEFAULT_440(prh[port].HintDescriptor)) {
223                         ret = 440.0f;
224                         earlier_hint = true;
225                 }
226                 else {
227                         /* no hint found */
228                         ret = 0.0f;
229                 }
230         }
231
232         /* defaults - case 2 */
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].LowerBound < 0) {
237                         ret = 0.0f;
238                 } else {
239                         ret = prh[port].LowerBound;
240                 }
241
242                 bounds_given = true;
243                 sr_scaling = true;
244         }
245
246         /* defaults - case 3 */
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].UpperBound > 0) {
251                         ret = 0.0f;
252                 } else {
253                         ret = prh[port].UpperBound;
254                 }
255
256                 bounds_given = true;
257                 sr_scaling = true;
258         }
259
260         /* defaults - case 4 */
261         else if (LADSPA_IS_HINT_BOUNDED_BELOW(prh[port].HintDescriptor) &&
262                  LADSPA_IS_HINT_BOUNDED_ABOVE(prh[port].HintDescriptor)) {
263
264                 if (prh[port].LowerBound < 0 && prh[port].UpperBound > 0) {
265                         ret = 0.0f;
266                 } else if (prh[port].LowerBound < 0 && prh[port].UpperBound < 0) {
267                         ret = prh[port].UpperBound;
268                 } else {
269                         ret = prh[port].LowerBound;
270                 }
271                 bounds_given = true;
272                 sr_scaling = true;
273         }
274
275         /* defaults - case 5 */
276
277         if (LADSPA_IS_HINT_SAMPLE_RATE(prh[port].HintDescriptor) && !earlier_hint) {
278                 if (bounds_given) {
279                         if (sr_scaling) {
280                                 ret *= _sample_rate;
281                         }
282                 } else {
283                         ret = _sample_rate;
284                 }
285         }
286
287         return ret;
288 }
289
290 void
291 LadspaPlugin::set_parameter (uint32_t which, float val)
292 {
293         if (which < _descriptor->PortCount) {
294
295                 if (get_parameter (which) == val) {
296                         return;
297                 }
298
299                 _shadow_data[which] = (LADSPA_Data) val;
300
301 #if 0
302                 if (which < parameter_count() && controls[which]) {
303                         controls[which]->Changed ();
304                 }
305 #endif
306
307         } else {
308                 warning << string_compose (_("illegal parameter number used with plugin \"%1\". This may "
309                                              "indicate a change in the plugin design, and presets may be "
310                                              "invalid"), name())
311                         << endmsg;
312         }
313
314         Plugin::set_parameter (which, val);
315 }
316
317 /** @return `plugin' value */
318 float
319 LadspaPlugin::get_parameter (uint32_t which) const
320 {
321         if (LADSPA_IS_PORT_INPUT(port_descriptor (which))) {
322                 return (float) _shadow_data[which];
323         } else {
324                 return (float) _control_data[which];
325         }
326 }
327
328 uint32_t
329 LadspaPlugin::nth_parameter (uint32_t n, bool& ok) const
330 {
331         uint32_t x, c;
332
333         ok = false;
334
335         for (c = 0, x = 0; x < _descriptor->PortCount; ++x) {
336                 if (LADSPA_IS_PORT_CONTROL (port_descriptor (x))) {
337                         if (c++ == n) {
338                                 ok = true;
339                                 return x;
340                         }
341                 }
342         }
343         return 0;
344 }
345
346 void
347 LadspaPlugin::add_state (XMLNode* root) const
348 {
349         XMLNode *child;
350         char buf[32];
351         LocaleGuard lg;
352
353         for (uint32_t i = 0; i < parameter_count(); ++i){
354
355                 if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) &&
356                     LADSPA_IS_PORT_CONTROL(port_descriptor (i))){
357
358                         child = new XMLNode("Port");
359                         snprintf(buf, sizeof(buf), "%u", i);
360                         child->add_property("number", string(buf));
361                         snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]);
362                         child->add_property("value", string(buf));
363                         root->add_child_nocopy (*child);
364                 }
365         }
366 }
367
368 int
369 LadspaPlugin::set_state (const XMLNode& node, int version)
370 {
371         if (version < 3000) {
372                 return set_state_2X (node, version);
373         }
374
375 #ifndef NO_PLUGIN_STATE
376         XMLNodeList nodes;
377         XMLProperty const * prop;
378         XMLNodeConstIterator iter;
379         XMLNode *child;
380         const char *port;
381         const char *data;
382         uint32_t port_id;
383 #endif
384         LocaleGuard lg;
385
386         if (node.name() != state_node_name()) {
387                 error << _("Bad node sent to LadspaPlugin::set_state") << endmsg;
388                 return -1;
389         }
390
391 #ifndef NO_PLUGIN_STATE
392
393         nodes = node.children ("Port");
394
395         for (iter = nodes.begin(); iter != nodes.end(); ++iter) {
396
397                 child = *iter;
398
399                 if ((prop = child->property("number")) != 0) {
400                         port = prop->value().c_str();
401                 } else {
402                         warning << _("LADSPA: no ladspa port number") << endmsg;
403                         continue;
404                 }
405                 if ((prop = child->property("value")) != 0) {
406                         data = prop->value().c_str();
407                 } else {
408                         warning << _("LADSPA: no ladspa port data") << endmsg;
409                         continue;
410                 }
411
412                 sscanf (port, "%" PRIu32, &port_id);
413                 set_parameter (port_id, atof(data));
414         }
415 #endif
416
417         latency_compute_run ();
418
419         return Plugin::set_state (node, version);
420 }
421
422 int
423 LadspaPlugin::set_state_2X (const XMLNode& node, int /* version */)
424 {
425 #ifndef NO_PLUGIN_STATE
426         XMLNodeList nodes;
427         XMLProperty const * prop;
428         XMLNodeConstIterator iter;
429         XMLNode *child;
430         const char *port;
431         const char *data;
432         uint32_t port_id;
433 #endif
434         LocaleGuard lg;
435
436         if (node.name() != state_node_name()) {
437                 error << _("Bad node sent to LadspaPlugin::set_state") << endmsg;
438                 return -1;
439         }
440
441 #ifndef NO_PLUGIN_STATE
442         nodes = node.children ("port");
443
444         for(iter = nodes.begin(); iter != nodes.end(); ++iter){
445
446                 child = *iter;
447
448                 if ((prop = child->property("number")) != 0) {
449                         port = prop->value().c_str();
450                 } else {
451                         warning << _("LADSPA: no ladspa port number") << endmsg;
452                         continue;
453                 }
454                 if ((prop = child->property("value")) != 0) {
455                         data = prop->value().c_str();
456                 } else {
457                         warning << _("LADSPA: no ladspa port data") << endmsg;
458                         continue;
459                 }
460
461                 sscanf (port, "%" PRIu32, &port_id);
462                 set_parameter (port_id, atof(data));
463         }
464
465         latency_compute_run ();
466 #endif
467
468         return 0;
469 }
470
471 int
472 LadspaPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) const
473 {
474         LADSPA_PortRangeHint prh;
475
476         prh  = port_range_hints()[which];
477
478
479         if (LADSPA_IS_HINT_BOUNDED_BELOW(prh.HintDescriptor)) {
480                 desc.min_unbound = false;
481                 if (LADSPA_IS_HINT_SAMPLE_RATE(prh.HintDescriptor)) {
482                         desc.lower = prh.LowerBound * _session.frame_rate();
483                 } else {
484                         desc.lower = prh.LowerBound;
485                 }
486         } else {
487                 desc.min_unbound = true;
488                 desc.lower = 0;
489         }
490
491
492         if (LADSPA_IS_HINT_BOUNDED_ABOVE(prh.HintDescriptor)) {
493                 desc.max_unbound = false;
494                 if (LADSPA_IS_HINT_SAMPLE_RATE(prh.HintDescriptor)) {
495                         desc.upper = prh.UpperBound * _session.frame_rate();
496                 } else {
497                         desc.upper = prh.UpperBound;
498                 }
499         } else {
500                 if (LADSPA_IS_HINT_TOGGLED (prh.HintDescriptor)) {
501                         desc.max_unbound = false;
502                         desc.upper = 1;
503                 } else {
504                         desc.max_unbound = true;
505                         desc.upper = 4; /* completely arbitrary */
506                 }
507         }
508
509         if (LADSPA_IS_HINT_HAS_DEFAULT (prh.HintDescriptor)) {
510                 desc.normal = _default_value(which);
511         } else {
512                 /* if there is no explicit hint for the default
513                  * value, use lower bound. This is not great but
514                  * better than just assuming '0' which may be out-of range.
515                  */
516                 desc.normal = desc.lower;
517         }
518
519         desc.toggled = LADSPA_IS_HINT_TOGGLED (prh.HintDescriptor);
520         desc.logarithmic = LADSPA_IS_HINT_LOGARITHMIC (prh.HintDescriptor);
521         desc.sr_dependent = LADSPA_IS_HINT_SAMPLE_RATE (prh.HintDescriptor);
522         desc.integer_step = LADSPA_IS_HINT_INTEGER (prh.HintDescriptor);
523
524         desc.label = port_names()[which];
525
526         desc.scale_points = get_scale_points(which);
527         desc.update_steps();
528
529         return 0;
530 }
531
532 string
533 LadspaPlugin::describe_parameter (Evoral::Parameter which)
534 {
535         if (which.type() == PluginAutomation && which.id() < parameter_count()) {
536                 return port_names()[which.id()];
537         } else {
538                 return "??";
539         }
540 }
541
542 ARDOUR::framecnt_t
543 LadspaPlugin::signal_latency () const
544 {
545         if (_user_latency) {
546                 return _user_latency;
547         }
548
549         if (_latency_control_port) {
550                 return (framecnt_t) floor (*_latency_control_port);
551         } else {
552                 return 0;
553         }
554 }
555
556 set<Evoral::Parameter>
557 LadspaPlugin::automatable () const
558 {
559         set<Evoral::Parameter> ret;
560
561         for (uint32_t i = 0; i < parameter_count(); ++i){
562                 if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) &&
563                     LADSPA_IS_PORT_CONTROL(port_descriptor (i))){
564
565                         ret.insert (ret.end(), Evoral::Parameter(PluginAutomation, 0, i));
566                 }
567         }
568
569         return ret;
570 }
571
572 int
573 LadspaPlugin::connect_and_run (BufferSet& bufs,
574                 framepos_t start, framepos_t end, double speed,
575                 ChanMapping in_map, ChanMapping out_map,
576                 pframes_t nframes, framecnt_t offset)
577 {
578         Plugin::connect_and_run (bufs, start, end, speed, in_map, out_map, nframes, offset);
579
580         cycles_t now;
581         cycles_t then = get_cycles ();
582
583         BufferSet& silent_bufs  = _session.get_silent_buffers(ChanCount(DataType::AUDIO, 1));
584         BufferSet& scratch_bufs = _session.get_scratch_buffers(ChanCount(DataType::AUDIO, 1));
585
586         uint32_t audio_in_index  = 0;
587         uint32_t audio_out_index = 0;
588         bool valid;
589         for (uint32_t port_index = 0; port_index < parameter_count(); ++port_index) {
590                 if (LADSPA_IS_PORT_AUDIO(port_descriptor(port_index))) {
591                         if (LADSPA_IS_PORT_INPUT(port_descriptor(port_index))) {
592                                 const uint32_t buf_index = in_map.get(DataType::AUDIO, audio_in_index++, &valid);
593                                 connect_port(port_index,
594                                              valid ? bufs.get_audio(buf_index).data(offset)
595                                                    : silent_bufs.get_audio(0).data(offset));
596                         } else if (LADSPA_IS_PORT_OUTPUT(port_descriptor(port_index))) {
597                                 const uint32_t buf_index = out_map.get(DataType::AUDIO, audio_out_index++, &valid);
598                                 connect_port(port_index,
599                                              valid ? bufs.get_audio(buf_index).data(offset)
600                                                    : scratch_bufs.get_audio(0).data(offset));
601                         }
602                 }
603         }
604
605         run_in_place (nframes);
606         now = get_cycles ();
607         set_cycles ((uint32_t) (now - then));
608
609         return 0;
610 }
611
612 bool
613 LadspaPlugin::parameter_is_control (uint32_t param) const
614 {
615         return LADSPA_IS_PORT_CONTROL(port_descriptor (param));
616 }
617
618 bool
619 LadspaPlugin::parameter_is_audio (uint32_t param) const
620 {
621         return LADSPA_IS_PORT_AUDIO(port_descriptor (param));
622 }
623
624 bool
625 LadspaPlugin::parameter_is_output (uint32_t param) const
626 {
627         return LADSPA_IS_PORT_OUTPUT(port_descriptor (param));
628 }
629
630 bool
631 LadspaPlugin::parameter_is_input (uint32_t param) const
632 {
633         return LADSPA_IS_PORT_INPUT(port_descriptor (param));
634 }
635
636 void
637 LadspaPlugin::print_parameter (uint32_t param, char *buf, uint32_t len) const
638 {
639         if (buf && len) {
640                 if (param < parameter_count()) {
641                         snprintf (buf, len, "%.3f", get_parameter (param));
642                 } else {
643                         strcat (buf, "0");
644                 }
645         }
646 }
647
648 boost::shared_ptr<ScalePoints>
649 LadspaPlugin::get_scale_points(uint32_t port_index) const
650 {
651         boost::shared_ptr<ScalePoints> ret;
652 #ifdef HAVE_LRDF
653         const uint32_t id     = atol(unique_id().c_str());
654         lrdf_defaults* points = lrdf_get_scale_values(id, port_index);
655
656         if (!points) {
657                 return ret;
658         }
659
660         ret = boost::shared_ptr<ScalePoints>(new ScalePoints());
661
662         for (uint32_t i = 0; i < points->count; ++i) {
663                 ret->insert(make_pair(points->items[i].label,
664                                       points->items[i].value));
665         }
666
667         lrdf_free_setting_values(points);
668 #endif
669         return ret;
670 }
671
672 void
673 LadspaPlugin::run_in_place (pframes_t nframes)
674 {
675         for (uint32_t i = 0; i < parameter_count(); ++i) {
676                 if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && LADSPA_IS_PORT_CONTROL(port_descriptor (i))) {
677                         _control_data[i] = _shadow_data[i];
678                 }
679         }
680
681         assert (_was_activated);
682
683         _descriptor->run (_handle, nframes);
684 }
685
686 void
687 LadspaPlugin::latency_compute_run ()
688 {
689         if (!_latency_control_port) {
690                 return;
691         }
692
693         /* we need to run the plugin so that it can set its latency
694            parameter.
695         */
696
697         activate ();
698
699         uint32_t port_index = 0;
700         uint32_t in_index = 0;
701         uint32_t out_index = 0;
702         const framecnt_t bufsize = 1024;
703         LADSPA_Data buffer[bufsize];
704
705         memset(buffer,0,sizeof(LADSPA_Data)*bufsize);
706
707         /* Note that we've already required that plugins
708            be able to handle in-place processing.
709         */
710
711         port_index = 0;
712
713         while (port_index < parameter_count()) {
714                 if (LADSPA_IS_PORT_AUDIO (port_descriptor (port_index))) {
715                         if (LADSPA_IS_PORT_INPUT (port_descriptor (port_index))) {
716                                 connect_port (port_index, buffer);
717                                 in_index++;
718                         } else if (LADSPA_IS_PORT_OUTPUT (port_descriptor (port_index))) {
719                                 connect_port (port_index, buffer);
720                                 out_index++;
721                         }
722                 }
723                 port_index++;
724         }
725
726         run_in_place (bufsize);
727         deactivate ();
728 }
729
730 PluginPtr
731 LadspaPluginInfo::load (Session& session)
732 {
733         try {
734                 PluginPtr plugin (new LadspaPlugin (path, session.engine(), session, index, session.frame_rate()));
735                 plugin->set_info(PluginInfoPtr(new LadspaPluginInfo(*this)));
736                 return plugin;
737         }
738
739         catch (failed_constructor &err) {
740                 return PluginPtr ((Plugin*) 0);
741         }
742 }
743
744 std::vector<Plugin::PresetRecord>
745 LadspaPluginInfo::get_presets (bool /*user_only*/) const
746 {
747         std::vector<Plugin::PresetRecord> p;
748 #if (defined HAVE_LRDF && !defined NO_PLUGIN_STATE)
749         if (!isdigit (unique_id[0])) {
750                 return p;
751         }
752         uint32_t id = atol (unique_id);
753         lrdf_uris* set_uris = lrdf_get_setting_uris(id);
754
755         if (set_uris) {
756                 for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) {
757                         if (char* label = lrdf_get_label (set_uris->items[i])) {
758                                 p.push_back (Plugin::PresetRecord (set_uris->items[i], label));
759                         }
760                 }
761                 lrdf_free_uris(set_uris);
762         }
763 #endif
764         return p;
765 }
766
767 LadspaPluginInfo::LadspaPluginInfo()
768 {
769        type = ARDOUR::LADSPA;
770 }
771
772
773 void
774 LadspaPlugin::find_presets ()
775 {
776 #ifdef HAVE_LRDF
777         uint32_t id;
778         std::string unique (unique_id());
779
780         if (!isdigit (unique[0])) {
781                 return;
782         }
783
784         id = atol (unique.c_str());
785
786         lrdf_uris* set_uris = lrdf_get_setting_uris(id);
787
788         if (set_uris) {
789                 for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) {
790                         if (char* label = lrdf_get_label(set_uris->items[i])) {
791                                 PresetRecord rec (set_uris->items[i], label);
792                                 _presets.insert (make_pair (set_uris->items[i], rec));
793                         }
794                 }
795                 lrdf_free_uris(set_uris);
796         }
797 #endif
798 }
799
800
801 bool
802 LadspaPlugin::load_preset (PresetRecord r)
803 {
804 #ifdef HAVE_LRDF
805         lrdf_defaults* defs = lrdf_get_setting_values (r.uri.c_str());
806
807         if (defs) {
808                 for (uint32_t i = 0; i < (uint32_t) defs->count; ++i) {
809                         if (parameter_is_input (defs->items[i].pid)) {
810                                 set_parameter(defs->items[i].pid, defs->items[i].value);
811                         }
812                 }
813                 lrdf_free_setting_values(defs);
814         }
815
816         Plugin::load_preset (r);
817 #endif
818         return true;
819 }
820
821 #ifdef HAVE_LRDF
822 /* XXX: should be in liblrdf */
823 static void
824 lrdf_remove_preset (const char* /*source*/, const char *setting_uri)
825 {
826         lrdf_statement p;
827         lrdf_statement *q;
828         lrdf_statement *i;
829         char setting_uri_copy[64];
830         char buf[64];
831
832         strncpy(setting_uri_copy, setting_uri, sizeof(setting_uri_copy));
833
834         p.subject = setting_uri_copy;
835         strncpy(buf, LADSPA_BASE "hasPortValue", sizeof(buf));
836         p.predicate = buf;
837         p.object = NULL;
838         q = lrdf_matches(&p);
839
840         p.predicate = NULL;
841         p.object = NULL;
842         for (i = q; i; i = i->next) {
843                 p.subject = i->object;
844                 lrdf_remove_matches(&p);
845         }
846
847         lrdf_free_statements(q);
848
849         p.subject = NULL;
850         strncpy(buf, LADSPA_BASE "hasSetting", sizeof(buf));
851         p.predicate = buf;
852         p.object = setting_uri_copy;
853         lrdf_remove_matches(&p);
854
855         p.subject = setting_uri_copy;
856         p.predicate = NULL;
857         p.object = NULL;
858         lrdf_remove_matches (&p);
859 }
860 #endif
861
862 void
863 LadspaPlugin::do_remove_preset (string name)
864 {
865 #ifdef HAVE_LRDF
866         string const envvar = preset_envvar ();
867         if (envvar.empty()) {
868                 warning << _("Could not locate HOME.  Preset not removed.") << endmsg;
869                 return;
870         }
871
872         Plugin::PresetRecord const * p = preset_by_label (name);
873         if (!p) {
874                 return;
875         }
876
877         string const source = preset_source (envvar);
878         lrdf_remove_preset (source.c_str(), p->uri.c_str ());
879
880         write_preset_file (envvar);
881 #endif
882 }
883
884 string
885 LadspaPlugin::preset_envvar () const
886 {
887         char* envvar;
888         if ((envvar = getenv ("HOME")) == 0) {
889                 return "";
890         }
891
892         return envvar;
893 }
894
895 string
896 LadspaPlugin::preset_source (string envvar) const
897 {
898         return string_compose ("file:%1/.ladspa/rdf/ardour-presets.n3", envvar);
899 }
900
901 bool
902 LadspaPlugin::write_preset_file (string envvar)
903 {
904 #ifdef HAVE_LRDF
905         string path = string_compose("%1/.ladspa", envvar);
906         if (g_mkdir_with_parents (path.c_str(), 0775)) {
907                 warning << string_compose(_("Could not create %1.  Preset not saved. (%2)"), path, strerror(errno)) << endmsg;
908                 return false;
909         }
910
911         path += "/rdf";
912         if (g_mkdir_with_parents (path.c_str(), 0775)) {
913                 warning << string_compose(_("Could not create %1.  Preset not saved. (%2)"), path, strerror(errno)) << endmsg;
914                 return false;
915         }
916
917         string const source = preset_source (envvar);
918
919         if (lrdf_export_by_source (source.c_str(), source.substr(5).c_str())) {
920                 warning << string_compose(_("Error saving presets file %1."), source) << endmsg;
921                 return false;
922         }
923
924         return true;
925 #else
926         return false;
927 #endif
928 }
929
930 string
931 LadspaPlugin::do_save_preset (string name)
932 {
933 #ifdef HAVE_LRDF
934         /* make a vector of pids that are input parameters */
935         vector<int> input_parameter_pids;
936         for (uint32_t i = 0; i < parameter_count(); ++i) {
937                 if (parameter_is_input (i)) {
938                         input_parameter_pids.push_back (i);
939                 }
940         }
941
942         std::string unique (unique_id());
943
944         if (!isdigit (unique[0])) {
945                 return "";
946         }
947
948         uint32_t const id = atol (unique.c_str());
949
950         lrdf_defaults defaults;
951         defaults.count = input_parameter_pids.size ();
952         std::vector<lrdf_portvalue> portvalues(input_parameter_pids.size());
953         defaults.items = &portvalues[0];
954
955         for (vector<int>::size_type i = 0; i < input_parameter_pids.size(); ++i) {
956                 portvalues[i].pid = input_parameter_pids[i];
957                 portvalues[i].value = get_parameter (input_parameter_pids[i]);
958         }
959
960         string const envvar = preset_envvar ();
961         if (envvar.empty()) {
962                 warning << _("Could not locate HOME.  Preset not saved.") << endmsg;
963                 return "";
964         }
965
966         string const source = preset_source (envvar);
967
968         char* uri_char = lrdf_add_preset (source.c_str(), name.c_str(), id, &defaults);
969         string uri (uri_char);
970         free (uri_char);
971
972         if (!write_preset_file (envvar)) {
973                 return "";
974         }
975
976         return uri;
977 #else
978         return string();
979 #endif
980 }
981
982 LADSPA_PortDescriptor
983 LadspaPlugin::port_descriptor (uint32_t i) const
984 {
985         if (i < _descriptor->PortCount) {
986                 return _descriptor->PortDescriptors[i];
987         }
988
989         warning << "LADSPA plugin port index " << i << " out of range." << endmsg;
990         return 0;
991 }
992
993
994