28 #include <sys/types.h>
39 #include <glib/gstdio.h>
44 #ifndef VST_SCANNER_APP
55 #define MAX_STRING_LEN 256
56 #define PLUGIN_SCAN_TIMEOUT (Config->get_vst_scan_timeout()) // in deciseconds
60 #define EXT_BLACKLIST ".fsb"
61 #define EXT_ERRORFILE ".err"
62 #define EXT_INFOFILE ".fsi"
64 #ifdef PLATFORM_WINDOWS
65 #define PFX_DOTFILE ""
67 #define PFX_DOTFILE "."
72 #ifndef VST_SCANNER_APP
77 #ifdef WINDOWS_VST_SUPPORT
80 vstfx_instantiate_and_get_info_fst (
const char* dllpath, vector<VSTInfo*> *infos,
int uniqueID);
84 static bool vstfx_instantiate_and_get_info_lx (
const char* dllpath, vector<VSTInfo*> *infos,
int uniqueID);
102 dir = Glib::path_get_dirname (std::string(dllpath));
106 s <<
PFX_DOTFILE << Glib::path_get_basename (dllpath) << ext;
107 return Glib::build_filename (dir, s.str ());
117 dir = Glib::path_get_dirname (std::string(dllpath));
122 return Glib::build_filename (dir, s.str ());
131 #ifndef VST_SCANNER_APP
146 for (
int i = 0; i < info->
numParams; i++) {
163 for (vector<VSTInfo *>::iterator i = infos->begin(); i != infos->end(); ++i) {
187 buf[strlen(buf)-1] = 0;
208 return (sscanf (p,
"%d", n) != 1);
241 for (
int i = 0; i < info->
numParams; ++i) {
249 for (
int i = 0; i < info->
numParams; ++i) {
266 if (strncmp (info->
Category,
"Shell", 5)) {
267 infos->push_back(info);
272 for (
int i = 0; i < plugin_cnt; i++) {
278 infos->push_back(info);
302 fprintf (fp,
"%s\n", info->
name);
303 fprintf (fp,
"%s\n", info->
creator);
304 fprintf (fp,
"%d\n", info->
UniqueID);
305 fprintf (fp,
"%s\n", info->
Category);
309 fprintf (fp,
"%d\n", info->
wantMidi);
313 for (
int i = 0; i < info->
numParams; i++) {
317 for (
int i = 0; i < info->
numParams; i++) {
328 if (infos->size() > 1) {
329 vector<VSTInfo *>::iterator x = infos->begin();
334 fprintf( fp,
"%d\n", (
int)infos->size() - 1 );
337 for (; x != infos->end(); ++x) {
340 }
else if (infos->size() == 1) {
354 const size_t slen = strlen (dllpath);
356 (slen <= 3 || g_ascii_strcasecmp (&dllpath[slen-3],
".so"))
358 (slen <= 4 || g_ascii_strcasecmp (&dllpath[slen-4],
".dll"))
365 if (Glib::file_test (path, Glib::FileTest (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR))) {
369 if (stat (dllpath, &dllstat) == 0 && stat (path.c_str(), &fsbstat) == 0) {
370 if (dllstat.st_mtime > fsbstat.st_mtime) {
444 const size_t slen = strlen (dllpath);
446 (slen <= 3 || g_ascii_strcasecmp (&dllpath[slen-3],
".so"))
448 (slen <= 4 || g_ascii_strcasecmp (&dllpath[slen-4],
".dll"))
455 if (Glib::file_test (path, Glib::FileTest (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR))) {
459 if (stat (dllpath, &dllstat) == 0) {
460 if (stat (path.c_str(), statbuf) == 0) {
461 if (dllstat.st_mtime <= statbuf->st_mtime) {
463 return strdup (path.c_str ());
477 struct stat own_statbuf;
478 struct stat sys_statbuf;
486 if (own_statbuf.st_mtime <= sys_statbuf.st_mtime) {
488 rv = g_fopen (sys_info,
"rb");
491 rv = g_fopen (own_info,
"rb");
493 }
else if (sys_info) {
494 rv = g_fopen (sys_info,
"rb");
508 const size_t slen = strlen (dllpath);
510 (slen <= 3 || g_ascii_strcasecmp (&dllpath[slen-3],
".so"))
512 (slen <= 4 || g_ascii_strcasecmp (&dllpath[slen-4],
".dll"))
521 return fopen (path.c_str(),
"wb");
552 PBD::warning <<
"Cannot get VST information form " << dllpath <<
": info file load failed." <<
endmsg;
569 if (vst_version >= 2) {
587 if (vst_version >= 2) {
590 if ( (plugin->
dispatcher (plugin,
effCanDo, 0, 0, const_cast<char*> (
"sendVstEvents"), 0.0f) > 0)
591 || (plugin->
dispatcher (plugin,
effCanDo, 0, 0, const_cast<char*> (
"sendVstMidiEvent"), 0.0f) > 0)
606 const char* vstfx_can_do_strings[] = {
612 "receiveVstMidiEvent",
617 const int vstfx_can_do_string_count = 9;
623 for (
int i = 0; i < vstfx_can_do_string_count; i++) {
624 if (! strcmp(vstfx_can_do_strings[i], (
const char*)ptr)) {
654 char creator[65] =
"Unknown";
662 if (strlen(name) == 0) {
666 if (strlen(name) == 0) {
669 info->
name = strdup (name);
680 if (strlen(creator) == 0) {
681 info->
creator = strdup (
"Unknown");
683 info->
creator = strdup (creator);
700 default: info->
Category = strdup (
"Unknown");
break;
714 for (
int i = 0; i < info->
numParams; ++i) {
720 strcpy (name,
"No Name");
721 strcpy (label,
"No Label");
746 infos->push_back(info);
747 #if 1 // shell-plugin support
751 if (!strncmp (info->
Category,
"Shell", 5)
754 vector< pair<int, string> > ids;
758 char name[65] =
"Unknown";
760 ids.push_back(std::make_pair(
id, name));
764 #ifdef WINDOWS_VST_SUPPORT
770 default: assert(0);
break;
773 for (vector< pair<int, string> >::iterator x = ids.begin(); x != ids.end(); ++x) {
775 if (
id == 0)
continue;
780 #ifdef WINDOWS_VST_SUPPORT
781 case ARDOUR::Windows_VST: ok = vstfx_instantiate_and_get_info_fst(dllpath, infos,
id);
break;
784 case ARDOUR::LXVST: ok = vstfx_instantiate_and_get_info_lx(dllpath, infos,
id);
break;
792 info = infos->back();
795 if ((*x).second.length() == 0) {
796 info->
name = strdup(
"Unknown");
799 info->
name = strdup ((*x).second.c_str());
805 #ifdef WINDOWS_VST_SUPPORT
811 default: assert(0);
break;
823 vstfx_instantiate_and_get_info_lx (
824 const char* dllpath, vector<VSTInfo*> *infos,
int uniqueID)
829 PBD::warning <<
"Cannot get LinuxVST information from " << dllpath <<
": load failed." <<
endmsg;
833 vstfx_current_loading_id = uniqueID;
837 PBD::warning <<
"Cannot get LinuxVST information from " << dllpath <<
": instantiation failed." <<
endmsg;
841 vstfx_current_loading_id = 0;
850 #ifdef WINDOWS_VST_SUPPORT
852 vstfx_instantiate_and_get_info_fst (
853 const char* dllpath, vector<VSTInfo*> *infos,
int uniqueID)
857 if(!(h = fst_load(dllpath))) {
858 PBD::warning <<
"Cannot get Windows VST information from " << dllpath <<
": load failed." <<
endmsg;
862 vstfx_current_loading_id = uniqueID;
866 vstfx_current_loading_id = 0;
867 PBD::warning <<
"Cannot get Windows VST information from " << dllpath <<
": instantiation failed." <<
endmsg;
870 vstfx_current_loading_id = 0;
881 #ifndef VST_SCANNER_APP
888 if (!_errorlog_fd && !_errorlog_dll) {
898 _errorlog_dll = NULL;
904 fprintf (_errorlog_fd,
"%s\n", msg.c_str());
912 assert(!_errorlog_fd);
913 assert(!_errorlog_dll);
914 _errorlog_dll = strdup(dllpath);
920 fclose(_errorlog_fd);
932 static vector<VSTInfo *> *
936 vector<VSTInfo*> *infos =
new vector<VSTInfo*>;
946 #ifndef VST_SCANNER_APP
956 char **argp= (
char**) calloc(3,
sizeof(
char*));
957 argp[0] = strdup(scanner_bin_path.c_str());
958 argp[1] = strdup(dllpath);
965 if (scanner.
start (2 )) {
966 PBD::error <<
"Cannot launch VST scanner app '" << scanner_bin_path <<
"': "<< strerror(errno) <<
endmsg;
971 bool no_timeout = (timeout <= 0);
973 while (scanner.
is_running() && (no_timeout || timeout > 0)) {
975 if (timeout%5 == 0) {
981 Glib::usleep (100000);
1013 #ifdef WINDOWS_VST_SUPPORT
1014 case ARDOUR::Windows_VST: ok = vstfx_instantiate_and_get_info_fst(dllpath, infos, 0);
break;
1016 #ifdef LXVST_SUPPORT
1017 case ARDOUR::LXVST: ok = vstfx_instantiate_and_get_info_lx(dllpath, infos, 0);
break;
1019 default: ok =
false;
1032 PBD::warning <<
"Cannot cache VST information for " << dllpath <<
": cannot create new FST info file." <<
endmsg;
1048 for (vector<VSTInfo *>::iterator i = infos->begin(); i != infos->end(); ++i) {
1058 if (!Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
1059 if (g_mkdir (dir.c_str (), 0700)) {
1060 PBD::error <<
"Cannot create VST blacklist folder '" << dir <<
"'" <<
endmsg;
1071 if (!Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
1072 if (g_mkdir (dir.c_str (), 0700)) {
1080 #ifdef LXVST_SUPPORT
1082 vstfx_get_info_lx (
char* dllpath,
enum VSTScanMode mode)
1088 #ifdef WINDOWS_VST_SUPPORT
1090 vstfx_get_info_fst (
char* dllpath,
enum VSTScanMode mode)
1096 #ifndef VST_SCANNER_APP
static void set_error_log(const char *dllpath)
static string vstfx_infofile_path(const char *dllpath, int personal)
static void vstfx_clear_info_list(vector< VSTInfo * > *infos)
static intptr_t simple_master_callback(AEffect *, int32_t opcode, int32_t, intptr_t, void *ptr, float)
static FILE * _errorlog_fd
static bool vstfx_load_info_file(FILE *fp, vector< VSTInfo * > *infos)
LIBARDOUR_API std::string get_personal_vst_blacklist_dir()
#define effGetProductString
#define effFlagsCanReplacing
static void vstfx_free_info(VSTInfo *info)
#define audioMasterVersion
static char * vstfx_infofile_stat(const char *dllpath, struct stat *statbuf, int personal)
LIBARDOUR_API VSTHandle * vstfx_load(const char *)
LIBARDOUR_API PBD::Signal1< void, int > PluginScanTimeout
intptr_t(* dispatcher)(struct _AEffect *, int, int, intptr_t, void *, float)
LIBPBD_API Transmitter error
LIBPBD_API Transmitter warning
static string vstfx_blacklist_path(const char *dllpath, int personal)
std::ostream & endmsg(std::ostream &ostr)
#define effShellGetNextPlugin
static int vstfx_current_loading_id
LIBARDOUR_API PBD::Signal0< void > GUIIdle
static void close_error_log()
static void parse_scanner_output(std::string msg, size_t)
static FILE * vstfx_blacklist_file(const char *dllpath)
static void vstfx_write_info_block(FILE *fp, VSTInfo *info)
LIBARDOUR_API VSTState * vstfx_instantiate(VSTHandle *, audioMasterCallback, void *)
static void vstfx_write_info_file(FILE *fp, vector< VSTInfo * > *infos)
static FILE * vstfx_infofile_for_write(const char *dllpath)
static vector< VSTInfo * > * vstfx_get_info(const char *dllpath, enum ARDOUR::PluginType type, enum VSTScanMode mode)
#define effGetPlugCategory
#define PLUGIN_SCAN_TIMEOUT
LIBARDOUR_API int vstfx_unload(VSTHandle *)
static bool vstfx_load_info_block(FILE *fp, VSTInfo *info)
#define effGetVendorString
LIBARDOUR_API std::string user_cache_directory()
LIBPBD_API Transmitter info
void vstfx_free_info_list(vector< VSTInfo * > *infos)
static FILE * vstfx_infofile_for_read(const char *dllpath)
static char * _errorlog_dll
static bool vstfx_get_info_from_file(const char *dllpath, vector< VSTInfo * > *infos)
static std::string scanner_bin_path
static void vstfx_un_blacklist(const char *dllpath)
#define effFlagsHasEditor
static bool read_int(FILE *fp, int *n)
static PluginManager & instance()
int start(int stderr_mode=1)
LIBARDOUR_API void vstfx_close(VSTState *)
static bool vstfx_blacklist(const char *dllpath)
LIBARDOUR_API std::string get_personal_vst_info_cache_dir()
PBD::Signal2< void, std::string, size_t > ReadStdout
static bool vstfx_midi_input(VSTState *vstfx)
static void vstfx_remove_infofile(const char *dllpath)
#define audioMasterCurrentId
static string vstfx_cache_file(const char *dllpath, int personal, const char *ext)
static char * read_string(FILE *fp)
static VSTInfo * vstfx_parse_vst_state(VSTState *vstfx)
static string vstfx_errorfile_path(const char *dllpath, int personal)
static FILE * vstfx_infofile_create(const char *dllpath, int personal)
static bool vstfx_blacklist_stat(const char *dllpath, int personal)
static void vstfx_info_from_plugin(const char *dllpath, VSTState *vstfx, vector< VSTInfo * > *infos, enum ARDOUR::PluginType type)
static bool vstfx_check_blacklist(const char *dllpath)
static bool vstfx_midi_output(VSTState *vstfx)