Fix range-separate for musically-locked MIDI regions
[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         LocaleGuard lg;
351
352         for (uint32_t i = 0; i < parameter_count(); ++i){
353
354                 if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) &&
355                     LADSPA_IS_PORT_CONTROL(port_descriptor (i))){
356
357                         child = new XMLNode("Port");
358                         child->set_property("number", i);
359                         child->set_property("value", _shadow_data[i]);
360                         root->add_child_nocopy (*child);
361                 }
362         }
363 }
364
365 int
366 LadspaPlugin::set_state (const XMLNode& node, int version)
367 {
368         if (version < 3000) {
369                 return set_state_2X (node, version);
370         }
371
372 #ifndef NO_PLUGIN_STATE
373         XMLNodeList nodes;
374         XMLNodeConstIterator iter;
375         XMLNode *child;
376 #endif
377         LocaleGuard lg;
378
379         if (node.name() != state_node_name()) {
380                 error << _("Bad node sent to LadspaPlugin::set_state") << endmsg;
381                 return -1;
382         }
383
384 #ifndef NO_PLUGIN_STATE
385
386         nodes = node.children ("Port");
387
388         for (iter = nodes.begin(); iter != nodes.end(); ++iter) {
389
390                 child = *iter;
391
392                 uint32_t port_id;
393                 float value;
394
395                 if (!child->get_property ("number", port_id)) {
396                         warning << _("LADSPA: no ladspa port number") << endmsg;
397                         continue;
398                 }
399
400                 if (!child->get_property ("value", value)) {
401                         warning << _("LADSPA: no ladspa port data") << endmsg;
402                         continue;
403                 }
404
405                 set_parameter (port_id, value);
406         }
407 #endif
408
409         latency_compute_run ();
410
411         return Plugin::set_state (node, version);
412 }
413
414 int
415 LadspaPlugin::set_state_2X (const XMLNode& node, int /* version */)
416 {
417 #ifndef NO_PLUGIN_STATE
418         XMLNodeList nodes;
419         XMLProperty const * prop;
420         XMLNodeConstIterator iter;
421         XMLNode *child;
422         const char *port;
423         const char *data;
424         uint32_t port_id;
425 #endif
426         LocaleGuard lg;
427
428         if (node.name() != state_node_name()) {
429                 error << _("Bad node sent to LadspaPlugin::set_state") << endmsg;
430                 return -1;
431         }
432
433 #ifndef NO_PLUGIN_STATE
434         nodes = node.children ("port");
435
436         for(iter = nodes.begin(); iter != nodes.end(); ++iter){
437
438                 child = *iter;
439
440                 if ((prop = child->property("number")) != 0) {
441                         port = prop->value().c_str();
442                 } else {
443                         warning << _("LADSPA: no ladspa port number") << endmsg;
444                         continue;
445                 }
446                 if ((prop = child->property("value")) != 0) {
447                         data = prop->value().c_str();
448                 } else {
449                         warning << _("LADSPA: no ladspa port data") << endmsg;
450                         continue;
451                 }
452
453                 sscanf (port, "%" PRIu32, &port_id);
454                 set_parameter (port_id, atof(data));
455         }
456
457         latency_compute_run ();
458 #endif
459
460         return 0;
461 }
462
463 int
464 LadspaPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) const
465 {
466         LADSPA_PortRangeHint prh;
467
468         prh  = port_range_hints()[which];
469
470
471         if (LADSPA_IS_HINT_BOUNDED_BELOW(prh.HintDescriptor)) {
472                 desc.min_unbound = false;
473                 if (LADSPA_IS_HINT_SAMPLE_RATE(prh.HintDescriptor)) {
474                         desc.lower = prh.LowerBound * _session.frame_rate();
475                 } else {
476                         desc.lower = prh.LowerBound;
477                 }
478         } else {
479                 desc.min_unbound = true;
480                 desc.lower = 0;
481         }
482
483
484         if (LADSPA_IS_HINT_BOUNDED_ABOVE(prh.HintDescriptor)) {
485                 desc.max_unbound = false;
486                 if (LADSPA_IS_HINT_SAMPLE_RATE(prh.HintDescriptor)) {
487                         desc.upper = prh.UpperBound * _session.frame_rate();
488                 } else {
489                         desc.upper = prh.UpperBound;
490                 }
491         } else {
492                 if (LADSPA_IS_HINT_TOGGLED (prh.HintDescriptor)) {
493                         desc.max_unbound = false;
494                         desc.upper = 1;
495                 } else {
496                         desc.max_unbound = true;
497                         desc.upper = 4; /* completely arbitrary */
498                 }
499         }
500
501         if (LADSPA_IS_HINT_HAS_DEFAULT (prh.HintDescriptor)) {
502                 desc.normal = _default_value(which);
503         } else {
504                 /* if there is no explicit hint for the default
505                  * value, use lower bound. This is not great but
506                  * better than just assuming '0' which may be out-of range.
507                  */
508                 desc.normal = desc.lower;
509         }
510
511         desc.toggled = LADSPA_IS_HINT_TOGGLED (prh.HintDescriptor);
512         desc.logarithmic = LADSPA_IS_HINT_LOGARITHMIC (prh.HintDescriptor);
513         desc.sr_dependent = LADSPA_IS_HINT_SAMPLE_RATE (prh.HintDescriptor);
514         desc.integer_step = LADSPA_IS_HINT_INTEGER (prh.HintDescriptor);
515
516         desc.label = port_names()[which];
517
518         desc.scale_points = get_scale_points(which);
519         desc.update_steps();
520
521         return 0;
522 }
523
524 string
525 LadspaPlugin::describe_parameter (Evoral::Parameter which)
526 {
527         if (which.type() == PluginAutomation && which.id() < parameter_count()) {
528                 return port_names()[which.id()];
529         } else {
530                 return "??";
531         }
532 }
533
534 ARDOUR::framecnt_t
535 LadspaPlugin::signal_latency () const
536 {
537         if (_user_latency) {
538                 return _user_latency;
539         }
540
541         if (_latency_control_port) {
542                 return (framecnt_t) floor (*_latency_control_port);
543         } else {
544                 return 0;
545         }
546 }
547
548 set<Evoral::Parameter>
549 LadspaPlugin::automatable () const
550 {
551         set<Evoral::Parameter> ret;
552
553         for (uint32_t i = 0; i < parameter_count(); ++i){
554                 if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) &&
555                     LADSPA_IS_PORT_CONTROL(port_descriptor (i))){
556
557                         ret.insert (ret.end(), Evoral::Parameter(PluginAutomation, 0, i));
558                 }
559         }
560
561         return ret;
562 }
563
564 int
565 LadspaPlugin::connect_and_run (BufferSet& bufs,
566                 framepos_t start, framepos_t end, double speed,
567                 ChanMapping in_map, ChanMapping out_map,
568                 pframes_t nframes, framecnt_t offset)
569 {
570         Plugin::connect_and_run (bufs, start, end, speed, in_map, out_map, nframes, offset);
571
572         cycles_t now;
573         cycles_t then = get_cycles ();
574
575         BufferSet& silent_bufs  = _session.get_silent_buffers(ChanCount(DataType::AUDIO, 1));
576         BufferSet& scratch_bufs = _session.get_scratch_buffers(ChanCount(DataType::AUDIO, 1));
577
578         uint32_t audio_in_index  = 0;
579         uint32_t audio_out_index = 0;
580         bool valid;
581         for (uint32_t port_index = 0; port_index < parameter_count(); ++port_index) {
582                 if (LADSPA_IS_PORT_AUDIO(port_descriptor(port_index))) {
583                         if (LADSPA_IS_PORT_INPUT(port_descriptor(port_index))) {
584                                 const uint32_t buf_index = in_map.get(DataType::AUDIO, audio_in_index++, &valid);
585                                 connect_port(port_index,
586                                              valid ? bufs.get_audio(buf_index).data(offset)
587                                                    : silent_bufs.get_audio(0).data(offset));
588                         } else if (LADSPA_IS_PORT_OUTPUT(port_descriptor(port_index))) {
589                                 const uint32_t buf_index = out_map.get(DataType::AUDIO, audio_out_index++, &valid);
590                                 connect_port(port_index,
591                                              valid ? bufs.get_audio(buf_index).data(offset)
592                                                    : scratch_bufs.get_audio(0).data(offset));
593                         }
594                 }
595         }
596
597         run_in_place (nframes);
598         now = get_cycles ();
599         set_cycles ((uint32_t) (now - then));
600
601         return 0;
602 }
603
604 bool
605 LadspaPlugin::parameter_is_control (uint32_t param) const
606 {
607         return LADSPA_IS_PORT_CONTROL(port_descriptor (param));
608 }
609
610 bool
611 LadspaPlugin::parameter_is_audio (uint32_t param) const
612 {
613         return LADSPA_IS_PORT_AUDIO(port_descriptor (param));
614 }
615
616 bool
617 LadspaPlugin::parameter_is_output (uint32_t param) const
618 {
619         return LADSPA_IS_PORT_OUTPUT(port_descriptor (param));
620 }
621
622 bool
623 LadspaPlugin::parameter_is_input (uint32_t param) const
624 {
625         return LADSPA_IS_PORT_INPUT(port_descriptor (param));
626 }
627
628 void
629 LadspaPlugin::print_parameter (uint32_t param, char *buf, uint32_t len) const
630 {
631         if (buf && len) {
632                 if (param < parameter_count()) {
633                         snprintf (buf, len, "%.3f", get_parameter (param));
634                 } else {
635                         strcat (buf, "0");
636                 }
637         }
638 }
639
640 boost::shared_ptr<ScalePoints>
641 LadspaPlugin::get_scale_points(uint32_t port_index) const
642 {
643         boost::shared_ptr<ScalePoints> ret;
644 #ifdef HAVE_LRDF
645         const uint32_t id     = atol(unique_id().c_str());
646         lrdf_defaults* points = lrdf_get_scale_values(id, port_index);
647
648         if (!points) {
649                 return ret;
650         }
651
652         ret = boost::shared_ptr<ScalePoints>(new ScalePoints());
653
654         for (uint32_t i = 0; i < points->count; ++i) {
655                 ret->insert(make_pair(points->items[i].label,
656                                       points->items[i].value));
657         }
658
659         lrdf_free_setting_values(points);
660 #endif
661         return ret;
662 }
663
664 void
665 LadspaPlugin::run_in_place (pframes_t nframes)
666 {
667         for (uint32_t i = 0; i < parameter_count(); ++i) {
668                 if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && LADSPA_IS_PORT_CONTROL(port_descriptor (i))) {
669                         _control_data[i] = _shadow_data[i];
670                 }
671         }
672
673         assert (_was_activated);
674
675         _descriptor->run (_handle, nframes);
676 }
677
678 void
679 LadspaPlugin::latency_compute_run ()
680 {
681         if (!_latency_control_port) {
682                 return;
683         }
684
685         /* we need to run the plugin so that it can set its latency
686            parameter.
687         */
688
689         activate ();
690
691         uint32_t port_index = 0;
692         uint32_t in_index = 0;
693         uint32_t out_index = 0;
694         const framecnt_t bufsize = 1024;
695         LADSPA_Data buffer[bufsize];
696
697         memset(buffer,0,sizeof(LADSPA_Data)*bufsize);
698
699         /* Note that we've already required that plugins
700            be able to handle in-place processing.
701         */
702
703         port_index = 0;
704
705         while (port_index < parameter_count()) {
706                 if (LADSPA_IS_PORT_AUDIO (port_descriptor (port_index))) {
707                         if (LADSPA_IS_PORT_INPUT (port_descriptor (port_index))) {
708                                 connect_port (port_index, buffer);
709                                 in_index++;
710                         } else if (LADSPA_IS_PORT_OUTPUT (port_descriptor (port_index))) {
711                                 connect_port (port_index, buffer);
712                                 out_index++;
713                         }
714                 }
715                 port_index++;
716         }
717
718         run_in_place (bufsize);
719         deactivate ();
720 }
721
722 PluginPtr
723 LadspaPluginInfo::load (Session& session)
724 {
725         try {
726                 PluginPtr plugin (new LadspaPlugin (path, session.engine(), session, index, session.frame_rate()));
727                 plugin->set_info(PluginInfoPtr(new LadspaPluginInfo(*this)));
728                 return plugin;
729         }
730
731         catch (failed_constructor &err) {
732                 return PluginPtr ((Plugin*) 0);
733         }
734 }
735
736 std::vector<Plugin::PresetRecord>
737 LadspaPluginInfo::get_presets (bool /*user_only*/) const
738 {
739         std::vector<Plugin::PresetRecord> p;
740 #if (defined HAVE_LRDF && !defined NO_PLUGIN_STATE)
741         if (!isdigit (unique_id[0])) {
742                 return p;
743         }
744         uint32_t id = atol (unique_id);
745         lrdf_uris* set_uris = lrdf_get_setting_uris(id);
746
747         if (set_uris) {
748                 for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) {
749                         if (char* label = lrdf_get_label (set_uris->items[i])) {
750                                 p.push_back (Plugin::PresetRecord (set_uris->items[i], label));
751                         }
752                 }
753                 lrdf_free_uris(set_uris);
754         }
755 #endif
756         return p;
757 }
758
759 LadspaPluginInfo::LadspaPluginInfo()
760 {
761        type = ARDOUR::LADSPA;
762 }
763
764
765 void
766 LadspaPlugin::find_presets ()
767 {
768 #ifdef HAVE_LRDF
769         uint32_t id;
770         std::string unique (unique_id());
771
772         if (!isdigit (unique[0])) {
773                 return;
774         }
775
776         id = atol (unique.c_str());
777
778         lrdf_uris* set_uris = lrdf_get_setting_uris(id);
779
780         if (set_uris) {
781                 for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) {
782                         if (char* label = lrdf_get_label(set_uris->items[i])) {
783                                 PresetRecord rec (set_uris->items[i], label);
784                                 _presets.insert (make_pair (set_uris->items[i], rec));
785                         }
786                 }
787                 lrdf_free_uris(set_uris);
788         }
789 #endif
790 }
791
792
793 bool
794 LadspaPlugin::load_preset (PresetRecord r)
795 {
796 #ifdef HAVE_LRDF
797         lrdf_defaults* defs = lrdf_get_setting_values (r.uri.c_str());
798
799         if (defs) {
800                 for (uint32_t i = 0; i < (uint32_t) defs->count; ++i) {
801                         if (parameter_is_input (defs->items[i].pid)) {
802                                 set_parameter(defs->items[i].pid, defs->items[i].value);
803                                 PresetPortSetValue (defs->items[i].pid, defs->items[i].value); /* EMIT SIGNAL */
804                         }
805                 }
806                 lrdf_free_setting_values(defs);
807         }
808
809         Plugin::load_preset (r);
810 #endif
811         return true;
812 }
813
814 #ifdef HAVE_LRDF
815 /* XXX: should be in liblrdf */
816 static void
817 lrdf_remove_preset (const char* /*source*/, const char *setting_uri)
818 {
819         lrdf_statement p;
820         lrdf_statement *q;
821         lrdf_statement *i;
822         char setting_uri_copy[64];
823         char buf[64];
824
825         strncpy(setting_uri_copy, setting_uri, sizeof(setting_uri_copy));
826
827         p.subject = setting_uri_copy;
828         strncpy(buf, LADSPA_BASE "hasPortValue", sizeof(buf));
829         p.predicate = buf;
830         p.object = NULL;
831         q = lrdf_matches(&p);
832
833         p.predicate = NULL;
834         p.object = NULL;
835         for (i = q; i; i = i->next) {
836                 p.subject = i->object;
837                 lrdf_remove_matches(&p);
838         }
839
840         lrdf_free_statements(q);
841
842         p.subject = NULL;
843         strncpy(buf, LADSPA_BASE "hasSetting", sizeof(buf));
844         p.predicate = buf;
845         p.object = setting_uri_copy;
846         lrdf_remove_matches(&p);
847
848         p.subject = setting_uri_copy;
849         p.predicate = NULL;
850         p.object = NULL;
851         lrdf_remove_matches (&p);
852 }
853 #endif
854
855 void
856 LadspaPlugin::do_remove_preset (string name)
857 {
858 #ifdef HAVE_LRDF
859         string const envvar = preset_envvar ();
860         if (envvar.empty()) {
861                 warning << _("Could not locate HOME.  Preset not removed.") << endmsg;
862                 return;
863         }
864
865         Plugin::PresetRecord const * p = preset_by_label (name);
866         if (!p) {
867                 return;
868         }
869
870         string const source = preset_source (envvar);
871         lrdf_remove_preset (source.c_str(), p->uri.c_str ());
872
873         write_preset_file (envvar);
874 #endif
875 }
876
877 string
878 LadspaPlugin::preset_envvar () const
879 {
880         char* envvar;
881         if ((envvar = getenv ("HOME")) == 0) {
882                 return "";
883         }
884
885         return envvar;
886 }
887
888 string
889 LadspaPlugin::preset_source (string envvar) const
890 {
891         return string_compose ("file:%1/.ladspa/rdf/ardour-presets.n3", envvar);
892 }
893
894 bool
895 LadspaPlugin::write_preset_file (string envvar)
896 {
897 #ifdef HAVE_LRDF
898         string path = string_compose("%1/.ladspa", envvar);
899         if (g_mkdir_with_parents (path.c_str(), 0775)) {
900                 warning << string_compose(_("Could not create %1.  Preset not saved. (%2)"), path, strerror(errno)) << endmsg;
901                 return false;
902         }
903
904         path += "/rdf";
905         if (g_mkdir_with_parents (path.c_str(), 0775)) {
906                 warning << string_compose(_("Could not create %1.  Preset not saved. (%2)"), path, strerror(errno)) << endmsg;
907                 return false;
908         }
909
910         string const source = preset_source (envvar);
911
912         if (lrdf_export_by_source (source.c_str(), source.substr(5).c_str())) {
913                 warning << string_compose(_("Error saving presets file %1."), source) << endmsg;
914                 return false;
915         }
916
917         return true;
918 #else
919         return false;
920 #endif
921 }
922
923 string
924 LadspaPlugin::do_save_preset (string name)
925 {
926 #ifdef HAVE_LRDF
927         /* make a vector of pids that are input parameters */
928         vector<int> input_parameter_pids;
929         for (uint32_t i = 0; i < parameter_count(); ++i) {
930                 if (parameter_is_input (i)) {
931                         input_parameter_pids.push_back (i);
932                 }
933         }
934
935         std::string unique (unique_id());
936
937         if (!isdigit (unique[0])) {
938                 return "";
939         }
940
941         uint32_t const id = atol (unique.c_str());
942
943         lrdf_defaults defaults;
944         defaults.count = input_parameter_pids.size ();
945         std::vector<lrdf_portvalue> portvalues(input_parameter_pids.size());
946         defaults.items = &portvalues[0];
947
948         for (vector<int>::size_type i = 0; i < input_parameter_pids.size(); ++i) {
949                 portvalues[i].pid = input_parameter_pids[i];
950                 portvalues[i].value = get_parameter (input_parameter_pids[i]);
951         }
952
953         string const envvar = preset_envvar ();
954         if (envvar.empty()) {
955                 warning << _("Could not locate HOME.  Preset not saved.") << endmsg;
956                 return "";
957         }
958
959         string const source = preset_source (envvar);
960
961         char* uri_char = lrdf_add_preset (source.c_str(), name.c_str(), id, &defaults);
962         string uri (uri_char);
963         free (uri_char);
964
965         if (!write_preset_file (envvar)) {
966                 return "";
967         }
968
969         return uri;
970 #else
971         return string();
972 #endif
973 }
974
975 LADSPA_PortDescriptor
976 LadspaPlugin::port_descriptor (uint32_t i) const
977 {
978         if (i < _descriptor->PortCount) {
979                 return _descriptor->PortDescriptors[i];
980         }
981
982         warning << "LADSPA plugin port index " << i << " out of range." << endmsg;
983         return 0;
984 }
985
986
987