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.

1830 lines
72KB

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