some notes on mem-leaks...
[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 <cstdlib>
29
30 #include <glib.h>
31 #include "pbd/gstdio_compat.h"
32
33 #ifdef HAVE_LRDF
34 #include <lrdf.h>
35 #endif
36
37 #ifdef WINDOWS_VST_SUPPORT
38 #include "ardour/vst_info_file.h"
39 #include "fst.h"
40 #include "pbd/basename.h"
41 #include <cstring>
42
43 // dll-info
44 #include <sys/stat.h>
45 #include <fcntl.h>
46 #include <unistd.h>
47 #include <stdint.h>
48
49 #endif // WINDOWS_VST_SUPPORT
50
51 #ifdef LXVST_SUPPORT
52 #include "ardour/vst_info_file.h"
53 #include "ardour/linux_vst_support.h"
54 #include "pbd/basename.h"
55 #include <cstring>
56 #endif //LXVST_SUPPORT
57
58 #include <glibmm/miscutils.h>
59 #include <glibmm/pattern.h>
60 #include <glibmm/fileutils.h>
61 #include <glibmm/miscutils.h>
62
63 #include "pbd/whitespace.h"
64 #include "pbd/file_utils.h"
65
66 #include "ardour/debug.h"
67 #include "ardour/filesystem_paths.h"
68 #include "ardour/ladspa.h"
69 #include "ardour/ladspa_plugin.h"
70 #include "ardour/plugin.h"
71 #include "ardour/plugin_manager.h"
72 #include "ardour/rc_configuration.h"
73
74 #include "ardour/search_paths.h"
75
76 #ifdef LV2_SUPPORT
77 #include "ardour/lv2_plugin.h"
78 #endif
79
80 #ifdef WINDOWS_VST_SUPPORT
81 #include "ardour/windows_vst_plugin.h"
82 #endif
83
84 #ifdef LXVST_SUPPORT
85 #include "ardour/lxvst_plugin.h"
86 #endif
87
88 #ifdef AUDIOUNIT_SUPPORT
89 #include "ardour/audio_unit.h"
90 #include <Carbon/Carbon.h>
91 #endif
92
93 #include "pbd/error.h"
94 #include "pbd/stl_delete.h"
95
96 #include "i18n.h"
97
98 #include "ardour/debug.h"
99
100 using namespace ARDOUR;
101 using namespace PBD;
102 using namespace std;
103
104 PluginManager* PluginManager::_instance = 0;
105 std::string PluginManager::scanner_bin_path = "";
106
107 PluginManager&
108 PluginManager::instance()
109 {
110         if (!_instance) {
111                 _instance = new PluginManager;
112         }
113         return *_instance;
114 }
115
116 PluginManager::PluginManager ()
117         : _windows_vst_plugin_info(0)
118         , _lxvst_plugin_info(0)
119         , _ladspa_plugin_info(0)
120         , _lv2_plugin_info(0)
121         , _au_plugin_info(0)
122         , _cancel_scan(false)
123         , _cancel_timeout(false)
124 {
125         char* s;
126         string lrdf_path;
127
128 #if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
129         // source-tree (ardev, etc)
130         PBD::Searchpath vstsp(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst"));
131
132 #ifdef PLATFORM_WINDOWS
133         // on windows the .exe needs to be in the same folder with libardour.dll
134         vstsp += Glib::build_filename(windows_package_directory_path(), "bin");
135 #else
136         // on Unices additional internal-use binaries are deployed to $libdir
137         vstsp += ARDOUR::ardour_dll_directory();
138 #endif
139
140         if (!PBD::find_file (vstsp,
141 #ifdef PLATFORM_WINDOWS
142     #ifdef DEBUGGABLE_SCANNER_APP
143         #if defined(DEBUG) || defined(_DEBUG)
144                                 "ardour-vst-scannerD.exe"
145         #else
146                                 "ardour-vst-scannerRDC.exe"
147         #endif
148     #else
149                                 "ardour-vst-scanner.exe"
150     #endif
151 #else
152                                 "ardour-vst-scanner"
153 #endif
154                                 , scanner_bin_path)) {
155                 PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << vstsp.to_string() <<  endmsg;
156         }
157 #endif
158
159         load_statuses ();
160
161         if ((s = getenv ("LADSPA_RDF_PATH"))){
162                 lrdf_path = s;
163         }
164
165         if (lrdf_path.length() == 0) {
166                 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
167         }
168
169         add_lrdf_data(lrdf_path);
170         add_ladspa_presets();
171 #ifdef WINDOWS_VST_SUPPORT
172         if (Config->get_use_windows_vst ()) {
173                 add_windows_vst_presets ();
174         }
175 #endif /* WINDOWS_VST_SUPPORT */
176
177 #ifdef LXVST_SUPPORT
178         if (Config->get_use_lxvst()) {
179                 add_lxvst_presets();
180         }
181 #endif /* Native LinuxVST support*/
182
183         if ((s = getenv ("VST_PATH"))) {
184                 windows_vst_path = s;
185         } else if ((s = getenv ("VST_PLUGINS"))) {
186                 windows_vst_path = s;
187         }
188
189         if (windows_vst_path.length() == 0) {
190                 windows_vst_path = vst_search_path ();
191         }
192
193         if ((s = getenv ("LXVST_PATH"))) {
194                 lxvst_path = s;
195         } else if ((s = getenv ("LXVST_PLUGINS"))) {
196                 lxvst_path = s;
197         }
198
199         if (lxvst_path.length() == 0) {
200                 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
201                         "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
202                         "/usr/lib/vst:/usr/local/lib/vst";
203         }
204
205         /* first time setup, use 'default' path */
206         if (Config->get_plugin_path_lxvst() == X_("@default@")) {
207                 Config->set_plugin_path_lxvst(get_default_lxvst_path());
208         }
209         if (Config->get_plugin_path_vst() == X_("@default@")) {
210                 Config->set_plugin_path_vst(get_default_windows_vst_path());
211         }
212
213         if (_instance == 0) {
214                 _instance = this;
215         }
216
217         BootMessage (_("Discovering Plugins"));
218 }
219
220
221 PluginManager::~PluginManager()
222 {
223         if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
224                 // don't bother, just exit quickly.
225                 delete _windows_vst_plugin_info;
226                 delete _lxvst_plugin_info;
227                 delete _ladspa_plugin_info;
228                 delete _lv2_plugin_info;
229                 delete _au_plugin_info;
230         }
231 }
232
233 void
234 PluginManager::refresh (bool cache_only)
235 {
236         Glib::Threads::Mutex::Lock lm (_lock, Glib::Threads::TRY_LOCK);
237
238         if (!lm.locked()) {
239                 return;
240         }
241
242         DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
243         _cancel_scan = false;
244
245         BootMessage (_("Scanning LADSPA Plugins"));
246         ladspa_refresh ();
247 #ifdef LV2_SUPPORT
248         BootMessage (_("Scanning LV2 Plugins"));
249         lv2_refresh ();
250 #endif
251 #ifdef WINDOWS_VST_SUPPORT
252         if (Config->get_use_windows_vst()) {
253                 if (cache_only) {
254                         BootMessage (_("Scanning Windows VST Plugins"));
255                 } else {
256                         BootMessage (_("Discovering Windows VST Plugins"));
257                 }
258                 windows_vst_refresh (cache_only);
259         }
260 #endif // WINDOWS_VST_SUPPORT
261
262 #ifdef LXVST_SUPPORT
263         if(Config->get_use_lxvst()) {
264                 if (cache_only) {
265                         BootMessage (_("Scanning Linux VST Plugins"));
266                 } else {
267                         BootMessage (_("Discovering Linux VST Plugins"));
268                 }
269                 lxvst_refresh(cache_only);
270         }
271 #endif //Native linuxVST SUPPORT
272
273 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
274                 if (!cache_only) {
275                         string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
276                         if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
277                                 gchar *bl = NULL;
278                                 if (g_file_get_contents(fn.c_str (), &bl, NULL, NULL)) {
279                                         if (Config->get_verbose_plugin_scan()) {
280                                                 PBD::info << _("VST Blacklist: ") << fn << "\n" << bl << "-----" << endmsg;
281                                         } else {
282                                                 PBD::info << _("VST Blacklist:") << "\n" << bl << "-----" << endmsg;
283                                         }
284                                         g_free (bl);
285                                 }
286                         }
287                 }
288 #endif
289
290 #ifdef AUDIOUNIT_SUPPORT
291         if (cache_only) {
292                 BootMessage (_("Scanning AU Plugins"));
293         } else {
294                 BootMessage (_("Discovering AU Plugins"));
295         }
296         au_refresh (cache_only);
297 #endif
298
299         BootMessage (_("Plugin Scan Complete..."));
300         PluginListChanged (); /* EMIT SIGNAL */
301         PluginScanMessage(X_("closeme"), "", false);
302         _cancel_scan = false;
303 }
304
305 void
306 PluginManager::cancel_plugin_scan ()
307 {
308         _cancel_scan = true;
309 }
310
311 void
312 PluginManager::cancel_plugin_timeout ()
313 {
314         _cancel_timeout = true;
315 }
316
317 void
318 PluginManager::clear_vst_cache ()
319 {
320 #if 1 // clean old cache and error files. (remove this code after 4.3 or 5.0)
321 #ifdef WINDOWS_VST_SUPPORT
322         {
323                 vector<string> fsi_files;
324                 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_INFOFILE "$", true);
325                 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
326                         ::g_unlink(i->c_str());
327                 }
328         }
329         {
330                 vector<string> fsi_files;
331                 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$", true);
332                 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
333                         ::g_unlink(i->c_str());
334                 }
335         }
336         {
337                 vector<string> fsi_files;
338                 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.err$", true);
339                 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
340                         ::g_unlink(i->c_str());
341                 }
342         }
343 #endif
344
345 #ifdef LXVST_SUPPORT
346         {
347                 vector<string> fsi_files;
348                 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_INFOFILE "$", true);
349                 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
350                         ::g_unlink(i->c_str());
351                 }
352         }
353         {
354                 vector<string> fsi_files;
355                 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$", true);
356                 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
357                         ::g_unlink(i->c_str());
358                 }
359         }
360         {
361                 vector<string> fsi_files;
362                 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.err$", true);
363                 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
364                         ::g_unlink(i->c_str());
365                 }
366         }
367 #endif
368 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
369         {
370                 string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_info");
371                 if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
372                         PBD::remove_directory (dir);
373                 }
374         }
375 #endif
376 #endif // old cache cleanup
377
378 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
379         {
380                 string dn = Glib::build_filename (ARDOUR::user_cache_directory(), "vst");
381                 vector<string> fsi_files;
382                 find_files_matching_regex (fsi_files, dn, "\\" VST_EXT_INFOFILE "$", /* user cache is flat, no recursion */ false);
383                 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
384                         ::g_unlink(i->c_str());
385                 }
386         }
387 #endif
388 }
389
390 void
391 PluginManager::clear_vst_blacklist ()
392 {
393 #if 1 // remove old blacklist files. (remove this code after 4.3 or 5.0)
394
395 #ifdef WINDOWS_VST_SUPPORT
396         {
397                 vector<string> fsi_files;
398                 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_BLACKLIST "$", true);
399                 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
400                         ::g_unlink(i->c_str());
401                 }
402         }
403 #endif
404
405 #ifdef LXVST_SUPPORT
406         {
407                 vector<string> fsi_files;
408                 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_BLACKLIST "$", true);
409                 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
410                         ::g_unlink(i->c_str());
411                 }
412         }
413 #endif
414 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
415         {
416                 string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_blacklist");
417                 if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
418                         PBD::remove_directory (dir);
419                 }
420         }
421 #endif
422
423 #endif // old blacklist cleanup
424
425 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
426         {
427                 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
428                 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
429                         ::g_unlink (fn.c_str());
430                 }
431         }
432 #endif
433
434 }
435
436 void
437 PluginManager::clear_au_cache ()
438 {
439 #ifdef AUDIOUNIT_SUPPORT
440         AUPluginInfo::clear_cache ();
441 #endif
442 }
443
444 void
445 PluginManager::clear_au_blacklist ()
446 {
447 #ifdef AUDIOUNIT_SUPPORT
448         string fn = Glib::build_filename (ARDOUR::user_cache_directory(), "au_blacklist.txt");
449         if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
450                 ::g_unlink(fn.c_str());
451         }
452 #endif
453 }
454
455 void
456 PluginManager::ladspa_refresh ()
457 {
458         if (_ladspa_plugin_info) {
459                 _ladspa_plugin_info->clear ();
460         } else {
461                 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
462         }
463
464         /* allow LADSPA_PATH to augment, not override standard locations */
465
466         /* Only add standard locations to ladspa_path if it doesn't
467          * already contain them. Check for trailing G_DIR_SEPARATOR too.
468          */
469
470         vector<string> ladspa_modules;
471
472         DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
473
474         find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.so");
475         find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dylib");
476         find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dll");
477
478         for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
479                 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
480                 ladspa_discover (*i);
481         }
482 }
483
484 #ifdef HAVE_LRDF
485 static bool rdf_filter (const string &str, void* /*arg*/)
486 {
487         return str[0] != '.' &&
488                    ((str.find(".rdf")  == (str.length() - 4)) ||
489             (str.find(".rdfs") == (str.length() - 5)) ||
490                     (str.find(".n3")   == (str.length() - 3)) ||
491                     (str.find(".ttl")  == (str.length() - 4)));
492 }
493 #endif
494
495 void
496 PluginManager::add_ladspa_presets()
497 {
498         add_presets ("ladspa");
499 }
500
501 void
502 PluginManager::add_windows_vst_presets()
503 {
504         add_presets ("windows-vst");
505 }
506
507 void
508 PluginManager::add_lxvst_presets()
509 {
510         add_presets ("lxvst");
511 }
512
513 void
514 PluginManager::add_presets(string domain)
515 {
516 #ifdef HAVE_LRDF
517         vector<string> presets;
518         vector<string>::iterator x;
519
520         char* envvar;
521         if ((envvar = getenv ("HOME")) == 0) {
522                 return;
523         }
524
525         string path = string_compose("%1/.%2/rdf", envvar, domain);
526         find_files_matching_filter (presets, path, rdf_filter, 0, false, true);
527
528         for (x = presets.begin(); x != presets.end (); ++x) {
529                 string file = "file:" + *x;
530                 if (lrdf_read_file(file.c_str())) {
531                         warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
532                 }
533         }
534
535 #endif
536 }
537
538 void
539 PluginManager::add_lrdf_data (const string &path)
540 {
541 #ifdef HAVE_LRDF
542         vector<string> rdf_files;
543         vector<string>::iterator x;
544
545         find_files_matching_filter (rdf_files, path, rdf_filter, 0, false, true);
546
547         for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
548                 const string uri(string("file://") + *x);
549
550                 if (lrdf_read_file(uri.c_str())) {
551                         warning << "Could not parse rdf file: " << uri << endmsg;
552                 }
553         }
554 #endif
555 }
556
557 int
558 PluginManager::ladspa_discover (string path)
559 {
560         DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
561
562         Glib::Module module(path);
563         const LADSPA_Descriptor *descriptor;
564         LADSPA_Descriptor_Function dfunc;
565         void* func = 0;
566
567         if (!module) {
568                 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
569                         path, Glib::Module::get_last_error()) << endmsg;
570                 return -1;
571         }
572
573
574         if (!module.get_symbol("ladspa_descriptor", func)) {
575                 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
576                 error << Glib::Module::get_last_error() << endmsg;
577                 return -1;
578         }
579
580         dfunc = (LADSPA_Descriptor_Function)func;
581
582         DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
583
584         for (uint32_t i = 0; ; ++i) {
585                 /* if a ladspa plugin allocates memory here
586                  * it is never free()ed (or plugin-dependent only when unloading).
587                  * For some plugins memory allocated is incremental, we should
588                  * avoid re-scanning plugins and file bug reports.
589                  */
590                 if ((descriptor = dfunc (i)) == 0) {
591                         break;
592                 }
593
594                 if (!ladspa_plugin_whitelist.empty()) {
595                         if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
596                                 continue;
597                         }
598                 }
599
600                 PluginInfoPtr info(new LadspaPluginInfo);
601                 info->name = descriptor->Name;
602                 info->category = get_ladspa_category(descriptor->UniqueID);
603                 info->creator = descriptor->Maker;
604                 info->path = path;
605                 info->index = i;
606                 info->n_inputs = ChanCount();
607                 info->n_outputs = ChanCount();
608                 info->type = ARDOUR::LADSPA;
609
610                 char buf[32];
611                 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
612                 info->unique_id = buf;
613
614                 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
615                         if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
616                                 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
617                                         info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
618                                 }
619                                 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
620                                         info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
621                                 }
622                         }
623                 }
624
625                 if(_ladspa_plugin_info->empty()){
626                         _ladspa_plugin_info->push_back (info);
627                 }
628
629                 //Ensure that the plugin is not already in the plugin list.
630
631                 bool found = false;
632
633                 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
634                         if(0 == info->unique_id.compare((*i)->unique_id)){
635                               found = true;
636                         }
637                 }
638
639                 if(!found){
640                     _ladspa_plugin_info->push_back (info);
641                 }
642
643                 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
644         }
645
646 // GDB WILL NOT LIKE YOU IF YOU DO THIS
647 //      dlclose (module);
648
649         return 0;
650 }
651
652 string
653 PluginManager::get_ladspa_category (uint32_t plugin_id)
654 {
655 #ifdef HAVE_LRDF
656         char buf[256];
657         lrdf_statement pattern;
658
659         snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
660         pattern.subject = buf;
661         pattern.predicate = const_cast<char*>(RDF_TYPE);
662         pattern.object = 0;
663         pattern.object_type = lrdf_uri;
664
665         lrdf_statement* matches1 = lrdf_matches (&pattern);
666
667         if (!matches1) {
668                 return "Unknown";
669         }
670
671         pattern.subject = matches1->object;
672         pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
673         pattern.object = 0;
674         pattern.object_type = lrdf_literal;
675
676         lrdf_statement* matches2 = lrdf_matches (&pattern);
677         lrdf_free_statements(matches1);
678
679         if (!matches2) {
680                 return ("Unknown");
681         }
682
683         string label = matches2->object;
684         lrdf_free_statements(matches2);
685
686         /* Kludge LADSPA class names to be singular and match LV2 class names.
687            This avoids duplicate plugin menus for every class, which is necessary
688            to make the plugin category menu at all usable, but is obviously a
689            filthy kludge.
690
691            In the short term, lrdf could be updated so the labels match and a new
692            release made. To support both specs, we should probably be mapping the
693            URIs to the same category in code and perhaps tweaking that hierarchy
694            dynamically to suit the user. Personally, I (drobilla) think that time
695            is better spent replacing the little-used LRDF.
696
697            In the longer term, we will abandon LRDF entirely in favour of LV2 and
698            use that class hierarchy. Aside from fixing this problem properly, that
699            will also allow for translated labels. SWH plugins have been LV2 for
700            ages; TAP needs porting. I don't know of anything else with LRDF data.
701         */
702         if (label == "Utilities") {
703                 return "Utility";
704         } else if (label == "Pitch shifters") {
705                 return "Pitch Shifter";
706         } else if (label != "Dynamics" && label != "Chorus"
707                    &&label[label.length() - 1] == 's'
708                    && label[label.length() - 2] != 's') {
709                 return label.substr(0, label.length() - 1);
710         } else {
711                 return label;
712         }
713 #else
714                 return ("Unknown");
715 #endif
716 }
717
718 #ifdef LV2_SUPPORT
719 void
720 PluginManager::lv2_refresh ()
721 {
722         DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
723         delete _lv2_plugin_info;
724         _lv2_plugin_info = LV2PluginInfo::discover();
725 }
726 #endif
727
728 #ifdef AUDIOUNIT_SUPPORT
729 void
730 PluginManager::au_refresh (bool cache_only)
731 {
732         DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
733
734         // disable automatic discovery in case we crash
735         bool discover_at_start = Config->get_discover_audio_units ();
736         Config->set_discover_audio_units (false);
737         Config->save_state();
738
739         delete _au_plugin_info;
740         _au_plugin_info = AUPluginInfo::discover(cache_only && !discover_at_start);
741
742         // successful scan re-enabled automatic discovery if it was set
743         Config->set_discover_audio_units (discover_at_start);
744         Config->save_state();
745 }
746
747 #endif
748
749 #ifdef WINDOWS_VST_SUPPORT
750
751 void
752 PluginManager::windows_vst_refresh (bool cache_only)
753 {
754         if (_windows_vst_plugin_info) {
755                 _windows_vst_plugin_info->clear ();
756         } else {
757                 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
758         }
759
760         windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
761 }
762
763 static bool windows_vst_filter (const string& str, void * /*arg*/)
764 {
765         /* Not a dotfile, has a prefix before a period, suffix is "dll" */
766         return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".dll", str.substr(str.length() - 4));
767 }
768
769 int
770 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
771 {
772         vector<string> plugin_objects;
773         vector<string>::iterator x;
774         int ret = 0;
775
776         DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering Windows VST plugins along %1\n", path));
777
778         if (Config->get_verbose_plugin_scan()) {
779                 info << string_compose (_("--- Windows VST plugins Scan: %1"), path) << endmsg;
780         }
781
782         find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true, true);
783
784         for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
785                 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
786                 windows_vst_discover (*x, cache_only || cancelled());
787         }
788
789         if (Config->get_verbose_plugin_scan()) {
790                 info << _("--- Windows VST plugins Scan Done") << endmsg;
791         }
792
793         return ret;
794 }
795
796 static std::string dll_info (std::string path) {
797         std::string rv;
798         uint8_t buf[68];
799         uint16_t type = 0;
800         off_t pe_hdr_off = 0;
801
802         int fd = g_open(path.c_str(), O_RDONLY, 0444);
803
804         if (fd < 0) {
805                 return _("cannot open dll"); // TODO strerror()
806         }
807
808         if (68 != read (fd, buf, 68)) {
809                 rv = _("invalid dll, file too small");
810                 goto errorout;
811         }
812         if (buf[0] != 'M' && buf[1] != 'Z') {
813                 rv = _("not a dll");
814                 goto errorout;
815         }
816
817         pe_hdr_off = *((int32_t*) &buf[60]);
818         if (pe_hdr_off !=lseek (fd, pe_hdr_off, SEEK_SET)) {
819                 rv = _("cannot determine dll type");
820                 goto errorout;
821         }
822         if (6 != read (fd, buf, 6)) {
823                 rv = _("cannot read dll PE header");
824                 goto errorout;
825         }
826
827         if (buf[0] != 'P' && buf[1] != 'E') {
828                 rv = _("invalid dll PE header");
829                 goto errorout;
830         }
831
832         type = *((uint16_t*) &buf[4]);
833         switch (type) {
834                 case 0x014c:
835                         rv = _("i386 (32-bit)");
836                         break;
837                 case  0x0200:
838                         rv = _("Itanium");
839                         break;
840                 case 0x8664:
841                         rv = _("x64 (64-bit)");
842                         break;
843                 case 0:
844                         rv = _("Native Architecture");
845                         break;
846                 default:
847                         rv = _("Unknown Architecture");
848                         break;
849         }
850 errorout:
851         assert (rv.length() > 0);
852         close (fd);
853         return rv;
854 }
855
856 int
857 PluginManager::windows_vst_discover (string path, bool cache_only)
858 {
859         DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
860
861         if (Config->get_verbose_plugin_scan()) {
862                 if (cache_only) {
863                         info << string_compose (_(" *  %1 (cache only)"), path) << endmsg;
864                 } else {
865                         info << string_compose (_(" *  %1 - %2"), path, dll_info (path)) << endmsg;
866                 }
867         }
868
869         _cancel_timeout = false;
870         vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
871                         cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
872
873         // TODO  get extended error messae from vstfx_get_info_fst() e.g  blacklisted, 32/64bit compat,
874         // .err file scanner output etc.
875
876         if (finfos->empty()) {
877                 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
878                 if (Config->get_verbose_plugin_scan()) {
879                         info << _(" -> Cannot get Windows VST information, plugin ignored.") << endmsg;
880                 }
881                 return -1;
882         }
883
884         uint32_t discovered = 0;
885         for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
886                 VSTInfo* finfo = *x;
887                 char buf[32];
888
889                 if (!finfo->canProcessReplacing) {
890                         warning << string_compose (_("VST plugin %1 does not support processReplacing, and cannot be used in %2 at this time"),
891                                                          finfo->name, PROGRAM_NAME)
892                                 << endl;
893                         continue;
894                 }
895
896                 PluginInfoPtr info (new WindowsVSTPluginInfo);
897
898                 /* what a joke freeware VST is */
899
900                 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
901                         info->name = PBD::basename_nosuffix (path);
902                 } else {
903                         info->name = finfo->name;
904                 }
905
906
907                 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
908                 info->unique_id = buf;
909                 info->category = "VST";
910                 info->path = path;
911                 info->creator = finfo->creator;
912                 info->index = 0;
913                 info->n_inputs.set_audio (finfo->numInputs);
914                 info->n_outputs.set_audio (finfo->numOutputs);
915                 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
916                 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
917                 info->type = ARDOUR::Windows_VST;
918
919                 // TODO: check dup-IDs (lxvst AND windows vst)
920                 bool duplicate = false;
921
922                 if (!_windows_vst_plugin_info->empty()) {
923                         for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
924                                 if ((info->type == (*i)->type) && (info->unique_id == (*i)->unique_id)) {
925                                         warning << string_compose (_("Ignoring duplicate Windows VST plugin \"%1\""), info->name) << endmsg;
926                                         duplicate = true;
927                                         break;
928                                 }
929                         }
930                 }
931
932                 if (!duplicate) {
933                         DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
934                         _windows_vst_plugin_info->push_back (info);
935                         discovered++;
936                         if (Config->get_verbose_plugin_scan()) {
937                                 PBD::info << string_compose (_(" -> OK (VST Plugin \"%1\" was added)."), info->name) << endmsg;
938                         }
939                 }
940         }
941
942         vstfx_free_info_list (finfos);
943         return discovered > 0 ? 0 : -1;
944 }
945
946 #endif // WINDOWS_VST_SUPPORT
947
948 #ifdef LXVST_SUPPORT
949
950 void
951 PluginManager::lxvst_refresh (bool cache_only)
952 {
953         if (_lxvst_plugin_info) {
954                 _lxvst_plugin_info->clear ();
955         } else {
956                 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
957         }
958
959         lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
960 }
961
962 static bool lxvst_filter (const string& str, void *)
963 {
964         /* Not a dotfile, has a prefix before a period, suffix is "so" */
965
966         return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
967 }
968
969 int
970 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
971 {
972         vector<string> plugin_objects;
973         vector<string>::iterator x;
974         int ret = 0;
975
976 #ifndef NDEBUG
977         (void) path;
978 #endif
979
980         DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
981
982         find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true, true);
983
984         for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
985                 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
986                 lxvst_discover (*x, cache_only || cancelled());
987         }
988
989         return ret;
990 }
991
992 int
993 PluginManager::lxvst_discover (string path, bool cache_only)
994 {
995         DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
996
997         _cancel_timeout = false;
998         vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
999                         cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
1000
1001         if (finfos->empty()) {
1002                 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
1003                 return -1;
1004         }
1005
1006         uint32_t discovered = 0;
1007         for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
1008                 VSTInfo* finfo = *x;
1009                 char buf[32];
1010
1011                 if (!finfo->canProcessReplacing) {
1012                         warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
1013                                                          finfo->name, PROGRAM_NAME)
1014                                 << endl;
1015                         continue;
1016                 }
1017
1018                 PluginInfoPtr info(new LXVSTPluginInfo);
1019
1020                 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
1021                         info->name = PBD::basename_nosuffix (path);
1022                 } else {
1023                         info->name = finfo->name;
1024                 }
1025
1026
1027                 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
1028                 info->unique_id = buf;
1029                 info->category = "linuxVSTs";
1030                 info->path = path;
1031                 info->creator = finfo->creator;
1032                 info->index = 0;
1033                 info->n_inputs.set_audio (finfo->numInputs);
1034                 info->n_outputs.set_audio (finfo->numOutputs);
1035                 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
1036                 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
1037                 info->type = ARDOUR::LXVST;
1038
1039                                         /* Make sure we don't find the same plugin in more than one place along
1040                          the LXVST_PATH We can't use a simple 'find' because the path is included
1041                          in the PluginInfo, and that is the one thing we can be sure MUST be
1042                          different if a duplicate instance is found.  So we just compare the type
1043                          and unique ID (which for some VSTs isn't actually unique...)
1044                 */
1045
1046                 // TODO: check dup-IDs with windowsVST, too
1047                 bool duplicate = false;
1048                 if (!_lxvst_plugin_info->empty()) {
1049                         for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
1050                                 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
1051                                         warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
1052                                         duplicate = true;
1053                                         break;
1054                                 }
1055                         }
1056                 }
1057
1058                 if (!duplicate) {
1059                         _lxvst_plugin_info->push_back (info);
1060                         discovered++;
1061                 }
1062         }
1063
1064         vstfx_free_info_list (finfos);
1065         return discovered > 0 ? 0 : -1;
1066 }
1067
1068 #endif // LXVST_SUPPORT
1069
1070
1071 PluginManager::PluginStatusType
1072 PluginManager::get_status (const PluginInfoPtr& pi)
1073 {
1074         PluginStatus ps (pi->type, pi->unique_id);
1075         PluginStatusList::const_iterator i =  find (statuses.begin(), statuses.end(), ps);
1076         if (i ==  statuses.end() ) {
1077                 return Normal;
1078         } else {
1079                 return i->status;
1080         }
1081 }
1082
1083 void
1084 PluginManager::save_statuses ()
1085 {
1086         std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1087         stringstream ofs;
1088
1089         for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
1090                 switch ((*i).type) {
1091                 case LADSPA:
1092                         ofs << "LADSPA";
1093                         break;
1094                 case AudioUnit:
1095                         ofs << "AudioUnit";
1096                         break;
1097                 case LV2:
1098                         ofs << "LV2";
1099                         break;
1100                 case Windows_VST:
1101                         ofs << "Windows-VST";
1102                         break;
1103                 case LXVST:
1104                         ofs << "LXVST";
1105                         break;
1106                 case Lua:
1107                         assert (0);
1108                         continue;
1109                         break;
1110                 }
1111
1112                 ofs << ' ';
1113
1114                 switch ((*i).status) {
1115                 case Normal:
1116                         ofs << "Normal";
1117                         break;
1118                 case Favorite:
1119                         ofs << "Favorite";
1120                         break;
1121                 case Hidden:
1122                         ofs << "Hidden";
1123                         break;
1124                 }
1125
1126                 ofs << ' ';
1127                 ofs << (*i).unique_id;;
1128                 ofs << endl;
1129         }
1130         g_file_set_contents (path.c_str(), ofs.str().c_str(), -1, NULL);
1131         PluginStatusesChanged (); /* EMIT SIGNAL */
1132 }
1133
1134 void
1135 PluginManager::load_statuses ()
1136 {
1137         std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1138         gchar *fbuf = NULL;
1139         if (!g_file_get_contents (path.c_str(), &fbuf, NULL, NULL))  {
1140                 return;
1141         }
1142         stringstream ifs (fbuf);
1143         g_free (fbuf);
1144
1145         std::string stype;
1146         std::string sstatus;
1147         std::string id;
1148         PluginType type;
1149         PluginStatusType status;
1150         char buf[1024];
1151
1152         while (ifs) {
1153
1154                 ifs >> stype;
1155                 if (!ifs) {
1156                         break;
1157
1158                 }
1159
1160                 ifs >> sstatus;
1161                 if (!ifs) {
1162                         break;
1163
1164                 }
1165
1166                 /* rest of the line is the plugin ID */
1167
1168                 ifs.getline (buf, sizeof (buf), '\n');
1169                 if (!ifs) {
1170                         break;
1171                 }
1172
1173                 if (sstatus == "Normal") {
1174                         status = Normal;
1175                 } else if (sstatus == "Favorite") {
1176                         status = Favorite;
1177                 } else if (sstatus == "Hidden") {
1178                         status = Hidden;
1179                 } else {
1180                         error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
1181                                   << endmsg;
1182                         statuses.clear ();
1183                         break;
1184                 }
1185
1186                 if (stype == "LADSPA") {
1187                         type = LADSPA;
1188                 } else if (stype == "AudioUnit") {
1189                         type = AudioUnit;
1190                 } else if (stype == "LV2") {
1191                         type = LV2;
1192                 } else if (stype == "Windows-VST") {
1193                         type = Windows_VST;
1194                 } else if (stype == "LXVST") {
1195                         type = LXVST;
1196                 } else {
1197                         error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
1198                               << endmsg;
1199                         continue;
1200                 }
1201
1202                 id = buf;
1203                 strip_whitespace_edges (id);
1204                 set_status (type, id, status);
1205         }
1206 }
1207
1208 void
1209 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
1210 {
1211         PluginStatus ps (t, id, status);
1212         statuses.erase (ps);
1213
1214         if (status == Normal) {
1215                 return;
1216         }
1217
1218         statuses.insert (ps);
1219 }
1220
1221 ARDOUR::PluginInfoList&
1222 PluginManager::windows_vst_plugin_info ()
1223 {
1224 #ifdef WINDOWS_VST_SUPPORT
1225         if (!_windows_vst_plugin_info) {
1226                 windows_vst_refresh ();
1227         }
1228         return *_windows_vst_plugin_info;
1229 #else
1230         return _empty_plugin_info;
1231 #endif
1232 }
1233
1234 ARDOUR::PluginInfoList&
1235 PluginManager::lxvst_plugin_info ()
1236 {
1237 #ifdef LXVST_SUPPORT
1238         assert(_lxvst_plugin_info);
1239         return *_lxvst_plugin_info;
1240 #else
1241         return _empty_plugin_info;
1242 #endif
1243 }
1244
1245 ARDOUR::PluginInfoList&
1246 PluginManager::ladspa_plugin_info ()
1247 {
1248         assert(_ladspa_plugin_info);
1249         return *_ladspa_plugin_info;
1250 }
1251
1252 ARDOUR::PluginInfoList&
1253 PluginManager::lv2_plugin_info ()
1254 {
1255 #ifdef LV2_SUPPORT
1256         assert(_lv2_plugin_info);
1257         return *_lv2_plugin_info;
1258 #else
1259         return _empty_plugin_info;
1260 #endif
1261 }
1262
1263 ARDOUR::PluginInfoList&
1264 PluginManager::au_plugin_info ()
1265 {
1266 #ifdef AUDIOUNIT_SUPPORT
1267         if (_au_plugin_info) {
1268                 return *_au_plugin_info;
1269         }
1270 #endif
1271         return _empty_plugin_info;
1272 }