21 #include "libardour-config.h"
26 #include <sys/types.h>
35 #ifdef WINDOWS_VST_SUPPORT
40 #endif // WINDOWS_VST_SUPPORT
47 #endif //LXVST_SUPPORT
49 #include <glib/gstdio.h>
50 #include <glibmm/miscutils.h>
51 #include <glibmm/pattern.h>
52 #include <glibmm/fileutils.h>
53 #include <glibmm/miscutils.h>
58 #include "ardour/debug.h"
72 #ifdef WINDOWS_VST_SUPPORT
80 #ifdef AUDIOUNIT_SUPPORT
82 #include <Carbon/Carbon.h>
90 #include "ardour/debug.h"
109 : _windows_vst_plugin_info(0)
110 , _lxvst_plugin_info(0)
111 , _ladspa_plugin_info(0)
112 , _lv2_plugin_info(0)
114 , _cancel_scan(false)
115 , _cancel_timeout(false)
120 #if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
124 #ifdef PLATFORM_WINDOWS
126 vstsp += Glib::build_filename(g_win32_get_package_installation_directory_of_module (0),
"bin");
133 #ifdef PLATFORM_WINDOWS
134 #ifdef DEBUGGABLE_SCANNER_APP
135 #
if defined(
DEBUG) || defined(_DEBUG)
136 "ardour-vst-scannerD.exe"
138 "ardour-vst-scannerRDC.exe"
141 "ardour-vst-scanner.exe"
153 if ((s = getenv (
"LADSPA_RDF_PATH"))){
157 if (lrdf_path.length() == 0) {
158 lrdf_path =
"/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
163 #ifdef WINDOWS_VST_SUPPORT
164 if (
Config->get_use_windows_vst ()) {
170 if (
Config->get_use_lxvst()) {
175 if ((s = getenv (
"VST_PATH"))) {
177 }
else if ((s = getenv (
"VST_PLUGINS"))) {
185 if ((s = getenv (
"LXVST_PATH"))) {
187 }
else if ((s = getenv (
"LXVST_PLUGINS"))) {
192 lxvst_path =
"/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
193 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
194 "/usr/lib/vst:/usr/local/lib/vst";
198 if (
Config->get_plugin_path_lxvst() ==
X_(
"@default@")) {
201 if (
Config->get_plugin_path_vst() ==
X_(
"@default@")) {
215 if (getenv (
"ARDOUR_RUNNING_UNDER_VALGRIND")) {
237 #ifdef WINDOWS_VST_SUPPORT
238 if (
Config->get_use_windows_vst()) {
242 #endif // WINDOWS_VST_SUPPORT
245 if(
Config->get_use_lxvst()) {
249 #endif //Native linuxVST SUPPORT
251 #ifdef AUDIOUNIT_SUPPORT
278 #ifdef WINDOWS_VST_SUPPORT
280 vector<string> fsi_files;
282 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
283 ::g_unlink(i->c_str());
290 vector<string> fsi_files;
292 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
293 ::g_unlink(i->c_str());
298 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
301 vector<string> fsi_files;
303 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
304 ::g_unlink(i->c_str());
313 #ifdef WINDOWS_VST_SUPPORT
315 vector<string> fsi_files;
317 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
318 ::g_unlink(i->c_str());
325 vector<string> fsi_files;
327 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
328 ::g_unlink(i->c_str());
333 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
337 vector<string> fsi_files;
339 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
340 ::g_unlink(i->c_str());
349 #ifdef AUDIOUNIT_SUPPORT
352 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
353 ::g_unlink(fn.c_str());
361 #ifdef AUDIOUNIT_SUPPORT
363 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
364 ::g_unlink(fn.c_str());
384 vector<string> ladspa_modules;
392 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
399 static bool rdf_filter (
const string &str,
void* )
401 return str[0] !=
'.' &&
402 ((str.find(
".rdf") == (str.length() - 4)) ||
403 (str.find(
".rdfs") == (str.length() - 5)) ||
404 (str.find(
".n3") == (str.length() - 3)) ||
405 (str.find(
".ttl") == (str.length() - 4)));
431 vector<string> presets;
432 vector<string>::iterator x;
435 if ((envvar = getenv (
"HOME")) == 0) {
442 for (x = presets.begin(); x != presets.end (); ++x) {
443 string file =
"file:" + *x;
444 if (lrdf_read_file(file.c_str())) {
456 vector<string> rdf_files;
457 vector<string>::iterator x;
461 for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
462 const string uri(
string(
"file://") + *x);
464 if (lrdf_read_file(uri.c_str())) {
476 Glib::Module module(path);
483 path, Glib::Module::get_last_error()) <<
endmsg;
488 if (!module.get_symbol(
"ladspa_descriptor", func)) {
498 for (uint32_t i = 0; ; ++i) {
499 if ((descriptor = dfunc (i)) == 0) {
520 snprintf (buf,
sizeof (buf),
"%lu", descriptor->
UniqueID);
523 for (uint32_t n=0; n < descriptor->
PortCount; ++n) {
543 if(0 == info->
unique_id.compare((*i)->unique_id)){
566 lrdf_statement pattern;
568 snprintf(buf,
sizeof(buf),
"%s%" PRIu32, LADSPA_BASE, plugin_id);
569 pattern.subject = buf;
570 pattern.predicate =
const_cast<char*
>(RDF_TYPE);
572 pattern.object_type = lrdf_uri;
574 lrdf_statement* matches1 = lrdf_matches (&pattern);
580 pattern.subject = matches1->object;
581 pattern.predicate =
const_cast<char*
>(LADSPA_BASE
"hasLabel");
583 pattern.object_type = lrdf_literal;
585 lrdf_statement* matches2 = lrdf_matches (&pattern);
586 lrdf_free_statements(matches1);
592 string label = matches2->object;
593 lrdf_free_statements(matches2);
611 if (label ==
"Utilities") {
613 }
else if (label ==
"Pitch shifters") {
614 return "Pitch Shifter";
615 }
else if (label !=
"Dynamics" && label !=
"Chorus"
616 &&label[label.length() - 1] ==
's'
617 && label[label.length() - 2] !=
's') {
618 return label.substr(0, label.length() - 1);
637 #ifdef AUDIOUNIT_SUPPORT
642 if (cache_only && !
Config->get_discover_audio_units ()) {
649 Config->set_discover_audio_units (
false);
666 Config->set_discover_audio_units (
true);
672 #ifdef WINDOWS_VST_SUPPORT
686 static bool windows_vst_filter (
const string& str,
void * )
695 vector<string> plugin_objects;
696 vector<string>::iterator x;
703 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
717 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
720 if (finfos->empty()) {
725 uint32_t discovered = 0;
726 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
731 warning <<
string_compose (
_(
"VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
732 finfo->
name, PROGRAM_NAME)
741 if (!strcasecmp (
"The Unnamed plugin", finfo->
name)) {
748 snprintf (buf,
sizeof (buf),
"%d", finfo->
UniqueID);
749 info->unique_id = buf;
750 info->category =
"VST";
761 bool duplicate =
false;
765 if ((
info->type == (*i)->type)&&(
info->unique_id == (*i)->unique_id)) {
766 warning <<
"Ignoring duplicate Windows VST plugin " <<
info->name <<
"\n";
781 return discovered > 0 ? 0 : -1;
784 #endif // WINDOWS_VST_SUPPORT
800 static bool lxvst_filter (
const string& str,
void *)
804 return str[0] !=
'.' && (str.length() > 3 && str.find (
".so") == (str.length() - 3));
810 vector<string> plugin_objects;
811 vector<string>::iterator x;
822 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
836 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
839 if (finfos->empty()) {
844 uint32_t discovered = 0;
845 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
850 warning <<
string_compose (
_(
"linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
851 finfo->
name, PROGRAM_NAME)
858 if (!strcasecmp (
"The Unnamed plugin", finfo->
name)) {
865 snprintf (buf,
sizeof (buf),
"%d", finfo->
UniqueID);
866 info->unique_id = buf;
867 info->category =
"linuxVSTs";
885 bool duplicate =
false;
888 if ((
info->type == (*i)->type)&&(
info->unique_id == (*i)->unique_id)) {
889 warning <<
"Ignoring duplicate Linux VST plugin " <<
info->name <<
"\n";
903 return discovered > 0 ? 0 : -1;
906 #endif // LXVST_SUPPORT
913 PluginStatusList::const_iterator i = find (
statuses.begin(),
statuses.end(), ps);
927 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
933 for (PluginStatusList::iterator i =
statuses.begin(); i !=
statuses.end(); ++i) {
945 ofs <<
"Windows-VST";
954 switch ((*i).status) {
967 ofs << (*i).unique_id;;
978 ifstream ifs (path.c_str());
1007 ifs.getline (buf,
sizeof (buf),
'\n');
1012 if (sstatus ==
"Normal") {
1014 }
else if (sstatus ==
"Favorite") {
1016 }
else if (sstatus ==
"Hidden") {
1019 error <<
string_compose (
_(
"unknown plugin status type \"%1\" - all entries ignored"), sstatus)
1025 if (stype ==
"LADSPA") {
1027 }
else if (stype ==
"AudioUnit") {
1029 }
else if (stype ==
"LV2") {
1031 }
else if (stype ==
"Windows-VST") {
1033 }
else if (stype ==
"LXVST") {
1065 #ifdef WINDOWS_VST_SUPPORT
1078 #ifdef LXVST_SUPPORT
1107 #ifdef AUDIOUNIT_SUPPORT
void add_windows_vst_presets()
std::string to_string(T t, std::ios_base &(*f)(std::ios_base &))
const LADSPA_Descriptor *(* LADSPA_Descriptor_Function)(unsigned long Index)
void cancel_plugin_scan()
ARDOUR::PluginInfoList * _au_plugin_info
int ladspa_discover(std::string path)
LIBARDOUR_API void vstfx_free_info_list(std::vector< VSTInfo * > *infos)
bool strings_equal_ignore_case(const string &a, const string &b)
LIBARDOUR_API PBD::Searchpath ladspa_search_path()
void windows_vst_refresh(bool cache_only=false)
LIBARDOUR_API std::string get_personal_vst_blacklist_dir()
#define DEBUG(format,...)
void find_files_matching_regex(vector< string > &result, const Searchpath &paths, const std::string ®exp, bool recurse)
ARDOUR::PluginInfoList & windows_vst_plugin_info()
PluginStatusList statuses
ARDOUR::PluginInfoList * _windows_vst_plugin_info
void set_status(ARDOUR::PluginType type, std::string unique_id, PluginStatusType status)
void lxvst_refresh(bool cache_only=false)
LIBPBD_API Transmitter error
LIBPBD_API Transmitter warning
int windows_vst_discover_from_path(std::string path, bool cache_only=false)
std::ostream & endmsg(std::ostream &ostr)
static PluginInfoList * discover()
LIBPBD_API void strip_whitespace_edges(std::string &str)
void clear_vst_blacklist()
ARDOUR::PluginInfoList & lv2_plugin_info()
bool find_file(const Searchpath &search_path, const string &filename, std::string &result)
void clear_au_blacklist()
ARDOUR::PluginInfoList * _lv2_plugin_info
LIBARDOUR_API const char * vst_search_path()
ARDOUR::PluginInfoList _empty_plugin_info
LIBARDOUR_API std::string user_config_directory(int version=-1)
const std::string get_default_windows_vst_path() const
LIBARDOUR_API uint64_t PluginManager
void add_ladspa_presets()
void find_files_matching_pattern(vector< string > &result, const Searchpath &paths, const Glib::PatternSpec &pattern)
PBD::Signal0< void > PluginListChanged
LIBARDOUR_API RCConfiguration * Config
static PluginManager * _instance
ARDOUR::PluginInfoList & ladspa_plugin_info()
void au_refresh(bool cache_only=false)
std::string windows_vst_path
LIBARDOUR_API std::string ardour_dll_directory()
#define DEBUG_TRACE(bits, str)
LIBARDOUR_API std::string user_cache_directory()
LIBPBD_API Transmitter info
void set_audio(uint32_t a)
static std::string scanner_bin_path
int lxvst_discover(std::string path, bool cache_only=false)
ARDOUR::PluginInfoList & au_plugin_info()
LIBPBD_API Glib::ustring basename_nosuffix(Glib::ustring)
#define LADSPA_IS_PORT_AUDIO(x)
static PluginManager & instance()
std::vector< uint32_t > ladspa_plugin_whitelist
ARDOUR::PluginInfoList & lxvst_plugin_info()
ARDOUR::PluginInfoList * _ladspa_plugin_info
ARDOUR::PluginInfoList * _lxvst_plugin_info
#define LADSPA_IS_PORT_INPUT(x)
void cancel_plugin_timeout()
LIBARDOUR_API PBD::Signal1< void, std::string > BootMessage
LIBPBD_TEMPLATE_MEMBER_API const std::string to_string() const
std::string get_ladspa_category(uint32_t id)
LIBARDOUR_API std::string get_personal_vst_info_cache_dir()
const LADSPA_PortDescriptor * PortDescriptors
void add_presets(std::string domain)
LIBARDOUR_API PBD::Signal3< void, std::string, std::string, bool > PluginScanMessage
std::list< PluginInfoPtr > PluginInfoList
#define LADSPA_IS_PORT_OUTPUT(x)
int windows_vst_discover(std::string path, bool cache_only=false)
void find_files_matching_filter(vector< string > &result, const Searchpath &paths, bool(*filter)(const string &, void *), void *arg, bool pass_fullpath, bool return_fullpath, bool recurse)
int lxvst_discover_from_path(std::string path, bool cache_only=false)
void add_lrdf_data(const std::string &path)
const std::string get_default_lxvst_path() const
static PluginInfoList * discover()
std::string string_compose(const std::string &fmt, const T1 &o1)
PluginStatusType get_status(const PluginInfoPtr &)
void refresh(bool cache_only=false)