Reset fades on regions copied from time ranges in other regions (#4035).
[ardour2.git] / libs / ardour / plugin_manager.cc
blob5f01d49a6444360357b7656b6bdc421f2ffd9326
1 /*
2 Copyright (C) 2000-2006 Paul Davis
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.
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.
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.
20 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
24 #include <stdint.h>
26 #include <sys/types.h>
27 #include <cstdio>
28 #include <lrdf.h>
29 #include <dlfcn.h>
30 #include <cstdlib>
31 #include <fstream>
33 #ifdef VST_SUPPORT
34 #include <fst.h>
35 #include "pbd/basename.h"
36 #include <cstring>
37 #endif // VST_SUPPORT
39 #include <glibmm/miscutils.h>
41 #include "pbd/pathscanner.h"
42 #include "pbd/whitespace.h"
44 #include "ardour/ladspa.h"
45 #include "ardour/session.h"
46 #include "ardour/plugin_manager.h"
47 #include "ardour/plugin.h"
48 #include "ardour/ladspa_plugin.h"
49 #include "ardour/filesystem_paths.h"
51 #ifdef HAVE_SLV2
52 #include <slv2/slv2.h>
53 #include "ardour/lv2_plugin.h"
54 #endif
56 #ifdef VST_SUPPORT
57 #include "ardour/vst_plugin.h"
58 #endif
60 #ifdef HAVE_AUDIOUNITS
61 #include "ardour/audio_unit.h"
62 #include <Carbon/Carbon.h>
63 #endif
65 #include "pbd/error.h"
66 #include "pbd/stl_delete.h"
68 #include "i18n.h"
70 using namespace ARDOUR;
71 using namespace PBD;
72 using namespace std;
74 PluginManager* PluginManager::_manager = 0;
76 PluginManager::PluginManager ()
77 : _vst_plugin_info(0)
78 , _ladspa_plugin_info(0)
79 , _lv2_plugin_info(0)
80 , _au_plugin_info(0)
82 char* s;
83 string lrdf_path;
85 load_statuses ();
87 #ifdef HAVE_AUDIOUNITS
88 ProcessSerialNumber psn = { 0, kCurrentProcess };
89 OSStatus returnCode = TransformProcessType(& psn, kProcessTransformToForegroundApplication);
90 if( returnCode != 0) {
91 error << _("Cannot become GUI app") << endmsg;
93 #endif
95 if ((s = getenv ("LADSPA_RDF_PATH"))){
96 lrdf_path = s;
99 if (lrdf_path.length() == 0) {
100 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
103 add_lrdf_data(lrdf_path);
104 add_ladspa_presets();
105 #ifdef VST_SUPPORT
106 if (Config->get_use_vst()) {
107 add_vst_presets();
109 #endif /* VST_SUPPORT */
111 if ((s = getenv ("LADSPA_PATH"))) {
112 ladspa_path = s;
115 if ((s = getenv ("VST_PATH"))) {
116 vst_path = s;
117 } else if ((s = getenv ("VST_PLUGINS"))) {
118 vst_path = s;
121 if (_manager == 0) {
122 _manager = this;
125 /* the plugin manager is constructed too early to use Profile */
127 if (getenv ("ARDOUR_SAE")) {
128 ladspa_plugin_whitelist.push_back (1203); // single band parametric
129 ladspa_plugin_whitelist.push_back (1772); // caps compressor
130 ladspa_plugin_whitelist.push_back (1913); // fast lookahead limiter
131 ladspa_plugin_whitelist.push_back (1075); // simple RMS expander
132 ladspa_plugin_whitelist.push_back (1061); // feedback delay line (max 5s)
133 ladspa_plugin_whitelist.push_back (1216); // gverb
134 ladspa_plugin_whitelist.push_back (2150); // tap pitch shifter
137 #ifdef HAVE_SLV2
138 _lv2_world = new LV2World();
139 #endif
141 BootMessage (_("Discovering Plugins"));
145 PluginManager::~PluginManager()
147 #ifdef HAVE_SLV2
148 delete _lv2_world;
149 #endif
153 void
154 PluginManager::refresh ()
156 ladspa_refresh ();
157 #ifdef HAVE_SLV2
158 lv2_refresh ();
159 #endif
160 #ifdef VST_SUPPORT
161 if (Config->get_use_vst()) {
162 vst_refresh ();
164 #endif // VST_SUPPORT
165 #ifdef HAVE_AUDIOUNITS
166 au_refresh ();
167 #endif
169 PluginListChanged (); /* EMIT SIGNAL */
172 void
173 PluginManager::ladspa_refresh ()
175 if (_ladspa_plugin_info)
176 _ladspa_plugin_info->clear ();
177 else
178 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
180 static const char *standard_paths[] = {
181 "/usr/local/lib64/ladspa",
182 "/usr/local/lib/ladspa",
183 "/usr/lib64/ladspa",
184 "/usr/lib/ladspa",
185 "/Library/Audio/Plug-Ins/LADSPA",
189 /* allow LADSPA_PATH to augment, not override standard locations */
191 /* Only add standard locations to ladspa_path if it doesn't
192 * already contain them. Check for trailing G_DIR_SEPARATOR too.
195 int i;
196 for (i = 0; standard_paths[i][0]; i++) {
197 size_t found = ladspa_path.find(standard_paths[i]);
198 if (found != ladspa_path.npos) {
199 switch (ladspa_path[found + strlen(standard_paths[i])]) {
200 case ':' :
201 case '\0':
202 continue;
203 case G_DIR_SEPARATOR :
204 if (ladspa_path[found + strlen(standard_paths[i]) + 1] == ':' ||
205 ladspa_path[found + strlen(standard_paths[i]) + 1] == '\0') {
206 continue;
210 if (!ladspa_path.empty())
211 ladspa_path += ":";
213 ladspa_path += standard_paths[i];
217 ladspa_discover_from_path (ladspa_path);
222 PluginManager::add_ladspa_directory (string path)
224 if (ladspa_discover_from_path (path) == 0) {
225 ladspa_path += ':';
226 ladspa_path += path;
227 return 0;
229 return -1;
232 static bool ladspa_filter (const string& str, void */*arg*/)
234 /* Not a dotfile, has a prefix before a period, suffix is "so" */
236 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
240 PluginManager::ladspa_discover_from_path (string /*path*/)
242 PathScanner scanner;
243 vector<string *> *plugin_objects;
244 vector<string *>::iterator x;
245 int ret = 0;
247 plugin_objects = scanner (ladspa_path, ladspa_filter, 0, true, true);
249 if (plugin_objects) {
250 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
251 ladspa_discover (**x);
255 vector_delete (plugin_objects);
256 return ret;
259 static bool rdf_filter (const string &str, void* /*arg*/)
261 return str[0] != '.' &&
262 ((str.find(".rdf") == (str.length() - 4)) ||
263 (str.find(".rdfs") == (str.length() - 5)) ||
264 (str.find(".n3") == (str.length() - 3)) ||
265 (str.find(".ttl") == (str.length() - 4)));
268 void
269 PluginManager::add_ladspa_presets()
271 add_presets ("ladspa");
274 void
275 PluginManager::add_vst_presets()
277 add_presets ("vst");
279 void
280 PluginManager::add_presets(string domain)
283 PathScanner scanner;
284 vector<string *> *presets;
285 vector<string *>::iterator x;
287 char* envvar;
288 if ((envvar = getenv ("HOME")) == 0) {
289 return;
292 string path = string_compose("%1/.%2/rdf", envvar, domain);
293 presets = scanner (path, rdf_filter, 0, true, true);
295 if (presets) {
296 for (x = presets->begin(); x != presets->end (); ++x) {
297 string file = "file:" + **x;
298 if (lrdf_read_file(file.c_str())) {
299 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
304 vector_delete (presets);
307 void
308 PluginManager::add_lrdf_data (const string &path)
310 PathScanner scanner;
311 vector<string *>* rdf_files;
312 vector<string *>::iterator x;
314 rdf_files = scanner (path, rdf_filter, 0, true, true);
316 if (rdf_files) {
317 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
318 const string uri(string("file://") + **x);
320 if (lrdf_read_file(uri.c_str())) {
321 warning << "Could not parse rdf file: " << uri << endmsg;
326 vector_delete (rdf_files);
330 PluginManager::ladspa_discover (string path)
332 void *module;
333 const LADSPA_Descriptor *descriptor;
334 LADSPA_Descriptor_Function dfunc;
335 const char *errstr;
337 if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
338 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg;
339 return -1;
342 dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor");
344 if ((errstr = dlerror()) != 0) {
345 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
346 error << errstr << endmsg;
347 dlclose (module);
348 return -1;
351 for (uint32_t i = 0; ; ++i) {
352 if ((descriptor = dfunc (i)) == 0) {
353 break;
356 if (!ladspa_plugin_whitelist.empty()) {
357 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
358 continue;
362 PluginInfoPtr info(new LadspaPluginInfo);
363 info->name = descriptor->Name;
364 info->category = get_ladspa_category(descriptor->UniqueID);
365 info->creator = descriptor->Maker;
366 info->path = path;
367 info->index = i;
368 info->n_inputs = ChanCount();
369 info->n_outputs = ChanCount();
370 info->type = ARDOUR::LADSPA;
372 char buf[32];
373 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
374 info->unique_id = buf;
376 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
377 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
378 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
379 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
381 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
382 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
387 if(_ladspa_plugin_info->empty()){
388 _ladspa_plugin_info->push_back (info);
391 //Ensure that the plugin is not already in the plugin list.
393 bool found = false;
395 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
396 if(0 == info->unique_id.compare((*i)->unique_id)){
397 found = true;
401 if(!found){
402 _ladspa_plugin_info->push_back (info);
406 // GDB WILL NOT LIKE YOU IF YOU DO THIS
407 // dlclose (module);
409 return 0;
412 string
413 PluginManager::get_ladspa_category (uint32_t plugin_id)
415 char buf[256];
416 lrdf_statement pattern;
418 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
419 pattern.subject = buf;
420 pattern.predicate = (char*)RDF_TYPE;
421 pattern.object = 0;
422 pattern.object_type = lrdf_uri;
424 lrdf_statement* matches1 = lrdf_matches (&pattern);
426 if (!matches1) {
427 return "Unknown";
430 pattern.subject = matches1->object;
431 pattern.predicate = (char*)(LADSPA_BASE "hasLabel");
432 pattern.object = 0;
433 pattern.object_type = lrdf_literal;
435 lrdf_statement* matches2 = lrdf_matches (&pattern);
436 lrdf_free_statements(matches1);
438 if (!matches2) {
439 return ("Unknown");
442 string label = matches2->object;
443 lrdf_free_statements(matches2);
445 /* Kludge LADSPA class names to be singular and match LV2 class names.
446 This avoids duplicate plugin menus for every class, which is necessary
447 to make the plugin category menu at all usable, but is obviously a
448 filthy kludge.
450 In the short term, lrdf could be updated so the labels match and a new
451 release made. To support both specs, we should probably be mapping the
452 URIs to the same category in code and perhaps tweaking that hierarchy
453 dynamically to suit the user. Personally, I (drobilla) think that time
454 is better spent replacing the little-used LRDF.
456 In the longer term, we will abandon LRDF entirely in favour of LV2 and
457 use that class hierarchy. Aside from fixing this problem properly, that
458 will also allow for translated labels. SWH plugins have been LV2 for
459 ages; TAP needs porting. I don't know of anything else with LRDF data.
461 if (label == "Utilities") {
462 return "Utility";
463 } else if (label == "Pitch shifters") {
464 return "Pitch Shifter";
465 } else if (label != "Dynamics" && label != "Chorus"
466 &&label[label.length() - 1] == 's'
467 && label[label.length() - 2] != 's') {
468 return label.substr(0, label.length() - 1);
469 } else {
470 return label;
474 #ifdef HAVE_SLV2
475 void
476 PluginManager::lv2_refresh ()
478 delete _lv2_plugin_info;
479 _lv2_plugin_info = LV2PluginInfo::discover(_lv2_world);
481 #endif
483 #ifdef HAVE_AUDIOUNITS
484 void
485 PluginManager::au_refresh ()
487 delete _au_plugin_info;
488 _au_plugin_info = AUPluginInfo::discover();
491 #endif
493 #ifdef VST_SUPPORT
495 void
496 PluginManager::vst_refresh ()
498 if (_vst_plugin_info)
499 _vst_plugin_info->clear ();
500 else
501 _vst_plugin_info = new ARDOUR::PluginInfoList();
503 if (vst_path.length() == 0) {
504 vst_path = "/usr/local/lib/vst:/usr/lib/vst";
507 vst_discover_from_path (vst_path);
511 PluginManager::add_vst_directory (string path)
513 if (vst_discover_from_path (path) == 0) {
514 vst_path += ':';
515 vst_path += path;
516 return 0;
518 return -1;
521 static bool vst_filter (const string& str, void *arg)
523 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
525 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
529 PluginManager::vst_discover_from_path (string path)
531 PathScanner scanner;
532 vector<string *> *plugin_objects;
533 vector<string *>::iterator x;
534 int ret = 0;
536 info << "detecting VST plugins along " << path << endmsg;
538 plugin_objects = scanner (vst_path, vst_filter, 0, true, true);
540 if (plugin_objects) {
541 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
542 vst_discover (**x);
546 vector_delete (plugin_objects);
547 return ret;
551 PluginManager::vst_discover (string path)
553 FSTInfo* finfo;
554 char buf[32];
556 if ((finfo = fst_get_info (const_cast<char *> (path.c_str()))) == 0) {
557 warning << "Cannot get VST information from " << path << endmsg;
558 return -1;
561 if (!finfo->canProcessReplacing) {
562 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in ardour at this time"),
563 finfo->name)
564 << endl;
567 PluginInfoPtr info(new VSTPluginInfo);
569 /* what a joke freeware VST is */
571 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
572 info->name = PBD::basename_nosuffix (path);
573 } else {
574 info->name = finfo->name;
578 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
579 info->unique_id = buf;
580 info->category = "VST";
581 info->path = path;
582 info->creator = finfo->creator;
583 info->index = 0;
584 info->n_inputs.set_audio (finfo->numInputs);
585 info->n_outputs.set_audio (finfo->numOutputs);
586 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
587 info->type = ARDOUR::VST;
589 _vst_plugin_info->push_back (info);
590 fst_free_info (finfo);
592 return 0;
595 #endif // VST_SUPPORT
597 PluginManager::PluginStatusType
598 PluginManager::get_status (const PluginInfoPtr& pi)
600 PluginStatus ps (pi->type, pi->unique_id);
601 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
602 if (i == statuses.end() ) {
603 return Normal;
604 } else {
605 return i->status;
609 void
610 PluginManager::save_statuses ()
612 ofstream ofs;
613 sys::path path = user_config_directory();
614 path /= "plugin_statuses";
616 ofs.open (path.to_string().c_str(), ios_base::openmode (ios::out|ios::trunc));
618 if (!ofs) {
619 return;
622 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
623 switch ((*i).type) {
624 case LADSPA:
625 ofs << "LADSPA";
626 break;
627 case AudioUnit:
628 ofs << "AudioUnit";
629 break;
630 case LV2:
631 ofs << "LV2";
632 break;
633 case VST:
634 ofs << "VST";
635 break;
638 ofs << ' ';
640 switch ((*i).status) {
641 case Normal:
642 ofs << "Normal";
643 break;
644 case Favorite:
645 ofs << "Favorite";
646 break;
647 case Hidden:
648 ofs << "Hidden";
649 break;
652 ofs << ' ';
653 ofs << (*i).unique_id;;
654 ofs << endl;
657 ofs.close ();
660 void
661 PluginManager::load_statuses ()
663 sys::path path = user_config_directory();
664 path /= "plugin_statuses";
665 ifstream ifs (path.to_string().c_str());
667 if (!ifs) {
668 return;
671 std::string stype;
672 std::string sstatus;
673 std::string id;
674 PluginType type;
675 PluginStatusType status;
676 char buf[1024];
678 while (ifs) {
680 ifs >> stype;
681 if (!ifs) {
682 break;
686 ifs >> sstatus;
687 if (!ifs) {
688 break;
692 /* rest of the line is the plugin ID */
694 ifs.getline (buf, sizeof (buf), '\n');
695 if (!ifs) {
696 break;
699 if (sstatus == "Normal") {
700 status = Normal;
701 } else if (sstatus == "Favorite") {
702 status = Favorite;
703 } else if (sstatus == "Hidden") {
704 status = Hidden;
705 } else {
706 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
707 << endmsg;
708 statuses.clear ();
709 break;
712 if (stype == "LADSPA") {
713 type = LADSPA;
714 } else if (stype == "AudioUnit") {
715 type = AudioUnit;
716 } else if (stype == "LV2") {
717 type = LV2;
718 } else if (stype == "VST") {
719 type = VST;
720 } else {
721 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
722 << endmsg;
723 continue;
726 id = buf;
727 strip_whitespace_edges (id);
728 set_status (type, id, status);
731 ifs.close ();
734 void
735 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
737 PluginStatus ps (t, id, status);
738 statuses.erase (ps);
740 if (status == Normal) {
741 return;
744 pair<PluginStatusList::iterator, bool> res = statuses.insert (ps);
745 //cerr << "Added " << t << " " << id << " " << status << " success ? " << res.second << endl;
748 ARDOUR::PluginInfoList&
749 PluginManager::vst_plugin_info ()
751 #ifdef VST_SUPPORT
752 if (!_vst_plugin_info)
753 vst_refresh();
754 return *_vst_plugin_info;
755 #else
756 return _empty_plugin_info;
757 #endif
760 ARDOUR::PluginInfoList&
761 PluginManager::ladspa_plugin_info ()
763 if (!_ladspa_plugin_info)
764 ladspa_refresh();
765 return *_ladspa_plugin_info;
768 ARDOUR::PluginInfoList&
769 PluginManager::lv2_plugin_info ()
771 #ifdef HAVE_SLV2
772 if (!_lv2_plugin_info)
773 lv2_refresh();
774 return *_lv2_plugin_info;
775 #else
776 return _empty_plugin_info;
777 #endif
780 ARDOUR::PluginInfoList&
781 PluginManager::au_plugin_info ()
783 #ifdef HAVE_AUDIOUNITS
784 if (!_au_plugin_info)
785 au_refresh();
786 return *_au_plugin_info;
787 #else
788 return _empty_plugin_info;
789 #endif