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.

carla_database.py 72KB

11 years ago
9 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829
  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 = 7
  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", "CarlaPlugins3")
  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)
  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", "CarlaPlugins3")
  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. # ------------------------------------------------------------------------------------------------------------