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.

1804 lines
70KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla plugin database code
  4. # Copyright (C) 2011-2014 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 (Config)
  19. from carla_config import *
  20. # ------------------------------------------------------------------------------------------------------------
  21. # Imports (Global)
  22. from copy import deepcopy
  23. from subprocess import Popen, PIPE
  24. if config_UseQt5:
  25. from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QThread, QSettings
  26. from PyQt5.QtWidgets import QDialog, QTableWidgetItem
  27. else:
  28. from PyQt4.QtCore import pyqtSignal, pyqtSlot, Qt, QThread, QSettings
  29. from PyQt4.QtGui import QDialog, QTableWidgetItem
  30. # ------------------------------------------------------------------------------------------------------------
  31. # Imports (Custom)
  32. import ui_carla_database
  33. import ui_carla_refresh
  34. from carla_shared import *
  35. # ------------------------------------------------------------------------------------------------------------
  36. # Try Import LADSPA-RDF
  37. try:
  38. import ladspa_rdf
  39. import json
  40. haveLRDF = True
  41. except:
  42. qWarning("LRDF Support not available (LADSPA-RDF will be disabled)")
  43. haveLRDF = False
  44. # ------------------------------------------------------------------------------------------------------------
  45. # Set LADSPA-RDF Path
  46. if haveLRDF and readEnvVars:
  47. LADSPA_RDF_PATH_env = os.getenv("LADSPA_RDF_PATH")
  48. if LADSPA_RDF_PATH_env:
  49. try:
  50. ladspa_rdf.set_rdf_path(LADSPA_RDF_PATH_env.split(splitter))
  51. except:
  52. pass
  53. del LADSPA_RDF_PATH_env
  54. # ------------------------------------------------------------------------------------------------------------
  55. # Plugin Query (helper functions)
  56. def findBinaries(binPath, OS):
  57. binaries = []
  58. if OS == "WINDOWS":
  59. extensions = (".dll",)
  60. elif OS == "MACOS":
  61. extensions = (".dylib", ".so")
  62. else:
  63. extensions = (".so",)
  64. for root, dirs, files in os.walk(binPath):
  65. for name in [name for name in files if name.lower().endswith(extensions)]:
  66. binaries.append(os.path.join(root, name))
  67. return binaries
  68. def findVST3Binaries(binPath):
  69. binaries = []
  70. for root, dirs, files in os.walk(binPath):
  71. for name in [name for name in files if name.lower().endswith(".vst3")]:
  72. binaries.append(os.path.join(root, name))
  73. return binaries
  74. def findLV2Bundles(bundlePath):
  75. bundles = []
  76. for root, dirs, files in os.walk(bundlePath, followlinks=True):
  77. if root == bundlePath: continue
  78. if os.path.exists(os.path.join(root, "manifest.ttl")):
  79. bundles.append(root)
  80. return bundles
  81. def findMacVSTBundles(bundlePath, isVST3):
  82. bundles = []
  83. for root, dirs, files in os.walk(bundlePath, followlinks=True):
  84. if root == bundlePath: continue
  85. for name in [name for name in dirs if name.lower().endswith(".vst3" if isVST3 else ".vst")]:
  86. bundles.append(os.path.join(root, name))
  87. return bundles
  88. def findFilenames(filePath, stype):
  89. filenames = []
  90. if stype == "gig":
  91. extensions = (".gig",)
  92. elif stype == "sf2":
  93. extensions = (".sf2",)
  94. elif stype == "sfz":
  95. extensions = (".sfz",)
  96. else:
  97. return []
  98. for root, dirs, files in os.walk(filePath):
  99. for name in [name for name in files if name.lower().endswith(extensions)]:
  100. filenames.append(os.path.join(root, name))
  101. return filenames
  102. # ------------------------------------------------------------------------------------------------------------
  103. # Plugin Query
  104. PLUGIN_QUERY_API_VERSION = 4
  105. PyPluginInfo = {
  106. 'API': PLUGIN_QUERY_API_VERSION,
  107. 'build': BINARY_NONE,
  108. 'type': PLUGIN_NONE,
  109. 'hints': 0x0,
  110. 'filename': "",
  111. 'name': "",
  112. 'label': "",
  113. 'maker': "",
  114. 'uniqueId': 0,
  115. 'audio.ins': 0,
  116. 'audio.outs': 0,
  117. 'midi.ins': 0,
  118. 'midi.outs': 0,
  119. 'parameters.ins': 0,
  120. 'parameters.outs': 0
  121. }
  122. global gDiscoveryProcess
  123. gDiscoveryProcess = None
  124. def runCarlaDiscovery(itype, stype, filename, tool, isWine=False):
  125. if not os.path.exists(tool):
  126. qWarning("runCarlaDiscovery() - tool '%s' does not exist" % tool)
  127. return
  128. command = []
  129. if LINUX or MACOS:
  130. command.append("env")
  131. command.append("LANG=C")
  132. if isWine:
  133. command.append("WINEDEBUG=-all")
  134. command.append("wine")
  135. command.append(tool)
  136. command.append(stype)
  137. command.append(filename)
  138. global gDiscoveryProcess
  139. gDiscoveryProcess = Popen(command, stdout=PIPE)
  140. pinfo = None
  141. plugins = []
  142. fakeLabel = os.path.basename(filename).rsplit(".", 1)[0]
  143. while True:
  144. try:
  145. line = gDiscoveryProcess.stdout.readline().decode("utf-8", errors="ignore")
  146. except:
  147. print("ERROR: discovery readline failed")
  148. break
  149. # line is valid, strip it
  150. if line:
  151. line = line.strip()
  152. # line is invalid, try poll() again
  153. elif gDiscoveryProcess.poll() is None:
  154. continue
  155. # line is invalid and poll() failed, stop here
  156. else:
  157. break
  158. if line == "carla-discovery::init::-----------":
  159. pinfo = deepcopy(PyPluginInfo)
  160. pinfo['type'] = itype
  161. pinfo['filename'] = filename
  162. elif line == "carla-discovery::end::------------":
  163. if pinfo is not None:
  164. plugins.append(pinfo)
  165. del pinfo
  166. pinfo = None
  167. elif line == "Segmentation fault":
  168. print("carla-discovery::crash::%s crashed during discovery" % filename)
  169. elif line.startswith("err:module:import_dll Library"):
  170. print(line)
  171. elif line.startswith("carla-discovery::info::"):
  172. print("%s - %s" % (line, filename))
  173. elif line.startswith("carla-discovery::warning::"):
  174. print("%s - %s" % (line, filename))
  175. elif line.startswith("carla-discovery::error::"):
  176. print("%s - %s" % (line, filename))
  177. elif line.startswith("carla-discovery::"):
  178. if pinfo == None:
  179. continue
  180. try:
  181. prop, value = line.replace("carla-discovery::", "").split("::", 1)
  182. except:
  183. continue
  184. if prop == "build":
  185. if value.isdigit(): pinfo['build'] = int(value)
  186. elif prop == "name":
  187. pinfo['name'] = value if value else fakeLabel
  188. elif prop == "label":
  189. pinfo['label'] = value if value else fakeLabel
  190. elif prop == "maker":
  191. pinfo['maker'] = value
  192. elif prop == "uniqueId":
  193. if value.isdigit(): pinfo['uniqueId'] = int(value)
  194. elif prop == "hints":
  195. if value.isdigit(): pinfo['hints'] = int(value)
  196. elif prop == "audio.ins":
  197. if value.isdigit(): pinfo['audio.ins'] = int(value)
  198. elif prop == "audio.outs":
  199. if value.isdigit(): pinfo['audio.outs'] = int(value)
  200. elif prop == "midi.ins":
  201. if value.isdigit(): pinfo['midi.ins'] = int(value)
  202. elif prop == "midi.outs":
  203. if value.isdigit(): pinfo['midi.outs'] = int(value)
  204. elif prop == "parameters.ins":
  205. if value.isdigit(): pinfo['parameters.ins'] = int(value)
  206. elif prop == "parameters.outs":
  207. if value.isdigit(): pinfo['parameters.outs'] = int(value)
  208. elif prop == "uri":
  209. if value:
  210. pinfo['label'] = value
  211. else:
  212. # cannot use empty URIs
  213. del pinfo
  214. pinfo = None
  215. continue
  216. else:
  217. print("%s - %s (unknown property)" % (line, filename))
  218. # FIXME?
  219. tmp = gDiscoveryProcess
  220. gDiscoveryProcess = None
  221. del gDiscoveryProcess, tmp
  222. return plugins
  223. def killDiscovery():
  224. global gDiscoveryProcess
  225. if gDiscoveryProcess is not None:
  226. gDiscoveryProcess.kill()
  227. def checkPluginInternal(desc):
  228. plugins = []
  229. pinfo = deepcopy(PyPluginInfo)
  230. pinfo['build'] = BINARY_NATIVE
  231. pinfo['type'] = PLUGIN_INTERNAL
  232. pinfo['hints'] = desc['hints']
  233. pinfo['name'] = desc['name']
  234. pinfo['label'] = desc['label']
  235. pinfo['maker'] = desc['maker']
  236. pinfo['audio.ins'] = desc['audioIns']
  237. pinfo['audio.outs'] = desc['audioOuts']
  238. pinfo['midi.ins'] = desc['midiIns']
  239. pinfo['midi.outs'] = desc['midiOuts']
  240. pinfo['parameters.ins'] = desc['parameterIns']
  241. pinfo['parameters.outs'] = desc['parameterOuts']
  242. plugins.append(pinfo)
  243. return plugins
  244. def checkPluginLADSPA(filename, tool, isWine=False):
  245. return runCarlaDiscovery(PLUGIN_LADSPA, "LADSPA", filename, tool, isWine)
  246. def checkPluginDSSI(filename, tool, isWine=False):
  247. return runCarlaDiscovery(PLUGIN_DSSI, "DSSI", filename, tool, isWine)
  248. def checkPluginLV2(filename, tool, isWine=False):
  249. return runCarlaDiscovery(PLUGIN_LV2, "LV2", filename, tool, isWine)
  250. def checkPluginVST(filename, tool, isWine=False):
  251. return runCarlaDiscovery(PLUGIN_VST, "VST", filename, tool, isWine)
  252. def checkPluginVST3(filename, tool, isWine=False):
  253. return runCarlaDiscovery(PLUGIN_VST3, "VST3", filename, tool, isWine)
  254. def checkPluginAU(filename, tool):
  255. return runCarlaDiscovery(PLUGIN_AU, "AU", filename, tool)
  256. def checkFileGIG(filename, tool):
  257. return runCarlaDiscovery(PLUGIN_GIG, "GIG", filename, tool)
  258. def checkFileSF2(filename, tool):
  259. return runCarlaDiscovery(PLUGIN_SF2, "SF2", filename, tool)
  260. def checkFileSFZ(filename, tool):
  261. return runCarlaDiscovery(PLUGIN_SFZ, "SFZ", filename, tool)
  262. # ------------------------------------------------------------------------------------------------------------
  263. # Separate Thread for Plugin Search
  264. class SearchPluginsThread(QThread):
  265. pluginLook = pyqtSignal(int, str)
  266. def __init__(self, parent, pathBinaries):
  267. QThread.__init__(self, parent)
  268. self.fContinueChecking = False
  269. self.fPathBinaries = pathBinaries
  270. self.fCheckNative = False
  271. self.fCheckPosix32 = False
  272. self.fCheckPosix64 = False
  273. self.fCheckWin32 = False
  274. self.fCheckWin64 = False
  275. self.fCheckLADSPA = False
  276. self.fCheckDSSI = False
  277. self.fCheckLV2 = False
  278. self.fCheckVST = False
  279. self.fCheckVST3 = False
  280. self.fCheckAU = False
  281. self.fCheckGIG = False
  282. self.fCheckSF2 = False
  283. self.fCheckSFZ = False
  284. if WINDOWS:
  285. toolNative = "carla-discovery-win64.exe" if kIs64bit else "carla-discovery-win32.exe"
  286. else:
  287. toolNative = "carla-discovery-native"
  288. self.fToolNative = os.path.join(pathBinaries, toolNative)
  289. if not os.path.exists(self.fToolNative):
  290. self.fToolNative = ""
  291. self.fCurCount = 0
  292. self.fCurPercentValue = 0
  293. self.fLastCheckValue = 0
  294. self.fSomethingChanged = False
  295. self.fLadspaPlugins = []
  296. self.fDssiPlugins = []
  297. self.fLv2Plugins = []
  298. self.fVstPlugins = []
  299. self.fVst3Plugins = []
  300. self.fAuPlugins = []
  301. self.fKitPlugins = []
  302. # -------------------------------------------------------------
  303. def hasSomethingChanged(self):
  304. return self.fSomethingChanged
  305. def setSearchBinaryTypes(self, native, posix32, posix64, win32, win64):
  306. self.fCheckNative = native
  307. self.fCheckPosix32 = posix32
  308. self.fCheckPosix64 = posix64
  309. self.fCheckWin32 = win32
  310. self.fCheckWin64 = win64
  311. def setSearchPluginTypes(self, ladspa, dssi, lv2, vst, vst3, au, gig, sf2, sfz):
  312. self.fCheckLADSPA = ladspa
  313. self.fCheckDSSI = dssi
  314. self.fCheckLV2 = lv2
  315. self.fCheckVST = vst
  316. self.fCheckVST3 = vst3
  317. self.fCheckAU = au and MACOS
  318. self.fCheckGIG = gig
  319. self.fCheckSF2 = sf2
  320. self.fCheckSFZ = sfz
  321. def stop(self):
  322. self.fContinueChecking = False
  323. def run(self):
  324. pluginCount = 0
  325. settingsDB = QSettings("falkTX", "CarlaPlugins2")
  326. self.fContinueChecking = True
  327. self.fCurCount = 0
  328. if self.fCheckLADSPA: pluginCount += 1
  329. if self.fCheckDSSI: pluginCount += 1
  330. if self.fCheckLV2: pluginCount += 1
  331. if self.fCheckVST: pluginCount += 1
  332. if self.fCheckVST3: pluginCount += 1
  333. if self.fCheckAU: pluginCount += 1
  334. if self.fCheckNative:
  335. self.fCurCount += pluginCount
  336. if self.fCheckPosix32:
  337. self.fCurCount += pluginCount
  338. if self.fCheckVST3 and not MACOS:
  339. self.fCurCount -= 1
  340. if self.fCheckPosix64:
  341. self.fCurCount += pluginCount
  342. if self.fCheckVST3 and not MACOS:
  343. self.fCurCount -= 1
  344. if self.fCheckWin32:
  345. self.fCurCount += pluginCount
  346. if self.fCheckAU:
  347. self.fCurCount -= 1
  348. if self.fCheckWin64:
  349. self.fCurCount += pluginCount
  350. if self.fCheckAU:
  351. self.fCurCount -= 1
  352. if self.fCheckNative and self.fToolNative:
  353. if self.fCheckGIG: self.fCurCount += 1
  354. if self.fCheckSF2: self.fCurCount += 1
  355. if self.fCheckSFZ: self.fCurCount += 1
  356. else:
  357. self.fCheckGIG = False
  358. self.fCheckSF2 = False
  359. self.fCheckSFZ = False
  360. if self.fCurCount == 0:
  361. return
  362. self.fCurPercentValue = 100.0 / self.fCurCount
  363. self.fLastCheckValue = 0.0
  364. if HAIKU:
  365. OS = "HAIKU"
  366. elif LINUX:
  367. OS = "LINUX"
  368. elif MACOS:
  369. OS = "MACOS"
  370. elif WINDOWS:
  371. OS = "WINDOWS"
  372. else:
  373. OS = "UNKNOWN"
  374. if not self.fContinueChecking: return
  375. if self.fCheckLADSPA:
  376. checkValue = 0.0
  377. if haveLRDF:
  378. if self.fCheckNative: checkValue += 0.1
  379. if self.fCheckPosix32: checkValue += 0.1
  380. if self.fCheckPosix64: checkValue += 0.1
  381. if self.fCheckWin32: checkValue += 0.1
  382. if self.fCheckWin64: checkValue += 0.1
  383. rdfPadValue = self.fCurPercentValue * checkValue
  384. if self.fCheckNative:
  385. self._checkLADSPA(OS, self.fToolNative)
  386. settingsDB.setValue("Plugins/LADSPA_native", self.fLadspaPlugins)
  387. if not self.fContinueChecking: return
  388. if self.fCheckPosix32:
  389. self._checkLADSPA(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  390. settingsDB.setValue("Plugins/LADSPA_posix32", self.fLadspaPlugins)
  391. if not self.fContinueChecking: return
  392. if self.fCheckPosix64:
  393. self._checkLADSPA(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix64"))
  394. settingsDB.setValue("Plugins/LADSPA_posix64", self.fLadspaPlugins)
  395. if not self.fContinueChecking: return
  396. if self.fCheckWin32:
  397. self._checkLADSPA("WINDOWS", os.path.join(self.fPathBinaries, "carla-discovery-win32.exe"), not WINDOWS)
  398. settingsDB.setValue("Plugins/LADSPA_win32", self.fLadspaPlugins)
  399. if not self.fContinueChecking: return
  400. if self.fCheckWin64:
  401. self._checkLADSPA("WINDOWS", os.path.join(self.fPathBinaries, "carla-discovery-win64.exe"), not WINDOWS)
  402. settingsDB.setValue("Plugins/LADSPA_win64", self.fLadspaPlugins)
  403. settingsDB.sync()
  404. if not self.fContinueChecking: return
  405. if haveLRDF and checkValue > 0:
  406. startValue = self.fLastCheckValue - rdfPadValue
  407. self._pluginLook(startValue, "LADSPA RDFs...")
  408. try:
  409. ladspaRdfInfo = ladspa_rdf.recheck_all_plugins(self, startValue, self.fCurPercentValue, checkValue)
  410. except:
  411. ladspaRdfInfo = None
  412. if ladspaRdfInfo is not None:
  413. settingsDir = os.path.join(HOME, ".config", "falkTX")
  414. fdLadspa = open(os.path.join(settingsDir, "ladspa_rdf.db"), 'w')
  415. json.dump(ladspaRdfInfo, fdLadspa)
  416. fdLadspa.close()
  417. if not self.fContinueChecking: return
  418. if self.fCheckDSSI:
  419. if self.fCheckNative:
  420. self._checkDSSI(OS, self.fToolNative)
  421. settingsDB.setValue("Plugins/DSSI_native", self.fDssiPlugins)
  422. if not self.fContinueChecking: return
  423. if self.fCheckPosix32:
  424. self._checkDSSI(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  425. settingsDB.setValue("Plugins/DSSI_posix32", self.fDssiPlugins)
  426. if not self.fContinueChecking: return
  427. if self.fCheckPosix64:
  428. self._checkDSSI(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix64"))
  429. settingsDB.setValue("Plugins/DSSI_posix64", self.fDssiPlugins)
  430. if not self.fContinueChecking: return
  431. if self.fCheckWin32:
  432. self._checkDSSI("WINDOWS", os.path.join(self.fPathBinaries, "carla-discovery-win32.exe"), not WINDOWS)
  433. settingsDB.setValue("Plugins/DSSI_win32", self.fDssiPlugins)
  434. if not self.fContinueChecking: return
  435. if self.fCheckWin64:
  436. self._checkDSSI("WINDOWS", os.path.join(self.fPathBinaries, "carla-discovery-win64.exe"), not WINDOWS)
  437. settingsDB.setValue("Plugins/DSSI_win64", self.fDssiPlugins)
  438. settingsDB.sync()
  439. if not self.fContinueChecking: return
  440. if self.fCheckLV2:
  441. if self.fCheckNative:
  442. self._checkLV2(self.fToolNative)
  443. settingsDB.setValue("Plugins/LV2_native", self.fLv2Plugins)
  444. if not self.fContinueChecking: return
  445. if self.fCheckPosix32:
  446. self._checkLV2(os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  447. settingsDB.setValue("Plugins/LV2_posix32", self.fLv2Plugins)
  448. if not self.fContinueChecking: return
  449. if self.fCheckPosix64:
  450. self._checkLV2(os.path.join(self.fPathBinaries, "carla-discovery-posix64"))
  451. settingsDB.setValue("Plugins/LV2_posix64", self.fLv2Plugins)
  452. if not self.fContinueChecking: return
  453. if self.fCheckWin32:
  454. self._checkLV2(os.path.join(self.fPathBinaries, "carla-discovery-win32.exe"), not WINDOWS)
  455. settingsDB.setValue("Plugins/LV2_win32", self.fLv2Plugins)
  456. if not self.fContinueChecking: return
  457. if self.fCheckWin64:
  458. self._checkLV2(os.path.join(self.fPathBinaries, "carla-discovery-win64.exe"), not WINDOWS)
  459. settingsDB.setValue("Plugins/LV2_win64", self.fLv2Plugins)
  460. settingsDB.sync()
  461. if not self.fContinueChecking: return
  462. if self.fCheckVST:
  463. if self.fCheckNative:
  464. self._checkVST(OS, self.fToolNative)
  465. settingsDB.setValue("Plugins/VST_native", self.fVstPlugins)
  466. if not self.fContinueChecking: return
  467. if self.fCheckPosix32:
  468. self._checkVST(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  469. settingsDB.setValue("Plugins/VST_posix32", self.fVstPlugins)
  470. if not self.fContinueChecking: return
  471. if self.fCheckPosix64:
  472. self._checkVST(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix64"))
  473. settingsDB.setValue("Plugins/VST_posix64", self.fVstPlugins)
  474. if not self.fContinueChecking: return
  475. if self.fCheckWin32:
  476. self._checkVST("WINDOWS", os.path.join(self.fPathBinaries, "carla-discovery-win32.exe"), not WINDOWS)
  477. settingsDB.setValue("Plugins/VST_win32", self.fVstPlugins)
  478. if not self.fContinueChecking: return
  479. if self.fCheckWin64:
  480. self._checkVST("WINDOWS", os.path.join(self.fPathBinaries, "carla-discovery-win64.exe"), not WINDOWS)
  481. settingsDB.setValue("Plugins/VST_win64", self.fVstPlugins)
  482. settingsDB.sync()
  483. if not self.fContinueChecking: return
  484. if self.fCheckVST3:
  485. if self.fCheckNative:
  486. self._checkVST3(self.fToolNative)
  487. settingsDB.setValue("Plugins/VST3_native", self.fVst3Plugins)
  488. if not self.fContinueChecking: return
  489. if self.fCheckPosix32 and MACOS:
  490. self._checkVST3(os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  491. settingsDB.setValue("Plugins/VST3_posix32", self.fVst3Plugins)
  492. if not self.fContinueChecking: return
  493. if self.fCheckPosix64 and MACOS:
  494. self._checkVST3(os.path.join(self.fPathBinaries, "carla-discovery-posix64"))
  495. settingsDB.setValue("Plugins/VST3_posix64", self.fVst3Plugins)
  496. if not self.fContinueChecking: return
  497. if self.fCheckWin32:
  498. self._checkVST3(os.path.join(self.fPathBinaries, "carla-discovery-win32.exe"), not WINDOWS)
  499. settingsDB.setValue("Plugins/VST3_win32", self.fVst3Plugins)
  500. if not self.fContinueChecking: return
  501. if self.fCheckWin64:
  502. self._checkVST3(os.path.join(self.fPathBinaries, "carla-discovery-win64.exe"), not WINDOWS)
  503. settingsDB.setValue("Plugins/VST3_win64", self.fVst3Plugins)
  504. settingsDB.sync()
  505. if not self.fContinueChecking: return
  506. if self.fCheckAU:
  507. if self.fCheckNative:
  508. self._checkAU(self.fToolNative)
  509. settingsDB.setValue("Plugins/AU_native", self.fAuPlugins)
  510. if not self.fContinueChecking: return
  511. if self.fCheckPosix32:
  512. self._checkAU(os.path.join(self.fPathBinaries, "carla-discovery-posix32"))
  513. settingsDB.setValue("Plugins/AU_posix32", self.fAuPlugins)
  514. if not self.fContinueChecking: return
  515. if self.fCheckPosix64:
  516. self._checkAU(os.path.join(self.fPathBinaries, "carla-discovery-posix64"))
  517. settingsDB.setValue("Plugins/AU_posix64", self.fAuPlugins)
  518. settingsDB.sync()
  519. if not self.fContinueChecking: return
  520. if self.fCheckGIG:
  521. settings = QSettings("falkTX", "Carla2")
  522. GIG_PATH = toList(settings.value(CARLA_KEY_PATHS_GIG, CARLA_DEFAULT_GIG_PATH))
  523. del settings
  524. self._checkKIT(GIG_PATH, "gig")
  525. settingsDB.setValue("Plugins/GIG", self.fKitPlugins)
  526. if not self.fContinueChecking: return
  527. if self.fCheckSF2:
  528. settings = QSettings("falkTX", "Carla2")
  529. SF2_PATH = toList(settings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH))
  530. del settings
  531. self._checkKIT(SF2_PATH, "sf2")
  532. settingsDB.setValue("Plugins/SF2", self.fKitPlugins)
  533. if not self.fContinueChecking: return
  534. if self.fCheckSFZ:
  535. settings = QSettings("falkTX", "Carla2")
  536. SFZ_PATH = toList(settings.value(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH))
  537. del settings
  538. self._checkKIT(SFZ_PATH, "sfz")
  539. settingsDB.setValue("Plugins/SFZ", self.fKitPlugins)
  540. settingsDB.sync()
  541. def _checkLADSPA(self, OS, tool, isWine=False):
  542. ladspaBinaries = []
  543. self.fLadspaPlugins = []
  544. self._pluginLook(self.fLastCheckValue, "LADSPA plugins...")
  545. settings = QSettings("falkTX", "Carla2")
  546. LADSPA_PATH = toList(settings.value(CARLA_KEY_PATHS_LADSPA, CARLA_DEFAULT_LADSPA_PATH))
  547. del settings
  548. for iPATH in LADSPA_PATH:
  549. binaries = findBinaries(iPATH, OS)
  550. for binary in binaries:
  551. if binary not in ladspaBinaries:
  552. ladspaBinaries.append(binary)
  553. ladspaBinaries.sort()
  554. if not self.fContinueChecking: return
  555. for i in range(len(ladspaBinaries)):
  556. ladspa = ladspaBinaries[i]
  557. percent = ( float(i) / len(ladspaBinaries) ) * self.fCurPercentValue
  558. self._pluginLook((self.fLastCheckValue + percent) * 0.9, ladspa)
  559. plugins = checkPluginLADSPA(ladspa, tool, isWine)
  560. if plugins:
  561. self.fLadspaPlugins.append(plugins)
  562. self.fSomethingChanged = True
  563. if not self.fContinueChecking: break
  564. self.fLastCheckValue += self.fCurPercentValue
  565. def _checkDSSI(self, OS, tool, isWine=False):
  566. dssiBinaries = []
  567. self.fDssiPlugins = []
  568. self._pluginLook(self.fLastCheckValue, "DSSI plugins...")
  569. settings = QSettings("falkTX", "Carla2")
  570. DSSI_PATH = toList(settings.value(CARLA_KEY_PATHS_DSSI, CARLA_DEFAULT_DSSI_PATH))
  571. del settings
  572. for iPATH in DSSI_PATH:
  573. binaries = findBinaries(iPATH, OS)
  574. for binary in binaries:
  575. if binary not in dssiBinaries:
  576. dssiBinaries.append(binary)
  577. dssiBinaries.sort()
  578. if not self.fContinueChecking: return
  579. for i in range(len(dssiBinaries)):
  580. dssi = dssiBinaries[i]
  581. percent = ( float(i) / len(dssiBinaries) ) * self.fCurPercentValue
  582. self._pluginLook(self.fLastCheckValue + percent, dssi)
  583. plugins = checkPluginDSSI(dssi, tool, isWine)
  584. if plugins:
  585. self.fDssiPlugins.append(plugins)
  586. self.fSomethingChanged = True
  587. if not self.fContinueChecking: break
  588. self.fLastCheckValue += self.fCurPercentValue
  589. def _checkLV2(self, tool, isWine=False):
  590. lv2Bundles = []
  591. self.fLv2Plugins = []
  592. self._pluginLook(self.fLastCheckValue, "LV2 bundles...")
  593. settings = QSettings("falkTX", "Carla2")
  594. LV2_PATH = toList(settings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH))
  595. del settings
  596. for iPATH in LV2_PATH:
  597. bundles = findLV2Bundles(iPATH)
  598. for bundle in bundles:
  599. if bundle not in lv2Bundles:
  600. lv2Bundles.append(bundle)
  601. lv2Bundles.sort()
  602. if not self.fContinueChecking: return
  603. for i in range(len(lv2Bundles)):
  604. lv2 = lv2Bundles[i]
  605. percent = ( float(i) / len(lv2Bundles) ) * self.fCurPercentValue
  606. self._pluginLook(self.fLastCheckValue + percent, lv2)
  607. plugins = checkPluginLV2(lv2, tool, isWine)
  608. if plugins:
  609. self.fLv2Plugins.append(plugins)
  610. self.fSomethingChanged = True
  611. if not self.fContinueChecking: break
  612. self.fLastCheckValue += self.fCurPercentValue
  613. def _checkVST(self, OS, tool, isWine=False):
  614. vstBinaries = []
  615. self.fVstPlugins = []
  616. if MACOS and not isWine:
  617. self._pluginLook(self.fLastCheckValue, "VST bundles...")
  618. else:
  619. self._pluginLook(self.fLastCheckValue, "VST plugins...")
  620. settings = QSettings("falkTX", "Carla2")
  621. VST_PATH = toList(settings.value(CARLA_KEY_PATHS_VST, CARLA_DEFAULT_VST_PATH))
  622. del settings
  623. for iPATH in VST_PATH:
  624. if MACOS and not isWine:
  625. binaries = findMacVSTBundles(iPATH, False)
  626. else:
  627. binaries = findBinaries(iPATH, OS)
  628. for binary in binaries:
  629. if binary not in vstBinaries:
  630. vstBinaries.append(binary)
  631. vstBinaries.sort()
  632. if not self.fContinueChecking: return
  633. for i in range(len(vstBinaries)):
  634. vst = vstBinaries[i]
  635. percent = ( float(i) / len(vstBinaries) ) * self.fCurPercentValue
  636. self._pluginLook(self.fLastCheckValue + percent, vst)
  637. plugins = checkPluginVST(vst, tool, isWine)
  638. if plugins:
  639. self.fVstPlugins.append(plugins)
  640. self.fSomethingChanged = True
  641. if not self.fContinueChecking: break
  642. self.fLastCheckValue += self.fCurPercentValue
  643. def _checkVST3(self, tool, isWine=False):
  644. vst3Binaries = []
  645. self.fVst3Plugins = []
  646. if MACOS and not isWine:
  647. self._pluginLook(self.fLastCheckValue, "VST3 bundles...")
  648. else:
  649. self._pluginLook(self.fLastCheckValue, "VST3 plugins...")
  650. settings = QSettings("falkTX", "Carla2")
  651. VST3_PATH = toList(settings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH))
  652. del settings
  653. for iPATH in VST3_PATH:
  654. if MACOS and not isWine:
  655. binaries = findMacVSTBundles(iPATH, True)
  656. else:
  657. binaries = findVST3Binaries(iPATH)
  658. for binary in binaries:
  659. if binary not in vst3Binaries:
  660. vst3Binaries.append(binary)
  661. vst3Binaries.sort()
  662. if not self.fContinueChecking: return
  663. for i in range(len(vst3Binaries)):
  664. vst3 = vst3Binaries[i]
  665. percent = ( float(i) / len(vst3Binaries) ) * self.fCurPercentValue
  666. self._pluginLook(self.fLastCheckValue + percent, vst3)
  667. plugins = checkPluginVST3(vst3, tool, isWine)
  668. if plugins:
  669. self.fVst3Plugins.append(plugins)
  670. self.fSomethingChanged = True
  671. if not self.fContinueChecking: break
  672. self.fLastCheckValue += self.fCurPercentValue
  673. def _checkAU(self, tool):
  674. auBinaries = []
  675. self.fAuPlugins = []
  676. # FIXME - this probably uses bundles
  677. self._pluginLook(self.fLastCheckValue, "AU plugins...")
  678. settings = QSettings("falkTX", "Carla2")
  679. AU_PATH = toList(settings.value(CARLA_KEY_PATHS_AU, CARLA_DEFAULT_AU_PATH))
  680. del settings
  681. for iPATH in AU_PATH:
  682. binaries = findBinaries(iPATH, "MACOS")
  683. for binary in binaries:
  684. if binary not in auBinaries:
  685. auBinaries.append(binary)
  686. auBinaries.sort()
  687. if not self.fContinueChecking: return
  688. for i in range(len(auBinaries)):
  689. au = auBinaries[i]
  690. percent = ( float(i) / len(auBinaries) ) * self.fCurPercentValue
  691. self._pluginLook(self.fLastCheckValue + percent, au)
  692. plugins = checkPluginAU(au, tool)
  693. if plugins:
  694. self.fAuPlugins.append(plugins)
  695. self.fSomethingChanged = True
  696. if not self.fContinueChecking: break
  697. self.fLastCheckValue += self.fCurPercentValue
  698. def _checkKIT(self, kitPATH, kitExtension):
  699. kitFiles = []
  700. self.fKitPlugins = []
  701. for iPATH in kitPATH:
  702. files = findFilenames(iPATH, kitExtension)
  703. for file_ in files:
  704. if file_ not in kitFiles:
  705. kitFiles.append(file_)
  706. kitFiles.sort()
  707. if not self.fContinueChecking: return
  708. for i in range(len(kitFiles)):
  709. kit = kitFiles[i]
  710. percent = ( float(i) / len(kitFiles) ) * self.fCurPercentValue
  711. self._pluginLook(self.fLastCheckValue + percent, kit)
  712. if kitExtension == "gig":
  713. plugins = checkFileGIG(kit, self.fToolNative)
  714. elif kitExtension == "sf2":
  715. plugins = checkFileSF2(kit, self.fToolNative)
  716. elif kitExtension == "sfz":
  717. plugins = checkFileSFZ(kit, self.fToolNative)
  718. else:
  719. plugins = None
  720. if plugins:
  721. self.fKitPlugins.append(plugins)
  722. self.fSomethingChanged = True
  723. if not self.fContinueChecking: break
  724. self.fLastCheckValue += self.fCurPercentValue
  725. def _pluginLook(self, percent, plugin):
  726. self.pluginLook.emit(percent, plugin)
  727. # ------------------------------------------------------------------------------------------------------------
  728. # Plugin Refresh Dialog
  729. class PluginRefreshW(QDialog):
  730. def __init__(self, parent, host):
  731. QDialog.__init__(self, parent)
  732. self.host = host
  733. self.ui = ui_carla_refresh.Ui_PluginRefreshW()
  734. self.ui.setupUi(self)
  735. if False:
  736. # kdevelop likes this :)
  737. host = CarlaHostMeta()
  738. self.host = host
  739. # ----------------------------------------------------------------------------------------------------
  740. # Internal stuff
  741. hasNative = os.path.exists(os.path.join(self.host.pathBinaries, "carla-discovery-native"))
  742. hasPosix32 = os.path.exists(os.path.join(self.host.pathBinaries, "carla-discovery-posix32"))
  743. hasPosix64 = os.path.exists(os.path.join(self.host.pathBinaries, "carla-discovery-posix64"))
  744. hasWin32 = os.path.exists(os.path.join(self.host.pathBinaries, "carla-discovery-win32.exe"))
  745. hasWin64 = os.path.exists(os.path.join(self.host.pathBinaries, "carla-discovery-win64.exe"))
  746. self.fThread = SearchPluginsThread(self, host.pathBinaries)
  747. self.fIconYes = getIcon("dialog-ok-apply").pixmap(16, 16)
  748. self.fIconNo = getIcon("dialog-error").pixmap(16, 16)
  749. # ----------------------------------------------------------------------------------------------------
  750. # Set-up GUI
  751. self.ui.b_skip.setVisible(False)
  752. if HAIKU:
  753. self.ui.ch_posix32.setText("Haiku 32bit")
  754. self.ui.ch_posix64.setText("Haiku 64bit")
  755. elif LINUX:
  756. self.ui.ch_posix32.setText("Linux 32bit")
  757. self.ui.ch_posix64.setText("Linux 64bit")
  758. elif MACOS:
  759. self.ui.ch_posix32.setText("MacOS 32bit")
  760. self.ui.ch_posix64.setText("MacOS 64bit")
  761. if hasPosix32 and not WINDOWS:
  762. self.ui.ico_posix32.setPixmap(self.fIconYes)
  763. else:
  764. self.ui.ico_posix32.setPixmap(self.fIconNo)
  765. self.ui.ch_posix32.setEnabled(False)
  766. if hasPosix64 and not WINDOWS:
  767. self.ui.ico_posix64.setPixmap(self.fIconYes)
  768. else:
  769. self.ui.ico_posix64.setPixmap(self.fIconNo)
  770. self.ui.ch_posix64.setEnabled(False)
  771. if hasWin32:
  772. self.ui.ico_win32.setPixmap(self.fIconYes)
  773. else:
  774. self.ui.ico_win32.setPixmap(self.fIconNo)
  775. self.ui.ch_win32.setEnabled(False)
  776. if hasWin64:
  777. self.ui.ico_win64.setPixmap(self.fIconYes)
  778. else:
  779. self.ui.ico_win64.setPixmap(self.fIconNo)
  780. self.ui.ch_win64.setEnabled(False)
  781. if haveLRDF:
  782. self.ui.ico_rdflib.setPixmap(self.fIconYes)
  783. else:
  784. self.ui.ico_rdflib.setPixmap(self.fIconNo)
  785. if WINDOWS:
  786. if kIs64bit:
  787. hasNative = hasWin64
  788. hasNonNative = hasWin32
  789. self.ui.ch_win64.setEnabled(False)
  790. self.ui.ch_win64.setVisible(False)
  791. self.ui.ico_win64.setVisible(False)
  792. self.ui.label_win64.setVisible(False)
  793. else:
  794. hasNative = hasWin32
  795. hasNonNative = hasWin64
  796. self.ui.ch_win32.setEnabled(False)
  797. self.ui.ch_win32.setVisible(False)
  798. self.ui.ico_win32.setVisible(False)
  799. self.ui.label_win32.setVisible(False)
  800. else:
  801. if kIs64bit:
  802. hasNonNative = bool(hasPosix32 or hasWin32 or hasWin64)
  803. self.ui.ch_posix64.setEnabled(False)
  804. self.ui.ch_posix64.setVisible(False)
  805. self.ui.ico_posix64.setVisible(False)
  806. self.ui.label_posix64.setVisible(False)
  807. else:
  808. hasNonNative = bool(hasPosix64 or hasWin32 or hasWin64)
  809. self.ui.ch_posix32.setEnabled(False)
  810. self.ui.ch_posix32.setVisible(False)
  811. self.ui.ico_posix32.setVisible(False)
  812. self.ui.label_posix32.setVisible(False)
  813. if hasNative:
  814. self.ui.ico_native.setPixmap(self.fIconYes)
  815. else:
  816. self.ui.ico_native.setPixmap(self.fIconNo)
  817. self.ui.ch_native.setEnabled(False)
  818. self.ui.ch_gig.setEnabled(False)
  819. self.ui.ch_sf2.setEnabled(False)
  820. self.ui.ch_sfz.setEnabled(False)
  821. if not hasNonNative:
  822. self.ui.ch_ladspa.setEnabled(False)
  823. self.ui.ch_dssi.setEnabled(False)
  824. self.ui.ch_lv2.setEnabled(False)
  825. self.ui.ch_vst.setEnabled(False)
  826. self.ui.ch_vst3.setEnabled(False)
  827. self.ui.ch_au.setEnabled(False)
  828. if not MACOS:
  829. self.ui.ch_au.setVisible(False)
  830. # ----------------------------------------------------------------------------------------------------
  831. # Load settings
  832. self.loadSettings()
  833. # ----------------------------------------------------------------------------------------------------
  834. # Set-up connections
  835. self.finished.connect(self.slot_saveSettings)
  836. self.ui.b_start.clicked.connect(self.slot_start)
  837. self.ui.b_skip.clicked.connect(self.slot_skip)
  838. self.ui.ch_native.clicked.connect(self.slot_checkTools)
  839. self.ui.ch_posix32.clicked.connect(self.slot_checkTools)
  840. self.ui.ch_posix64.clicked.connect(self.slot_checkTools)
  841. self.ui.ch_win32.clicked.connect(self.slot_checkTools)
  842. self.ui.ch_win64.clicked.connect(self.slot_checkTools)
  843. self.ui.ch_ladspa.clicked.connect(self.slot_checkTools)
  844. self.ui.ch_dssi.clicked.connect(self.slot_checkTools)
  845. self.ui.ch_lv2.clicked.connect(self.slot_checkTools)
  846. self.ui.ch_vst.clicked.connect(self.slot_checkTools)
  847. self.ui.ch_vst3.clicked.connect(self.slot_checkTools)
  848. self.ui.ch_au.clicked.connect(self.slot_checkTools)
  849. self.ui.ch_gig.clicked.connect(self.slot_checkTools)
  850. self.ui.ch_sf2.clicked.connect(self.slot_checkTools)
  851. self.ui.ch_sfz.clicked.connect(self.slot_checkTools)
  852. self.fThread.pluginLook.connect(self.slot_handlePluginLook)
  853. self.fThread.finished.connect(self.slot_handlePluginThreadFinished)
  854. # ----------------------------------------------------------------------------------------------------
  855. # Post-connect setup
  856. self.slot_checkTools()
  857. # --------------------------------------------------------------------------------------------------------
  858. def loadSettings(self):
  859. settings = QSettings("falkTX", "CarlaRefresh2")
  860. self.ui.ch_ladspa.setChecked(settings.value("PluginDatabase/SearchLADSPA", True, type=bool) and self.ui.ch_ladspa.isEnabled())
  861. self.ui.ch_dssi.setChecked(settings.value("PluginDatabase/SearchDSSI", True, type=bool) and self.ui.ch_dssi.isEnabled())
  862. self.ui.ch_lv2.setChecked(settings.value("PluginDatabase/SearchLV2", True, type=bool) and self.ui.ch_lv2.isEnabled())
  863. self.ui.ch_vst.setChecked(settings.value("PluginDatabase/SearchVST", True, type=bool) and self.ui.ch_vst.isEnabled())
  864. self.ui.ch_vst3.setChecked(settings.value("PluginDatabase/SearchVST3", (MACOS or WINDOWS), type=bool) and self.ui.ch_vst3.isEnabled())
  865. self.ui.ch_au.setChecked(settings.value("PluginDatabase/SearchAU", True, type=bool) and self.ui.ch_au.isEnabled())
  866. self.ui.ch_gig.setChecked(settings.value("PluginDatabase/SearchGIG", False, type=bool) and self.ui.ch_gig.isEnabled())
  867. self.ui.ch_sf2.setChecked(settings.value("PluginDatabase/SearchSF2", False, type=bool) and self.ui.ch_sf2.isEnabled())
  868. self.ui.ch_sfz.setChecked(settings.value("PluginDatabase/SearchSFZ", False, type=bool) and self.ui.ch_sfz.isEnabled())
  869. self.ui.ch_native.setChecked(settings.value("PluginDatabase/SearchNative", True, type=bool) and self.ui.ch_native.isEnabled())
  870. self.ui.ch_posix32.setChecked(settings.value("PluginDatabase/SearchPOSIX32", False, type=bool) and self.ui.ch_posix32.isEnabled())
  871. self.ui.ch_posix64.setChecked(settings.value("PluginDatabase/SearchPOSIX64", False, type=bool) and self.ui.ch_posix64.isEnabled())
  872. self.ui.ch_win32.setChecked(settings.value("PluginDatabase/SearchWin32", False, type=bool) and self.ui.ch_win32.isEnabled())
  873. self.ui.ch_win64.setChecked(settings.value("PluginDatabase/SearchWin64", False, type=bool) and self.ui.ch_win64.isEnabled())
  874. self.ui.ch_do_checks.setChecked(settings.value("PluginDatabase/DoChecks", False, type=bool))
  875. # --------------------------------------------------------------------------------------------------------
  876. @pyqtSlot()
  877. def slot_saveSettings(self):
  878. settings = QSettings("falkTX", "CarlaRefresh2")
  879. settings.setValue("PluginDatabase/SearchLADSPA", self.ui.ch_ladspa.isChecked())
  880. settings.setValue("PluginDatabase/SearchDSSI", self.ui.ch_dssi.isChecked())
  881. settings.setValue("PluginDatabase/SearchLV2", self.ui.ch_lv2.isChecked())
  882. settings.setValue("PluginDatabase/SearchVST", self.ui.ch_vst.isChecked())
  883. settings.setValue("PluginDatabase/SearchVST3", self.ui.ch_vst3.isChecked())
  884. settings.setValue("PluginDatabase/SearchAU", self.ui.ch_au.isChecked())
  885. settings.setValue("PluginDatabase/SearchGIG", self.ui.ch_gig.isChecked())
  886. settings.setValue("PluginDatabase/SearchSF2", self.ui.ch_sf2.isChecked())
  887. settings.setValue("PluginDatabase/SearchSFZ", self.ui.ch_sfz.isChecked())
  888. settings.setValue("PluginDatabase/SearchNative", self.ui.ch_native.isChecked())
  889. settings.setValue("PluginDatabase/SearchPOSIX32", self.ui.ch_posix32.isChecked())
  890. settings.setValue("PluginDatabase/SearchPOSIX64", self.ui.ch_posix64.isChecked())
  891. settings.setValue("PluginDatabase/SearchWin32", self.ui.ch_win32.isChecked())
  892. settings.setValue("PluginDatabase/SearchWin64", self.ui.ch_win64.isChecked())
  893. settings.setValue("PluginDatabase/DoChecks", self.ui.ch_do_checks.isChecked())
  894. # --------------------------------------------------------------------------------------------------------
  895. @pyqtSlot()
  896. def slot_start(self):
  897. self.ui.progressBar.setMinimum(0)
  898. self.ui.progressBar.setMaximum(100)
  899. self.ui.progressBar.setValue(0)
  900. self.ui.b_start.setEnabled(False)
  901. self.ui.b_skip.setVisible(True)
  902. self.ui.b_close.setVisible(False)
  903. self.ui.group_types.setEnabled(False)
  904. self.ui.group_options.setEnabled(False)
  905. if self.ui.ch_do_checks.isChecked():
  906. self.host.unsetenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS")
  907. else:
  908. self.host.setenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS", "true")
  909. native, posix32, posix64, win32, win64 = (self.ui.ch_native.isChecked(),
  910. self.ui.ch_posix32.isChecked(), self.ui.ch_posix64.isChecked(),
  911. self.ui.ch_win32.isChecked(), self.ui.ch_win64.isChecked())
  912. ladspa, dssi, lv2, vst, vst3, au, gig, sf2, sfz = (self.ui.ch_ladspa.isChecked(), self.ui.ch_dssi.isChecked(),
  913. self.ui.ch_lv2.isChecked(), self.ui.ch_vst.isChecked(),
  914. self.ui.ch_vst3.isChecked(), self.ui.ch_au.isChecked(),
  915. self.ui.ch_gig.isChecked(), self.ui.ch_sf2.isChecked(), self.ui.ch_sfz.isChecked())
  916. self.fThread.setSearchBinaryTypes(native, posix32, posix64, win32, win64)
  917. self.fThread.setSearchPluginTypes(ladspa, dssi, lv2, vst, vst3, au, gig, sf2, sfz)
  918. self.fThread.start()
  919. # --------------------------------------------------------------------------------------------------------
  920. @pyqtSlot()
  921. def slot_skip(self):
  922. killDiscovery()
  923. # --------------------------------------------------------------------------------------------------------
  924. @pyqtSlot()
  925. def slot_checkTools(self):
  926. enabled1 = bool(self.ui.ch_native.isChecked() or self.ui.ch_posix32.isChecked() or self.ui.ch_posix64.isChecked() or self.ui.ch_win32.isChecked() or self.ui.ch_win64.isChecked())
  927. 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
  928. self.ui.ch_au.isChecked() or self.ui.ch_gig.isChecked() or self.ui.ch_sf2.isChecked() or self.ui.ch_sfz.isChecked())
  929. self.ui.b_start.setEnabled(enabled1 and enabled2)
  930. # --------------------------------------------------------------------------------------------------------
  931. @pyqtSlot(int, str)
  932. def slot_handlePluginLook(self, percent, plugin):
  933. self.ui.progressBar.setFormat("%s" % plugin)
  934. self.ui.progressBar.setValue(percent)
  935. # --------------------------------------------------------------------------------------------------------
  936. @pyqtSlot()
  937. def slot_handlePluginThreadFinished(self):
  938. self.ui.progressBar.setMinimum(0)
  939. self.ui.progressBar.setMaximum(1)
  940. self.ui.progressBar.setValue(1)
  941. self.ui.progressBar.setFormat(self.tr("Done"))
  942. self.ui.b_start.setEnabled(True)
  943. self.ui.b_skip.setVisible(False)
  944. self.ui.b_close.setVisible(True)
  945. self.ui.group_types.setEnabled(True)
  946. self.ui.group_options.setEnabled(True)
  947. # --------------------------------------------------------------------------------------------------------
  948. def closeEvent(self, event):
  949. if self.fThread.isRunning():
  950. self.fThread.stop()
  951. killDiscovery()
  952. #self.fThread.terminate()
  953. self.fThread.wait()
  954. if self.fThread.hasSomethingChanged():
  955. self.accept()
  956. else:
  957. self.reject()
  958. QDialog.closeEvent(self, event)
  959. # --------------------------------------------------------------------------------------------------------
  960. def done(self, r):
  961. QDialog.done(self, r)
  962. self.close()
  963. # ------------------------------------------------------------------------------------------------------------
  964. # Plugin Database Dialog
  965. class PluginDatabaseW(QDialog):
  966. def __init__(self, parent, host):
  967. QDialog.__init__(self, parent)
  968. self.host = host
  969. self.ui = ui_carla_database.Ui_PluginDatabaseW()
  970. self.ui.setupUi(self)
  971. if False:
  972. # kdevelop likes this :)
  973. host = CarlaHostMeta()
  974. self.host = host
  975. # ----------------------------------------------------------------------------------------------------
  976. # Internal stuff
  977. self.fLastTableIndex = 0
  978. self.fRetPlugin = None
  979. self.fRealParent = parent
  980. # ----------------------------------------------------------------------------------------------------
  981. # Set-up GUI
  982. self.ui.b_add.setEnabled(False)
  983. if BINARY_NATIVE in (BINARY_POSIX32, BINARY_WIN32):
  984. self.ui.ch_bridged.setText(self.tr("Bridged (64bit)"))
  985. else:
  986. self.ui.ch_bridged.setText(self.tr("Bridged (32bit)"))
  987. if not (LINUX or MACOS):
  988. self.ui.ch_bridged_wine.setChecked(False)
  989. self.ui.ch_bridged_wine.setEnabled(False)
  990. # ----------------------------------------------------------------------------------------------------
  991. # Load settings
  992. self.loadSettings()
  993. # ----------------------------------------------------------------------------------------------------
  994. # Set-up connections
  995. self.finished.connect(self.slot_saveSettings)
  996. self.ui.b_add.clicked.connect(self.slot_addPlugin)
  997. self.ui.b_refresh.clicked.connect(self.slot_refreshPlugins)
  998. self.ui.tb_filters.clicked.connect(self.slot_maybeShowFilters)
  999. self.ui.lineEdit.textChanged.connect(self.slot_checkFilters)
  1000. self.ui.tableWidget.currentCellChanged.connect(self.slot_checkPlugin)
  1001. self.ui.tableWidget.cellDoubleClicked.connect(self.slot_addPlugin)
  1002. self.ui.ch_effects.clicked.connect(self.slot_checkFilters)
  1003. self.ui.ch_instruments.clicked.connect(self.slot_checkFilters)
  1004. self.ui.ch_midi.clicked.connect(self.slot_checkFilters)
  1005. self.ui.ch_other.clicked.connect(self.slot_checkFilters)
  1006. self.ui.ch_internal.clicked.connect(self.slot_checkFilters)
  1007. self.ui.ch_ladspa.clicked.connect(self.slot_checkFilters)
  1008. self.ui.ch_dssi.clicked.connect(self.slot_checkFilters)
  1009. self.ui.ch_lv2.clicked.connect(self.slot_checkFilters)
  1010. self.ui.ch_vst.clicked.connect(self.slot_checkFilters)
  1011. self.ui.ch_vst3.clicked.connect(self.slot_checkFilters)
  1012. self.ui.ch_au.clicked.connect(self.slot_checkFilters)
  1013. self.ui.ch_kits.clicked.connect(self.slot_checkFilters)
  1014. self.ui.ch_native.clicked.connect(self.slot_checkFilters)
  1015. self.ui.ch_bridged.clicked.connect(self.slot_checkFilters)
  1016. self.ui.ch_bridged_wine.clicked.connect(self.slot_checkFilters)
  1017. self.ui.ch_rtsafe.clicked.connect(self.slot_checkFilters)
  1018. self.ui.ch_gui.clicked.connect(self.slot_checkFilters)
  1019. self.ui.ch_stereo.clicked.connect(self.slot_checkFilters)
  1020. # ----------------------------------------------------------------------------------------------------
  1021. # Post-connect setup
  1022. self._reAddPlugins()
  1023. # --------------------------------------------------------------------------------------------------------
  1024. @pyqtSlot()
  1025. def slot_addPlugin(self):
  1026. if self.ui.tableWidget.currentRow() >= 0:
  1027. self.fRetPlugin = self.ui.tableWidget.item(self.ui.tableWidget.currentRow(), 0).data(Qt.UserRole)
  1028. self.accept()
  1029. else:
  1030. self.reject()
  1031. @pyqtSlot(int)
  1032. def slot_checkPlugin(self, row):
  1033. self.ui.b_add.setEnabled(row >= 0)
  1034. @pyqtSlot()
  1035. def slot_checkFilters(self):
  1036. self._checkFilters()
  1037. @pyqtSlot()
  1038. def slot_maybeShowFilters(self):
  1039. self._showFilters(not self.ui.frame.isVisible())
  1040. @pyqtSlot()
  1041. def slot_refreshPlugins(self):
  1042. if PluginRefreshW(self, self.host).exec_():
  1043. self._reAddPlugins()
  1044. if self.fRealParent:
  1045. self.fRealParent.setLoadRDFsNeeded()
  1046. # --------------------------------------------------------------------------------------------------------
  1047. @pyqtSlot()
  1048. def slot_saveSettings(self):
  1049. settings = QSettings("falkTX", "CarlaDatabase2")
  1050. settings.setValue("PluginDatabase/Geometry", self.saveGeometry())
  1051. settings.setValue("PluginDatabase/TableGeometry%s" % ("5" if config_UseQt5 else "4"), self.ui.tableWidget.horizontalHeader().saveState())
  1052. settings.setValue("PluginDatabase/ShowFilters", (self.ui.tb_filters.arrowType() == Qt.UpArrow))
  1053. settings.setValue("PluginDatabase/ShowEffects", self.ui.ch_effects.isChecked())
  1054. settings.setValue("PluginDatabase/ShowInstruments", self.ui.ch_instruments.isChecked())
  1055. settings.setValue("PluginDatabase/ShowMIDI", self.ui.ch_midi.isChecked())
  1056. settings.setValue("PluginDatabase/ShowOther", self.ui.ch_other.isChecked())
  1057. settings.setValue("PluginDatabase/ShowInternal", self.ui.ch_internal.isChecked())
  1058. settings.setValue("PluginDatabase/ShowLADSPA", self.ui.ch_ladspa.isChecked())
  1059. settings.setValue("PluginDatabase/ShowDSSI", self.ui.ch_dssi.isChecked())
  1060. settings.setValue("PluginDatabase/ShowLV2", self.ui.ch_lv2.isChecked())
  1061. settings.setValue("PluginDatabase/ShowVST", self.ui.ch_vst.isChecked())
  1062. settings.setValue("PluginDatabase/ShowVST3", self.ui.ch_vst3.isChecked())
  1063. settings.setValue("PluginDatabase/ShowAU", self.ui.ch_au.isChecked())
  1064. settings.setValue("PluginDatabase/ShowKits", self.ui.ch_kits.isChecked())
  1065. settings.setValue("PluginDatabase/ShowNative", self.ui.ch_native.isChecked())
  1066. settings.setValue("PluginDatabase/ShowBridged", self.ui.ch_bridged.isChecked())
  1067. settings.setValue("PluginDatabase/ShowBridgedWine", self.ui.ch_bridged_wine.isChecked())
  1068. settings.setValue("PluginDatabase/ShowRtSafe", self.ui.ch_rtsafe.isChecked())
  1069. settings.setValue("PluginDatabase/ShowHasGUI", self.ui.ch_gui.isChecked())
  1070. settings.setValue("PluginDatabase/ShowStereoOnly", self.ui.ch_stereo.isChecked())
  1071. # --------------------------------------------------------------------------------------------------------
  1072. def loadSettings(self):
  1073. settings = QSettings("falkTX", "CarlaDatabase2")
  1074. self.restoreGeometry(settings.value("PluginDatabase/Geometry", ""))
  1075. self.ui.tableWidget.horizontalHeader().restoreState(settings.value("PluginDatabase/TableGeometry%s" % ("_5" if config_UseQt5 else ""), ""))
  1076. self.ui.ch_effects.setChecked(settings.value("PluginDatabase/ShowEffects", True, type=bool))
  1077. self.ui.ch_instruments.setChecked(settings.value("PluginDatabase/ShowInstruments", True, type=bool))
  1078. self.ui.ch_midi.setChecked(settings.value("PluginDatabase/ShowMIDI", True, type=bool))
  1079. self.ui.ch_other.setChecked(settings.value("PluginDatabase/ShowOther", True, type=bool))
  1080. self.ui.ch_internal.setChecked(settings.value("PluginDatabase/ShowInternal", True, type=bool))
  1081. self.ui.ch_ladspa.setChecked(settings.value("PluginDatabase/ShowLADSPA", True, type=bool))
  1082. self.ui.ch_dssi.setChecked(settings.value("PluginDatabase/ShowDSSI", True, type=bool))
  1083. self.ui.ch_lv2.setChecked(settings.value("PluginDatabase/ShowLV2", True, type=bool))
  1084. self.ui.ch_vst.setChecked(settings.value("PluginDatabase/ShowVST", True, type=bool))
  1085. self.ui.ch_vst3.setChecked(settings.value("PluginDatabase/ShowVST3", (MACOS or WINDOWS), type=bool))
  1086. self.ui.ch_au.setChecked(settings.value("PluginDatabase/ShowAU", True, type=bool))
  1087. self.ui.ch_kits.setChecked(settings.value("PluginDatabase/ShowKits", True, type=bool))
  1088. self.ui.ch_native.setChecked(settings.value("PluginDatabase/ShowNative", True, type=bool))
  1089. self.ui.ch_bridged.setChecked(settings.value("PluginDatabase/ShowBridged", True, type=bool))
  1090. self.ui.ch_bridged_wine.setChecked(settings.value("PluginDatabase/ShowBridgedWine", True, type=bool))
  1091. self.ui.ch_rtsafe.setChecked(settings.value("PluginDatabase/ShowRtSafe", False, type=bool))
  1092. self.ui.ch_gui.setChecked(settings.value("PluginDatabase/ShowHasGUI", False, type=bool))
  1093. self.ui.ch_stereo.setChecked(settings.value("PluginDatabase/ShowStereoOnly", False, type=bool))
  1094. self._showFilters(settings.value("PluginDatabase/ShowFilters", False, type=bool))
  1095. # --------------------------------------------------------------------------------------------------------
  1096. def _checkFilters(self):
  1097. text = self.ui.lineEdit.text().lower()
  1098. hideEffects = not self.ui.ch_effects.isChecked()
  1099. hideInstruments = not self.ui.ch_instruments.isChecked()
  1100. hideMidi = not self.ui.ch_midi.isChecked()
  1101. hideOther = not self.ui.ch_other.isChecked()
  1102. hideInternal = not self.ui.ch_internal.isChecked()
  1103. hideLadspa = not self.ui.ch_ladspa.isChecked()
  1104. hideDssi = not self.ui.ch_dssi.isChecked()
  1105. hideLV2 = not self.ui.ch_lv2.isChecked()
  1106. hideVST = not self.ui.ch_vst.isChecked()
  1107. hideVST3 = not self.ui.ch_vst3.isChecked()
  1108. hideAU = not self.ui.ch_au.isChecked()
  1109. hideKits = not self.ui.ch_kits.isChecked()
  1110. hideNative = not self.ui.ch_native.isChecked()
  1111. hideBridged = not self.ui.ch_bridged.isChecked()
  1112. hideBridgedWine = not self.ui.ch_bridged_wine.isChecked()
  1113. hideNonRtSafe = self.ui.ch_rtsafe.isChecked()
  1114. hideNonGui = self.ui.ch_gui.isChecked()
  1115. hideNonStereo = self.ui.ch_stereo.isChecked()
  1116. if HAIKU or LINUX or MACOS:
  1117. nativeBins = [BINARY_POSIX32, BINARY_POSIX64]
  1118. wineBins = [BINARY_WIN32, BINARY_WIN64]
  1119. elif WINDOWS:
  1120. nativeBins = [BINARY_WIN32, BINARY_WIN64]
  1121. wineBins = []
  1122. else:
  1123. nativeBins = []
  1124. wineBins = []
  1125. rowCount = self.ui.tableWidget.rowCount()
  1126. for i in range(rowCount):
  1127. self.ui.tableWidget.showRow(i)
  1128. plugin = self.ui.tableWidget.item(i, 0).data(Qt.UserRole)
  1129. aIns = plugin['audio.ins']
  1130. aOuts = plugin['audio.outs']
  1131. mIns = plugin['midi.ins']
  1132. mOuts = plugin['midi.outs']
  1133. ptype = self.ui.tableWidget.item(i, 12).text()
  1134. isSynth = bool(plugin['hints'] & PLUGIN_IS_SYNTH)
  1135. isEffect = bool(aIns > 0 < aOuts and not isSynth)
  1136. isMidi = bool(aIns == 0 and aOuts == 0 and mIns > 0 < mOuts)
  1137. isKit = bool(ptype in ("GIG", "SF2", "SFZ"))
  1138. isOther = bool(not (isEffect or isSynth or isMidi or isKit))
  1139. isNative = bool(plugin['build'] == BINARY_NATIVE)
  1140. isRtSafe = bool(plugin['hints'] & PLUGIN_IS_RTSAFE)
  1141. isStereo = bool(aIns == 2 and aOuts == 2) or (isSynth and aOuts == 2)
  1142. hasGui = bool(plugin['hints'] & PLUGIN_HAS_CUSTOM_UI)
  1143. isBridged = bool(not isNative and plugin['build'] in nativeBins)
  1144. isBridgedWine = bool(not isNative and plugin['build'] in wineBins)
  1145. if hideEffects and isEffect:
  1146. self.ui.tableWidget.hideRow(i)
  1147. elif hideInstruments and isSynth:
  1148. self.ui.tableWidget.hideRow(i)
  1149. elif hideMidi and isMidi:
  1150. self.ui.tableWidget.hideRow(i)
  1151. elif hideOther and isOther:
  1152. self.ui.tableWidget.hideRow(i)
  1153. elif hideKits and isKit:
  1154. self.ui.tableWidget.hideRow(i)
  1155. elif hideInternal and ptype == self.tr("Internal"):
  1156. self.ui.tableWidget.hideRow(i)
  1157. elif hideLadspa and ptype == "LADSPA":
  1158. self.ui.tableWidget.hideRow(i)
  1159. elif hideDssi and ptype == "DSSI":
  1160. self.ui.tableWidget.hideRow(i)
  1161. elif hideLV2 and ptype == "LV2":
  1162. self.ui.tableWidget.hideRow(i)
  1163. elif hideVST and ptype == "VST":
  1164. self.ui.tableWidget.hideRow(i)
  1165. elif hideVST3 and ptype == "VST3":
  1166. self.ui.tableWidget.hideRow(i)
  1167. elif hideAU and ptype == "AU":
  1168. self.ui.tableWidget.hideRow(i)
  1169. elif hideNative and isNative:
  1170. self.ui.tableWidget.hideRow(i)
  1171. elif hideBridged and isBridged:
  1172. self.ui.tableWidget.hideRow(i)
  1173. elif hideBridgedWine and isBridgedWine:
  1174. self.ui.tableWidget.hideRow(i)
  1175. elif hideNonRtSafe and not isRtSafe:
  1176. self.ui.tableWidget.hideRow(i)
  1177. elif hideNonGui and not hasGui:
  1178. self.ui.tableWidget.hideRow(i)
  1179. elif hideNonStereo and not isStereo:
  1180. self.ui.tableWidget.hideRow(i)
  1181. elif (text and not (
  1182. text in self.ui.tableWidget.item(i, 0).text().lower() or
  1183. text in self.ui.tableWidget.item(i, 1).text().lower() or
  1184. text in self.ui.tableWidget.item(i, 2).text().lower() or
  1185. text in self.ui.tableWidget.item(i, 3).text().lower() or
  1186. text in self.ui.tableWidget.item(i, 13).text().lower())):
  1187. self.ui.tableWidget.hideRow(i)
  1188. # --------------------------------------------------------------------------------------------------------
  1189. def _showFilters(self, yesNo):
  1190. self.ui.tb_filters.setArrowType(Qt.UpArrow if yesNo else Qt.DownArrow)
  1191. self.ui.frame.setVisible(yesNo)
  1192. # --------------------------------------------------------------------------------------------------------
  1193. def _addPluginToTable(self, plugin, ptype):
  1194. if plugin['API'] != PLUGIN_QUERY_API_VERSION and not ptype == self.tr("Internal"):
  1195. return
  1196. index = self.fLastTableIndex
  1197. if plugin['build'] == BINARY_NATIVE:
  1198. bridgeText = self.tr("No")
  1199. else:
  1200. if LINUX or MACOS:
  1201. if plugin['build'] == BINARY_WIN32:
  1202. typeText = "32bit"
  1203. elif plugin['build'] == BINARY_WIN64:
  1204. typeText = "64bit"
  1205. else:
  1206. typeText = self.tr("Unknown")
  1207. else:
  1208. if plugin['build'] == BINARY_POSIX32:
  1209. typeText = "32bit"
  1210. elif plugin['build'] == BINARY_POSIX64:
  1211. typeText = "64bit"
  1212. elif plugin['build'] == BINARY_WIN32:
  1213. typeText = "Windows 32bit"
  1214. elif plugin['build'] == BINARY_WIN64:
  1215. typeText = "Windows 64bit"
  1216. else:
  1217. typeText = self.tr("Unknown")
  1218. bridgeText = self.tr("Yes (%s)" % typeText)
  1219. self.ui.tableWidget.insertRow(index)
  1220. self.ui.tableWidget.setItem(index, 0, QTableWidgetItem(str(plugin['name'])))
  1221. self.ui.tableWidget.setItem(index, 1, QTableWidgetItem(str(plugin['label'])))
  1222. self.ui.tableWidget.setItem(index, 2, QTableWidgetItem(str(plugin['maker'])))
  1223. self.ui.tableWidget.setItem(index, 3, QTableWidgetItem(str(plugin['uniqueId'])))
  1224. self.ui.tableWidget.setItem(index, 4, QTableWidgetItem(str(plugin['audio.ins'])))
  1225. self.ui.tableWidget.setItem(index, 5, QTableWidgetItem(str(plugin['audio.outs'])))
  1226. self.ui.tableWidget.setItem(index, 6, QTableWidgetItem(str(plugin['parameters.ins'])))
  1227. self.ui.tableWidget.setItem(index, 7, QTableWidgetItem(str(plugin['parameters.outs'])))
  1228. self.ui.tableWidget.setItem(index, 9, QTableWidgetItem(self.tr("Yes") if (plugin['hints'] & PLUGIN_HAS_CUSTOM_UI) else self.tr("No")))
  1229. self.ui.tableWidget.setItem(index, 10, QTableWidgetItem(self.tr("Yes") if (plugin['hints'] & PLUGIN_IS_SYNTH) else self.tr("No")))
  1230. self.ui.tableWidget.setItem(index, 11, QTableWidgetItem(bridgeText))
  1231. self.ui.tableWidget.setItem(index, 12, QTableWidgetItem(ptype))
  1232. self.ui.tableWidget.setItem(index, 13, QTableWidgetItem(str(plugin['filename'])))
  1233. self.ui.tableWidget.item(index, 0).setData(Qt.UserRole, plugin)
  1234. self.fLastTableIndex += 1
  1235. # --------------------------------------------------------------------------------------------------------
  1236. def _reAddPlugins(self):
  1237. settingsDB = QSettings("falkTX", "CarlaPlugins2")
  1238. for x in range(self.ui.tableWidget.rowCount()):
  1239. self.ui.tableWidget.removeRow(0)
  1240. self.fLastTableIndex = 0
  1241. self.ui.tableWidget.setSortingEnabled(False)
  1242. internalCount = 0
  1243. ladspaCount = 0
  1244. dssiCount = 0
  1245. lv2Count = 0
  1246. vstCount = 0
  1247. vst3Count = 0
  1248. auCount = 0
  1249. kitCount = 0
  1250. # ----------------------------------------------------------------------------------------------------
  1251. # Internal
  1252. internalPlugins = toList(settingsDB.value("Plugins/Internal", []))
  1253. for plugins in internalPlugins:
  1254. internalCount += len(plugins)
  1255. canRefreshInternals = not (self.host.isControl or self.host.isPlugin)
  1256. if canRefreshInternals and internalCount != self.host.get_internal_plugin_count():
  1257. internalCount = self.host.get_internal_plugin_count()
  1258. internalPlugins = []
  1259. for i in range(self.host.get_internal_plugin_count()):
  1260. descInfo = self.host.get_internal_plugin_info(i)
  1261. plugins = checkPluginInternal(descInfo)
  1262. if plugins:
  1263. internalPlugins.append(plugins)
  1264. settingsDB.setValue("Plugins/Internal", internalPlugins)
  1265. for plugins in internalPlugins:
  1266. for plugin in plugins:
  1267. self._addPluginToTable(plugin, self.tr("Internal"))
  1268. del internalPlugins
  1269. # ----------------------------------------------------------------------------------------------------
  1270. # LADSPA
  1271. ladspaPlugins = []
  1272. ladspaPlugins += toList(settingsDB.value("Plugins/LADSPA_native", []))
  1273. ladspaPlugins += toList(settingsDB.value("Plugins/LADSPA_posix32", []))
  1274. ladspaPlugins += toList(settingsDB.value("Plugins/LADSPA_posix64", []))
  1275. ladspaPlugins += toList(settingsDB.value("Plugins/LADSPA_win32", []))
  1276. ladspaPlugins += toList(settingsDB.value("Plugins/LADSPA_win64", []))
  1277. for plugins in ladspaPlugins:
  1278. for plugin in plugins:
  1279. self._addPluginToTable(plugin, "LADSPA")
  1280. ladspaCount += 1
  1281. del ladspaPlugins
  1282. # ----------------------------------------------------------------------------------------------------
  1283. # DSSI
  1284. dssiPlugins = []
  1285. dssiPlugins += toList(settingsDB.value("Plugins/DSSI_native", []))
  1286. dssiPlugins += toList(settingsDB.value("Plugins/DSSI_posix32", []))
  1287. dssiPlugins += toList(settingsDB.value("Plugins/DSSI_posix64", []))
  1288. dssiPlugins += toList(settingsDB.value("Plugins/DSSI_win32", []))
  1289. dssiPlugins += toList(settingsDB.value("Plugins/DSSI_win64", []))
  1290. for plugins in dssiPlugins:
  1291. for plugin in plugins:
  1292. self._addPluginToTable(plugin, "DSSI")
  1293. dssiCount += 1
  1294. del dssiPlugins
  1295. # ----------------------------------------------------------------------------------------------------
  1296. # LV2
  1297. lv2Plugins = []
  1298. lv2Plugins += toList(settingsDB.value("Plugins/LV2_native", []))
  1299. lv2Plugins += toList(settingsDB.value("Plugins/LV2_posix32", []))
  1300. lv2Plugins += toList(settingsDB.value("Plugins/LV2_posix64", []))
  1301. lv2Plugins += toList(settingsDB.value("Plugins/LV2_win32", []))
  1302. lv2Plugins += toList(settingsDB.value("Plugins/LV2_win64", []))
  1303. for plugins in lv2Plugins:
  1304. for plugin in plugins:
  1305. self._addPluginToTable(plugin, "LV2")
  1306. lv2Count += 1
  1307. del lv2Plugins
  1308. # ----------------------------------------------------------------------------------------------------
  1309. # VST
  1310. vstPlugins = []
  1311. vstPlugins += toList(settingsDB.value("Plugins/VST_native", []))
  1312. vstPlugins += toList(settingsDB.value("Plugins/VST_posix32", []))
  1313. vstPlugins += toList(settingsDB.value("Plugins/VST_posix64", []))
  1314. vstPlugins += toList(settingsDB.value("Plugins/VST_win32", []))
  1315. vstPlugins += toList(settingsDB.value("Plugins/VST_win64", []))
  1316. for plugins in vstPlugins:
  1317. for plugin in plugins:
  1318. self._addPluginToTable(plugin, "VST")
  1319. vstCount += 1
  1320. del vstPlugins
  1321. # ----------------------------------------------------------------------------------------------------
  1322. # VST3
  1323. vst3Plugins = []
  1324. vst3Plugins += toList(settingsDB.value("Plugins/VST3_native", []))
  1325. vst3Plugins += toList(settingsDB.value("Plugins/VST3_posix32", []))
  1326. vst3Plugins += toList(settingsDB.value("Plugins/VST3_posix64", []))
  1327. vst3Plugins += toList(settingsDB.value("Plugins/VST3_win32", []))
  1328. vst3Plugins += toList(settingsDB.value("Plugins/VST3_win64", []))
  1329. for plugins in vst3Plugins:
  1330. for plugin in plugins:
  1331. self._addPluginToTable(plugin, "VST3")
  1332. vst3Count += 1
  1333. del vst3Plugins
  1334. # ----------------------------------------------------------------------------------------------------
  1335. # AU
  1336. if MACOS:
  1337. auPlugins = []
  1338. auPlugins += toList(settingsDB.value("Plugins/AU_native", []))
  1339. auPlugins += toList(settingsDB.value("Plugins/AU_posix32", []))
  1340. auPlugins += toList(settingsDB.value("Plugins/AU_posix64", []))
  1341. for plugins in auPlugins:
  1342. for plugin in plugins:
  1343. self._addPluginToTable(plugin, "AU")
  1344. auCount += 1
  1345. del auPlugins
  1346. # ----------------------------------------------------------------------------------------------------
  1347. # Kits
  1348. gigs = toList(settingsDB.value("Plugins/GIG", []))
  1349. for gig in gigs:
  1350. for gig_i in gig:
  1351. self._addPluginToTable(gig_i, "GIG")
  1352. kitCount += 1
  1353. del gigs
  1354. # ----------------------------------------------------------------------------------------------------
  1355. sf2s = toList(settingsDB.value("Plugins/SF2", []))
  1356. for sf2 in sf2s:
  1357. for sf2_i in sf2:
  1358. self._addPluginToTable(sf2_i, "SF2")
  1359. kitCount += 1
  1360. del sf2s
  1361. # ----------------------------------------------------------------------------------------------------
  1362. sfzs = toList(settingsDB.value("Plugins/SFZ", []))
  1363. for sfz in sfzs:
  1364. for sfz_i in sfz:
  1365. self._addPluginToTable(sfz_i, "SFZ")
  1366. kitCount += 1
  1367. del sfzs
  1368. # ----------------------------------------------------------------------------------------------------
  1369. self.ui.tableWidget.setSortingEnabled(True)
  1370. self.ui.tableWidget.sortByColumn(0, Qt.AscendingOrder)
  1371. if MACOS:
  1372. self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2, %i VST, %i VST3 and %i AudioUnit plugins, plus %i Sound Kits" % (
  1373. internalCount, ladspaCount, dssiCount, lv2Count, vstCount, vst3Count, auCount, kitCount)))
  1374. else:
  1375. self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2, %i VST and %i VST3 plugins, plus %i Sound Kits" % (
  1376. internalCount, ladspaCount, dssiCount, lv2Count, vstCount, vst3Count, kitCount)))
  1377. self._checkFilters()
  1378. # --------------------------------------------------------------------------------------------------------
  1379. def done(self, r):
  1380. QDialog.done(self, r)
  1381. self.close()
  1382. # ------------------------------------------------------------------------------------------------------------
  1383. # Main
  1384. if __name__ == '__main__':
  1385. from carla_app import CarlaApplication
  1386. from carla_host import initHost, loadHostSettings
  1387. app = CarlaApplication()
  1388. host = initHost("Database", None, False, False, False)
  1389. loadHostSettings(host)
  1390. gui = PluginDatabaseW(None, host)
  1391. gui.show()
  1392. app.exit_exec()
  1393. # ------------------------------------------------------------------------------------------------------------