Build plugin menu only when plugins change, and build the first version of it before...
[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 #define __STDC_FORMAT_MACROS 1
25 #include <stdint.h>
26
27 #include <sys/types.h>
28 #include <cstdio>
29 #include <lrdf.h>
30 #include <dlfcn.h>
31 #include <cstdlib>
32 #include <fstream>
33
34 #ifdef VST_SUPPORT
35 #include <fst.h>
36 #include "pbd/basename.h"
37 #include <cstring>
38 #endif // VST_SUPPORT
39
40 #include <glibmm/miscutils.h>
41
42 #include "pbd/pathscanner.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 void
145 PluginManager::refresh ()
146 {
147         ladspa_refresh ();
148 #ifdef HAVE_SLV2
149         lv2_refresh ();
150 #endif
151 #ifdef VST_SUPPORT
152         if (Config->get_use_vst()) {
153                 vst_refresh ();
154         }
155 #endif // VST_SUPPORT
156 #ifdef HAVE_AUDIOUNITS
157         au_refresh ();
158 #endif
159
160         PluginListChanged (); /* EMIT SIGNAL */
161 }
162
163 void
164 PluginManager::ladspa_refresh ()
165 {
166         if (_ladspa_plugin_info)
167                 _ladspa_plugin_info->clear ();
168         else
169                 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
170
171         static const char *standard_paths[] = {
172                 "/usr/local/lib64/ladspa",
173                 "/usr/local/lib/ladspa",
174                 "/usr/lib64/ladspa",
175                 "/usr/lib/ladspa",
176                 "/Library/Audio/Plug-Ins/LADSPA",
177                 ""
178         };
179
180         /* allow LADSPA_PATH to augment, not override standard locations */
181
182         /* Only add standard locations to ladspa_path if it doesn't
183          * already contain them. Check for trailing '/'s too.
184          */
185
186         int i;
187         for (i = 0; standard_paths[i][0]; i++) {
188                 size_t found = ladspa_path.find(standard_paths[i]);
189                 if (found != ladspa_path.npos) {
190                         switch (ladspa_path[found + strlen(standard_paths[i])]) {
191                                 case ':' :
192                                 case '\0':
193                                         continue;
194                                 case '/' :
195                                         if (ladspa_path[found + strlen(standard_paths[i]) + 1] == ':' ||
196                                             ladspa_path[found + strlen(standard_paths[i]) + 1] == '\0') {
197                                                 continue;
198                                         }
199                         }
200                 }
201                 if (!ladspa_path.empty())
202                         ladspa_path += ":";
203
204                 ladspa_path += standard_paths[i];
205
206         }
207
208         ladspa_discover_from_path (ladspa_path);
209 }
210
211
212 int
213 PluginManager::add_ladspa_directory (string path)
214 {
215         if (ladspa_discover_from_path (path) == 0) {
216                 ladspa_path += ':';
217                 ladspa_path += path;
218                 return 0;
219         }
220         return -1;
221 }
222
223 static bool ladspa_filter (const string& str, void */*arg*/)
224 {
225         /* Not a dotfile, has a prefix before a period, suffix is "so" */
226
227         return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
228 }
229
230 int
231 PluginManager::ladspa_discover_from_path (string /*path*/)
232 {
233         PathScanner scanner;
234         vector<string *> *plugin_objects;
235         vector<string *>::iterator x;
236         int ret = 0;
237
238         plugin_objects = scanner (ladspa_path, ladspa_filter, 0, true, true);
239
240         if (plugin_objects) {
241                 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
242                         ladspa_discover (**x);
243                 }
244         }
245
246         vector_delete (plugin_objects);
247         return ret;
248 }
249
250 static bool rdf_filter (const string &str, void* /*arg*/)
251 {
252         return str[0] != '.' &&
253                    ((str.find(".rdf")  == (str.length() - 4)) ||
254             (str.find(".rdfs") == (str.length() - 5)) ||
255                     (str.find(".n3")   == (str.length() - 3)) ||
256                     (str.find(".ttl")  == (str.length() - 4)));
257 }
258
259 void
260 PluginManager::add_ladspa_presets()
261 {
262         add_presets ("ladspa");
263 }
264
265 void
266 PluginManager::add_vst_presets()
267 {
268         add_presets ("vst");
269 }
270 void
271 PluginManager::add_presets(string domain)
272 {
273
274         PathScanner scanner;
275         vector<string *> *presets;
276         vector<string *>::iterator x;
277
278         char* envvar;
279         if ((envvar = getenv ("HOME")) == 0) {
280                 return;
281         }
282
283         string path = string_compose("%1/.%2/rdf", envvar, domain);
284         presets = scanner (path, rdf_filter, 0, true, true);
285
286         if (presets) {
287                 for (x = presets->begin(); x != presets->end (); ++x) {
288                         string file = "file:" + **x;
289                         if (lrdf_read_file(file.c_str())) {
290                                 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
291                         }
292                 }
293         }
294
295         vector_delete (presets);
296 }
297
298 void
299 PluginManager::add_lrdf_data (const string &path)
300 {
301         PathScanner scanner;
302         vector<string *>* rdf_files;
303         vector<string *>::iterator x;
304         string uri;
305
306         rdf_files = scanner (path, rdf_filter, 0, true, true);
307
308         if (rdf_files) {
309                 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
310                         uri = "file://" + **x;
311
312                         if (lrdf_read_file(uri.c_str())) {
313                                 warning << "Could not parse rdf file: " << uri << endmsg;
314                         }
315                 }
316         }
317
318         vector_delete (rdf_files);
319 }
320
321 int
322 PluginManager::ladspa_discover (string path)
323 {
324         void *module;
325         const LADSPA_Descriptor *descriptor;
326         LADSPA_Descriptor_Function dfunc;
327         const char *errstr;
328
329         if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
330                 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg;
331                 return -1;
332         }
333
334         dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor");
335
336         if ((errstr = dlerror()) != 0) {
337                 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
338                 error << errstr << endmsg;
339                 dlclose (module);
340                 return -1;
341         }
342
343         for (uint32_t i = 0; ; ++i) {
344                 if ((descriptor = dfunc (i)) == 0) {
345                         break;
346                 }
347
348                 if (!ladspa_plugin_whitelist.empty()) {
349                         if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
350                                 continue;
351                         }
352                 }
353
354                 PluginInfoPtr info(new LadspaPluginInfo);
355                 info->name = descriptor->Name;
356                 info->category = get_ladspa_category(descriptor->UniqueID);
357                 info->creator = descriptor->Maker;
358                 info->path = path;
359                 info->index = i;
360                 info->n_inputs = ChanCount();
361                 info->n_outputs = ChanCount();
362                 info->type = ARDOUR::LADSPA;
363
364                 char buf[32];
365                 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
366                 info->unique_id = buf;
367
368                 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
369                         if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
370                                 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
371                                         info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
372                                 }
373                                 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
374                                         info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
375                                 }
376                         }
377                 }
378
379                 if(_ladspa_plugin_info->empty()){
380                         _ladspa_plugin_info->push_back (info);
381                 }
382
383                 //Ensure that the plugin is not already in the plugin list.
384
385                 bool found = false;
386
387                 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
388                         if(0 == info->unique_id.compare((*i)->unique_id)){
389                               found = true;
390                         }
391                 }
392
393                 if(!found){
394                     _ladspa_plugin_info->push_back (info);
395                 }
396         }
397
398 // GDB WILL NOT LIKE YOU IF YOU DO THIS
399 //      dlclose (module);
400
401         return 0;
402 }
403
404 string
405 PluginManager::get_ladspa_category (uint32_t plugin_id)
406 {
407         char buf[256];
408         lrdf_statement pattern;
409
410         snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
411         pattern.subject = buf;
412         pattern.predicate = (char*)RDF_TYPE;
413         pattern.object = 0;
414         pattern.object_type = lrdf_uri;
415
416         lrdf_statement* matches1 = lrdf_matches (&pattern);
417
418         if (!matches1) {
419                 return "Unknown";
420         }
421
422         pattern.subject = matches1->object;
423         pattern.predicate = (char*)(LADSPA_BASE "hasLabel");
424         pattern.object = 0;
425         pattern.object_type = lrdf_literal;
426
427         lrdf_statement* matches2 = lrdf_matches (&pattern);
428         lrdf_free_statements(matches1);
429
430         if (!matches2) {
431                 return ("Unknown");
432         }
433
434         string label = matches2->object;
435         lrdf_free_statements(matches2);
436
437         return label;
438 }
439
440 #ifdef HAVE_SLV2
441 void
442 PluginManager::lv2_refresh ()
443 {
444         delete _lv2_plugin_info;
445         _lv2_plugin_info = LV2PluginInfo::discover(_lv2_world);
446 }
447 #endif
448
449 #ifdef HAVE_AUDIOUNITS
450 void
451 PluginManager::au_refresh ()
452 {
453         delete _au_plugin_info;
454         _au_plugin_info = AUPluginInfo::discover();
455 }
456
457 #endif
458
459 #ifdef VST_SUPPORT
460
461 void
462 PluginManager::vst_refresh ()
463 {
464         if (_vst_plugin_info)
465                 _vst_plugin_info->clear ();
466         else
467                 _vst_plugin_info = new ARDOUR::PluginInfoList();
468
469         if (vst_path.length() == 0) {
470                 vst_path = "/usr/local/lib/vst:/usr/lib/vst";
471         }
472
473         vst_discover_from_path (vst_path);
474 }
475
476 int
477 PluginManager::add_vst_directory (string path)
478 {
479         if (vst_discover_from_path (path) == 0) {
480                 vst_path += ':';
481                 vst_path += path;
482                 return 0;
483         }
484         return -1;
485 }
486
487 static bool vst_filter (const string& str, void *arg)
488 {
489         /* Not a dotfile, has a prefix before a period, suffix is "dll" */
490
491         return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
492 }
493
494 int
495 PluginManager::vst_discover_from_path (string path)
496 {
497         PathScanner scanner;
498         vector<string *> *plugin_objects;
499         vector<string *>::iterator x;
500         int ret = 0;
501
502         info << "detecting VST plugins along " << path << endmsg;
503
504         plugin_objects = scanner (vst_path, vst_filter, 0, true, true);
505
506         if (plugin_objects) {
507                 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
508                         vst_discover (**x);
509                 }
510         }
511
512         vector_delete (plugin_objects);
513         return ret;
514 }
515
516 int
517 PluginManager::vst_discover (string path)
518 {
519         FSTInfo* finfo;
520         char buf[32];
521
522         if ((finfo = fst_get_info (const_cast<char *> (path.c_str()))) == 0) {
523                 warning << "Cannot get VST information from " << path << endmsg;
524                 return -1;
525         }
526
527         if (!finfo->canProcessReplacing) {
528                 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in ardour at this time"),
529                                     finfo->name)
530                         << endl;
531         }
532
533         PluginInfoPtr info(new VSTPluginInfo);
534
535         /* what a joke freeware VST is */
536
537         if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
538                 info->name = PBD::basename_nosuffix (path);
539         } else {
540                 info->name = finfo->name;
541         }
542
543
544         snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
545         info->unique_id = buf;
546         info->category = "VST";
547         info->path = path;
548         info->creator = finfo->creator;
549         info->index = 0;
550         info->n_inputs.set_audio (finfo->numInputs);
551         info->n_outputs.set_audio (finfo->numOutputs);
552         info->type = ARDOUR::VST;
553
554         _vst_plugin_info->push_back (info);
555         fst_free_info (finfo);
556
557         return 0;
558 }
559
560 #endif // VST_SUPPORT
561
562 PluginManager::PluginStatusType
563 PluginManager::get_status (const PluginInfoPtr& pi)
564 {
565         PluginStatus ps (pi->type, pi->unique_id);
566         PluginStatusList::const_iterator i =  find (statuses.begin(), statuses.end(), ps);
567         if (i ==  statuses.end() ) {
568                 return Normal;
569         } else {
570                 return i->status;
571         }
572 }
573
574 void
575 PluginManager::save_statuses ()
576 {
577         ofstream ofs;
578         sys::path path = user_config_directory();
579         path /= "plugin_statuses";
580
581         ofs.open (path.to_string().c_str(), ios_base::openmode (ios::out|ios::trunc));
582
583         if (!ofs) {
584                 return;
585         }
586
587         for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
588                 switch ((*i).type) {
589                 case LADSPA:
590                         ofs << "LADSPA";
591                         break;
592                 case AudioUnit:
593                         ofs << "AudioUnit";
594                         break;
595                 case LV2:
596                         ofs << "LV2";
597                         break;
598                 case VST:
599                         ofs << "VST";
600                         break;
601                 }
602
603                 ofs << ' ' << (*i).unique_id << ' ';
604
605                 switch ((*i).status) {
606                 case Normal:
607                         ofs << "Normal";
608                         break;
609                 case Favorite:
610                         ofs << "Favorite";
611                         break;
612                 case Hidden:
613                         ofs << "Hidden";
614                         break;
615                 }
616
617                 ofs << endl;
618         }
619
620         ofs.close ();
621 }
622
623 void
624 PluginManager::load_statuses ()
625 {
626         sys::path path = user_config_directory();
627         path /= "plugin_statuses";
628         ifstream ifs (path.to_string().c_str());
629
630         if (!ifs) {
631                 return;
632         }
633
634         std::string stype;
635         std::string id;
636         std::string sstatus;
637         PluginType type;
638         PluginStatusType status;
639
640         while (ifs) {
641
642                 ifs >> stype;
643                 if (!ifs) {
644                         break;
645
646                 }
647                 ifs >> id;
648                 if (!ifs) {
649                         break;
650                 }
651
652                 ifs >> sstatus;
653                 if (!ifs) {
654                         break;
655
656                 }
657
658                 if (stype == "LADSPA") {
659                         type = LADSPA;
660                 } else if (stype == "AudioUnit") {
661                         type = AudioUnit;
662                 } else if (stype == "LV2") {
663                         type = LV2;
664                 } else if (stype == "VST") {
665                         type = VST;
666                 } else {
667                         error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
668                               << endmsg;
669                         continue;
670                 }
671                 if (sstatus == "Normal") {
672                         status = Normal;
673                 } else if (sstatus == "Favorite") {
674                         status = Favorite;
675                 } else if (sstatus == "Hidden") {
676                         status = Hidden;
677                 } else {
678                         error << string_compose (_("unknown plugin status type \"%1\" - ignored"), stype)
679                               << endmsg;
680                         continue;
681                 }
682
683                 set_status (type, id, status);
684         }
685
686         ifs.close ();
687 }
688
689 void
690 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
691 {
692         PluginStatus ps (t, id, status);
693         statuses.erase (ps);
694
695         if (status == Normal) {
696                 return;
697         }
698
699         pair<PluginStatusList::iterator, bool> res = statuses.insert (ps);
700         //cerr << "Added " << t << " " << id << " " << status << " success ? " << res.second << endl;
701 }
702
703 ARDOUR::PluginInfoList&
704 PluginManager::vst_plugin_info ()
705 {
706 #ifdef VST_SUPPORT
707         if (!_vst_plugin_info)
708                 vst_refresh();
709         return *_vst_plugin_info;
710 #else
711         return _empty_plugin_info;
712 #endif
713 }
714
715 ARDOUR::PluginInfoList&
716 PluginManager::ladspa_plugin_info ()
717 {
718         if (!_ladspa_plugin_info)
719                 ladspa_refresh();
720         return *_ladspa_plugin_info;
721 }
722
723 ARDOUR::PluginInfoList&
724 PluginManager::lv2_plugin_info ()
725 {
726 #ifdef HAVE_SLV2
727         if (!_lv2_plugin_info)
728                 lv2_refresh();
729         return *_lv2_plugin_info;
730 #else
731         return _empty_plugin_info;
732 #endif
733 }
734
735 ARDOUR::PluginInfoList&
736 PluginManager::au_plugin_info ()
737 {
738 #ifdef HAVE_AUDIOUNITS
739         if (!_au_plugin_info)
740                 au_refresh();
741         return *_au_plugin_info;
742 #else
743         return _empty_plugin_info;
744 #endif
745 }