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.

1702 lines
67KB

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