/* static */ void VSTEffect::Scan() { wxArrayString audacityPathList = wxGetApp().audacityPathList; wxArrayString pathList; wxArrayString files; // Check for the VST_PATH environment variable wxString vstpath = wxGetenv(wxT("VST_PATH")); if (!vstpath.IsEmpty()) { wxGetApp().AddUniquePathToPathList(vstpath, pathList); } // Add Audacity specific paths for (size_t i = 0; i < audacityPathList.GetCount(); i++) { wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH; wxGetApp().AddUniquePathToPathList(prefix + VSTPLUGINTYPE, pathList); wxGetApp().AddUniquePathToPathList(prefix + wxT("plugins"), pathList); wxGetApp().AddUniquePathToPathList(prefix + wxT("plug-ins"), pathList); } #if defined(__WXMAC__) #define VSTPATH wxT("/Library/Audio/Plug-Ins/VST") // Look in /Library/Audio/Plug-Ins/VST and $HOME/Library/Audio/Plug-Ins/VST wxGetApp().AddUniquePathToPathList(VSTPATH, pathList); wxGetApp().AddUniquePathToPathList(wxString(wxGetenv(wxT("HOME"))) + VSTPATH, pathList); // Recursively search all paths for Info.plist files. This will identify all // bundles. wxGetApp().FindFilesInPathList(wxT("Info.plist"), pathList, files, wxDIR_DEFAULT); // Remove the 'Contents/Info.plist' portion of the names for (size_t i = 0, cnt = files.GetCount(); i < cnt; i++) { files[i] = wxPathOnly(wxPathOnly(files[i])); } #elif defined(__WXMSW__) TCHAR dpath[MAX_PATH]; TCHAR tpath[MAX_PATH]; DWORD len = WXSIZEOF(tpath); // Setup the default VST path. dpath[0] = '\0'; ExpandEnvironmentStrings(wxT("%ProgramFiles%\\Steinberg\\VSTPlugins"), dpath, WXSIZEOF(dpath)); // Check registry for the real path if (SHRegGetUSValue(wxT("Software\\VST"), wxT("VSTPluginsPath"), NULL, tpath, &len, FALSE, dpath, (DWORD) _tcslen(dpath)) == ERROR_SUCCESS) { tpath[len] = 0; ExpandEnvironmentStrings(tpath, dpath, WXSIZEOF(dpath)); wxGetApp().AddUniquePathToPathList(LAT1CTOWX(dpath), pathList); } // Recursively scan for all DLLs wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files, wxDIR_DEFAULT); #else // Recursively scan for all shared objects wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files); #endif // This is a hack to allow for long paths in the progress dialog. The // progress dialog should really truncate the message if it's too wide // for the dialog. size_t cnt = files.GetCount(); wxString longest; // JKC: Let's not show the progress dialog if there are no // files to test. if( cnt <= 0 ) return; for (size_t i = 0; i < cnt; i++) { if (files[i].Length() > longest.Length()) { longest = files[i]; } } ProgressDialog *progress = new ProgressDialog(_("Scanning VST Plugins"), longest, pdlgHideStopButton); // progress->SetSize(wxSize(500, -1)); progress->CenterOnScreen(); const wxChar * argv[4]; argv[0] = PlatformCompatibility::GetExecutablePath().c_str(); argv[1] = VSTCMDKEY; argv[2] = NULL; argv[3] = NULL; for (size_t i = 0; i < cnt; i++) { wxString file = files[i]; int status = progress->Update(wxLongLong(i), wxLongLong(cnt), wxString::Format(_("Checking %s"), file.c_str())); if (status != eProgressSuccess) { break; } argv[2] = file.c_str(); // ToDo: do we need a try--catch around this in case a bad plug-in // fails? (JKC Nov09) wxExecute((wxChar **) argv, wxEXEC_SYNC | wxEXEC_NODISABLE, NULL); } delete progress; }