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