Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

discoverythread.py 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla plugin host
  4. # Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
  5. #
  6. # This program is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU General Public License as
  8. # published by the Free Software Foundation; either version 2 of
  9. # the License, or any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # For a full copy of the GNU General Public License see the doc/GPL.txt file.
  17. # ---------------------------------------------------------------------------------------------------------------------
  18. # Imports (Global)
  19. import os
  20. from PyQt5.QtCore import pyqtSignal, QThread
  21. from PyQt5.QtWidgets import QWidget
  22. # ---------------------------------------------------------------------------------------------------------------------
  23. # Imports (Custom)
  24. from carla_backend import (
  25. PLUGIN_AU,
  26. PLUGIN_DSSI,
  27. PLUGIN_JSFX,
  28. PLUGIN_LADSPA,
  29. PLUGIN_LV2,
  30. PLUGIN_SFZ,
  31. PLUGIN_VST2,
  32. PLUGIN_VST3,
  33. PLUGIN_CLAP,
  34. )
  35. from carla_shared import (
  36. CARLA_DEFAULT_DSSI_PATH,
  37. CARLA_DEFAULT_JSFX_PATH,
  38. CARLA_DEFAULT_LADSPA_PATH,
  39. CARLA_DEFAULT_LV2_PATH,
  40. CARLA_DEFAULT_SF2_PATH,
  41. CARLA_DEFAULT_SFZ_PATH,
  42. CARLA_DEFAULT_VST2_PATH,
  43. CARLA_DEFAULT_VST3_PATH,
  44. CARLA_DEFAULT_CLAP_PATH,
  45. CARLA_DEFAULT_WINE_AUTO_PREFIX,
  46. CARLA_DEFAULT_WINE_EXECUTABLE,
  47. CARLA_DEFAULT_WINE_FALLBACK_PREFIX,
  48. CARLA_KEY_PATHS_DSSI,
  49. CARLA_KEY_PATHS_JSFX,
  50. CARLA_KEY_PATHS_LADSPA,
  51. CARLA_KEY_PATHS_LV2,
  52. CARLA_KEY_PATHS_SF2,
  53. CARLA_KEY_PATHS_SFZ,
  54. CARLA_KEY_PATHS_VST2,
  55. CARLA_KEY_PATHS_VST3,
  56. CARLA_KEY_PATHS_CLAP,
  57. CARLA_KEY_WINE_AUTO_PREFIX,
  58. CARLA_KEY_WINE_EXECUTABLE,
  59. CARLA_KEY_WINE_FALLBACK_PREFIX,
  60. HAIKU,
  61. LINUX,
  62. MACOS,
  63. WINDOWS,
  64. gCarla,
  65. splitter,
  66. )
  67. from utils import QSafeSettings
  68. from .discovery import (
  69. checkAllPluginsAU,
  70. checkFileSF2,
  71. checkPluginCached,
  72. checkPluginDSSI,
  73. checkPluginLADSPA,
  74. checkPluginVST2,
  75. checkPluginVST3,
  76. checkPluginCLAP,
  77. findBinaries,
  78. findFilenames,
  79. findMacBundles,
  80. findVST3Binaries,
  81. findCLAPBinaries
  82. )
  83. # ---------------------------------------------------------------------------------------------------------------------
  84. # Separate Thread for Plugin Search
  85. class SearchPluginsThread(QThread):
  86. pluginLook = pyqtSignal(float, str)
  87. def __init__(self, parent: QWidget, pathBinaries: str):
  88. QThread.__init__(self, parent)
  89. self.fContinueChecking = False
  90. self.fPathBinaries = pathBinaries
  91. self.fCheckNative = False
  92. self.fCheckPosix32 = False
  93. self.fCheckPosix64 = False
  94. self.fCheckWin32 = False
  95. self.fCheckWin64 = False
  96. self.fCheckLADSPA = False
  97. self.fCheckDSSI = False
  98. self.fCheckLV2 = False
  99. self.fCheckVST2 = False
  100. self.fCheckVST3 = False
  101. self.fCheckCLAP = False
  102. self.fCheckAU = False
  103. self.fCheckSF2 = False
  104. self.fCheckSFZ = False
  105. self.fCheckJSFX = False
  106. if WINDOWS:
  107. toolNative = "carla-discovery-native.exe"
  108. self.fWineSettings = None
  109. else:
  110. toolNative = "carla-discovery-native"
  111. settings = QSafeSettings("falkTX", "Carla2")
  112. self.fWineSettings = {
  113. 'executable' : settings.value(CARLA_KEY_WINE_EXECUTABLE,
  114. CARLA_DEFAULT_WINE_EXECUTABLE, str),
  115. 'autoPrefix' : settings.value(CARLA_KEY_WINE_AUTO_PREFIX,
  116. CARLA_DEFAULT_WINE_AUTO_PREFIX, bool),
  117. 'fallbackPrefix': settings.value(CARLA_KEY_WINE_FALLBACK_PREFIX,
  118. CARLA_DEFAULT_WINE_FALLBACK_PREFIX, str),
  119. }
  120. del settings
  121. self.fToolNative = os.path.join(pathBinaries, toolNative)
  122. if not os.path.exists(self.fToolNative):
  123. self.fToolNative = ""
  124. self.fCurCount = 0
  125. self.fCurPercentValue = 0
  126. self.fLastCheckValue = 0
  127. self.fSomethingChanged = False
  128. # -----------------------------------------------------------------------------------------------------------------
  129. # public methods
  130. def hasSomethingChanged(self):
  131. return self.fSomethingChanged
  132. def setSearchBinaryTypes(self, native: bool, posix32: bool, posix64: bool, win32: bool, win64: bool):
  133. self.fCheckNative = native
  134. self.fCheckPosix32 = posix32
  135. self.fCheckPosix64 = posix64
  136. self.fCheckWin32 = win32
  137. self.fCheckWin64 = win64
  138. def setSearchPluginTypes(self, ladspa: bool, dssi: bool, lv2: bool, vst2: bool, vst3: bool, clap: bool,
  139. au: bool, sf2: bool, sfz: bool, jsfx: bool):
  140. self.fCheckLADSPA = ladspa
  141. self.fCheckDSSI = dssi
  142. self.fCheckLV2 = lv2
  143. self.fCheckVST2 = vst2
  144. self.fCheckVST3 = vst3
  145. self.fCheckCLAP = clap
  146. self.fCheckAU = au and MACOS
  147. self.fCheckSF2 = sf2
  148. self.fCheckSFZ = sfz
  149. self.fCheckJSFX = jsfx
  150. def stop(self):
  151. self.fContinueChecking = False
  152. # -----------------------------------------------------------------------------------------------------------------
  153. # protected reimplemented methods
  154. def run(self):
  155. settingsDB = QSafeSettings("falkTX", "CarlaPlugins5")
  156. self.fContinueChecking = True
  157. self.fCurCount = 0
  158. if self.fCheckNative and not self.fToolNative:
  159. self.fCheckNative = False
  160. # looking for plugins via external discovery
  161. pluginCount = 0
  162. if self.fCheckLADSPA:
  163. pluginCount += 1
  164. if self.fCheckDSSI:
  165. pluginCount += 1
  166. if self.fCheckVST2:
  167. pluginCount += 1
  168. if self.fCheckVST3:
  169. pluginCount += 1
  170. if self.fCheckCLAP:
  171. pluginCount += 1
  172. # Increase count by the number of externally discoverable plugin types
  173. if self.fCheckNative:
  174. self.fCurCount += pluginCount
  175. if self.fCheckPosix32:
  176. self.fCurCount += pluginCount
  177. if self.fCheckPosix64:
  178. self.fCurCount += pluginCount
  179. if self.fCheckWin32:
  180. self.fCurCount += pluginCount
  181. if self.fCheckWin64:
  182. self.fCurCount += pluginCount
  183. if self.fCheckLV2:
  184. if self.fCheckNative:
  185. self.fCurCount += 1
  186. else:
  187. self.fCheckLV2 = False
  188. if self.fCheckAU:
  189. if self.fCheckNative or self.fCheckPosix32:
  190. self.fCurCount += int(self.fCheckNative) + int(self.fCheckPosix32)
  191. else:
  192. self.fCheckAU = False
  193. if self.fCheckSF2:
  194. if self.fCheckNative:
  195. self.fCurCount += 1
  196. else:
  197. self.fCheckSF2 = False
  198. if self.fCheckSFZ:
  199. if self.fCheckNative:
  200. self.fCurCount += 1
  201. else:
  202. self.fCheckSFZ = False
  203. if self.fCheckJSFX:
  204. if self.fCheckNative:
  205. self.fCurCount += 1
  206. else:
  207. self.fCheckJSFX = False
  208. if self.fCurCount == 0:
  209. return
  210. self.fCurPercentValue = 100.0 / self.fCurCount
  211. self.fLastCheckValue = 0.0
  212. del pluginCount
  213. if HAIKU:
  214. OS = "HAIKU"
  215. elif LINUX:
  216. OS = "LINUX"
  217. elif MACOS:
  218. OS = "MACOS"
  219. elif WINDOWS:
  220. OS = "WINDOWS"
  221. else:
  222. OS = "UNKNOWN"
  223. if not self.fContinueChecking:
  224. return
  225. self.fSomethingChanged = True
  226. if self.fCheckLADSPA:
  227. if self.fCheckNative:
  228. plugins = self._checkLADSPA(OS, self.fToolNative)
  229. settingsDB.setValue("Plugins/LADSPA_native", plugins)
  230. if not self.fContinueChecking:
  231. return
  232. if self.fCheckPosix32:
  233. tool = os.path.join(self.fPathBinaries, "carla-discovery-posix32")
  234. plugins = self._checkLADSPA(OS, tool)
  235. settingsDB.setValue("Plugins/LADSPA_posix32", plugins)
  236. if not self.fContinueChecking:
  237. return
  238. if self.fCheckPosix64:
  239. tool = os.path.join(self.fPathBinaries, "carla-discovery-posix64")
  240. plugins = self._checkLADSPA(OS, tool)
  241. settingsDB.setValue("Plugins/LADSPA_posix64", plugins)
  242. if not self.fContinueChecking:
  243. return
  244. if self.fCheckWin32:
  245. tool = os.path.join(self.fPathBinaries, "carla-discovery-win32.exe")
  246. plugins = self._checkLADSPA("WINDOWS", tool, not WINDOWS)
  247. settingsDB.setValue("Plugins/LADSPA_win32", plugins)
  248. if not self.fContinueChecking:
  249. return
  250. if self.fCheckWin64:
  251. tool = os.path.join(self.fPathBinaries, "carla-discovery-win64.exe")
  252. plugins = self._checkLADSPA("WINDOWS", tool, not WINDOWS)
  253. settingsDB.setValue("Plugins/LADSPA_win64", plugins)
  254. settingsDB.sync()
  255. if not self.fContinueChecking:
  256. return
  257. if self.fCheckDSSI:
  258. if self.fCheckNative:
  259. plugins = self._checkDSSI(OS, self.fToolNative)
  260. settingsDB.setValue("Plugins/DSSI_native", plugins)
  261. if not self.fContinueChecking:
  262. return
  263. if self.fCheckPosix32:
  264. plugins = self._checkDSSI(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  265. settingsDB.setValue("Plugins/DSSI_posix32", plugins)
  266. if not self.fContinueChecking:
  267. return
  268. if self.fCheckPosix64:
  269. plugins = self._checkDSSI(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix64"))
  270. settingsDB.setValue("Plugins/DSSI_posix64", plugins)
  271. if not self.fContinueChecking:
  272. return
  273. if self.fCheckWin32:
  274. tool = os.path.join(self.fPathBinaries, "carla-discovery-win32.exe")
  275. plugins = self._checkDSSI("WINDOWS", tool, not WINDOWS)
  276. settingsDB.setValue("Plugins/DSSI_win32", plugins)
  277. if not self.fContinueChecking:
  278. return
  279. if self.fCheckWin64:
  280. tool = os.path.join(self.fPathBinaries, "carla-discovery-win64.exe")
  281. plugins = self._checkDSSI("WINDOWS", tool, not WINDOWS)
  282. settingsDB.setValue("Plugins/DSSI_win64", plugins)
  283. settingsDB.sync()
  284. if not self.fContinueChecking:
  285. return
  286. if self.fCheckLV2:
  287. plugins = self._checkCached(True)
  288. settingsDB.setValue("Plugins/LV2", plugins)
  289. settingsDB.sync()
  290. if not self.fContinueChecking:
  291. return
  292. if self.fCheckVST2:
  293. if self.fCheckNative:
  294. plugins = self._checkVST2(OS, self.fToolNative)
  295. settingsDB.setValue("Plugins/VST2_native", plugins)
  296. if not self.fContinueChecking:
  297. return
  298. if self.fCheckPosix32:
  299. plugins = self._checkVST2(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  300. settingsDB.setValue("Plugins/VST2_posix32", plugins)
  301. if not self.fContinueChecking:
  302. return
  303. if self.fCheckPosix64:
  304. plugins = self._checkVST2(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix64"))
  305. settingsDB.setValue("Plugins/VST2_posix64", plugins)
  306. if not self.fContinueChecking:
  307. return
  308. if self.fCheckWin32:
  309. tool = os.path.join(self.fPathBinaries, "carla-discovery-win32.exe")
  310. plugins = self._checkVST2("WINDOWS", tool, not WINDOWS)
  311. settingsDB.setValue("Plugins/VST2_win32", plugins)
  312. if not self.fContinueChecking:
  313. return
  314. if self.fCheckWin64:
  315. tool = os.path.join(self.fPathBinaries, "carla-discovery-win64.exe")
  316. plugins = self._checkVST2("WINDOWS", tool, not WINDOWS)
  317. settingsDB.setValue("Plugins/VST2_win64", plugins)
  318. if not self.fContinueChecking:
  319. return
  320. settingsDB.sync()
  321. if not self.fContinueChecking:
  322. return
  323. if self.fCheckVST3:
  324. if self.fCheckNative and (LINUX or MACOS or WINDOWS):
  325. plugins = self._checkVST3(self.fToolNative)
  326. settingsDB.setValue("Plugins/VST3_native", plugins)
  327. if not self.fContinueChecking:
  328. return
  329. if self.fCheckPosix32:
  330. plugins = self._checkVST3(os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  331. settingsDB.setValue("Plugins/VST3_posix32", plugins)
  332. if not self.fContinueChecking:
  333. return
  334. if self.fCheckPosix64:
  335. plugins = self._checkVST3(os.path.join(self.fPathBinaries, "carla-discovery-posix64"))
  336. settingsDB.setValue("Plugins/VST3_posix64", plugins)
  337. if not self.fContinueChecking:
  338. return
  339. if self.fCheckWin32:
  340. tool = os.path.join(self.fPathBinaries, "carla-discovery-win32.exe")
  341. plugins = self._checkVST3(tool, not WINDOWS)
  342. settingsDB.setValue("Plugins/VST3_win32", plugins)
  343. if not self.fContinueChecking:
  344. return
  345. if self.fCheckWin64:
  346. tool = os.path.join(self.fPathBinaries, "carla-discovery-win64.exe")
  347. plugins = self._checkVST3(tool, not WINDOWS)
  348. settingsDB.setValue("Plugins/VST3_win64", plugins)
  349. if not self.fContinueChecking:
  350. return
  351. settingsDB.sync()
  352. if not self.fContinueChecking:
  353. return
  354. if self.fCheckCLAP:
  355. if self.fCheckNative:
  356. plugins = self._checkCLAP(self.fToolNative)
  357. settingsDB.setValue("Plugins/CLAP_native", plugins)
  358. if not self.fContinueChecking:
  359. return
  360. if self.fCheckPosix32:
  361. plugins = self._checkCLAP(os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  362. settingsDB.setValue("Plugins/CLAP_posix32", plugins)
  363. if not self.fContinueChecking:
  364. return
  365. if self.fCheckPosix64:
  366. plugins = self._checkCLAP(os.path.join(self.fPathBinaries, "carla-discovery-posix64"))
  367. settingsDB.setValue("Plugins/CLAP_posix64", plugins)
  368. if not self.fContinueChecking:
  369. return
  370. if self.fCheckWin32:
  371. tool = os.path.join(self.fPathBinaries, "carla-discovery-win32.exe")
  372. plugins = self._checkCLAP(tool, not WINDOWS)
  373. settingsDB.setValue("Plugins/CLAP_win32", plugins)
  374. if not self.fContinueChecking:
  375. return
  376. if self.fCheckWin64:
  377. tool = os.path.join(self.fPathBinaries, "carla-discovery-win64.exe")
  378. plugins = self._checkCLAP(tool, not WINDOWS)
  379. settingsDB.setValue("Plugins/CLAP_win64", plugins)
  380. if not self.fContinueChecking:
  381. return
  382. settingsDB.sync()
  383. if not self.fContinueChecking:
  384. return
  385. if self.fCheckAU:
  386. if self.fCheckNative:
  387. plugins = self._checkCached(False)
  388. settingsDB.setValue("Plugins/AU", plugins)
  389. settingsDB.sync()
  390. if not self.fContinueChecking:
  391. return
  392. if self.fCheckPosix32:
  393. plugins = self._checkAU(os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  394. settingsDB.setValue("Plugins/AU_posix32", self.fAuPlugins)
  395. if not self.fContinueChecking:
  396. return
  397. settingsDB.sync()
  398. if not self.fContinueChecking:
  399. return
  400. if self.fCheckSF2:
  401. settings = QSafeSettings("falkTX", "Carla2")
  402. SF2_PATH = settings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH, list)
  403. del settings
  404. kits = self._checkKIT(SF2_PATH, "sf2")
  405. settingsDB.setValue("Plugins/SF2", kits)
  406. settingsDB.sync()
  407. if not self.fContinueChecking:
  408. return
  409. if self.fCheckSFZ:
  410. kits = self._checkSfzCached()
  411. settingsDB.setValue("Plugins/SFZ", kits)
  412. settingsDB.sync()
  413. if self.fCheckJSFX:
  414. kits = self._checkJsfxCached()
  415. settingsDB.setValue("Plugins/JSFX", kits)
  416. settingsDB.sync()
  417. # -----------------------------------------------------------------------------------------------------------------
  418. # private methods
  419. def _checkLADSPA(self, OS, tool, isWine=False):
  420. ladspaBinaries = []
  421. ladspaPlugins = []
  422. self._pluginLook(self.fLastCheckValue, "LADSPA plugins...")
  423. settings = QSafeSettings("falkTX", "Carla2")
  424. LADSPA_PATH = settings.value(CARLA_KEY_PATHS_LADSPA, CARLA_DEFAULT_LADSPA_PATH, list)
  425. del settings
  426. for iPATH in LADSPA_PATH:
  427. binaries = findBinaries(iPATH, PLUGIN_LADSPA, OS)
  428. for binary in binaries:
  429. if binary not in ladspaBinaries:
  430. ladspaBinaries.append(binary)
  431. ladspaBinaries.sort()
  432. if not self.fContinueChecking:
  433. return ladspaPlugins
  434. for i in range(len(ladspaBinaries)):
  435. ladspa = ladspaBinaries[i]
  436. percent = ( float(i) / len(ladspaBinaries) ) * self.fCurPercentValue
  437. self._pluginLook((self.fLastCheckValue + percent) * 0.9, ladspa)
  438. plugins = checkPluginLADSPA(ladspa, tool, self.fWineSettings if isWine else None)
  439. if plugins:
  440. ladspaPlugins.append(plugins)
  441. if not self.fContinueChecking:
  442. break
  443. self.fLastCheckValue += self.fCurPercentValue
  444. return ladspaPlugins
  445. def _checkDSSI(self, OS, tool, isWine=False):
  446. dssiBinaries = []
  447. dssiPlugins = []
  448. self._pluginLook(self.fLastCheckValue, "DSSI plugins...")
  449. settings = QSafeSettings("falkTX", "Carla2")
  450. DSSI_PATH = settings.value(CARLA_KEY_PATHS_DSSI, CARLA_DEFAULT_DSSI_PATH, list)
  451. del settings
  452. for iPATH in DSSI_PATH:
  453. binaries = findBinaries(iPATH, PLUGIN_DSSI, OS)
  454. for binary in binaries:
  455. if binary not in dssiBinaries:
  456. dssiBinaries.append(binary)
  457. dssiBinaries.sort()
  458. if not self.fContinueChecking:
  459. return dssiPlugins
  460. for i in range(len(dssiBinaries)):
  461. dssi = dssiBinaries[i]
  462. percent = ( float(i) / len(dssiBinaries) ) * self.fCurPercentValue
  463. self._pluginLook(self.fLastCheckValue + percent, dssi)
  464. plugins = checkPluginDSSI(dssi, tool, self.fWineSettings if isWine else None)
  465. if plugins:
  466. dssiPlugins.append(plugins)
  467. if not self.fContinueChecking:
  468. break
  469. self.fLastCheckValue += self.fCurPercentValue
  470. return dssiPlugins
  471. def _checkVST2(self, OS, tool, isWine=False):
  472. vst2Binaries = []
  473. vst2Plugins = []
  474. if MACOS and not isWine:
  475. self._pluginLook(self.fLastCheckValue, "VST2 bundles...")
  476. else:
  477. self._pluginLook(self.fLastCheckValue, "VST2 plugins...")
  478. settings = QSafeSettings("falkTX", "Carla2")
  479. VST2_PATH = settings.value(CARLA_KEY_PATHS_VST2, CARLA_DEFAULT_VST2_PATH, list)
  480. del settings
  481. for iPATH in VST2_PATH:
  482. if MACOS and not isWine:
  483. binaries = findMacBundles(iPATH, PLUGIN_VST2)
  484. else:
  485. binaries = findBinaries(iPATH, PLUGIN_VST2, OS)
  486. for binary in binaries:
  487. if binary not in vst2Binaries:
  488. vst2Binaries.append(binary)
  489. vst2Binaries.sort()
  490. if not self.fContinueChecking:
  491. return vst2Plugins
  492. for i in range(len(vst2Binaries)):
  493. vst2 = vst2Binaries[i]
  494. percent = ( float(i) / len(vst2Binaries) ) * self.fCurPercentValue
  495. self._pluginLook(self.fLastCheckValue + percent, vst2)
  496. plugins = checkPluginVST2(vst2, tool, self.fWineSettings if isWine else None)
  497. if plugins:
  498. vst2Plugins.append(plugins)
  499. if not self.fContinueChecking:
  500. break
  501. self.fLastCheckValue += self.fCurPercentValue
  502. return vst2Plugins
  503. def _checkVST3(self, tool, isWine=False):
  504. vst3Binaries = []
  505. vst3Plugins = []
  506. if MACOS and not isWine:
  507. self._pluginLook(self.fLastCheckValue, "VST3 bundles...")
  508. else:
  509. self._pluginLook(self.fLastCheckValue, "VST3 plugins...")
  510. settings = QSafeSettings("falkTX", "Carla2")
  511. VST3_PATH = settings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH, list)
  512. del settings
  513. for iPATH in VST3_PATH:
  514. if MACOS and not isWine:
  515. binaries = findMacBundles(iPATH, PLUGIN_VST3)
  516. else:
  517. binaries = findVST3Binaries(iPATH)
  518. for binary in binaries:
  519. if binary not in vst3Binaries:
  520. vst3Binaries.append(binary)
  521. vst3Binaries.sort()
  522. if not self.fContinueChecking:
  523. return vst3Plugins
  524. for i in range(len(vst3Binaries)):
  525. vst3 = vst3Binaries[i]
  526. percent = ( float(i) / len(vst3Binaries) ) * self.fCurPercentValue
  527. self._pluginLook(self.fLastCheckValue + percent, vst3)
  528. plugins = checkPluginVST3(vst3, tool, self.fWineSettings if isWine else None)
  529. if plugins:
  530. vst3Plugins.append(plugins)
  531. if not self.fContinueChecking:
  532. break
  533. self.fLastCheckValue += self.fCurPercentValue
  534. return vst3Plugins
  535. def _checkCLAP(self, tool, isWine=False):
  536. clapBinaries = []
  537. clapPlugins = []
  538. self._pluginLook(self.fLastCheckValue, "CLAP plugins...")
  539. settings = QSafeSettings("falkTX", "Carla2")
  540. CLAP_PATH = settings.value(CARLA_KEY_PATHS_CLAP, CARLA_DEFAULT_CLAP_PATH, list)
  541. del settings
  542. for iPATH in CLAP_PATH:
  543. if MACOS and not isWine:
  544. binaries = findMacBundles(iPATH, PLUGIN_CLAP)
  545. else:
  546. binaries = findCLAPBinaries(iPATH)
  547. for binary in binaries:
  548. if binary not in clapBinaries:
  549. clapBinaries.append(binary)
  550. clapBinaries.sort()
  551. if not self.fContinueChecking:
  552. return clapPlugins
  553. for i in range(len(clapBinaries)):
  554. clap = clapBinaries[i]
  555. percent = ( float(i) / len(clapBinaries) ) * self.fCurPercentValue
  556. self._pluginLook(self.fLastCheckValue + percent, clap)
  557. plugins = checkPluginCLAP(clap, tool, self.fWineSettings if isWine else None)
  558. if plugins:
  559. clapPlugins.append(plugins)
  560. if not self.fContinueChecking:
  561. break
  562. self.fLastCheckValue += self.fCurPercentValue
  563. return clapPlugins
  564. def _checkAU(self, tool):
  565. auPlugins = []
  566. plugins = checkAllPluginsAU(tool)
  567. if plugins:
  568. auPlugins.append(plugins)
  569. self.fLastCheckValue += self.fCurPercentValue
  570. return auPlugins
  571. def _checkKIT(self, kitPATH, kitExtension):
  572. kitFiles = []
  573. kitPlugins = []
  574. for iPATH in kitPATH:
  575. files = findFilenames(iPATH, kitExtension)
  576. for file_ in files:
  577. if file_ not in kitFiles:
  578. kitFiles.append(file_)
  579. kitFiles.sort()
  580. if not self.fContinueChecking:
  581. return kitPlugins
  582. for i in range(len(kitFiles)):
  583. kit = kitFiles[i]
  584. percent = ( float(i) / len(kitFiles) ) * self.fCurPercentValue
  585. self._pluginLook(self.fLastCheckValue + percent, kit)
  586. if kitExtension == "sf2":
  587. plugins = checkFileSF2(kit, self.fToolNative)
  588. else:
  589. plugins = None
  590. if plugins:
  591. kitPlugins.append(plugins)
  592. if not self.fContinueChecking:
  593. break
  594. self.fLastCheckValue += self.fCurPercentValue
  595. return kitPlugins
  596. def _checkCached(self, isLV2):
  597. if isLV2:
  598. settings = QSafeSettings("falkTX", "Carla2")
  599. PLUG_PATH = splitter.join(settings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH, list))
  600. del settings
  601. PLUG_TEXT = "LV2"
  602. PLUG_TYPE = PLUGIN_LV2
  603. else: # AU
  604. PLUG_PATH = ""
  605. PLUG_TEXT = "AU"
  606. PLUG_TYPE = PLUGIN_AU
  607. plugins = []
  608. self._pluginLook(self.fLastCheckValue, f"{PLUG_TEXT} plugins...")
  609. if not isLV2:
  610. gCarla.utils.juce_init()
  611. count = gCarla.utils.get_cached_plugin_count(PLUG_TYPE, PLUG_PATH)
  612. if not self.fContinueChecking:
  613. return plugins
  614. for i in range(count):
  615. descInfo = gCarla.utils.get_cached_plugin_info(PLUG_TYPE, i)
  616. percent = ( float(i) / count ) * self.fCurPercentValue
  617. self._pluginLook(self.fLastCheckValue + percent, descInfo['label'])
  618. if not descInfo['valid']:
  619. continue
  620. plugins.append(checkPluginCached(descInfo, PLUG_TYPE))
  621. if not self.fContinueChecking:
  622. break
  623. if not isLV2:
  624. gCarla.utils.juce_cleanup()
  625. self.fLastCheckValue += self.fCurPercentValue
  626. return plugins
  627. def _checkSfzCached(self):
  628. settings = QSafeSettings("falkTX", "Carla2")
  629. PLUG_PATH = splitter.join(settings.value(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH, list))
  630. del settings
  631. sfzKits = []
  632. self._pluginLook(self.fLastCheckValue, "SFZ kits...")
  633. count = gCarla.utils.get_cached_plugin_count(PLUGIN_SFZ, PLUG_PATH)
  634. if not self.fContinueChecking:
  635. return sfzKits
  636. for i in range(count):
  637. descInfo = gCarla.utils.get_cached_plugin_info(PLUGIN_SFZ, i)
  638. percent = ( float(i) / count ) * self.fCurPercentValue
  639. self._pluginLook(self.fLastCheckValue + percent, descInfo['label'])
  640. if not descInfo['valid']:
  641. continue
  642. sfzKits.append(checkPluginCached(descInfo, PLUGIN_SFZ))
  643. if not self.fContinueChecking:
  644. break
  645. self.fLastCheckValue += self.fCurPercentValue
  646. return sfzKits
  647. def _checkJsfxCached(self):
  648. settings = QSafeSettings("falkTX", "Carla2")
  649. PLUG_PATH = splitter.join(settings.value(CARLA_KEY_PATHS_JSFX, CARLA_DEFAULT_JSFX_PATH, list))
  650. del settings
  651. jsfxPlugins = []
  652. self._pluginLook(self.fLastCheckValue, "JSFX plugins...")
  653. count = gCarla.utils.get_cached_plugin_count(PLUGIN_JSFX, PLUG_PATH)
  654. if not self.fContinueChecking:
  655. return jsfxPlugins
  656. for i in range(count):
  657. descInfo = gCarla.utils.get_cached_plugin_info(PLUGIN_JSFX, i)
  658. percent = ( float(i) / count ) * self.fCurPercentValue
  659. self._pluginLook(self.fLastCheckValue + percent, descInfo['label'])
  660. if not descInfo['valid']:
  661. continue
  662. jsfxPlugins.append(checkPluginCached(descInfo, PLUGIN_JSFX))
  663. if not self.fContinueChecking:
  664. break
  665. self.fLastCheckValue += self.fCurPercentValue
  666. return jsfxPlugins
  667. def _pluginLook(self, percent, plugin):
  668. self.pluginLook.emit(percent, plugin)
  669. # ---------------------------------------------------------------------------------------------------------------------