5f01d49a6444360357b7656b6bdc421f2ffd9326
[ardour.git] / libs / ardour / plugin_manager.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 <stdint.h>
25
26 #include <sys/types.h>
27 #include <cstdio>
28 #include <lrdf.h>
29 #include <dlfcn.h>
30 #include <cstdlib>
31 #include <fstream>
32
33 #ifdef VST_SUPPORT
34 #include <fst.h>
35 #include "pbd/basename.h"
36 #include <cstring>
37 #endif // VST_SUPPORT
38
39 #include <glibmm/miscutils.h>
40
41 #include "pbd/pathscanner.h"
42 #include "pbd/whitespace.h"
43
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"
50
51 #ifdef HAVE_SLV2
52 #include <slv2/slv2.h>
53 #include "ardour/lv2_plugin.h"
54 #endif
55
56 #ifdef VST_SUPPORT
57 #include "ardour/vst_plugin.h"
58 #endif
59
60 #ifdef HAVE_AUDIOUNITS
61 #include "ardour/audio_unit.h"
62 #include <Carbon/Carbon.h>
63 #endif
64
65 #include "pbd/error.h"
66 #include "pbd/stl_delete.h"
67
68 #include "i18n.h"
69
70 using namespace ARDOUR;
71 using namespace PBD;
72 using namespace std;
73
74 PluginManager* PluginManager::_manager = 0;
75
76 PluginManager::PluginManager ()
77         : _vst_plugin_info(0)
78         , _ladspa_plugin_info(0)
79         , _lv2_plugin_info(0)
80         , _au_plugin_info(0)
81 {
82         char* s;
83         string lrdf_path;
84
85         load_statuses ();
86
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;
92         }
93 #endif
94
95         if ((s = getenv ("LADSPA_RDF_PATH"))){
96                 lrdf_path = s;
97         }
98
99         if (lrdf_path.length() == 0) {
100                 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
101         }
102
103         add_lrdf_data(lrdf_path);
104         add_ladspa_presets();
105 #ifdef VST_SUPPORT
106         if (Config->get_use_vst()) {
107                 add_vst_presets();
108         }
109 #endif /* VST_SUPPORT */
110
111         if ((s = getenv ("LADSPA_PATH"))) {
112                 ladspa_path = s;
113         }
114
115         if ((s = getenv ("VST_PATH"))) {
116                 vst_path = s;
117         } else if ((s = getenv ("VST_PLUGINS"))) {
118                 vst_path = s;
119         }
120
121         if (_manager == 0) {
122                 _manager = this;
123         }
124
125         /* the plugin manager is constructed too early to use Profile */
126
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
135         }
136
137 #ifdef HAVE_SLV2
138         _lv2_world = new LV2World();
139 #endif
140
141         BootMessage (_("Discovering Plugins"));
142 }
143
144
145 PluginManager::~PluginManager()
146 {
147 #ifdef HAVE_SLV2
148         delete _lv2_world;
149 #endif
150 }
151
152
153 void
154 PluginManager::refresh ()
155 {
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 ();
163         }
164 #endif // VST_SUPPORT
165 #ifdef HAVE_AUDIOUNITS
166         au_refresh ();
167 #endif
168
169         PluginListChanged (); /* EMIT SIGNAL */
170 }
171
172 void
173 PluginManager::ladspa_refresh ()
174 {
175         if (_ladspa_plugin_info)
176                 _ladspa_plugin_info->clear ();
177         else
178                 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
179
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",
186                 ""
187         };
188
189         /* allow LADSPA_PATH to augment, not override standard locations */
190
191         /* Only add standard locations to ladspa_path if it doesn't
192          * already contain them. Check for trailing G_DIR_SEPARATOR too.
193          */
194
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;
207                                         }
208                         }
209                 }
210                 if (!ladspa_path.empty())
211                         ladspa_path += ":";
212
213                 ladspa_path += standard_paths[i];
214
215         }
216
217         ladspa_discover_from_path (ladspa_path);
218 }
219
220
221 int
222 PluginManager::add_ladspa_directory (string path)
223 {
224         if (ladspa_discover_from_path (path) == 0) {
225                 ladspa_path += ':';
226                 ladspa_path += path;
227                 return 0;
228         }
229         return -1;
230 }
231
232 static bool ladspa_filter (const string& str, void */*arg*/)
233 {
234         /* Not a dotfile, has a prefix before a period, suffix is "so" */
235
236         return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
237 }
238
239 int
240 PluginManager::ladspa_discover_from_path (string /*path*/)
241 {
242         PathScanner scanner;
243         vector<string *> *plugin_objects;
244         vector<string *>::iterator x;
245         int ret = 0;
246
247         plugin_objects = scanner (ladspa_path, ladspa_filter, 0, true, true);
248
249         if (plugin_objects) {
250                 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
251                         ladspa_discover (**x);
252                 }
253         }
254
255         vector_delete (plugin_objects);
256         return ret;
257 }
258
259 static bool rdf_filter (const string &str, void* /*arg*/)
260 {
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)));
266 }
267
268 void
269 PluginManager::add_ladspa_presets()
270 {
271         add_presets ("ladspa");
272 }
273
274 void
275 PluginManager::add_vst_presets()
276 {
277         add_presets ("vst");
278 }
279 void
280 PluginManager::add_presets(string domain)
281 {
282
283         PathScanner scanner;
284         vector<string *> *presets;
285         vector<string *>::iterator x;
286
287         char* envvar;
288         if ((envvar = getenv ("HOME")) == 0) {
289                 return;
290         }
291
292         string path = string_compose("%1/.%2/rdf", envvar, domain);
293         presets = scanner (path, rdf_filter, 0, true, true);
294
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;
300                         }
301                 }
302         }
303
304         vector_delete (presets);
305 }
306
307 void
308 PluginManager::add_lrdf_data (const string &path)
309 {
310         PathScanner scanner;
311         vector<string *>* rdf_files;
312         vector<string *>::iterator x;
313
314         rdf_files = scanner (path, rdf_filter, 0, true, true);
315
316         if (rdf_files) {
317                 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
318                         const string uri(string("file://") + **x);
319
320                         if (lrdf_read_file(uri.c_str())) {
321                                 warning << "Could not parse rdf file: " << uri << endmsg;
322                         }
323                 }
324         }
325
326         vector_delete (rdf_files);
327 }
328
329 int
330 PluginManager::ladspa_discover (string path)
331 {
332         void *module;
333         const LADSPA_Descriptor *descriptor;
334         LADSPA_Descriptor_Function dfunc;
335         const char *errstr;
336
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;
340         }
341
342         dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor");
343
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;
349         }
350
351         for (uint32_t i = 0; ; ++i) {
352                 if ((descriptor = dfunc (i)) == 0) {
353                         break;
354                 }
355
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;
359                         }
360                 }
361
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;
371
372                 char buf[32];
373                 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
374                 info->unique_id = buf;
375
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);
380                                 }
381                                 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
382                                         info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
383                                 }
384                         }
385                 }
386
387                 if(_ladspa_plugin_info->empty()){
388                         _ladspa_plugin_info->push_back (info);
389                 }
390
391                 //Ensure that the plugin is not already in the plugin list.
392
393                 bool found = false;
394
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;
398                         }
399                 }
400
401                 if(!found){
402                     _ladspa_plugin_info->push_back (info);
403                 }
404         }
405
406 // GDB WILL NOT LIKE YOU IF YOU DO THIS
407 //      dlclose (module);
408
409         return 0;
410 }
411
412 string
413 PluginManager::get_ladspa_category (uint32_t plugin_id)
414 {
415         char buf[256];
416         lrdf_statement pattern;
417
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;
423
424         lrdf_statement* matches1 = lrdf_matches (&pattern);
425
426         if (!matches1) {
427                 return "Unknown";
428         }
429
430         pattern.subject = matches1->object;
431         pattern.predicate = (char*)(LADSPA_BASE "hasLabel");
432         pattern.object = 0;
433         pattern.object_type = lrdf_literal;
434
435         lrdf_statement* matches2 = lrdf_matches (&pattern);
436         lrdf_free_statements(matches1);
437
438         if (!matches2) {
439                 return ("Unknown");
440         }
441
442         string label = matches2->object;
443         lrdf_free_statements(matches2);
444
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.
449
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.
455
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.
460         */
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;
471         }
472 }
473
474 #ifdef HAVE_SLV2
475 void
476 PluginManager::lv2_refresh ()
477 {
478         delete _lv2_plugin_info;
479         _lv2_plugin_info = LV2PluginInfo::discover(_lv2_world);
480 }
481 #endif
482
483 #ifdef HAVE_AUDIOUNITS
484 void
485 PluginManager::au_refresh ()
486 {
487         delete _au_plugin_info;
488         _au_plugin_info = AUPluginInfo::discover();
489 }
490
491 #endif
492
493 #ifdef VST_SUPPORT
494
495 void
496 PluginManager::vst_refresh ()
497 {
498         if (_vst_plugin_info)
499                 _vst_plugin_info->clear ();
500         else
501                 _vst_plugin_info = new ARDOUR::PluginInfoList();
502
503         if (vst_path.length() == 0) {
504                 vst_path = "/usr/local/lib/vst:/usr/lib/vst";
505         }
506
507         vst_discover_from_path (vst_path);
508 }
509
510 int
511 PluginManager::add_vst_directory (string path)
512 {
513         if (vst_discover_from_path (path) == 0) {
514                 vst_path += ':';
515                 vst_path += path;
516                 return 0;
517         }
518         return -1;
519 }
520
521 static bool vst_filter (const string& str, void *arg)
522 {
523         /* Not a dotfile, has a prefix before a period, suffix is "dll" */
524
525         return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
526 }
527
528 int
529 PluginManager::vst_discover_from_path (string path)
530 {
531         PathScanner scanner;
532         vector<string *> *plugin_objects;
533         vector<string *>::iterator x;
534         int ret = 0;
535
536         info << "detecting VST plugins along " << path << endmsg;
537
538         plugin_objects = scanner (vst_path, vst_filter, 0, true, true);
539
540         if (plugin_objects) {
541                 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
542                         vst_discover (**x);
543                 }
544         }
545
546         vector_delete (plugin_objects);
547         return ret;
548 }
549
550 int
551 PluginManager::vst_discover (string path)
552 {
553         FSTInfo* finfo;
554         char buf[32];
555
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;
559         }
560
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;
565         }
566
567         PluginInfoPtr info(new VSTPluginInfo);
568
569         /* what a joke freeware VST is */
570
571         if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
572                 info->name = PBD::basename_nosuffix (path);
573         } else {
574                 info->name = finfo->name;
575         }
576
577
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;
588
589         _vst_plugin_info->push_back (info);
590         fst_free_info (finfo);
591
592         return 0;
593 }
594
595 #endif // VST_SUPPORT
596
597 PluginManager::PluginStatusType
598 PluginManager::get_status (const PluginInfoPtr& pi)
599 {
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;
606         }
607 }
608
609 void
610 PluginManager::save_statuses ()
611 {
612         ofstream ofs;
613         sys::path path = user_config_directory();
614         path /= "plugin_statuses";
615
616         ofs.open (path.to_string().c_str(), ios_base::openmode (ios::out|ios::trunc));
617
618         if (!ofs) {
619                 return;
620         }
621
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;
636                 }
637
638                 ofs << ' ';
639
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;
650                 }
651         
652                 ofs << ' ';
653                 ofs << (*i).unique_id;;
654                 ofs << endl;
655         }
656
657         ofs.close ();
658 }
659
660 void
661 PluginManager::load_statuses ()
662 {
663         sys::path path = user_config_directory();
664         path /= "plugin_statuses";
665         ifstream ifs (path.to_string().c_str());
666
667         if (!ifs) {
668                 return;
669         }
670         
671         std::string stype;
672         std::string sstatus;
673         std::string id;
674         PluginType type;
675         PluginStatusType status;
676         char buf[1024];
677
678         while (ifs) {
679
680                 ifs >> stype;
681                 if (!ifs) {
682                         break;
683
684                 }
685
686                 ifs >> sstatus;
687                 if (!ifs) {
688                         break;
689
690                 }
691
692                 /* rest of the line is the plugin ID */
693
694                 ifs.getline (buf, sizeof (buf), '\n');
695                 if (!ifs) {
696                         break;
697                 }
698
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;
710                 }
711
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;
724                 }
725                 
726                 id = buf;
727                 strip_whitespace_edges (id);
728                 set_status (type, id, status);
729         }
730         
731         ifs.close ();
732 }
733
734 void
735 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
736 {
737         PluginStatus ps (t, id, status);
738         statuses.erase (ps);
739
740         if (status == Normal) {
741                 return;
742         }
743
744         pair<PluginStatusList::iterator, bool> res = statuses.insert (ps);
745         //cerr << "Added " << t << " " << id << " " << status << " success ? " << res.second << endl;
746 }
747
748 ARDOUR::PluginInfoList&
749 PluginManager::vst_plugin_info ()
750 {
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
758 }
759
760 ARDOUR::PluginInfoList&
761 PluginManager::ladspa_plugin_info ()
762 {
763         if (!_ladspa_plugin_info)
764                 ladspa_refresh();
765         return *_ladspa_plugin_info;
766 }
767
768 ARDOUR::PluginInfoList&
769 PluginManager::lv2_plugin_info ()
770 {
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
778 }
779
780 ARDOUR::PluginInfoList&
781 PluginManager::au_plugin_info ()
782 {
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
790 }