diff --git a/source/frontend/carla_database.py b/source/frontend/carla_database.py index 853fc69d9..756115569 100755 --- a/source/frontend/carla_database.py +++ b/source/frontend/carla_database.py @@ -360,6 +360,9 @@ def checkFileSF2(filename, tool): def checkFileSFZ(filename, tool): return runCarlaDiscovery(PLUGIN_SFZ, "SFZ", filename, tool) +def checkAllPluginsAU(tool): + return runCarlaDiscovery(PLUGIN_AU, "AU", ":all", tool) + # ---------------------------------------------------------------------------------------------------------------------- # Separate Thread for Plugin Search @@ -601,7 +604,7 @@ class SearchPluginsThread(QThread): if not self.fContinueChecking: return if self.fCheckLV2: - plugins = self._checkLv2Cached() + plugins = self._checkCached(True) settingsDB.setValue("Plugins/LV2", plugins) settingsDB.sync() if not self.fContinueChecking: return @@ -635,6 +638,50 @@ class SearchPluginsThread(QThread): settingsDB.sync() if not self.fContinueChecking: return + if self.fCheckVST3: + if self.fCheckNative and (MACOS or WINDOWS): + plugins = self._checkVST3(OS, self.fToolNative) + settingsDB.setValue("Plugins/VST3_native", plugins) + if not self.fContinueChecking: return + + if self.fCheckPosix32: + plugins = self._checkVST3(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix32")) + settingsDB.setValue("Plugins/VST3_posix32", plugins) + if not self.fContinueChecking: return + + if self.fCheckPosix64: + plugins = self._checkVST3(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix64")) + settingsDB.setValue("Plugins/VST3_posix64", plugins) + if not self.fContinueChecking: return + + if self.fCheckWin32: + plugins = self._checkVST3("WINDOWS", os.path.join(self.fPathBinaries, "carla-discovery-win32.exe"), not WINDOWS) + settingsDB.setValue("Plugins/VST3_win32", plugins) + if not self.fContinueChecking: return + + if self.fCheckWin64: + plugins = self._checkVST3("WINDOWS", os.path.join(self.fPathBinaries, "carla-discovery-win64.exe"), not WINDOWS) + settingsDB.setValue("Plugins/VST3_win64", plugins) + if not self.fContinueChecking: return + + settingsDB.sync() + if not self.fContinueChecking: return + + if self.fCheckAU: + if self.fCheckNative: + plugins = self._checkCached(False) + settingsDB.setValue("Plugins/AU", plugins) + settingsDB.sync() + if not self.fContinueChecking: return + + if self.fCheckPosix32: + plugins = self._checkAU(os.path.join(self.fPathBinaries, "carla-discovery-posix32")) + settingsDB.setValue("Plugins/AU_posix32", self.fAuPlugins) + if not self.fContinueChecking: return + + settingsDB.sync() + if not self.fContinueChecking: return + if self.fCheckSF2: settings = QSettings("falkTX", "Carla2") SF2_PATH = toList(settings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH)) @@ -764,6 +811,58 @@ class SearchPluginsThread(QThread): self.fLastCheckValue += self.fCurPercentValue return vstPlugins + def _checkVST3(self, OS, tool, isWine=False): + vst3Binaries = [] + vst3Plugins = [] + + if MACOS and not isWine: + self._pluginLook(self.fLastCheckValue, "VST2 bundles...") + else: + self._pluginLook(self.fLastCheckValue, "VST2 plugins...") + + settings = QSettings("falkTX", "Carla2") + VST3_PATH = toList(settings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH)) + del settings + + for iPATH in VST3_PATH: + if MACOS and not isWine: + binaries = findMacVSTBundles(iPATH, False) + else: + binaries = findVST3Binaries(iPATH) + for binary in binaries: + if binary not in vst3Binaries: + vst3Binaries.append(binary) + + vst3Binaries.sort() + + if not self.fContinueChecking: + return vst3Plugins + + for i in range(len(vst3Binaries)): + vst3 = vst3Binaries[i] + percent = ( float(i) / len(vst3Binaries) ) * self.fCurPercentValue + self._pluginLook(self.fLastCheckValue + percent, vst3) + + plugins = checkPluginVST3(vst3, tool, self.fWineSettings if isWine else None) + if plugins: + vst3Plugins.append(plugins) + + if not self.fContinueChecking: + break + + self.fLastCheckValue += self.fCurPercentValue + return vst3Plugins + + def _checkAU(self, tool): + auPlugins = [] + + plugins = checkAllPluginsAU(tool) + if plugins: + auPlugins.append(plugins) + + self.fLastCheckValue += self.fCurPercentValue + return auPlugins + def _checkKIT(self, kitPATH, kitExtension): kitFiles = [] kitPlugins = [] @@ -798,21 +897,28 @@ class SearchPluginsThread(QThread): self.fLastCheckValue += self.fCurPercentValue return kitPlugins - def _checkLv2Cached(self): - settings = QSettings("falkTX", "Carla2") - PLUG_PATH = splitter.join(toList(settings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH))) - del settings + def _checkCached(self, isLV2): + if isLV2: + settings = QSettings("falkTX", "Carla2") + PLUG_PATH = splitter.join(toList(settings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH))) + del settings + PLUG_TEXT = "LV2" + PLUG_TYPE = PLUGIN_LV2 + else: # AU + PLUG_PATH = "" + PLUG_TEXT = "AU" + PLUG_TYPE = PLUGIN_AU - lv2Plugins = [] - self._pluginLook(self.fLastCheckValue, "LV2 plugins...") + plugins = [] + self._pluginLook(self.fLastCheckValue, "{} plugins...".format(PLUG_TEXT)) - count = gCarla.utils.get_cached_plugin_count(PLUGIN_LV2, PLUG_PATH) + count = gCarla.utils.get_cached_plugin_count(PLUG_TYPE, PLUG_PATH) if not self.fContinueChecking: - return lv2Plugins + return plugins for i in range(count): - descInfo = gCarla.utils.get_cached_plugin_info(PLUGIN_LV2, i) + descInfo = gCarla.utils.get_cached_plugin_info(PLUG_TYPE, i) percent = ( float(i) / count ) * self.fCurPercentValue self._pluginLook(self.fLastCheckValue + percent, descInfo['label']) @@ -820,13 +926,13 @@ class SearchPluginsThread(QThread): if not descInfo['valid']: continue - lv2Plugins.append(checkPluginCached(descInfo, PLUGIN_LV2)) + plugins.append(checkPluginCached(descInfo, PLUG_TYPE)) if not self.fContinueChecking: break self.fLastCheckValue += self.fCurPercentValue - return lv2Plugins + return plugins def _checkSfzCached(self): settings = QSettings("falkTX", "Carla2") @@ -973,6 +1079,14 @@ class PluginRefreshW(QDialog): self.ui.ico_posix32.setVisible(False) self.ui.label_posix32.setVisible(False) + if not MACOS: + self.ui.ch_au.setEnabled(False) + self.ui.ch_au.setVisible(False) + + if not (hasWin32 or hasWin64): + self.ui.ch_vst3.setEnabled(False) + self.ui.ch_vst3.setVisible(False) + if hasNative: self.ui.ico_native.setPixmap(self.fIconYes) else: @@ -1041,6 +1155,10 @@ class PluginRefreshW(QDialog): self.ui.ch_sf2.setChecked(False) self.ui.ch_sf2.setEnabled(False) + if MACOS and "juce" not in features: + self.ui.ch_au.setChecked(False) + self.ui.ch_au.setEnabled(False) + # ------------------------------------------------------------------------------------------------------------- # Resize to minimum size, as it's very likely UI stuff was hidden @@ -1061,6 +1179,8 @@ class PluginRefreshW(QDialog): self.ui.ch_dssi.clicked.connect(self.slot_checkTools) self.ui.ch_lv2.clicked.connect(self.slot_checkTools) self.ui.ch_vst.clicked.connect(self.slot_checkTools) + self.ui.ch_vst3.clicked.connect(self.slot_checkTools) + self.ui.ch_au.clicked.connect(self.slot_checkTools) self.ui.ch_sf2.clicked.connect(self.slot_checkTools) self.ui.ch_sfz.clicked.connect(self.slot_checkTools) self.fThread.pluginLook.connect(self.slot_handlePluginLook) @@ -1088,6 +1208,15 @@ class PluginRefreshW(QDialog): check = settings.value("PluginDatabase/SearchVST2", True, type=bool) and self.ui.ch_vst.isEnabled() self.ui.ch_vst.setChecked(check) + check = settings.value("PluginDatabase/SearchVST3", True, type=bool) and self.ui.ch_vst3.isEnabled() + self.ui.ch_vst3.setChecked(check) + + if MACOS: + check = settings.value("PluginDatabase/SearchAU", True, type=bool) and self.ui.ch_au.isEnabled() + else: + check = False + self.ui.ch_au.setChecked(check) + check = settings.value("PluginDatabase/SearchSF2", False, type=bool) and self.ui.ch_sf2.isEnabled() self.ui.ch_sf2.setChecked(check) @@ -1120,6 +1249,8 @@ class PluginRefreshW(QDialog): settings.setValue("PluginDatabase/SearchDSSI", self.ui.ch_dssi.isChecked()) settings.setValue("PluginDatabase/SearchLV2", self.ui.ch_lv2.isChecked()) settings.setValue("PluginDatabase/SearchVST2", self.ui.ch_vst.isChecked()) + settings.setValue("PluginDatabase/SearchVST3", self.ui.ch_vst3.isChecked()) + settings.setValue("PluginDatabase/SearchAU", self.ui.ch_au.isChecked()) settings.setValue("PluginDatabase/SearchSF2", self.ui.ch_sf2.isChecked()) settings.setValue("PluginDatabase/SearchSFZ", self.ui.ch_sfz.isChecked()) settings.setValue("PluginDatabase/SearchNative", self.ui.ch_native.isChecked()) @@ -1151,13 +1282,10 @@ class PluginRefreshW(QDialog): self.ui.ch_posix32.isChecked(), self.ui.ch_posix64.isChecked(), self.ui.ch_win32.isChecked(), self.ui.ch_win64.isChecked()) - ladspa, dssi, lv2, vst, sf2, sfz = (self.ui.ch_ladspa.isChecked(), self.ui.ch_dssi.isChecked(), - self.ui.ch_lv2.isChecked(), self.ui.ch_vst.isChecked(), - self.ui.ch_sf2.isChecked(), self.ui.ch_sfz.isChecked()) - - # TODO - vst3 = False - au = False + ladspa, dssi, lv2, vst, vst3, au, sf2, sfz = (self.ui.ch_ladspa.isChecked(), self.ui.ch_dssi.isChecked(), + self.ui.ch_lv2.isChecked(), self.ui.ch_vst.isChecked(), + self.ui.ch_vst3.isChecked(), self.ui.ch_au.isChecked(), + self.ui.ch_sf2.isChecked(), self.ui.ch_sfz.isChecked()) self.fThread.setSearchBinaryTypes(native, posix32, posix64, win32, win64) self.fThread.setSearchPluginTypes(ladspa, dssi, lv2, vst, vst3, au, sf2, sfz) @@ -1179,6 +1307,7 @@ class PluginRefreshW(QDialog): enabled2 = bool(self.ui.ch_ladspa.isChecked() or self.ui.ch_dssi.isChecked() or self.ui.ch_lv2.isChecked() or self.ui.ch_vst.isChecked() or + self.ui.ch_vst3.isChecked() or self.ui.ch_au.isChecked() or self.ui.ch_sf2.isChecked() or self.ui.ch_sfz.isChecked()) self.ui.b_start.setEnabled(enabled1 and enabled2) @@ -1262,6 +1391,11 @@ class PluginDatabaseW(QDialog): self.ui.ch_bridged_wine.setChecked(False) self.ui.ch_bridged_wine.setEnabled(False) + if not MACOS: + self.ui.ch_au.setChecked(False) + self.ui.ch_au.setEnabled(False) + self.ui.ch_au.setVisible(False) + self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) # ---------------------------------------------------------------------------------------------------- @@ -1311,6 +1445,8 @@ class PluginDatabaseW(QDialog): self.ui.ch_dssi.clicked.connect(self.slot_checkFilters) self.ui.ch_lv2.clicked.connect(self.slot_checkFilters) self.ui.ch_vst.clicked.connect(self.slot_checkFilters) + self.ui.ch_vst3.clicked.connect(self.slot_checkFilters) + self.ui.ch_au.clicked.connect(self.slot_checkFilters) self.ui.ch_kits.clicked.connect(self.slot_checkFilters) self.ui.ch_native.clicked.connect(self.slot_checkFilters) self.ui.ch_bridged.clicked.connect(self.slot_checkFilters) @@ -1371,6 +1507,8 @@ class PluginDatabaseW(QDialog): settings.setValue("PluginDatabase/ShowDSSI", self.ui.ch_dssi.isChecked()) settings.setValue("PluginDatabase/ShowLV2", self.ui.ch_lv2.isChecked()) settings.setValue("PluginDatabase/ShowVST2", self.ui.ch_vst.isChecked()) + settings.setValue("PluginDatabase/ShowVST3", self.ui.ch_vst3.isChecked()) + settings.setValue("PluginDatabase/ShowAU", self.ui.ch_au.isChecked()) settings.setValue("PluginDatabase/ShowKits", self.ui.ch_kits.isChecked()) settings.setValue("PluginDatabase/ShowNative", self.ui.ch_native.isChecked()) settings.setValue("PluginDatabase/ShowBridged", self.ui.ch_bridged.isChecked()) @@ -1394,6 +1532,8 @@ class PluginDatabaseW(QDialog): self.ui.ch_dssi.setChecked(settings.value("PluginDatabase/ShowDSSI", True, type=bool)) self.ui.ch_lv2.setChecked(settings.value("PluginDatabase/ShowLV2", True, type=bool)) self.ui.ch_vst.setChecked(settings.value("PluginDatabase/ShowVST2", True, type=bool)) + self.ui.ch_vst3.setChecked(settings.value("PluginDatabase/ShowVST3", (MACOS or WINDOWS), type=bool)) + self.ui.ch_au.setChecked(settings.value("PluginDatabase/ShowAU", MACOS, type=bool)) self.ui.ch_kits.setChecked(settings.value("PluginDatabase/ShowKits", True, type=bool)) self.ui.ch_native.setChecked(settings.value("PluginDatabase/ShowNative", True, type=bool)) self.ui.ch_bridged.setChecked(settings.value("PluginDatabase/ShowBridged", True, type=bool)) @@ -1426,6 +1566,8 @@ class PluginDatabaseW(QDialog): hideDssi = not self.ui.ch_dssi.isChecked() hideLV2 = not self.ui.ch_lv2.isChecked() hideVST2 = not self.ui.ch_vst.isChecked() + hideVST3 = not self.ui.ch_vst3.isChecked() + hideAU = not self.ui.ch_au.isChecked() hideKits = not self.ui.ch_kits.isChecked() hideNative = not self.ui.ch_native.isChecked() @@ -1488,6 +1630,10 @@ class PluginDatabaseW(QDialog): self.ui.tableWidget.hideRow(i) elif hideVST2 and ptype == "VST2": self.ui.tableWidget.hideRow(i) + elif hideVST3 and ptype == "VST3": + self.ui.tableWidget.hideRow(i) + elif hideAU and ptype == "AU": + self.ui.tableWidget.hideRow(i) elif hideNative and isNative: self.ui.tableWidget.hideRow(i) elif hideBridged and isBridged: @@ -1637,6 +1783,7 @@ class PluginDatabaseW(QDialog): internalCount = self._reAddInternalHelper(settingsDB, PLUGIN_INTERNAL, "") lv2Count = self._reAddInternalHelper(settingsDB, PLUGIN_LV2, LV2_PATH) + auCount = self._reAddInternalHelper(settingsDB, PLUGIN_AU, "") if MACOS else 0 # ---------------------------------------------------------------------------------------------------- # LADSPA @@ -1668,6 +1815,21 @@ class PluginDatabaseW(QDialog): vst2Plugins += toList(settingsDB.value("Plugins/VST2_win32", [])) vst2Plugins += toList(settingsDB.value("Plugins/VST2_win64", [])) + # ---------------------------------------------------------------------------------------------------- + # VST3 + + vst3Plugins = [] + vst3Plugins += toList(settingsDB.value("Plugins/VST3_native", [])) + vst3Plugins += toList(settingsDB.value("Plugins/VST3_posix32", [])) + vst3Plugins += toList(settingsDB.value("Plugins/VST3_posix64", [])) + vst3Plugins += toList(settingsDB.value("Plugins/VST3_win32", [])) + vst3Plugins += toList(settingsDB.value("Plugins/VST3_win64", [])) + + # ---------------------------------------------------------------------------------------------------- + # AU (extra non-cached) + + auPlugins = toList(settingsDB.value("Plugins/AU_posix32", [])) if MACOS else [] + # ---------------------------------------------------------------------------------------------------- # Kits @@ -1680,6 +1842,7 @@ class PluginDatabaseW(QDialog): ladspaCount = 0 dssiCount = 0 vstCount = 0 + vst3Count = 0 sf2Count = 0 sfzCount = 0 @@ -1692,6 +1855,12 @@ class PluginDatabaseW(QDialog): for plugins in vst2Plugins: vstCount += len(plugins) + for plugins in vst3Plugins: + vst3Count += len(plugins) + + for plugins in auPlugins: + auCount += len(plugins) + for plugins in sf2s: sf2Count += len(plugins) @@ -1699,8 +1868,12 @@ class PluginDatabaseW(QDialog): self.ui.tableWidget.setRowCount(self.fLastTableIndex+ladspaCount+dssiCount+vstCount+sf2Count+sfzCount) - self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2 and %i VST plugins, plus %i Sound Kits" % ( - internalCount, ladspaCount, dssiCount, lv2Count, vstCount, sf2Count+sfzCount))) + if MACOS: + self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2, %i VST2, %i VST3 and %i AudioUnit plugins, plus %i Sound Kits" % ( + internalCount, ladspaCount, dssiCount, lv2Count, vstCount, vst3Count, auCount, sf2Count+sfzCount))) + else: + self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2, %i VST2 and %i VST3 plugins, plus %i Sound Kits" % ( + internalCount, ladspaCount, dssiCount, lv2Count, vstCount, vst3Count, sf2Count+sfzCount))) # ---------------------------------------------------------------------------------------------------- # now add all plugins to the table @@ -1717,6 +1890,14 @@ class PluginDatabaseW(QDialog): for plugin in plugins: self._addPluginToTable(plugin, "VST2") + for plugins in vst3Plugins: + for plugin in plugins: + self._addPluginToTable(plugin, "VST3") + + for plugins in auPlugins: + for plugin in plugins: + self._addPluginToTable(plugin, "AU") + for sf2 in sf2s: for sf2_i in sf2: self._addPluginToTable(sf2_i, "SF2")