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.

2150 lines
89KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla Backend code
  4. # Copyright (C) 2011-2012 Filipe Coelho <falktx@falktx.com>
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # 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 COPYING file
  17. # Imports (Global)
  18. import json
  19. from PyQt4.QtCore import QThread
  20. from PyQt4.QtGui import QApplication, QMainWindow, QTableWidgetItem
  21. # Imports (Custom Stuff)
  22. import ui_carla, ui_carla_database, ui_carla_refresh
  23. from carla_backend import *
  24. from shared_settings import *
  25. # set defaults
  26. DEFAULT_PROJECT_FOLDER = HOME
  27. setDefaultProjectFolder(DEFAULT_PROJECT_FOLDER)
  28. setDefaultPluginsPaths(LADSPA_PATH, DSSI_PATH, LV2_PATH, VST_PATH, GIG_PATH, SF2_PATH, SFZ_PATH)
  29. # Separate Thread for Plugin Search
  30. class SearchPluginsThread(QThread):
  31. def __init__(self, parent):
  32. QThread.__init__(self, parent)
  33. self.settings_db = self.parent().settings_db
  34. self.check_native = False
  35. self.check_posix32 = False
  36. self.check_posix64 = False
  37. self.check_win32 = False
  38. self.check_win64 = False
  39. self.check_ladspa = False
  40. self.check_dssi = False
  41. self.check_lv2 = False
  42. self.check_vst = False
  43. self.check_gig = False
  44. self.check_sf2 = False
  45. self.check_sfz = False
  46. self.tool_native = carla_discovery_native
  47. def skipPlugin(self):
  48. # TODO - windows and mac support
  49. apps = ""
  50. apps += " carla-discovery"
  51. apps += " carla-discovery-native"
  52. apps += " carla-discovery-posix32"
  53. apps += " carla-discovery-posix64"
  54. apps += " carla-discovery-win32.exe"
  55. apps += " carla-discovery-win64.exe"
  56. if LINUX:
  57. os.system("killall -KILL %s" % apps)
  58. def pluginLook(self, percent, plugin):
  59. self.emit(SIGNAL("PluginLook(int, QString)"), percent, plugin)
  60. def setSearchBinaryTypes(self, native, posix32, posix64, win32, win64):
  61. self.check_native = native
  62. self.check_posix32 = posix32
  63. self.check_posix64 = posix64
  64. self.check_win32 = win32
  65. self.check_win64 = win64
  66. def setSearchPluginTypes(self, ladspa, dssi, lv2, vst, gig, sf2, sfz):
  67. self.check_ladspa = ladspa
  68. self.check_dssi = dssi
  69. self.check_lv2 = lv2
  70. self.check_vst = vst
  71. self.check_gig = gig
  72. self.check_sf2 = sf2
  73. self.check_sfz = sfz
  74. def setSearchToolNative(self, tool):
  75. self.tool_native = tool
  76. def setLastLoadedBinary(self, binary):
  77. self.settings_db.setValue("Plugins/LastLoadedBinary", binary)
  78. def checkLADSPA(self, OS, tool, isWine=False):
  79. global LADSPA_PATH
  80. ladspa_binaries = []
  81. self.ladspa_plugins = []
  82. for iPATH in LADSPA_PATH:
  83. binaries = findBinaries(iPATH, OS)
  84. for binary in binaries:
  85. if binary not in ladspa_binaries:
  86. ladspa_binaries.append(binary)
  87. ladspa_binaries.sort()
  88. for i in range(len(ladspa_binaries)):
  89. ladspa = ladspa_binaries[i]
  90. if os.path.basename(ladspa) in self.blacklist:
  91. print("plugin %s is blacklisted, skip it" % ladspa)
  92. continue
  93. else:
  94. percent = ( float(i) / len(ladspa_binaries) ) * self.m_percent_value
  95. self.pluginLook((self.m_last_value + percent) * 0.9, ladspa)
  96. self.setLastLoadedBinary(ladspa)
  97. plugins = checkPluginLADSPA(ladspa, tool, isWine)
  98. if plugins:
  99. self.ladspa_plugins.append(plugins)
  100. self.m_last_value += self.m_percent_value
  101. self.setLastLoadedBinary("")
  102. def checkDSSI(self, OS, tool, isWine=False):
  103. global DSSI_PATH
  104. dssi_binaries = []
  105. self.dssi_plugins = []
  106. for iPATH in DSSI_PATH:
  107. binaries = findBinaries(iPATH, OS)
  108. for binary in binaries:
  109. if binary not in dssi_binaries:
  110. dssi_binaries.append(binary)
  111. dssi_binaries.sort()
  112. for i in range(len(dssi_binaries)):
  113. dssi = dssi_binaries[i]
  114. if os.path.basename(dssi) in self.blacklist:
  115. print("plugin %s is blacklisted, skip it" % dssi)
  116. continue
  117. else:
  118. percent = ( float(i) / len(dssi_binaries) ) * self.m_percent_value
  119. self.pluginLook(self.m_last_value + percent, dssi)
  120. self.setLastLoadedBinary(dssi)
  121. plugins = checkPluginDSSI(dssi, tool, isWine)
  122. if plugins:
  123. self.dssi_plugins.append(plugins)
  124. self.m_last_value += self.m_percent_value
  125. self.setLastLoadedBinary("")
  126. def checkLV2(self, tool, isWine=False):
  127. global LV2_PATH
  128. lv2_bundles = []
  129. self.lv2_plugins = []
  130. self.pluginLook(self.m_last_value, "LV2 bundles...")
  131. for iPATH in LV2_PATH:
  132. bundles = findLV2Bundles(iPATH)
  133. for bundle in bundles:
  134. if bundle not in lv2_bundles:
  135. lv2_bundles.append(bundle)
  136. lv2_bundles.sort()
  137. for i in range(len(lv2_bundles)):
  138. lv2 = lv2_bundles[i]
  139. if (os.path.basename(lv2) in self.blacklist):
  140. print("bundle %s is blacklisted, skip it" % lv2)
  141. continue
  142. else:
  143. percent = ( float(i) / len(lv2_bundles) ) * self.m_percent_value
  144. self.pluginLook(self.m_last_value + percent, lv2)
  145. self.setLastLoadedBinary(lv2)
  146. plugins = checkPluginLV2(lv2, tool, isWine)
  147. if plugins:
  148. self.lv2_plugins.append(plugins)
  149. self.m_last_value += self.m_percent_value
  150. self.setLastLoadedBinary("")
  151. def checkVST(self, OS, tool, isWine=False):
  152. global VST_PATH
  153. vst_binaries = []
  154. self.vst_plugins = []
  155. for iPATH in VST_PATH:
  156. binaries = findBinaries(iPATH, OS)
  157. for binary in binaries:
  158. if binary not in vst_binaries:
  159. vst_binaries.append(binary)
  160. vst_binaries.sort()
  161. for i in range(len(vst_binaries)):
  162. vst = vst_binaries[i]
  163. if os.path.basename(vst) in self.blacklist:
  164. print("plugin %s is blacklisted, skip it" % vst)
  165. continue
  166. else:
  167. percent = ( float(i) / len(vst_binaries) ) * self.m_percent_value
  168. self.pluginLook(self.m_last_value + percent, vst)
  169. self.setLastLoadedBinary(vst)
  170. plugins = checkPluginVST(vst, tool, isWine)
  171. if plugins:
  172. self.vst_plugins.append(plugins)
  173. self.m_last_value += self.m_percent_value
  174. self.setLastLoadedBinary("")
  175. def checkKIT(self, kPATH, kType):
  176. kit_files = []
  177. self.kit_plugins = []
  178. for iPATH in kPATH:
  179. files = findSoundKits(iPATH, kType)
  180. for file_ in files:
  181. if file_ not in kit_files:
  182. kit_files.append(file_)
  183. kit_files.sort()
  184. for i in range(len(kit_files)):
  185. kit = kit_files[i]
  186. if os.path.basename(kit) in self.blacklist:
  187. print("plugin %s is blacklisted, skip it" % kit)
  188. continue
  189. else:
  190. percent = ( float(i) / len(kit_files) ) * self.m_percent_value
  191. self.pluginLook(self.m_last_value + percent, kit)
  192. self.setLastLoadedBinary(kit)
  193. if kType == "gig":
  194. plugins = checkPluginGIG(kit, self.tool_native)
  195. elif kType == "sf2":
  196. plugins = checkPluginSF2(kit, self.tool_native)
  197. elif kType == "sfz":
  198. plugins = checkPluginSFZ(kit, self.tool_native)
  199. else:
  200. plugins = None
  201. if plugins:
  202. self.kit_plugins.append(plugins)
  203. self.m_last_value += self.m_percent_value
  204. self.setLastLoadedBinary("")
  205. def run(self):
  206. global LADSPA_PATH, DSSI_PATH, LV2_PATH, VST_PATH, GIG_PATH, SF2_PATH, SFZ_PATH
  207. self.blacklist = toList(self.settings_db.value("Plugins/Blacklisted", []))
  208. self.m_count = 0
  209. plugin_count = 0
  210. if self.check_ladspa: plugin_count += 1
  211. if self.check_dssi: plugin_count += 1
  212. if self.check_lv2: plugin_count += 1
  213. if self.check_vst: plugin_count += 1
  214. if self.check_native:
  215. self.m_count += plugin_count
  216. if self.check_posix32:
  217. self.m_count += plugin_count
  218. if self.check_posix64:
  219. self.m_count += plugin_count
  220. if self.check_win32:
  221. self.m_count += plugin_count
  222. if self.check_win64:
  223. self.m_count += plugin_count
  224. if self.tool_native:
  225. if self.check_gig: self.m_count += 1
  226. if self.check_sf2: self.m_count += 1
  227. if self.check_sfz: self.m_count += 1
  228. else:
  229. self.check_gig = False
  230. self.check_sf2 = False
  231. self.check_sfz = False
  232. if self.m_count == 0:
  233. return
  234. self.m_last_value = 0
  235. self.m_percent_value = 100 / self.m_count
  236. if HAIKU:
  237. OS = "HAIKU"
  238. elif LINUX:
  239. OS = "LINUX"
  240. elif MACOS:
  241. OS = "MACOS"
  242. elif WINDOWS:
  243. OS = "WINDOWS"
  244. else:
  245. OS = "UNKNOWN"
  246. if self.check_ladspa:
  247. m_value = 0
  248. if haveLRDF:
  249. if self.check_native: m_value += 0.1
  250. if self.check_posix32: m_value += 0.1
  251. if self.check_posix64: m_value += 0.1
  252. if self.check_win32: m_value += 0.1
  253. if self.check_win64: m_value += 0.1
  254. rdf_pad_value = self.m_percent_value * m_value
  255. if self.check_native:
  256. self.checkLADSPA(OS, carla_discovery_native)
  257. self.settings_db.setValue("Plugins/LADSPA_native", self.ladspa_plugins)
  258. self.settings_db.sync()
  259. if self.check_posix32:
  260. self.checkLADSPA(OS, carla_discovery_posix32)
  261. self.settings_db.setValue("Plugins/LADSPA_posix32", self.ladspa_plugins)
  262. self.settings_db.sync()
  263. if self.check_posix64:
  264. self.checkLADSPA(OS, carla_discovery_posix64)
  265. self.settings_db.setValue("Plugins/LADSPA_posix64", self.ladspa_plugins)
  266. self.settings_db.sync()
  267. if self.check_win32:
  268. self.checkLADSPA("WINDOWS", carla_discovery_win32, not WINDOWS)
  269. self.settings_db.setValue("Plugins/LADSPA_win32", self.ladspa_plugins)
  270. self.settings_db.sync()
  271. if self.check_win64:
  272. self.checkLADSPA("WINDOWS", carla_discovery_win64, not WINDOWS)
  273. self.settings_db.setValue("Plugins/LADSPA_win64", self.ladspa_plugins)
  274. self.settings_db.sync()
  275. if haveLRDF:
  276. if m_value > 0:
  277. start_value = self.m_last_value - rdf_pad_value
  278. self.pluginLook(start_value, "LADSPA RDFs...")
  279. ladspa_rdf_info = ladspa_rdf.recheck_all_plugins(self, start_value, self.m_percent_value, m_value)
  280. SettingsDir = os.path.join(HOME, ".config", "Cadence")
  281. f_ladspa = open(os.path.join(SettingsDir, "ladspa_rdf.db"), 'w')
  282. json.dump(ladspa_rdf_info, f_ladspa)
  283. f_ladspa.close()
  284. if self.check_dssi:
  285. if self.check_native:
  286. self.checkDSSI(OS, carla_discovery_native)
  287. self.settings_db.setValue("Plugins/DSSI_native", self.dssi_plugins)
  288. self.settings_db.sync()
  289. if self.check_posix32:
  290. self.checkDSSI(OS, carla_discovery_posix32)
  291. self.settings_db.setValue("Plugins/DSSI_posix32", self.dssi_plugins)
  292. self.settings_db.sync()
  293. if self.check_posix64:
  294. self.checkDSSI(OS, carla_discovery_posix64)
  295. self.settings_db.setValue("Plugins/DSSI_posix64", self.dssi_plugins)
  296. self.settings_db.sync()
  297. if self.check_win32:
  298. self.checkDSSI("WINDOWS", carla_discovery_win32, not WINDOWS)
  299. self.settings_db.setValue("Plugins/DSSI_win32", self.dssi_plugins)
  300. self.settings_db.sync()
  301. if self.check_win64:
  302. self.checkDSSI("WINDOWS", carla_discovery_win64, not WINDOWS)
  303. self.settings_db.setValue("Plugins/DSSI_win64", self.dssi_plugins)
  304. self.settings_db.sync()
  305. if self.check_lv2:
  306. if self.check_native:
  307. self.checkLV2(carla_discovery_native)
  308. self.settings_db.setValue("Plugins/LV2_native", self.lv2_plugins)
  309. self.settings_db.sync()
  310. if self.check_posix32:
  311. self.checkLV2(carla_discovery_posix32)
  312. self.settings_db.setValue("Plugins/LV2_posix32", self.lv2_plugins)
  313. self.settings_db.sync()
  314. if self.check_posix64:
  315. self.checkLV2(carla_discovery_posix64)
  316. self.settings_db.setValue("Plugins/LV2_posix64", self.lv2_plugins)
  317. self.settings_db.sync()
  318. if self.check_win32:
  319. self.checkLV2(carla_discovery_win32, not WINDOWS)
  320. self.settings_db.setValue("Plugins/LV2_win32", self.lv2_plugins)
  321. self.settings_db.sync()
  322. if self.check_win64:
  323. self.checkLV2(carla_discovery_win64, not WINDOWS)
  324. self.settings_db.setValue("Plugins/LV2_win64", self.lv2_plugins)
  325. self.settings_db.sync()
  326. if self.check_vst:
  327. if self.check_native:
  328. self.checkVST(OS, carla_discovery_native)
  329. self.settings_db.setValue("Plugins/VST_native", self.vst_plugins)
  330. self.settings_db.sync()
  331. if self.check_posix32:
  332. self.checkVST(OS, carla_discovery_posix32)
  333. self.settings_db.setValue("Plugins/VST_posix32", self.vst_plugins)
  334. self.settings_db.sync()
  335. if self.check_posix64:
  336. self.checkVST(OS, carla_discovery_posix64)
  337. self.settings_db.setValue("Plugins/VST_posix64", self.vst_plugins)
  338. self.settings_db.sync()
  339. if self.check_win32:
  340. self.checkVST("WINDOWS", carla_discovery_win32, not WINDOWS)
  341. self.settings_db.setValue("Plugins/VST_win32", self.vst_plugins)
  342. self.settings_db.sync()
  343. if self.check_win64:
  344. self.checkVST("WINDOWS", carla_discovery_win64, not WINDOWS)
  345. self.settings_db.setValue("Plugins/VST_win64", self.vst_plugins)
  346. self.settings_db.sync()
  347. if self.check_gig:
  348. self.checkKIT(GIG_PATH, "gig")
  349. self.settings_db.setValue("Plugins/GIG", self.kit_plugins)
  350. self.settings_db.sync()
  351. if self.check_sf2:
  352. self.checkKIT(SF2_PATH, "sf2")
  353. self.settings_db.setValue("Plugins/SF2", self.kit_plugins)
  354. self.settings_db.sync()
  355. if self.check_sfz:
  356. self.checkKIT(SFZ_PATH, "sfz")
  357. self.settings_db.setValue("Plugins/SFZ", self.kit_plugins)
  358. self.settings_db.sync()
  359. # Plugin Refresh Dialog
  360. class PluginRefreshW(QDialog, ui_carla_refresh.Ui_PluginRefreshW):
  361. def __init__(self, parent):
  362. QDialog.__init__(self, parent)
  363. self.setupUi(self)
  364. self.b_skip.setVisible(False)
  365. if HAIKU:
  366. self.ch_posix32.setText("Haiku 32bit")
  367. self.ch_posix64.setText("Haiku 64bit")
  368. elif LINUX:
  369. self.ch_posix32.setText("Linux 32bit")
  370. self.ch_posix64.setText("Linux 64bit")
  371. elif MACOS:
  372. self.ch_posix32.setText("MacOS 32bit")
  373. self.ch_posix64.setText("MacOS 64bit")
  374. self.settings = self.parent().settings
  375. self.settings_db = self.parent().settings_db
  376. self.loadSettings()
  377. self.pThread = SearchPluginsThread(self)
  378. if carla_discovery_posix32 and not WINDOWS:
  379. self.ico_posix32.setPixmap(getIcon("dialog-ok-apply").pixmap(16, 16))
  380. else:
  381. self.ico_posix32.setPixmap(getIcon("dialog-error").pixmap(16, 16))
  382. self.ch_posix32.setChecked(False)
  383. self.ch_posix32.setEnabled(False)
  384. if carla_discovery_posix64 and not WINDOWS:
  385. self.ico_posix64.setPixmap(getIcon("dialog-ok-apply").pixmap(16, 16))
  386. else:
  387. self.ico_posix64.setPixmap(getIcon("dialog-error").pixmap(16, 16))
  388. self.ch_posix64.setChecked(False)
  389. self.ch_posix64.setEnabled(False)
  390. if carla_discovery_win32:
  391. self.ico_win32.setPixmap(getIcon("dialog-ok-apply").pixmap(16, 16))
  392. else:
  393. self.ico_win32.setPixmap(getIcon("dialog-error").pixmap(16, 16))
  394. self.ch_win32.setChecked(False)
  395. self.ch_win32.setEnabled(False)
  396. if carla_discovery_win64:
  397. self.ico_win64.setPixmap(getIcon("dialog-ok-apply").pixmap(16, 16))
  398. else:
  399. self.ico_win64.setPixmap(getIcon("dialog-error").pixmap(16, 16))
  400. self.ch_win64.setChecked(False)
  401. self.ch_win64.setEnabled(False)
  402. if haveLRDF:
  403. self.ico_rdflib.setPixmap(getIcon("dialog-ok-apply").pixmap(16, 16))
  404. else:
  405. self.ico_rdflib.setPixmap(getIcon("dialog-error").pixmap(16, 16))
  406. hasNative = bool(carla_discovery_native)
  407. hasNonNative = False
  408. if WINDOWS:
  409. if is64bit:
  410. hasNative = bool(carla_discovery_win64)
  411. hasNonNative = bool(carla_discovery_win32)
  412. self.pThread.setSearchToolNative(carla_discovery_win64)
  413. self.ch_win64.setChecked(False)
  414. self.ch_win64.setVisible(False)
  415. self.ico_win64.setVisible(False)
  416. self.label_win64.setVisible(False)
  417. else:
  418. hasNative = bool(carla_discovery_win32)
  419. hasNonNative = bool(carla_discovery_win64)
  420. self.pThread.setSearchToolNative(carla_discovery_win32)
  421. self.ch_win32.setChecked(False)
  422. self.ch_win32.setVisible(False)
  423. self.ico_win32.setVisible(False)
  424. self.label_win32.setVisible(False)
  425. elif LINUX or MACOS:
  426. if is64bit:
  427. hasNonNative = bool(carla_discovery_posix32 or carla_discovery_win32 or carla_discovery_win64)
  428. self.ch_posix64.setChecked(False)
  429. self.ch_posix64.setVisible(False)
  430. self.ico_posix64.setVisible(False)
  431. self.label_posix64.setVisible(False)
  432. else:
  433. hasNonNative = bool(carla_discovery_posix64 or carla_discovery_win32 or carla_discovery_win64)
  434. self.ch_posix32.setChecked(False)
  435. self.ch_posix32.setVisible(False)
  436. self.ico_posix32.setVisible(False)
  437. self.label_posix32.setVisible(False)
  438. if hasNative:
  439. self.ico_native.setPixmap(getIcon("dialog-ok-apply").pixmap(16, 16))
  440. else:
  441. self.ico_native.setPixmap(getIcon("dialog-error").pixmap(16, 16))
  442. self.ch_native.setChecked(False)
  443. self.ch_native.setEnabled(False)
  444. self.ch_gig.setChecked(False)
  445. self.ch_gig.setEnabled(False)
  446. self.ch_sf2.setChecked(False)
  447. self.ch_sf2.setEnabled(False)
  448. self.ch_sfz.setChecked(False)
  449. self.ch_sfz.setEnabled(False)
  450. if not hasNonNative:
  451. self.ch_ladspa.setChecked(False)
  452. self.ch_ladspa.setEnabled(False)
  453. self.ch_dssi.setChecked(False)
  454. self.ch_dssi.setEnabled(False)
  455. self.ch_vst.setChecked(False)
  456. self.ch_vst.setEnabled(False)
  457. self.b_start.setEnabled(False)
  458. self.connect(self.b_start, SIGNAL("clicked()"), SLOT("slot_start()"))
  459. self.connect(self.b_skip, SIGNAL("clicked()"), SLOT("slot_skip()"))
  460. self.connect(self.pThread, SIGNAL("PluginLook(int, QString)"), SLOT("slot_handlePluginLook(int, QString)"))
  461. self.connect(self.pThread, SIGNAL("finished()"), SLOT("slot_handlePluginThreadFinished()"))
  462. @pyqtSlot()
  463. def slot_start(self):
  464. self.progressBar.setMinimum(0)
  465. self.progressBar.setMaximum(100)
  466. self.progressBar.setValue(0)
  467. self.b_start.setEnabled(False)
  468. self.b_skip.setVisible(True)
  469. self.b_close.setVisible(False)
  470. native, posix32, posix64, win32, win64 = (self.ch_native.isChecked(), self.ch_posix32.isChecked(), self.ch_posix64.isChecked(), self.ch_win32.isChecked(), self.ch_win64.isChecked())
  471. ladspa, dssi, lv2, vst, gig, sf2, sfz = (self.ch_ladspa.isChecked(), self.ch_dssi.isChecked(), self.ch_lv2.isChecked(), self.ch_vst.isChecked(),
  472. self.ch_gig.isChecked(), self.ch_sf2.isChecked(), self.ch_sfz.isChecked())
  473. self.pThread.setSearchBinaryTypes(native, posix32, posix64, win32, win64)
  474. self.pThread.setSearchPluginTypes(ladspa, dssi, lv2, vst, gig, sf2, sfz)
  475. self.pThread.start()
  476. @pyqtSlot()
  477. def slot_skip(self):
  478. self.pThread.skipPlugin()
  479. @pyqtSlot(int, str)
  480. def slot_handlePluginLook(self, percent, plugin):
  481. self.progressBar.setFormat("%s" % plugin)
  482. self.progressBar.setValue(percent)
  483. @pyqtSlot()
  484. def slot_handlePluginThreadFinished(self):
  485. self.progressBar.setMinimum(0)
  486. self.progressBar.setMaximum(1)
  487. self.progressBar.setValue(1)
  488. self.progressBar.setFormat(self.tr("Done"))
  489. self.b_start.setEnabled(True)
  490. self.b_skip.setVisible(False)
  491. self.b_close.setVisible(True)
  492. def saveSettings(self):
  493. self.settings.setValue("PluginDatabase/SearchLADSPA", self.ch_ladspa.isChecked())
  494. self.settings.setValue("PluginDatabase/SearchDSSI", self.ch_dssi.isChecked())
  495. self.settings.setValue("PluginDatabase/SearchLV2", self.ch_lv2.isChecked())
  496. self.settings.setValue("PluginDatabase/SearchVST", self.ch_vst.isChecked())
  497. self.settings.setValue("PluginDatabase/SearchGIG", self.ch_gig.isChecked())
  498. self.settings.setValue("PluginDatabase/SearchSF2", self.ch_sf2.isChecked())
  499. self.settings.setValue("PluginDatabase/SearchSFZ", self.ch_sfz.isChecked())
  500. self.settings.setValue("PluginDatabase/SearchNative", self.ch_native.isChecked())
  501. self.settings.setValue("PluginDatabase/SearchPOSIX32", self.ch_posix32.isChecked())
  502. self.settings.setValue("PluginDatabase/SearchPOSIX64", self.ch_posix64.isChecked())
  503. self.settings.setValue("PluginDatabase/SearchWin32", self.ch_win32.isChecked())
  504. self.settings.setValue("PluginDatabase/SearchWin64", self.ch_win64.isChecked())
  505. self.settings_db.setValue("Plugins/LastLoadedBinary", "")
  506. def loadSettings(self):
  507. self.ch_ladspa.setChecked(self.settings.value("PluginDatabase/SearchLADSPA", True, type=bool))
  508. self.ch_dssi.setChecked(self.settings.value("PluginDatabase/SearchDSSI", True, type=bool))
  509. self.ch_lv2.setChecked(self.settings.value("PluginDatabase/SearchLV2", True, type=bool))
  510. self.ch_vst.setChecked(self.settings.value("PluginDatabase/SearchVST", True, type=bool))
  511. self.ch_gig.setChecked(self.settings.value("PluginDatabase/SearchGIG", True, type=bool))
  512. self.ch_sf2.setChecked(self.settings.value("PluginDatabase/SearchSF2", True, type=bool))
  513. self.ch_sfz.setChecked(self.settings.value("PluginDatabase/SearchSFZ", True, type=bool))
  514. self.ch_native.setChecked(self.settings.value("PluginDatabase/SearchNative", True, type=bool))
  515. self.ch_posix32.setChecked(self.settings.value("PluginDatabase/SearchPOSIX32", False, type=bool))
  516. self.ch_posix64.setChecked(self.settings.value("PluginDatabase/SearchPOSIX64", False, type=bool))
  517. self.ch_win32.setChecked(self.settings.value("PluginDatabase/SearchWin32", False, type=bool))
  518. self.ch_win64.setChecked(self.settings.value("PluginDatabase/SearchWin64", False, type=bool))
  519. def closeEvent(self, event):
  520. if self.pThread.isRunning():
  521. self.pThread.terminate()
  522. self.pThread.wait()
  523. self.saveSettings()
  524. QDialog.closeEvent(self, event)
  525. def done(self, r):
  526. QDialog.done(self, r)
  527. self.close()
  528. # Plugin Database Dialog
  529. class PluginDatabaseW(QDialog, ui_carla_database.Ui_PluginDatabaseW):
  530. def __init__(self, parent):
  531. QDialog.__init__(self, parent)
  532. self.setupUi(self)
  533. self.m_showOldWarning = False
  534. self.settings = self.parent().settings
  535. self.settings_db = self.parent().settings_db
  536. self.loadSettings()
  537. self.b_add.setEnabled(False)
  538. if BINARY_NATIVE in (BINARY_POSIX32, BINARY_WIN32):
  539. self.ch_bridged.setText(self.tr("Bridged (64bit)"))
  540. else:
  541. self.ch_bridged.setText(self.tr("Bridged (32bit)"))
  542. if not (LINUX or MACOS):
  543. self.ch_bridged_wine.setChecked(False)
  544. self.ch_bridged_wine.setEnabled(False)
  545. # Blacklist plugins
  546. if not self.settings_db.contains("Plugins/Blacklisted"):
  547. blacklist = [] # FIXME
  548. # Broken or useless plugins
  549. #blacklist.append("dssi-vst.so")
  550. blacklist.append("liteon_biquad-vst.so")
  551. blacklist.append("liteon_biquad-vst_64bit.so")
  552. blacklist.append("fx_blur-vst.so")
  553. blacklist.append("fx_blur-vst_64bit.so")
  554. blacklist.append("fx_tempodelay-vst.so")
  555. blacklist.append("Scrubby_64bit.so")
  556. blacklist.append("Skidder_64bit.so")
  557. blacklist.append("libwormhole2_64bit.so")
  558. blacklist.append("vexvst.so")
  559. #blacklist.append("deckadance.dll")
  560. self.settings_db.setValue("Plugins/Blacklisted", blacklist)
  561. self.connect(self.b_add, SIGNAL("clicked()"), SLOT("slot_add_plugin()"))
  562. self.connect(self.b_refresh, SIGNAL("clicked()"), SLOT("slot_refresh_plugins()"))
  563. self.connect(self.tb_filters, SIGNAL("clicked()"), SLOT("slot_maybe_show_filters()"))
  564. self.connect(self.tableWidget, SIGNAL("currentCellChanged(int, int, int, int)"), SLOT("slot_checkPlugin(int)"))
  565. self.connect(self.tableWidget, SIGNAL("cellDoubleClicked(int, int)"), SLOT("slot_add_plugin()"))
  566. self.connect(self.lineEdit, SIGNAL("textChanged(QString)"), SLOT("slot_checkFilters()"))
  567. self.connect(self.ch_effects, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  568. self.connect(self.ch_instruments, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  569. self.connect(self.ch_midi, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  570. self.connect(self.ch_other, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  571. self.connect(self.ch_kits, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  572. self.connect(self.ch_internal, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  573. self.connect(self.ch_ladspa, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  574. self.connect(self.ch_dssi, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  575. self.connect(self.ch_lv2, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  576. self.connect(self.ch_vst, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  577. self.connect(self.ch_native, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  578. self.connect(self.ch_bridged, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  579. self.connect(self.ch_bridged_wine, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  580. self.connect(self.ch_gui, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  581. self.connect(self.ch_stereo, SIGNAL("clicked()"), SLOT("slot_checkFilters()"))
  582. self.ret_plugin = None
  583. if self.m_showOldWarning:
  584. QTimer.singleShot(0, self, SLOT("slot_showOldWarning()"))
  585. def showFilters(self, yesno):
  586. self.tb_filters.setArrowType(Qt.UpArrow if yesno else Qt.DownArrow)
  587. self.frame.setVisible(yesno)
  588. def checkInternalPlugins(self):
  589. internals = toList(self.settings_db.value("Plugins/Internal", []))
  590. count = 0
  591. for plugins in internals:
  592. for x in plugins:
  593. count += 1
  594. if count != Carla.host.get_internal_plugin_count():
  595. internal_plugins = []
  596. for i in range(Carla.host.get_internal_plugin_count()):
  597. descInfo = Carla.host.get_internal_plugin_info(i)
  598. plugins = checkPluginInternal(descInfo)
  599. if plugins:
  600. internal_plugins.append(plugins)
  601. self.settings_db.setValue("Plugins/Internal", internal_plugins)
  602. self.settings_db.sync()
  603. def reAddPlugins(self):
  604. row_count = self.tableWidget.rowCount()
  605. for x in range(row_count):
  606. self.tableWidget.removeRow(0)
  607. self.last_table_index = 0
  608. self.tableWidget.setSortingEnabled(False)
  609. self.checkInternalPlugins()
  610. internals = toList(self.settings_db.value("Plugins/Internal", []))
  611. ladspa_plugins = []
  612. ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_native", []))
  613. ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_posix32", []))
  614. ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_posix64", []))
  615. ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_win32", []))
  616. ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_win64", []))
  617. dssi_plugins = []
  618. dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_native", []))
  619. dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_posix32", []))
  620. dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_posix64", []))
  621. dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_win32", []))
  622. dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_win64", []))
  623. lv2_plugins = []
  624. lv2_plugins += toList(self.settings_db.value("Plugins/LV2_native", []))
  625. lv2_plugins += toList(self.settings_db.value("Plugins/LV2_posix32", []))
  626. lv2_plugins += toList(self.settings_db.value("Plugins/LV2_posix64", []))
  627. lv2_plugins += toList(self.settings_db.value("Plugins/LV2_win32", []))
  628. lv2_plugins += toList(self.settings_db.value("Plugins/LV2_win64", []))
  629. vst_plugins = []
  630. vst_plugins += toList(self.settings_db.value("Plugins/VST_native", []))
  631. vst_plugins += toList(self.settings_db.value("Plugins/VST_posix32", []))
  632. vst_plugins += toList(self.settings_db.value("Plugins/VST_posix64", []))
  633. vst_plugins += toList(self.settings_db.value("Plugins/VST_win32", []))
  634. vst_plugins += toList(self.settings_db.value("Plugins/VST_win64", []))
  635. gigs = toList(self.settings_db.value("Plugins/GIG", []))
  636. sf2s = toList(self.settings_db.value("Plugins/SF2", []))
  637. sfzs = toList(self.settings_db.value("Plugins/SFZ", []))
  638. internal_count = 0
  639. ladspa_count = 0
  640. dssi_count = 0
  641. lv2_count = 0
  642. vst_count = 0
  643. kit_count = 0
  644. for plugins in internals:
  645. for plugin in plugins:
  646. self.addPluginToTable(plugin, self.tr("Internal"))
  647. internal_count += 1
  648. for plugins in ladspa_plugins:
  649. for plugin in plugins:
  650. self.addPluginToTable(plugin, "LADSPA")
  651. ladspa_count += 1
  652. for plugins in dssi_plugins:
  653. for plugin in plugins:
  654. self.addPluginToTable(plugin, "DSSI")
  655. dssi_count += 1
  656. for plugins in lv2_plugins:
  657. for plugin in plugins:
  658. self.addPluginToTable(plugin, "LV2")
  659. lv2_count += 1
  660. for plugins in vst_plugins:
  661. for plugin in plugins:
  662. self.addPluginToTable(plugin, "VST")
  663. vst_count += 1
  664. for gig in gigs:
  665. for gig_i in gig:
  666. self.addPluginToTable(gig_i, "GIG")
  667. kit_count += 1
  668. for sf2 in sf2s:
  669. for sf2_i in sf2:
  670. self.addPluginToTable(sf2_i, "SF2")
  671. kit_count += 1
  672. for sfz in sfzs:
  673. for sfz_i in sfz:
  674. self.addPluginToTable(sfz_i, "SFZ")
  675. kit_count += 1
  676. self.slot_checkFilters()
  677. self.tableWidget.setSortingEnabled(True)
  678. self.tableWidget.sortByColumn(0, Qt.AscendingOrder)
  679. self.label.setText(self.tr("Have %i %s, %i LADSPA, %i DSSI, %i LV2, %i VST and %i Sound Kits" % (internal_count, self.tr("Internal"), ladspa_count, dssi_count, lv2_count, vst_count, kit_count)))
  680. def addPluginToTable(self, plugin, ptype):
  681. index = self.last_table_index
  682. if self.m_showOldWarning or 'API' not in plugin.keys() or plugin['API'] < PLUGIN_QUERY_API_VERSION:
  683. self.m_showOldWarning = True
  684. return
  685. if plugin['build'] == BINARY_NATIVE:
  686. bridge_text = self.tr("No")
  687. else:
  688. type_text = self.tr("Unknown")
  689. if LINUX or MACOS:
  690. if plugin['build'] == BINARY_POSIX32:
  691. type_text = "32bit"
  692. elif plugin['build'] == BINARY_POSIX64:
  693. type_text = "64bit"
  694. elif plugin['build'] == BINARY_WIN32:
  695. type_text = "Windows 32bit"
  696. elif plugin['build'] == BINARY_WIN64:
  697. type_text = "Windows 64bit"
  698. elif WINDOWS:
  699. if plugin['build'] == BINARY_WIN32:
  700. type_text = "32bit"
  701. elif plugin['build'] == BINARY_WIN64:
  702. type_text = "64bit"
  703. bridge_text = self.tr("Yes (%s)" % type_text)
  704. self.tableWidget.insertRow(index)
  705. self.tableWidget.setItem(index, 0, QTableWidgetItem(plugin['name']))
  706. self.tableWidget.setItem(index, 1, QTableWidgetItem(plugin['label']))
  707. self.tableWidget.setItem(index, 2, QTableWidgetItem(plugin['maker']))
  708. self.tableWidget.setItem(index, 3, QTableWidgetItem(str(plugin['unique_id'])))
  709. self.tableWidget.setItem(index, 4, QTableWidgetItem(str(plugin['audio.ins'])))
  710. self.tableWidget.setItem(index, 5, QTableWidgetItem(str(plugin['audio.outs'])))
  711. self.tableWidget.setItem(index, 6, QTableWidgetItem(str(plugin['parameters.ins'])))
  712. self.tableWidget.setItem(index, 7, QTableWidgetItem(str(plugin['parameters.outs'])))
  713. self.tableWidget.setItem(index, 8, QTableWidgetItem(str(plugin['programs.total'])))
  714. self.tableWidget.setItem(index, 9, QTableWidgetItem(self.tr("Yes") if (plugin['hints'] & PLUGIN_HAS_GUI) else self.tr("No")))
  715. self.tableWidget.setItem(index, 10, QTableWidgetItem(self.tr("Yes") if (plugin['hints'] & PLUGIN_IS_SYNTH) else self.tr("No")))
  716. self.tableWidget.setItem(index, 11, QTableWidgetItem(bridge_text))
  717. self.tableWidget.setItem(index, 12, QTableWidgetItem(ptype))
  718. self.tableWidget.setItem(index, 13, QTableWidgetItem(plugin['binary']))
  719. self.tableWidget.item(self.last_table_index, 0).plugin_data = plugin
  720. self.last_table_index += 1
  721. @pyqtSlot()
  722. def slot_add_plugin(self):
  723. if self.tableWidget.currentRow() >= 0:
  724. self.ret_plugin = self.tableWidget.item(self.tableWidget.currentRow(), 0).plugin_data
  725. self.accept()
  726. else:
  727. self.reject()
  728. @pyqtSlot()
  729. def slot_refresh_plugins(self):
  730. lastLoadedPlugin = self.settings_db.value("Plugins/LastLoadedBinary", "", type=str)
  731. if lastLoadedPlugin:
  732. lastLoadedPlugin = os.path.basename(lastLoadedPlugin)
  733. ask = QMessageBox.question(self, self.tr("Warning"), self.tr("There was an error while checking the plugin %s.\n"
  734. "Do you want to blacklist it?" % lastLoadedPlugin),
  735. QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
  736. if ask == QMessageBox.Yes:
  737. blacklist = toList(self.settings_db.value("Plugins/Blacklisted", []))
  738. blacklist.append(lastLoadedPlugin)
  739. self.settings_db.setValue("Plugins/Blacklisted", blacklist)
  740. #self.label.setText(self.tr("Looking for plugins..."))
  741. PluginRefreshW(self).exec_()
  742. self.reAddPlugins()
  743. self.parent().loadRDFs()
  744. @pyqtSlot()
  745. def slot_maybe_show_filters(self):
  746. self.showFilters(not self.frame.isVisible())
  747. @pyqtSlot(int)
  748. def slot_checkPlugin(self, row):
  749. self.b_add.setEnabled(row >= 0)
  750. @pyqtSlot()
  751. def slot_checkFilters(self):
  752. text = self.lineEdit.text().lower()
  753. hide_effects = not self.ch_effects.isChecked()
  754. hide_instruments = not self.ch_instruments.isChecked()
  755. hide_midi = not self.ch_midi.isChecked()
  756. hide_other = not self.ch_other.isChecked()
  757. hide_internal = not self.ch_internal.isChecked()
  758. hide_ladspa = not self.ch_ladspa.isChecked()
  759. hide_dssi = not self.ch_dssi.isChecked()
  760. hide_lv2 = not self.ch_lv2.isChecked()
  761. hide_vst = not self.ch_vst.isChecked()
  762. hide_kits = not self.ch_kits.isChecked()
  763. hide_native = not self.ch_native.isChecked()
  764. hide_bridged = not self.ch_bridged.isChecked()
  765. hide_bridged_wine = not self.ch_bridged_wine.isChecked()
  766. hide_non_gui = self.ch_gui.isChecked()
  767. hide_non_stereo = self.ch_stereo.isChecked()
  768. if HAIKU or LINUX or MACOS:
  769. native_bins = [BINARY_POSIX32, BINARY_POSIX64]
  770. wine_bins = [BINARY_WIN32, BINARY_WIN64]
  771. elif WINDOWS:
  772. native_bins = [BINARY_WIN32, BINARY_WIN64]
  773. wine_bins = []
  774. else:
  775. native_bins = []
  776. wine_bins = []
  777. row_count = self.tableWidget.rowCount()
  778. for i in range(row_count):
  779. self.tableWidget.showRow(i)
  780. plugin = self.tableWidget.item(i, 0).plugin_data
  781. ains = plugin['audio.ins']
  782. aouts = plugin['audio.outs']
  783. mins = plugin['midi.ins']
  784. mouts = plugin['midi.outs']
  785. ptype = self.tableWidget.item(i, 12).text()
  786. is_synth = bool(plugin['hints'] & PLUGIN_IS_SYNTH)
  787. is_effect = bool(ains > 0 < aouts and not is_synth)
  788. is_midi = bool(ains == 0 and aouts == 0 and mins > 0 < mouts)
  789. is_kit = bool(ptype in ("GIG", "SF2", "SFZ"))
  790. is_other = bool(not (is_effect or is_synth or is_midi or is_kit))
  791. is_native = bool(plugin['build'] == BINARY_NATIVE)
  792. is_stereo = bool(ains == 2 and aouts == 2) or (is_synth and aouts == 2)
  793. has_gui = bool(plugin['hints'] & PLUGIN_HAS_GUI)
  794. is_bridged = bool(not is_native and plugin['build'] in native_bins)
  795. is_bridged_wine = bool(not is_native and plugin['build'] in wine_bins)
  796. if (hide_effects and is_effect):
  797. self.tableWidget.hideRow(i)
  798. elif (hide_instruments and is_synth):
  799. self.tableWidget.hideRow(i)
  800. elif (hide_midi and is_midi):
  801. self.tableWidget.hideRow(i)
  802. elif (hide_other and is_other):
  803. self.tableWidget.hideRow(i)
  804. elif (hide_kits and is_kit):
  805. self.tableWidget.hideRow(i)
  806. elif (hide_internal and ptype == self.tr("Internal")):
  807. self.tableWidget.hideRow(i)
  808. elif (hide_ladspa and ptype == "LADSPA"):
  809. self.tableWidget.hideRow(i)
  810. elif (hide_dssi and ptype == "DSSI"):
  811. self.tableWidget.hideRow(i)
  812. elif (hide_lv2 and ptype == "LV2"):
  813. self.tableWidget.hideRow(i)
  814. elif (hide_vst and ptype == "VST"):
  815. self.tableWidget.hideRow(i)
  816. elif (hide_native and is_native):
  817. self.tableWidget.hideRow(i)
  818. elif (hide_bridged and is_bridged):
  819. self.tableWidget.hideRow(i)
  820. elif (hide_bridged_wine and is_bridged_wine):
  821. self.tableWidget.hideRow(i)
  822. elif (hide_non_gui and not has_gui):
  823. self.tableWidget.hideRow(i)
  824. elif (hide_non_stereo and not is_stereo):
  825. self.tableWidget.hideRow(i)
  826. elif (text and not (
  827. text in self.tableWidget.item(i, 0).text().lower() or
  828. text in self.tableWidget.item(i, 1).text().lower() or
  829. text in self.tableWidget.item(i, 2).text().lower() or
  830. text in self.tableWidget.item(i, 3).text().lower() or
  831. text in self.tableWidget.item(i, 13).text().lower())):
  832. self.tableWidget.hideRow(i)
  833. @pyqtSlot()
  834. def slot_showOldWarning(self):
  835. QMessageBox.warning(self, self.tr("Warning"), self.tr("You're using a Carla-Database from an old version of Carla, please update *all* the plugins"))
  836. def saveSettings(self):
  837. self.settings.setValue("PluginDatabase/Geometry", self.saveGeometry())
  838. self.settings.setValue("PluginDatabase/TableGeometry", self.tableWidget.horizontalHeader().saveState())
  839. self.settings.setValue("PluginDatabase/ShowFilters", (self.tb_filters.arrowType() == Qt.UpArrow))
  840. self.settings.setValue("PluginDatabase/ShowEffects", self.ch_effects.isChecked())
  841. self.settings.setValue("PluginDatabase/ShowInstruments", self.ch_instruments.isChecked())
  842. self.settings.setValue("PluginDatabase/ShowMIDI", self.ch_midi.isChecked())
  843. self.settings.setValue("PluginDatabase/ShowOther", self.ch_other.isChecked())
  844. self.settings.setValue("PluginDatabase/ShowInternal", self.ch_internal.isChecked())
  845. self.settings.setValue("PluginDatabase/ShowLADSPA", self.ch_ladspa.isChecked())
  846. self.settings.setValue("PluginDatabase/ShowDSSI", self.ch_dssi.isChecked())
  847. self.settings.setValue("PluginDatabase/ShowLV2", self.ch_lv2.isChecked())
  848. self.settings.setValue("PluginDatabase/ShowVST", self.ch_vst.isChecked())
  849. self.settings.setValue("PluginDatabase/ShowKits", self.ch_kits.isChecked())
  850. self.settings.setValue("PluginDatabase/ShowNative", self.ch_native.isChecked())
  851. self.settings.setValue("PluginDatabase/ShowBridged", self.ch_bridged.isChecked())
  852. self.settings.setValue("PluginDatabase/ShowBridgedWine", self.ch_bridged_wine.isChecked())
  853. self.settings.setValue("PluginDatabase/ShowHasGUI", self.ch_gui.isChecked())
  854. self.settings.setValue("PluginDatabase/ShowStereoOnly", self.ch_stereo.isChecked())
  855. def loadSettings(self):
  856. self.restoreGeometry(self.settings.value("PluginDatabase/Geometry", ""))
  857. self.tableWidget.horizontalHeader().restoreState(self.settings.value("PluginDatabase/TableGeometry", ""))
  858. self.showFilters(self.settings.value("PluginDatabase/ShowFilters", False, type=bool))
  859. self.ch_effects.setChecked(self.settings.value("PluginDatabase/ShowEffects", True, type=bool))
  860. self.ch_instruments.setChecked(self.settings.value("PluginDatabase/ShowInstruments", True, type=bool))
  861. self.ch_midi.setChecked(self.settings.value("PluginDatabase/ShowMIDI", True, type=bool))
  862. self.ch_other.setChecked(self.settings.value("PluginDatabase/ShowOther", True, type=bool))
  863. self.ch_internal.setChecked(self.settings.value("PluginDatabase/ShowInternal", True, type=bool))
  864. self.ch_ladspa.setChecked(self.settings.value("PluginDatabase/ShowLADSPA", True, type=bool))
  865. self.ch_dssi.setChecked(self.settings.value("PluginDatabase/ShowDSSI", True, type=bool))
  866. self.ch_lv2.setChecked(self.settings.value("PluginDatabase/ShowLV2", True, type=bool))
  867. self.ch_vst.setChecked(self.settings.value("PluginDatabase/ShowVST", True, type=bool))
  868. self.ch_kits.setChecked(self.settings.value("PluginDatabase/ShowKits", True, type=bool))
  869. self.ch_native.setChecked(self.settings.value("PluginDatabase/ShowNative", True, type=bool))
  870. self.ch_bridged.setChecked(self.settings.value("PluginDatabase/ShowBridged", True, type=bool))
  871. self.ch_bridged_wine.setChecked(self.settings.value("PluginDatabase/ShowBridgedWine", True, type=bool))
  872. self.ch_gui.setChecked(self.settings.value("PluginDatabase/ShowHasGUI", False, type=bool))
  873. self.ch_stereo.setChecked(self.settings.value("PluginDatabase/ShowStereoOnly", False, type=bool))
  874. self.reAddPlugins()
  875. def closeEvent(self, event):
  876. self.saveSettings()
  877. QDialog.closeEvent(self, event)
  878. def done(self, r):
  879. QDialog.done(self, r)
  880. self.close()
  881. # Main Window
  882. class CarlaMainW(QMainWindow, ui_carla.Ui_CarlaMainW):
  883. def __init__(self, parent=None):
  884. QMainWindow.__init__(self, parent)
  885. self.setupUi(self)
  886. # -------------------------------------------------------------
  887. # Load Settings
  888. self.settings = QSettings("Cadence", "Carla")
  889. self.settings_db = QSettings("Cadence", "Carla-Database")
  890. self.loadSettings(True)
  891. self.loadRDFs()
  892. self.setStyleSheet("""
  893. QWidget#centralwidget {
  894. background-color: qlineargradient(spread:pad,
  895. x1:0.0, y1:0.0,
  896. x2:0.2, y2:1.0,
  897. stop:0 rgb( 7, 7, 7),
  898. stop:1 rgb(28, 28, 28)
  899. );
  900. }
  901. """)
  902. # -------------------------------------------------------------
  903. # Internal stuff
  904. self.m_engine_started = False
  905. self.m_project_filename = None
  906. self.m_firstEngineInit = True
  907. self.m_pluginCount = 0
  908. self._nsmAnnounce2str = ""
  909. self._nsmOpen1str = ""
  910. self._nsmOpen2str = ""
  911. self.nsm_server = None
  912. self.nsm_url = None
  913. self.m_plugin_list = []
  914. for x in range(MAX_PLUGINS):
  915. self.m_plugin_list.append(None)
  916. # -------------------------------------------------------------
  917. # Set-up GUI stuff
  918. self.act_engine_start.setEnabled(False)
  919. self.act_engine_stop.setEnabled(False)
  920. self.act_plugin_remove_all.setEnabled(False)
  921. #self.m_scene = CarlaScene(self, self.graphicsView)
  922. #self.graphicsView.setScene(self.m_scene)
  923. self.resize(self.width(), 0)
  924. #self.m_fakeEdit = PluginEdit(self, -1)
  925. #self.m_curEdit = self.m_fakeEdit
  926. #self.w_edit.layout().addWidget(self.m_curEdit)
  927. #self.w_edit.layout().addStretch()
  928. # -------------------------------------------------------------
  929. # Connect actions to functions
  930. self.connect(self.act_file_new, SIGNAL("triggered()"), SLOT("slot_file_new()"))
  931. self.connect(self.act_file_open, SIGNAL("triggered()"), SLOT("slot_file_open()"))
  932. self.connect(self.act_file_save, SIGNAL("triggered()"), SLOT("slot_file_save()"))
  933. self.connect(self.act_file_save_as, SIGNAL("triggered()"), SLOT("slot_file_save_as()"))
  934. self.connect(self.act_engine_start, SIGNAL("triggered()"), SLOT("slot_engine_start()"))
  935. self.connect(self.act_engine_stop, SIGNAL("triggered()"), SLOT("slot_engine_stop()"))
  936. self.connect(self.act_plugin_add, SIGNAL("triggered()"), SLOT("slot_plugin_add()"))
  937. self.connect(self.act_plugin_remove_all, SIGNAL("triggered()"), SLOT("slot_remove_all()"))
  938. self.connect(self.act_settings_configure, SIGNAL("triggered()"), SLOT("slot_configureCarla()"))
  939. self.connect(self.act_help_about, SIGNAL("triggered()"), SLOT("slot_aboutCarla()"))
  940. self.connect(self.act_help_about_qt, SIGNAL("triggered()"), app, SLOT("aboutQt()"))
  941. self.connect(self, SIGNAL("SIGUSR1()"), SLOT("slot_handleSIGUSR1()"))
  942. self.connect(self, SIGNAL("DebugCallback(int, int, int, double, QString)"), SLOT("slot_handleDebugCallback(int, int, int, double, QString)"))
  943. self.connect(self, SIGNAL("ParameterValueCallback(int, int, double)"), SLOT("slot_handleParameterValueCallback(int, int, double)"))
  944. self.connect(self, SIGNAL("ParameterMidiChannelCallback(int, int, int)"), SLOT("slot_handleParameterMidiChannelCallback(int, int, int)"))
  945. self.connect(self, SIGNAL("ParameterMidiCcCallback(int, int, int)"), SLOT("slot_handleParameterMidiCcCallback(int, int, int)"))
  946. self.connect(self, SIGNAL("ProgramCallback(int, int)"), SLOT("slot_handleProgramCallback(int, int)"))
  947. self.connect(self, SIGNAL("MidiProgramCallback(int, int)"), SLOT("slot_handleMidiProgramCallback(int, int)"))
  948. self.connect(self, SIGNAL("NoteOnCallback(int, int, int, int)"), SLOT("slot_handleNoteOnCallback(int, int, int, int)"))
  949. self.connect(self, SIGNAL("NoteOffCallback(int, int, int)"), SLOT("slot_handleNoteOffCallback(int, int, int)"))
  950. self.connect(self, SIGNAL("ShowGuiCallback(int, int)"), SLOT("slot_handleShowGuiCallback(int, int)"))
  951. self.connect(self, SIGNAL("ResizeGuiCallback(int, int, int)"), SLOT("slot_handleResizeGuiCallback(int, int, int)"))
  952. self.connect(self, SIGNAL("UpdateCallback(int)"), SLOT("slot_handleUpdateCallback(int)"))
  953. self.connect(self, SIGNAL("ReloadInfoCallback(int)"), SLOT("slot_handleReloadInfoCallback(int)"))
  954. self.connect(self, SIGNAL("ReloadParametersCallback(int)"), SLOT("slot_handleReloadParametersCallback(int)"))
  955. self.connect(self, SIGNAL("ReloadProgramsCallback(int)"), SLOT("slot_handleReloadProgramsCallback(int)"))
  956. self.connect(self, SIGNAL("ReloadAllCallback(int)"), SLOT("slot_handleReloadAllCallback(int)"))
  957. self.connect(self, SIGNAL("NSM_AnnounceCallback()"), SLOT("slot_handleNSM_AnnounceCallback()"))
  958. self.connect(self, SIGNAL("NSM_Open1Callback()"), SLOT("slot_handleNSM_Open1Callback()"))
  959. self.connect(self, SIGNAL("NSM_Open2Callback()"), SLOT("slot_handleNSM_Open2Callback()"))
  960. self.connect(self, SIGNAL("NSM_SaveCallback()"), SLOT("slot_handleNSM_SaveCallback()"))
  961. self.connect(self, SIGNAL("ErrorCallback(QString)"), SLOT("slot_handleErrorCallback(QString)"))
  962. self.connect(self, SIGNAL("QuitCallback()"), SLOT("slot_handleQuitCallback()"))
  963. self.TIMER_GUI_STUFF = self.startTimer(self.m_savedSettings["Main/RefreshInterval"]) # Peaks
  964. self.TIMER_GUI_STUFF2 = self.startTimer(self.m_savedSettings["Main/RefreshInterval"] * 2) # LEDs and edit dialog
  965. NSM_URL = os.getenv("NSM_URL")
  966. if NSM_URL:
  967. Carla.host.nsm_announce(NSM_URL, os.getpid())
  968. else:
  969. QTimer.singleShot(0, self, SLOT("slot_engine_start()"))
  970. QTimer.singleShot(0, self, SLOT("slot_showInitialWarning()"))
  971. def loadProjectLater(self):
  972. QTimer.singleShot(0, self.load_project)
  973. def startEngine(self, clientName = "Carla"):
  974. # ---------------------------------------------
  975. # engine
  976. Carla.processMode = self.settings.value("Engine/ProcessMode", PROCESS_MODE_MULTIPLE_CLIENTS, type=int)
  977. Carla.maxParameters = self.settings.value("Engine/MaxParameters", MAX_PARAMETERS, type=int)
  978. processHighPrecision = self.settings.value("Engine/ProcessHighPrecision", False, type=bool)
  979. preferredBufferSize = self.settings.value("Engine/PreferredBufferSize", 512, type=int)
  980. preferredSampleRate = self.settings.value("Engine/PreferredSampleRate", 44100, type=int)
  981. forceStereo = self.settings.value("Engine/ForceStereo", False, type=bool)
  982. useDssiVstChunks = self.settings.value("Engine/UseDssiVstChunks", False, type=bool)
  983. preferPluginBridges = self.settings.value("Engine/PreferPluginBridges", False, type=bool)
  984. preferUiBridges = self.settings.value("Engine/PreferUiBridges", True, type=bool)
  985. oscUiTimeout = self.settings.value("Engine/OscUiTimeout", 40, type=int)
  986. if Carla.processMode == PROCESS_MODE_CONTINUOUS_RACK:
  987. forceStereo = True
  988. elif Carla.processMode == PROCESS_MODE_MULTIPLE_CLIENTS and os.getenv("LADISH_APP_NAME"):
  989. print("LADISH detected but using multiple clients (not allowed), forcing single client now")
  990. Carla.processMode = PROCESS_MODE_SINGLE_CLIENT
  991. Carla.host.set_option(OPTION_PROCESS_MODE, Carla.processMode, "")
  992. Carla.host.set_option(OPTION_PROCESS_HIGH_PRECISION, processHighPrecision, "")
  993. Carla.host.set_option(OPTION_MAX_PARAMETERS, Carla.maxParameters, "")
  994. Carla.host.set_option(OPTION_PREFERRED_BUFFER_SIZE, preferredBufferSize, "")
  995. Carla.host.set_option(OPTION_PREFERRED_SAMPLE_RATE, preferredSampleRate, "")
  996. Carla.host.set_option(OPTION_FORCE_STEREO, forceStereo, "")
  997. Carla.host.set_option(OPTION_USE_DSSI_VST_CHUNKS, useDssiVstChunks, "")
  998. Carla.host.set_option(OPTION_PREFER_PLUGIN_BRIDGES, preferPluginBridges, "")
  999. Carla.host.set_option(OPTION_PREFER_UI_BRIDGES, preferUiBridges, "")
  1000. Carla.host.set_option(OPTION_OSC_UI_TIMEOUT, oscUiTimeout, "")
  1001. # ---------------------------------------------
  1002. # start
  1003. audioDriver = self.settings.value("Engine/AudioDriver", "JACK", type=str)
  1004. if not Carla.host.engine_init(audioDriver, clientName):
  1005. if self.m_firstEngineInit:
  1006. self.m_firstEngineInit = False
  1007. return
  1008. self.act_engine_start.setEnabled(True)
  1009. self.act_engine_stop.setEnabled(False)
  1010. audioError = cString(Carla.host.get_last_error())
  1011. if audioError:
  1012. QMessageBox.critical(self, self.tr("Error"), self.tr("Could not connect to Audio backend '%s', possible reasons: %s" % (audioDriver, audioError)))
  1013. else:
  1014. QMessageBox.critical(self, self.tr("Error"), self.tr("Could not connect to Audio backend '%s'" % audioDriver))
  1015. return
  1016. if self.m_firstEngineInit:
  1017. self.m_firstEngineInit = False
  1018. self.m_engine_started = True
  1019. def stopEngine(self):
  1020. if self.m_pluginCount > 0:
  1021. ask = QMessageBox.question(self, self.tr("Warning"), self.tr("There are still some plugins loaded, you need to remove them to stop the engine.\n"
  1022. "Do you want to do this now?"),
  1023. QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
  1024. if ask == QMessageBox.Yes:
  1025. self.slot_remove_all()
  1026. else:
  1027. return
  1028. if Carla.host.is_engine_running() and not Carla.host.engine_close():
  1029. print(cString(Carla.host.get_last_error()))
  1030. self.m_engine_started = False
  1031. #def pluginWidgetActivated(self, widget):
  1032. #if self.m_curEdit == widget:
  1033. #self.keyboard.allNotesOff()
  1034. #def pluginWidgetClicked(self, widget):
  1035. #if self.m_curEdit == widget:
  1036. #return
  1037. #self.w_edit.layout().removeWidget(self.m_curEdit)
  1038. #self.w_edit.layout().insertWidget(0, widget)
  1039. #widget.show()
  1040. #self.m_curEdit.hide()
  1041. #self.m_curEdit = widget
  1042. @pyqtSlot()
  1043. def slot_showInitialWarning(self):
  1044. QMessageBox.warning(self, self.tr("Carla is incomplete"), self.tr(""
  1045. "The version of Carla you're currently running is incomplete.\n"
  1046. "Although most things work fine, Carla is not yet in a stable state.\n"
  1047. "\n"
  1048. "It will be fully functional for the next Cadence beta release."
  1049. ""))
  1050. @pyqtSlot()
  1051. def slot_engine_start(self):
  1052. self.startEngine()
  1053. check = Carla.host.is_engine_running()
  1054. self.act_file_open.setEnabled(check)
  1055. self.act_engine_start.setEnabled(not check)
  1056. self.act_engine_stop.setEnabled(check)
  1057. @pyqtSlot()
  1058. def slot_engine_stop(self):
  1059. self.stopEngine()
  1060. check = Carla.host.is_engine_running()
  1061. self.act_file_open.setEnabled(check)
  1062. self.act_engine_start.setEnabled(not check)
  1063. self.act_engine_stop.setEnabled(check)
  1064. @pyqtSlot()
  1065. def slot_handleSIGUSR1(self):
  1066. print("Got SIGUSR1 -> Saving project now")
  1067. QTimer.singleShot(0, self, SLOT("slot_file_save()"))
  1068. @pyqtSlot(int, int, int, float, str)
  1069. def slot_handleDebugCallback(self, plugin_id, value1, value2, value3, valueStr):
  1070. print("DEBUG :: %i, %i, %i, %f, \"%s\")" % (plugin_id, value1, value2, value3, valueStr))
  1071. @pyqtSlot(int, int, float)
  1072. def slot_handleParameterValueCallback(self, pluginId, parameterId, value):
  1073. pwidget = self.m_plugin_list[pluginId]
  1074. if pwidget:
  1075. pwidget.m_parameterIconTimer = ICON_STATE_ON
  1076. if parameterId == PARAMETER_ACTIVE:
  1077. pwidget.set_active((value > 0.0), True, False)
  1078. elif parameterId == PARAMETER_DRYWET:
  1079. pwidget.set_drywet(value * 1000, True, False)
  1080. elif parameterId == PARAMETER_VOLUME:
  1081. pwidget.set_volume(value * 1000, True, False)
  1082. elif parameterId == PARAMETER_BALANCE_LEFT:
  1083. pwidget.set_balance_left(value * 1000, True, False)
  1084. elif parameterId == PARAMETER_BALANCE_RIGHT:
  1085. pwidget.set_balance_right(value * 1000, True, False)
  1086. elif parameterId >= 0:
  1087. pwidget.edit_dialog.set_parameter_to_update(parameterId)
  1088. @pyqtSlot(int, int, int)
  1089. def slot_handleParameterMidiChannelCallback(self, pluginId, parameterId, channel):
  1090. pwidget = self.m_plugin_list[pluginId]
  1091. if pwidget:
  1092. pwidget.edit_dialog.set_parameter_midi_channel(parameterId, channel, True)
  1093. @pyqtSlot(int, int, int)
  1094. def slot_handleParameterMidiCcCallback(self, pluginId, parameterId, cc):
  1095. pwidget = self.m_plugin_list[pluginId]
  1096. if pwidget:
  1097. pwidget.edit_dialog.set_parameter_midi_cc(parameterId, cc, True)
  1098. @pyqtSlot(int, int)
  1099. def slot_handleProgramCallback(self, plugin_id, program_id):
  1100. pwidget = self.m_plugin_list[plugin_id]
  1101. if pwidget:
  1102. pwidget.edit_dialog.set_program(program_id)
  1103. pwidget.m_parameterIconTimer = ICON_STATE_ON
  1104. @pyqtSlot(int, int)
  1105. def slot_handleMidiProgramCallback(self, plugin_id, midi_program_id):
  1106. pwidget = self.m_plugin_list[plugin_id]
  1107. if pwidget:
  1108. pwidget.edit_dialog.set_midi_program(midi_program_id)
  1109. pwidget.m_parameterIconTimer = ICON_STATE_ON
  1110. @pyqtSlot(int, int, int, int)
  1111. def slot_handleNoteOnCallback(self, plugin_id, channel, note, velo):
  1112. pwidget = self.m_plugin_list[plugin_id]
  1113. if pwidget:
  1114. pwidget.edit_dialog.keyboard.sendNoteOn(note, False)
  1115. @pyqtSlot(int, int, int)
  1116. def slot_handleNoteOffCallback(self, plugin_id, channel, note):
  1117. pwidget = self.m_plugin_list[plugin_id]
  1118. if pwidget:
  1119. pwidget.edit_dialog.keyboard.sendNoteOff(note, False)
  1120. @pyqtSlot(int, int)
  1121. def slot_handleShowGuiCallback(self, plugin_id, show):
  1122. pwidget = self.m_plugin_list[plugin_id]
  1123. if pwidget:
  1124. if show == 0:
  1125. pwidget.b_gui.setChecked(False)
  1126. pwidget.b_gui.setEnabled(True)
  1127. elif show == 1:
  1128. pwidget.b_gui.setChecked(True)
  1129. pwidget.b_gui.setEnabled(True)
  1130. elif show == -1:
  1131. pwidget.b_gui.setChecked(False)
  1132. pwidget.b_gui.setEnabled(False)
  1133. @pyqtSlot(int, int, int)
  1134. def slot_handleResizeGuiCallback(self, plugin_id, width, height):
  1135. pwidget = self.m_plugin_list[plugin_id]
  1136. if pwidget:
  1137. gui_dialog = pwidget.gui_dialog
  1138. if gui_dialog:
  1139. gui_dialog.setNewSize(width, height)
  1140. @pyqtSlot(int)
  1141. def slot_handleUpdateCallback(self, plugin_id):
  1142. pwidget = self.m_plugin_list[plugin_id]
  1143. if pwidget:
  1144. pwidget.edit_dialog.do_update()
  1145. @pyqtSlot(int)
  1146. def slot_handleReloadInfoCallback(self, plugin_id):
  1147. pwidget = self.m_plugin_list[plugin_id]
  1148. if pwidget:
  1149. pwidget.edit_dialog.do_reload_info()
  1150. @pyqtSlot(int)
  1151. def slot_handleReloadParametersCallback(self, plugin_id):
  1152. pwidget = self.m_plugin_list[plugin_id]
  1153. if pwidget:
  1154. pwidget.edit_dialog.do_reload_parameters()
  1155. @pyqtSlot(int)
  1156. def slot_handleReloadProgramsCallback(self, plugin_id):
  1157. pwidget = self.m_plugin_list[plugin_id]
  1158. if pwidget:
  1159. pwidget.edit_dialog.do_reload_programs()
  1160. @pyqtSlot(int)
  1161. def slot_handleReloadAllCallback(self, plugin_id):
  1162. pwidget = self.m_plugin_list[plugin_id]
  1163. if pwidget:
  1164. pwidget.edit_dialog.do_reload_all()
  1165. @pyqtSlot()
  1166. def slot_handleNSM_AnnounceCallback(self):
  1167. smName = self._nsmAnnounce2str
  1168. self.act_file_new.setEnabled(False)
  1169. self.act_file_open.setEnabled(False)
  1170. self.act_file_save_as.setEnabled(False)
  1171. self.setWindowTitle("Carla (%s)" % smName)
  1172. @pyqtSlot()
  1173. def slot_handleNSM_Open1Callback(self):
  1174. clientId = self._nsmOpen1str
  1175. # remove all previous plugins
  1176. self.slot_remove_all()
  1177. # restart engine
  1178. if Carla.host.is_engine_running():
  1179. self.stopEngine()
  1180. self.startEngine(clientId)
  1181. @pyqtSlot()
  1182. def slot_handleNSM_Open2Callback(self):
  1183. projectPath = self._nsmOpen2str
  1184. self.m_project_filename = projectPath
  1185. if os.path.exists(self.m_project_filename):
  1186. self.load_project()
  1187. else:
  1188. self.save_project()
  1189. self.setWindowTitle("Carla - %s" % os.path.basename(self.m_project_filename))
  1190. Carla.host.nsm_reply_open()
  1191. @pyqtSlot()
  1192. def slot_handleNSM_SaveCallback(self):
  1193. self.save_project()
  1194. Carla.host.nsm_reply_save()
  1195. @pyqtSlot(str)
  1196. def slot_handleErrorCallback(self, error):
  1197. QMessageBox.critical(self, self.tr("Error"), error)
  1198. @pyqtSlot()
  1199. def slot_handleQuitCallback(self):
  1200. CustomMessageBox(self, QMessageBox.Warning, self.tr("Warning"),
  1201. self.tr("JACK has been stopped or crashed.\nPlease start JACK and restart Carla"),
  1202. self.tr("You may want to save your session now..."), QMessageBox.Ok, QMessageBox.Ok)
  1203. def add_plugin(self, btype, ptype, filename, name, label, extra_stuff, activate):
  1204. if not self.m_engine_started:
  1205. if activate:
  1206. QMessageBox.warning(self, self.tr("Warning"), self.tr("Cannot add new plugins while engine is stopped"))
  1207. return -1
  1208. new_plugin_id = Carla.host.add_plugin(btype, ptype, filename, name, label, extra_stuff)
  1209. if new_plugin_id < 0:
  1210. CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), cString(Carla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok)
  1211. return -1
  1212. else:
  1213. pwidget = PluginWidget(self, new_plugin_id)
  1214. self.w_plugins.layout().addWidget(pwidget)
  1215. #self.m_scene.addWidget(new_plugin_id, pwidget)
  1216. self.m_plugin_list[new_plugin_id] = pwidget
  1217. self.act_plugin_remove_all.setEnabled(True)
  1218. pwidget.peak_in.setRefreshRate(self.m_savedSettings["Main/RefreshInterval"])
  1219. pwidget.peak_out.setRefreshRate(self.m_savedSettings["Main/RefreshInterval"])
  1220. if activate:
  1221. pwidget.set_active(True, True, True)
  1222. self.m_pluginCount += 1
  1223. return new_plugin_id
  1224. def remove_plugin(self, plugin_id, showError):
  1225. pwidget = self.m_plugin_list[plugin_id]
  1226. #if pwidget.edit_dialog == self.m_curEdit:
  1227. #self.w_edit.layout().removeWidget(self.m_curEdit)
  1228. #self.w_edit.layout().insertWidget(0, self.m_fakeEdit)
  1229. #self.m_fakeEdit.show()
  1230. #self.m_curEdit.hide()
  1231. #self.m_curEdit = self.m_fakeEdit
  1232. pwidget.edit_dialog.close()
  1233. if pwidget.gui_dialog:
  1234. pwidget.gui_dialog.close()
  1235. if Carla.host.remove_plugin(plugin_id):
  1236. pwidget.close()
  1237. pwidget.deleteLater()
  1238. self.w_plugins.layout().removeWidget(pwidget)
  1239. self.m_plugin_list[plugin_id] = None
  1240. self.m_pluginCount -= 1
  1241. elif showError:
  1242. CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to remove plugin"), cString(Carla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok)
  1243. # push all plugins 1 slot if rack mode
  1244. if Carla.processMode == PROCESS_MODE_CONTINUOUS_RACK:
  1245. for i in range(MAX_PLUGINS-1):
  1246. if i < plugin_id: continue
  1247. self.m_plugin_list[i] = self.m_plugin_list[i+1]
  1248. if self.m_plugin_list[i]:
  1249. self.m_plugin_list[i].setId(i)
  1250. self.m_plugin_list[MAX_PLUGINS-1] = None
  1251. # check if there are still plugins
  1252. for i in range(MAX_PLUGINS):
  1253. if self.m_plugin_list[i]: break
  1254. else:
  1255. self.act_plugin_remove_all.setEnabled(False)
  1256. def get_extra_stuff(self, plugin):
  1257. ptype = plugin['type']
  1258. if ptype == PLUGIN_LADSPA:
  1259. unique_id = plugin['unique_id']
  1260. for rdf_item in self.ladspa_rdf_list:
  1261. if rdf_item.UniqueID == unique_id:
  1262. return pointer(rdf_item)
  1263. elif ptype == PLUGIN_DSSI:
  1264. if plugin['hints'] & PLUGIN_HAS_GUI:
  1265. gui = findDSSIGUI(plugin['binary'], plugin['name'], plugin['label'])
  1266. if gui:
  1267. return gui.encode("utf-8")
  1268. return c_nullptr
  1269. def save_project(self):
  1270. content = ("<?xml version='1.0' encoding='UTF-8'?>\n"
  1271. "<!DOCTYPE CARLA-PROJECT>\n"
  1272. "<CARLA-PROJECT VERSION='%s'>\n") % (VERSION)
  1273. first_plugin = True
  1274. for pwidget in self.m_plugin_list:
  1275. if pwidget:
  1276. if not first_plugin:
  1277. content += "\n"
  1278. real_plugin_name = cString(Carla.host.get_real_plugin_name(pwidget.m_pluginId))
  1279. if real_plugin_name:
  1280. content += " <!-- %s -->\n" % xmlSafeString(real_plugin_name, True)
  1281. content += " <Plugin>\n"
  1282. content += pwidget.getSaveXMLContent()
  1283. content += " </Plugin>\n"
  1284. first_plugin = False
  1285. content += "</CARLA-PROJECT>\n"
  1286. try:
  1287. fd = uopen(self.m_project_filename, "w")
  1288. fd.write(content)
  1289. fd.close()
  1290. except:
  1291. QMessageBox.critical(self, self.tr("Error"), self.tr("Failed to save project file"))
  1292. def load_project(self):
  1293. try:
  1294. fd = uopen(self.m_project_filename, "r")
  1295. projectRead = fd.read()
  1296. fd.close()
  1297. except:
  1298. projectRead = None
  1299. if not projectRead:
  1300. QMessageBox.critical(self, self.tr("Error"), self.tr("Failed to load project file"))
  1301. return
  1302. xml = QDomDocument()
  1303. xml.setContent(projectRead.encode("utf-8"))
  1304. xml_node = xml.documentElement()
  1305. if xml_node.tagName() != "CARLA-PROJECT":
  1306. QMessageBox.critical(self, self.tr("Error"), self.tr("Not a valid Carla project file"))
  1307. return
  1308. x_internal_plugins = None
  1309. x_ladspa_plugins = None
  1310. x_dssi_plugins = None
  1311. x_lv2_plugins = None
  1312. x_vst_plugins = None
  1313. x_gig_plugins = None
  1314. x_sf2_plugins = None
  1315. x_sfz_plugins = None
  1316. x_failedPlugins = []
  1317. x_saveStates = []
  1318. node = xml_node.firstChild()
  1319. while not node.isNull():
  1320. if node.toElement().tagName() == "Plugin":
  1321. x_saveState = getSaveStateDictFromXML(node)
  1322. x_saveStates.append(x_saveState)
  1323. node = node.nextSibling()
  1324. for x_saveState in x_saveStates:
  1325. ptype = x_saveState['Type']
  1326. label = x_saveState['Label']
  1327. binary = x_saveState['Binary']
  1328. binaryS = os.path.basename(binary)
  1329. unique_id = x_saveState['UniqueID']
  1330. if ptype == "Internal":
  1331. if not x_internal_plugins: x_internal_plugins = toList(self.settings_db.value("Plugins/Internal", []))
  1332. x_plugins = x_internal_plugins
  1333. elif ptype == "LADSPA":
  1334. if not x_ladspa_plugins:
  1335. x_ladspa_plugins = []
  1336. x_ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_native", []))
  1337. x_ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_posix32", []))
  1338. x_ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_posix64", []))
  1339. x_ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_win32", []))
  1340. x_ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_win64", []))
  1341. x_plugins = x_ladspa_plugins
  1342. elif ptype == "DSSI":
  1343. if not x_dssi_plugins:
  1344. x_dssi_plugins = []
  1345. x_dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_native", []))
  1346. x_dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_posix32", []))
  1347. x_dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_posix64", []))
  1348. x_dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_win32", []))
  1349. x_dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_win64", []))
  1350. x_plugins = x_dssi_plugins
  1351. elif ptype == "LV2":
  1352. if not x_lv2_plugins:
  1353. x_lv2_plugins = []
  1354. x_lv2_plugins += toList(self.settings_db.value("Plugins/LV2_native", []))
  1355. x_lv2_plugins += toList(self.settings_db.value("Plugins/LV2_posix32", []))
  1356. x_lv2_plugins += toList(self.settings_db.value("Plugins/LV2_posix64", []))
  1357. x_lv2_plugins += toList(self.settings_db.value("Plugins/LV2_win32", []))
  1358. x_lv2_plugins += toList(self.settings_db.value("Plugins/LV2_win64", []))
  1359. x_plugins = x_lv2_plugins
  1360. elif ptype == "VST":
  1361. if not x_vst_plugins:
  1362. x_vst_plugins = []
  1363. x_vst_plugins += toList(self.settings_db.value("Plugins/VST_native", []))
  1364. x_vst_plugins += toList(self.settings_db.value("Plugins/VST_posix32", []))
  1365. x_vst_plugins += toList(self.settings_db.value("Plugins/VST_posix64", []))
  1366. x_vst_plugins += toList(self.settings_db.value("Plugins/VST_win32", []))
  1367. x_vst_plugins += toList(self.settings_db.value("Plugins/VST_win64", []))
  1368. x_plugins = x_vst_plugins
  1369. elif ptype == "GIG":
  1370. if not x_gig_plugins: x_gig_plugins = toList(self.settings_db.value("Plugins/GIG", []))
  1371. x_plugins = x_gig_plugins
  1372. elif ptype == "SF2":
  1373. if not x_sf2_plugins: x_sf2_plugins = toList(self.settings_db.value("Plugins/SF2", []))
  1374. x_plugins = x_sf2_plugins
  1375. elif ptype == "SFZ":
  1376. if not x_sfz_plugins: x_sfz_plugins = toList(self.settings_db.value("Plugins/SFZ", []))
  1377. x_plugins = x_sfz_plugins
  1378. else:
  1379. print("load_project() - ptype '%s' not recognized" % ptype)
  1380. x_failedPlugins.append(x_saveState['Name'])
  1381. continue
  1382. # Try UniqueID -> Label -> Binary (full) -> Binary (short)
  1383. plugin_ulB = None
  1384. plugin_ulb = None
  1385. plugin_ul = None
  1386. plugin_uB = None
  1387. plugin_ub = None
  1388. plugin_lB = None
  1389. plugin_lb = None
  1390. plugin_u = None
  1391. plugin_l = None
  1392. plugin_B = None
  1393. for _plugins in x_plugins:
  1394. for x_plugin in _plugins:
  1395. if unique_id == x_plugin['unique_id'] and label == x_plugin['label'] and binary == x_plugin['binary']:
  1396. plugin_ulB = x_plugin
  1397. break
  1398. elif unique_id == x_plugin['unique_id'] and label == x_plugin['label'] and binaryS == os.path.basename(x_plugin['binary']):
  1399. plugin_ulb = x_plugin
  1400. elif unique_id == x_plugin['unique_id'] and label == x_plugin['label']:
  1401. plugin_ul = x_plugin
  1402. elif unique_id == x_plugin['unique_id'] and binary == x_plugin['binary']:
  1403. plugin_uB = x_plugin
  1404. elif unique_id == x_plugin['unique_id'] and binaryS == os.path.basename(x_plugin['binary']):
  1405. plugin_ub = x_plugin
  1406. elif label == x_plugin['label'] and binary == x_plugin['binary']:
  1407. plugin_lB = x_plugin
  1408. elif label == x_plugin['label'] and binaryS == os.path.basename(x_plugin['binary']):
  1409. plugin_lb = x_plugin
  1410. elif unique_id == x_plugin['unique_id']:
  1411. plugin_u = x_plugin
  1412. elif label == x_plugin['label']:
  1413. plugin_l = x_plugin
  1414. elif binary == x_plugin['binary']:
  1415. plugin_B = x_plugin
  1416. # LADSPA uses UniqueID or binary+label
  1417. if ptype == "LADSPA":
  1418. plugin_l = None
  1419. plugin_B = None
  1420. # DSSI uses binary+label (UniqueID ignored)
  1421. elif ptype == "DSSI":
  1422. plugin_ul = None
  1423. plugin_uB = None
  1424. plugin_ub = None
  1425. plugin_u = None
  1426. plugin_l = None
  1427. plugin_B = None
  1428. # LV2 uses URIs (label in this case)
  1429. elif ptype == "LV2":
  1430. plugin_uB = None
  1431. plugin_ub = None
  1432. plugin_u = None
  1433. plugin_B = None
  1434. # VST uses UniqueID
  1435. elif ptype == "VST":
  1436. plugin_lB = None
  1437. plugin_lb = None
  1438. plugin_l = None
  1439. plugin_B = None
  1440. # Sound Kits use binaries
  1441. elif ptype in ("GIG", "SF2", "SFZ"):
  1442. plugin_ul = None
  1443. plugin_u = None
  1444. plugin_l = None
  1445. plugin_B = binary
  1446. if plugin_ulB:
  1447. plugin = plugin_ulB
  1448. elif plugin_ulb:
  1449. plugin = plugin_ulb
  1450. elif plugin_ul:
  1451. plugin = plugin_ul
  1452. elif plugin_uB:
  1453. plugin = plugin_uB
  1454. elif plugin_ub:
  1455. plugin = plugin_ub
  1456. elif plugin_lB:
  1457. plugin = plugin_lB
  1458. elif plugin_lb:
  1459. plugin = plugin_lb
  1460. elif plugin_u:
  1461. plugin = plugin_u
  1462. elif plugin_l:
  1463. plugin = plugin_l
  1464. elif plugin_B:
  1465. plugin = plugin_B
  1466. else:
  1467. plugin = None
  1468. if plugin:
  1469. btype = plugin['build']
  1470. ptype = plugin['type']
  1471. filename = plugin['binary']
  1472. name = x_saveState['Name']
  1473. label = plugin['label']
  1474. extra_stuff = self.get_extra_stuff(plugin)
  1475. new_plugin_id = self.add_plugin(btype, ptype, filename, name, label, extra_stuff, False)
  1476. if new_plugin_id >= 0:
  1477. pwidget = self.m_plugin_list[new_plugin_id]
  1478. pwidget.loadStateDict(x_saveState)
  1479. else:
  1480. x_failedPlugins.append(x_saveState['Name'])
  1481. else:
  1482. x_failedPlugins.append(x_saveState['Name'])
  1483. if len(x_failedPlugins) > 0:
  1484. text = self.tr("The following plugins were not found or failed to initialize:\n")
  1485. for plugin in x_failedPlugins:
  1486. text += " - %s\n" % plugin
  1487. self.statusBar().showMessage("State file loaded with errors")
  1488. QMessageBox.critical(self, self.tr("Error"), text)
  1489. else:
  1490. self.statusBar().showMessage("State file loaded sucessfully!")
  1491. def loadRDFs(self):
  1492. # Save RDF info for later
  1493. if haveLRDF:
  1494. SettingsDir = os.path.join(HOME, ".config", "Cadence")
  1495. fr_ladspa_file = os.path.join(SettingsDir, "ladspa_rdf.db")
  1496. if os.path.exists(fr_ladspa_file):
  1497. fr_ladspa = open(fr_ladspa_file, 'r')
  1498. try:
  1499. self.ladspa_rdf_list = ladspa_rdf.get_c_ladspa_rdfs(json.load(fr_ladspa))
  1500. except:
  1501. self.ladspa_rdf_list = []
  1502. fr_ladspa.close()
  1503. return
  1504. self.ladspa_rdf_list = []
  1505. @pyqtSlot()
  1506. def slot_file_new(self):
  1507. self.slot_remove_all()
  1508. self.m_project_filename = None
  1509. self.setWindowTitle("Carla")
  1510. @pyqtSlot()
  1511. def slot_file_open(self):
  1512. fileFilter = self.tr("Carla Project File (*.carxp)")
  1513. filenameTry = QFileDialog.getOpenFileName(self, self.tr("Open Carla Project File"), self.m_savedSettings["Main/DefaultProjectFolder"], filter=fileFilter)
  1514. if filenameTry:
  1515. self.m_project_filename = filenameTry
  1516. self.slot_remove_all()
  1517. self.load_project()
  1518. self.setWindowTitle("Carla - %s" % os.path.basename(self.m_project_filename))
  1519. @pyqtSlot()
  1520. def slot_file_save(self, saveAs=False):
  1521. if self.m_project_filename == None or saveAs:
  1522. fileFilter = self.tr("Carla Project File (*.carxp)")
  1523. filenameTry = QFileDialog.getSaveFileName(self, self.tr("Save Carla Project File"), self.m_savedSettings["Main/DefaultProjectFolder"], filter=fileFilter)
  1524. if filenameTry:
  1525. if not filenameTry.endswith(".carxp"):
  1526. filenameTry += ".carxp"
  1527. self.m_project_filename = filenameTry
  1528. self.save_project()
  1529. self.setWindowTitle("Carla - %s" % os.path.basename(self.m_project_filename))
  1530. else:
  1531. self.save_project()
  1532. @pyqtSlot()
  1533. def slot_file_save_as(self):
  1534. self.slot_file_save(True)
  1535. @pyqtSlot()
  1536. def slot_plugin_add(self):
  1537. dialog = PluginDatabaseW(self)
  1538. if dialog.exec_():
  1539. btype = dialog.ret_plugin['build']
  1540. ptype = dialog.ret_plugin['type']
  1541. filename = dialog.ret_plugin['binary']
  1542. label = dialog.ret_plugin['label']
  1543. extra_stuff = self.get_extra_stuff(dialog.ret_plugin)
  1544. self.add_plugin(btype, ptype, filename, None, label, extra_stuff, True)
  1545. @pyqtSlot()
  1546. def slot_remove_all(self):
  1547. h = 0
  1548. for i in range(MAX_PLUGINS):
  1549. pwidget = self.m_plugin_list[i]
  1550. if not pwidget:
  1551. continue
  1552. pwidget.setId(i-h)
  1553. pwidget.edit_dialog.close()
  1554. if pwidget.gui_dialog:
  1555. pwidget.gui_dialog.close()
  1556. if Carla.host.remove_plugin(i-h):
  1557. pwidget.close()
  1558. pwidget.deleteLater()
  1559. self.w_plugins.layout().removeWidget(pwidget)
  1560. self.m_plugin_list[i] = None
  1561. if Carla.processMode == PROCESS_MODE_CONTINUOUS_RACK:
  1562. h += 1
  1563. self.m_pluginCount = 0
  1564. self.act_plugin_remove_all.setEnabled(False)
  1565. @pyqtSlot()
  1566. def slot_configureCarla(self):
  1567. dialog = SettingsW(self, "carla")
  1568. if dialog.exec_():
  1569. self.loadSettings(False)
  1570. for pwidget in self.m_plugin_list:
  1571. if pwidget:
  1572. pwidget.peak_in.setRefreshRate(self.m_savedSettings["Main/RefreshInterval"])
  1573. pwidget.peak_out.setRefreshRate(self.m_savedSettings["Main/RefreshInterval"])
  1574. @pyqtSlot()
  1575. def slot_aboutCarla(self):
  1576. CarlaAboutW(self).exec_()
  1577. def saveSettings(self):
  1578. self.settings.setValue("Geometry", self.saveGeometry())
  1579. self.settings.setValue("ShowToolbar", self.toolBar.isVisible())
  1580. def loadSettings(self, geometry):
  1581. if geometry:
  1582. self.restoreGeometry(self.settings.value("Geometry", ""))
  1583. show_toolbar = self.settings.value("ShowToolbar", True, type=bool)
  1584. self.act_settings_show_toolbar.setChecked(show_toolbar)
  1585. self.toolBar.setVisible(show_toolbar)
  1586. self.m_savedSettings = {
  1587. "Main/DefaultProjectFolder": self.settings.value("Main/DefaultProjectFolder", DEFAULT_PROJECT_FOLDER, type=str),
  1588. "Main/RefreshInterval": self.settings.value("Main/RefreshInterval", 120, type=int)
  1589. }
  1590. # ---------------------------------------------
  1591. # plugin checks
  1592. disableChecks = self.settings.value("Engine/DisableChecks", False, type=bool)
  1593. if disableChecks:
  1594. os.environ["CARLA_DISCOVERY_NO_PROCESSING_CHECKS"] = "true"
  1595. elif os.getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS"):
  1596. os.environ.pop("CARLA_DISCOVERY_NO_PROCESSING_CHECKS")
  1597. # ---------------------------------------------
  1598. # plugin paths
  1599. global LADSPA_PATH, DSSI_PATH, LV2_PATH, VST_PATH, GIG_PATH, SF2_PATH, SFZ_PATH
  1600. LADSPA_PATH = toList(self.settings.value("Paths/LADSPA", LADSPA_PATH))
  1601. DSSI_PATH = toList(self.settings.value("Paths/DSSI", DSSI_PATH))
  1602. LV2_PATH = toList(self.settings.value("Paths/LV2", LV2_PATH))
  1603. VST_PATH = toList(self.settings.value("Paths/VST", VST_PATH))
  1604. GIG_PATH = toList(self.settings.value("Paths/GIG", GIG_PATH))
  1605. SF2_PATH = toList(self.settings.value("Paths/SF2", SF2_PATH))
  1606. SFZ_PATH = toList(self.settings.value("Paths/SFZ", SFZ_PATH))
  1607. os.environ["LADSPA_PATH"] = splitter.join(LADSPA_PATH)
  1608. os.environ["DSSI_PATH"] = splitter.join(DSSI_PATH)
  1609. os.environ["LV2_PATH"] = splitter.join(LV2_PATH)
  1610. os.environ["VST_PATH"] = splitter.join(VST_PATH)
  1611. os.environ["GIG_PATH"] = splitter.join(GIG_PATH)
  1612. os.environ["SF2_PATH"] = splitter.join(SF2_PATH)
  1613. os.environ["SFZ_PATH"] = splitter.join(SFZ_PATH)
  1614. #def resizeEvent(self, event):
  1615. #self.m_scene.resize()
  1616. #QMainWindow.resizeEvent(self, event)
  1617. def timerEvent(self, event):
  1618. if event.timerId() == self.TIMER_GUI_STUFF:
  1619. for pwidget in self.m_plugin_list:
  1620. if pwidget: pwidget.check_gui_stuff()
  1621. if self.m_engine_started and self.m_pluginCount > 0:
  1622. Carla.host.idle_guis()
  1623. elif event.timerId() == self.TIMER_GUI_STUFF2:
  1624. for pwidget in self.m_plugin_list:
  1625. if pwidget: pwidget.check_gui_stuff2()
  1626. QMainWindow.timerEvent(self, event)
  1627. def closeEvent(self, event):
  1628. if self.nsm_server:
  1629. self.nsm_server.stop()
  1630. self.saveSettings()
  1631. self.slot_remove_all()
  1632. QMainWindow.closeEvent(self, event)
  1633. # ------------------------------------------------------------------------------------------------
  1634. def callback_function(ptr, action, pluginId, value1, value2, value3, valueStr):
  1635. if pluginId< 0 or pluginId >= MAX_PLUGINS or not Carla.gui:
  1636. return
  1637. if action == CALLBACK_DEBUG:
  1638. Carla.gui.emit(SIGNAL("DebugCallback(int, int, int, double, QString)"), pluginId, value1, value2, value3, cString(valueStr))
  1639. elif action == CALLBACK_PARAMETER_VALUE_CHANGED:
  1640. Carla.gui.emit(SIGNAL("ParameterValueCallback(int, int, double)"), pluginId, value1, value3)
  1641. elif action == CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED:
  1642. Carla.gui.emit(SIGNAL("ParameterMidiChannelCallback(int, int, int)"), pluginId, value1, value2)
  1643. elif action == CALLBACK_PARAMETER_MIDI_CC_CHANGED:
  1644. Carla.gui.emit(SIGNAL("ParameterMidiCcCallback(int, int, int)"), pluginId, value1, value2)
  1645. elif action == CALLBACK_PROGRAM_CHANGED:
  1646. Carla.gui.emit(SIGNAL("ProgramCallback(int, int)"), pluginId, value1)
  1647. elif action == CALLBACK_MIDI_PROGRAM_CHANGED:
  1648. Carla.gui.emit(SIGNAL("MidiProgramCallback(int, int)"), pluginId, value1)
  1649. elif action == CALLBACK_NOTE_ON:
  1650. Carla.gui.emit(SIGNAL("NoteOnCallback(int, int, int, int)"), pluginId, value1, value2, value3)
  1651. elif action == CALLBACK_NOTE_OFF:
  1652. Carla.gui.emit(SIGNAL("NoteOffCallback(int, int, int)"), pluginId, value1, value2)
  1653. elif action == CALLBACK_SHOW_GUI:
  1654. Carla.gui.emit(SIGNAL("ShowGuiCallback(int, int)"), pluginId, value1)
  1655. elif action == CALLBACK_RESIZE_GUI:
  1656. Carla.gui.emit(SIGNAL("ResizeGuiCallback(int, int, int)"), pluginId, value1, value2)
  1657. elif action == CALLBACK_UPDATE:
  1658. Carla.gui.emit(SIGNAL("UpdateCallback(int)"), pluginId)
  1659. elif action == CALLBACK_RELOAD_INFO:
  1660. Carla.gui.emit(SIGNAL("ReloadInfoCallback(int)"), pluginId)
  1661. elif action == CALLBACK_RELOAD_PARAMETERS:
  1662. Carla.gui.emit(SIGNAL("ReloadParametersCallback(int)"), pluginId)
  1663. elif action == CALLBACK_RELOAD_PROGRAMS:
  1664. Carla.gui.emit(SIGNAL("ReloadProgramsCallback(int)"), pluginId)
  1665. elif action == CALLBACK_RELOAD_ALL:
  1666. Carla.gui.emit(SIGNAL("ReloadAllCallback(int)"), pluginId)
  1667. elif action == CALLBACK_NSM_ANNOUNCE:
  1668. Carla.gui._nsmAnnounce2str = cString(Carla.host.get_last_error())
  1669. Carla.gui.emit(SIGNAL("NSM_AnnounceCallback()"))
  1670. elif action == CALLBACK_NSM_OPEN1:
  1671. Carla.gui._nsmOpen1str = cString(valueStr)
  1672. Carla.gui.emit(SIGNAL("NSM_Open1Callback()"))
  1673. elif action == CALLBACK_NSM_OPEN2:
  1674. Carla.gui._nsmOpen2str = cString(valueStr)
  1675. Carla.gui.emit(SIGNAL("NSM_Open2Callback()"))
  1676. elif action == CALLBACK_NSM_SAVE:
  1677. Carla.gui.emit(SIGNAL("NSM_SaveCallback()"))
  1678. elif action == CALLBACK_ERROR:
  1679. Carla.gui.emit(SIGNAL("ErrorCallback(QString)"), cString(Carla.host.get_last_error()))
  1680. elif action == CALLBACK_QUIT:
  1681. Carla.gui.emit(SIGNAL("QuitCallback()"))
  1682. #--------------- main ------------------
  1683. if __name__ == '__main__':
  1684. # App initialization
  1685. app = QApplication(sys.argv)
  1686. app.setApplicationName("Carla")
  1687. app.setApplicationVersion(VERSION)
  1688. app.setOrganizationName("Cadence")
  1689. app.setWindowIcon(QIcon(":/scalable/carla.svg"))
  1690. libPrefix = None
  1691. projectFilename = None
  1692. for i in range(len(app.arguments())):
  1693. if i == 0: continue
  1694. argument = app.arguments()[i]
  1695. if argument.startswith("--with-libprefix="):
  1696. libPrefix = argument.replace("--with-libprefix=", "")
  1697. elif os.path.exists(argument):
  1698. projectFilename = argument
  1699. # Init backend
  1700. Carla.host = Host(libPrefix)
  1701. Carla.host.set_callback_function(callback_function)
  1702. Carla.host.set_option(OPTION_PROCESS_NAME, 0, "carla")
  1703. # Set bridge paths
  1704. if carla_bridge_posix32:
  1705. Carla.host.set_option(OPTION_PATH_BRIDGE_POSIX32, 0, carla_bridge_posix32)
  1706. if carla_bridge_posix64:
  1707. Carla.host.set_option(OPTION_PATH_BRIDGE_POSIX64, 0, carla_bridge_posix64)
  1708. if carla_bridge_win32:
  1709. Carla.host.set_option(OPTION_PATH_BRIDGE_WIN32, 0, carla_bridge_win32)
  1710. if carla_bridge_win64:
  1711. Carla.host.set_option(OPTION_PATH_BRIDGE_WIN64, 0, carla_bridge_win64)
  1712. if WINDOWS:
  1713. if carla_bridge_lv2_windows:
  1714. Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_WINDOWS, 0, carla_bridge_lv2_windows)
  1715. if carla_bridge_vst_hwnd:
  1716. Carla.host.set_option(OPTION_PATH_BRIDGE_VST_HWND, 0, carla_bridge_vst_hwnd)
  1717. elif MACOS:
  1718. if carla_bridge_lv2_cocoa:
  1719. Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_COCOA, 0, carla_bridge_lv2_cocoa)
  1720. if carla_bridge_vst_cocoa:
  1721. Carla.host.set_option(OPTION_PATH_BRIDGE_VST_COCOA, 0, carla_bridge_vst_cocoa)
  1722. else:
  1723. if carla_bridge_lv2_gtk2:
  1724. Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_GTK2, 0, carla_bridge_lv2_gtk2)
  1725. if carla_bridge_lv2_gtk3:
  1726. Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_GTK3, 0, carla_bridge_lv2_gtk3)
  1727. if carla_bridge_lv2_qt4:
  1728. Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_QT4, 0, carla_bridge_lv2_qt4)
  1729. if carla_bridge_lv2_qt5:
  1730. Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_QT5, 0, carla_bridge_lv2_qt5)
  1731. if carla_bridge_lv2_x11:
  1732. Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_X11, 0, carla_bridge_lv2_x11)
  1733. if carla_bridge_vst_x11:
  1734. Carla.host.set_option(OPTION_PATH_BRIDGE_VST_X11, 0, carla_bridge_vst_x11)
  1735. # Set available drivers
  1736. driverCount = Carla.host.get_engine_driver_count()
  1737. driverList = []
  1738. for i in range(driverCount):
  1739. driver = cString(Carla.host.get_engine_driver_name(i))
  1740. if driver:
  1741. driverList.append(driver)
  1742. setAvailableEngineDrivers(driverList)
  1743. # Create GUI and start engine
  1744. Carla.gui = CarlaMainW()
  1745. # Set-up custom signal handling
  1746. setUpSignals(Carla.gui)
  1747. # Show GUI
  1748. Carla.gui.show()
  1749. # Load project file if set
  1750. if projectFilename:
  1751. Carla.gui.m_project_filename = projectFilename
  1752. Carla.gui.loadProjectLater()
  1753. Carla.gui.setWindowTitle("Carla - %s" % os.path.basename(projectFilename)) # FIXME - put in loadProject
  1754. # App-Loop
  1755. ret = app.exec_()
  1756. # Close Host
  1757. Carla.gui.stopEngine()
  1758. # Exit properly
  1759. sys.exit(ret)