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.

2149 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 kIs64bit:
  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 kIs64bit:
  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_DEFAULT_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_DEFAULT_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. pass
  1030. #print(cString(Carla.host.get_last_error()))
  1031. self.m_engine_started = False
  1032. #def pluginWidgetActivated(self, widget):
  1033. #if self.m_curEdit == widget:
  1034. #self.keyboard.allNotesOff()
  1035. #def pluginWidgetClicked(self, widget):
  1036. #if self.m_curEdit == widget:
  1037. #return
  1038. #self.w_edit.layout().removeWidget(self.m_curEdit)
  1039. #self.w_edit.layout().insertWidget(0, widget)
  1040. #widget.show()
  1041. #self.m_curEdit.hide()
  1042. #self.m_curEdit = widget
  1043. @pyqtSlot()
  1044. def slot_showInitialWarning(self):
  1045. QMessageBox.warning(self, self.tr("Carla is incomplete"), self.tr(""
  1046. "The version of Carla you're currently running is incomplete.\n"
  1047. "Although most things work fine, Carla is not yet in a stable state.\n"
  1048. "\n"
  1049. "It will be fully functional for the next Cadence beta release."
  1050. ""))
  1051. @pyqtSlot()
  1052. def slot_engine_start(self):
  1053. self.startEngine()
  1054. check = Carla.host.is_engine_running()
  1055. self.act_file_open.setEnabled(check)
  1056. self.act_engine_start.setEnabled(not check)
  1057. self.act_engine_stop.setEnabled(check)
  1058. @pyqtSlot()
  1059. def slot_engine_stop(self):
  1060. self.stopEngine()
  1061. check = Carla.host.is_engine_running()
  1062. self.act_file_open.setEnabled(check)
  1063. self.act_engine_start.setEnabled(not check)
  1064. self.act_engine_stop.setEnabled(check)
  1065. @pyqtSlot()
  1066. def slot_handleSIGUSR1(self):
  1067. print("Got SIGUSR1 -> Saving project now")
  1068. QTimer.singleShot(0, self, SLOT("slot_file_save()"))
  1069. @pyqtSlot(int, int, int, float, str)
  1070. def slot_handleDebugCallback(self, plugin_id, value1, value2, value3, valueStr):
  1071. print("DEBUG :: %i, %i, %i, %f, \"%s\")" % (plugin_id, value1, value2, value3, valueStr))
  1072. @pyqtSlot(int, int, float)
  1073. def slot_handleParameterValueCallback(self, pluginId, parameterId, value):
  1074. pwidget = self.m_plugin_list[pluginId]
  1075. if pwidget:
  1076. pwidget.m_parameterIconTimer = ICON_STATE_ON
  1077. if parameterId == PARAMETER_ACTIVE:
  1078. pwidget.set_active((value > 0.0), True, False)
  1079. elif parameterId == PARAMETER_DRYWET:
  1080. pwidget.set_drywet(value * 1000, True, False)
  1081. elif parameterId == PARAMETER_VOLUME:
  1082. pwidget.set_volume(value * 1000, True, False)
  1083. elif parameterId == PARAMETER_BALANCE_LEFT:
  1084. pwidget.set_balance_left(value * 1000, True, False)
  1085. elif parameterId == PARAMETER_BALANCE_RIGHT:
  1086. pwidget.set_balance_right(value * 1000, True, False)
  1087. elif parameterId >= 0:
  1088. pwidget.edit_dialog.set_parameter_to_update(parameterId)
  1089. @pyqtSlot(int, int, int)
  1090. def slot_handleParameterMidiChannelCallback(self, pluginId, parameterId, channel):
  1091. pwidget = self.m_plugin_list[pluginId]
  1092. if pwidget:
  1093. pwidget.edit_dialog.set_parameter_midi_channel(parameterId, channel, True)
  1094. @pyqtSlot(int, int, int)
  1095. def slot_handleParameterMidiCcCallback(self, pluginId, parameterId, cc):
  1096. pwidget = self.m_plugin_list[pluginId]
  1097. if pwidget:
  1098. pwidget.edit_dialog.set_parameter_midi_cc(parameterId, cc, True)
  1099. @pyqtSlot(int, int)
  1100. def slot_handleProgramCallback(self, plugin_id, program_id):
  1101. pwidget = self.m_plugin_list[plugin_id]
  1102. if pwidget:
  1103. pwidget.edit_dialog.set_program(program_id)
  1104. pwidget.m_parameterIconTimer = ICON_STATE_ON
  1105. @pyqtSlot(int, int)
  1106. def slot_handleMidiProgramCallback(self, plugin_id, midi_program_id):
  1107. pwidget = self.m_plugin_list[plugin_id]
  1108. if pwidget:
  1109. pwidget.edit_dialog.set_midi_program(midi_program_id)
  1110. pwidget.m_parameterIconTimer = ICON_STATE_ON
  1111. @pyqtSlot(int, int, int, int)
  1112. def slot_handleNoteOnCallback(self, plugin_id, channel, note, velo):
  1113. pwidget = self.m_plugin_list[plugin_id]
  1114. if pwidget:
  1115. pwidget.edit_dialog.keyboard.sendNoteOn(note, False)
  1116. @pyqtSlot(int, int, int)
  1117. def slot_handleNoteOffCallback(self, plugin_id, channel, note):
  1118. pwidget = self.m_plugin_list[plugin_id]
  1119. if pwidget:
  1120. pwidget.edit_dialog.keyboard.sendNoteOff(note, False)
  1121. @pyqtSlot(int, int)
  1122. def slot_handleShowGuiCallback(self, plugin_id, show):
  1123. pwidget = self.m_plugin_list[plugin_id]
  1124. if pwidget:
  1125. if show == 0:
  1126. pwidget.b_gui.setChecked(False)
  1127. pwidget.b_gui.setEnabled(True)
  1128. elif show == 1:
  1129. pwidget.b_gui.setChecked(True)
  1130. pwidget.b_gui.setEnabled(True)
  1131. elif show == -1:
  1132. pwidget.b_gui.setChecked(False)
  1133. pwidget.b_gui.setEnabled(False)
  1134. @pyqtSlot(int, int, int)
  1135. def slot_handleResizeGuiCallback(self, plugin_id, width, height):
  1136. pwidget = self.m_plugin_list[plugin_id]
  1137. if pwidget:
  1138. gui_dialog = pwidget.gui_dialog
  1139. if gui_dialog:
  1140. gui_dialog.setNewSize(width, height)
  1141. @pyqtSlot(int)
  1142. def slot_handleUpdateCallback(self, plugin_id):
  1143. pwidget = self.m_plugin_list[plugin_id]
  1144. if pwidget:
  1145. pwidget.edit_dialog.do_update()
  1146. @pyqtSlot(int)
  1147. def slot_handleReloadInfoCallback(self, plugin_id):
  1148. pwidget = self.m_plugin_list[plugin_id]
  1149. if pwidget:
  1150. pwidget.edit_dialog.do_reload_info()
  1151. @pyqtSlot(int)
  1152. def slot_handleReloadParametersCallback(self, plugin_id):
  1153. pwidget = self.m_plugin_list[plugin_id]
  1154. if pwidget:
  1155. pwidget.edit_dialog.do_reload_parameters()
  1156. @pyqtSlot(int)
  1157. def slot_handleReloadProgramsCallback(self, plugin_id):
  1158. pwidget = self.m_plugin_list[plugin_id]
  1159. if pwidget:
  1160. pwidget.edit_dialog.do_reload_programs()
  1161. @pyqtSlot(int)
  1162. def slot_handleReloadAllCallback(self, plugin_id):
  1163. pwidget = self.m_plugin_list[plugin_id]
  1164. if pwidget:
  1165. pwidget.edit_dialog.do_reload_all()
  1166. @pyqtSlot()
  1167. def slot_handleNSM_AnnounceCallback(self):
  1168. smName = self._nsmAnnounce2str
  1169. self.act_file_new.setEnabled(False)
  1170. self.act_file_open.setEnabled(False)
  1171. self.act_file_save_as.setEnabled(False)
  1172. self.setWindowTitle("Carla (%s)" % smName)
  1173. @pyqtSlot()
  1174. def slot_handleNSM_Open1Callback(self):
  1175. clientId = self._nsmOpen1str
  1176. # remove all previous plugins
  1177. self.slot_remove_all()
  1178. # restart engine
  1179. if Carla.host.is_engine_running():
  1180. self.stopEngine()
  1181. self.startEngine(clientId)
  1182. @pyqtSlot()
  1183. def slot_handleNSM_Open2Callback(self):
  1184. projectPath = self._nsmOpen2str
  1185. self.m_project_filename = projectPath
  1186. if os.path.exists(self.m_project_filename):
  1187. self.load_project()
  1188. else:
  1189. self.save_project()
  1190. self.setWindowTitle("Carla - %s" % os.path.basename(self.m_project_filename))
  1191. Carla.host.nsm_reply_open()
  1192. @pyqtSlot()
  1193. def slot_handleNSM_SaveCallback(self):
  1194. self.save_project()
  1195. Carla.host.nsm_reply_save()
  1196. @pyqtSlot(str)
  1197. def slot_handleErrorCallback(self, error):
  1198. QMessageBox.critical(self, self.tr("Error"), error)
  1199. @pyqtSlot()
  1200. def slot_handleQuitCallback(self):
  1201. CustomMessageBox(self, QMessageBox.Warning, self.tr("Warning"),
  1202. self.tr("JACK has been stopped or crashed.\nPlease start JACK and restart Carla"),
  1203. self.tr("You may want to save your session now..."), QMessageBox.Ok, QMessageBox.Ok)
  1204. def add_plugin(self, btype, ptype, filename, name, label, extra_stuff, activate):
  1205. if not self.m_engine_started:
  1206. if activate:
  1207. QMessageBox.warning(self, self.tr("Warning"), self.tr("Cannot add new plugins while engine is stopped"))
  1208. return -1
  1209. new_plugin_id = Carla.host.add_plugin(btype, ptype, filename, name, label, extra_stuff)
  1210. if new_plugin_id < 0:
  1211. CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), cString(Carla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok)
  1212. return -1
  1213. else:
  1214. pwidget = PluginWidget(self, new_plugin_id)
  1215. self.w_plugins.layout().addWidget(pwidget)
  1216. #self.m_scene.addWidget(new_plugin_id, pwidget)
  1217. self.m_plugin_list[new_plugin_id] = pwidget
  1218. self.act_plugin_remove_all.setEnabled(True)
  1219. pwidget.peak_in.setRefreshRate(self.m_savedSettings["Main/RefreshInterval"])
  1220. pwidget.peak_out.setRefreshRate(self.m_savedSettings["Main/RefreshInterval"])
  1221. if activate:
  1222. pwidget.set_active(True, True, True)
  1223. self.m_pluginCount += 1
  1224. return new_plugin_id
  1225. def remove_plugin(self, plugin_id, showError):
  1226. pwidget = self.m_plugin_list[plugin_id]
  1227. #if pwidget.edit_dialog == self.m_curEdit:
  1228. #self.w_edit.layout().removeWidget(self.m_curEdit)
  1229. #self.w_edit.layout().insertWidget(0, self.m_fakeEdit)
  1230. #self.m_fakeEdit.show()
  1231. #self.m_curEdit.hide()
  1232. #self.m_curEdit = self.m_fakeEdit
  1233. pwidget.edit_dialog.close()
  1234. if pwidget.gui_dialog:
  1235. pwidget.gui_dialog.close()
  1236. if Carla.host.remove_plugin(plugin_id):
  1237. pwidget.close()
  1238. pwidget.deleteLater()
  1239. self.w_plugins.layout().removeWidget(pwidget)
  1240. self.m_plugin_list[plugin_id] = None
  1241. self.m_pluginCount -= 1
  1242. elif showError:
  1243. CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to remove plugin"), cString(Carla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok)
  1244. # push all plugins 1 slot if rack mode
  1245. if Carla.processMode == PROCESS_MODE_CONTINUOUS_RACK:
  1246. for i in range(MAX_DEFAULT_PLUGINS-1):
  1247. if i < plugin_id: continue
  1248. self.m_plugin_list[i] = self.m_plugin_list[i+1]
  1249. if self.m_plugin_list[i]:
  1250. self.m_plugin_list[i].setId(i)
  1251. self.m_plugin_list[MAX_DEFAULT_PLUGINS-1] = None
  1252. # check if there are still plugins
  1253. for i in range(MAX_DEFAULT_PLUGINS):
  1254. if self.m_plugin_list[i]: break
  1255. else:
  1256. self.act_plugin_remove_all.setEnabled(False)
  1257. def get_extra_stuff(self, plugin):
  1258. ptype = plugin['type']
  1259. if ptype == PLUGIN_LADSPA:
  1260. unique_id = plugin['unique_id']
  1261. for rdf_item in self.ladspa_rdf_list:
  1262. if rdf_item.UniqueID == unique_id:
  1263. return pointer(rdf_item)
  1264. elif ptype == PLUGIN_DSSI:
  1265. if plugin['hints'] & PLUGIN_HAS_GUI:
  1266. gui = findDSSIGUI(plugin['binary'], plugin['name'], plugin['label'])
  1267. if gui:
  1268. return gui.encode("utf-8")
  1269. return c_nullptr
  1270. def save_project(self):
  1271. content = ("<?xml version='1.0' encoding='UTF-8'?>\n"
  1272. "<!DOCTYPE CARLA-PROJECT>\n"
  1273. "<CARLA-PROJECT VERSION='%s'>\n") % (VERSION)
  1274. first_plugin = True
  1275. for pwidget in self.m_plugin_list:
  1276. if pwidget:
  1277. if not first_plugin:
  1278. content += "\n"
  1279. real_plugin_name = cString(Carla.host.get_real_plugin_name(pwidget.m_pluginId))
  1280. if real_plugin_name:
  1281. content += " <!-- %s -->\n" % xmlSafeString(real_plugin_name, True)
  1282. content += " <Plugin>\n"
  1283. content += pwidget.getSaveXMLContent()
  1284. content += " </Plugin>\n"
  1285. first_plugin = False
  1286. content += "</CARLA-PROJECT>\n"
  1287. try:
  1288. fd = uopen(self.m_project_filename, "w")
  1289. fd.write(content)
  1290. fd.close()
  1291. except:
  1292. QMessageBox.critical(self, self.tr("Error"), self.tr("Failed to save project file"))
  1293. def load_project(self):
  1294. try:
  1295. fd = uopen(self.m_project_filename, "r")
  1296. projectRead = fd.read()
  1297. fd.close()
  1298. except:
  1299. projectRead = None
  1300. if not projectRead:
  1301. QMessageBox.critical(self, self.tr("Error"), self.tr("Failed to load project file"))
  1302. return
  1303. xml = QDomDocument()
  1304. xml.setContent(projectRead.encode("utf-8"))
  1305. xml_node = xml.documentElement()
  1306. if xml_node.tagName() != "CARLA-PROJECT":
  1307. QMessageBox.critical(self, self.tr("Error"), self.tr("Not a valid Carla project file"))
  1308. return
  1309. x_internal_plugins = None
  1310. x_ladspa_plugins = None
  1311. x_dssi_plugins = None
  1312. x_lv2_plugins = None
  1313. x_vst_plugins = None
  1314. x_gig_plugins = None
  1315. x_sf2_plugins = None
  1316. x_sfz_plugins = None
  1317. x_failedPlugins = []
  1318. x_saveStates = []
  1319. node = xml_node.firstChild()
  1320. while not node.isNull():
  1321. if node.toElement().tagName() == "Plugin":
  1322. x_saveState = getSaveStateDictFromXML(node)
  1323. x_saveStates.append(x_saveState)
  1324. node = node.nextSibling()
  1325. for x_saveState in x_saveStates:
  1326. ptype = x_saveState['Type']
  1327. label = x_saveState['Label']
  1328. binary = x_saveState['Binary']
  1329. binaryS = os.path.basename(binary)
  1330. unique_id = x_saveState['UniqueID']
  1331. if ptype == "Internal":
  1332. if not x_internal_plugins: x_internal_plugins = toList(self.settings_db.value("Plugins/Internal", []))
  1333. x_plugins = x_internal_plugins
  1334. elif ptype == "LADSPA":
  1335. if not x_ladspa_plugins:
  1336. x_ladspa_plugins = []
  1337. x_ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_native", []))
  1338. x_ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_posix32", []))
  1339. x_ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_posix64", []))
  1340. x_ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_win32", []))
  1341. x_ladspa_plugins += toList(self.settings_db.value("Plugins/LADSPA_win64", []))
  1342. x_plugins = x_ladspa_plugins
  1343. elif ptype == "DSSI":
  1344. if not x_dssi_plugins:
  1345. x_dssi_plugins = []
  1346. x_dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_native", []))
  1347. x_dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_posix32", []))
  1348. x_dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_posix64", []))
  1349. x_dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_win32", []))
  1350. x_dssi_plugins += toList(self.settings_db.value("Plugins/DSSI_win64", []))
  1351. x_plugins = x_dssi_plugins
  1352. elif ptype == "LV2":
  1353. if not x_lv2_plugins:
  1354. x_lv2_plugins = []
  1355. x_lv2_plugins += toList(self.settings_db.value("Plugins/LV2_native", []))
  1356. x_lv2_plugins += toList(self.settings_db.value("Plugins/LV2_posix32", []))
  1357. x_lv2_plugins += toList(self.settings_db.value("Plugins/LV2_posix64", []))
  1358. x_lv2_plugins += toList(self.settings_db.value("Plugins/LV2_win32", []))
  1359. x_lv2_plugins += toList(self.settings_db.value("Plugins/LV2_win64", []))
  1360. x_plugins = x_lv2_plugins
  1361. elif ptype == "VST":
  1362. if not x_vst_plugins:
  1363. x_vst_plugins = []
  1364. x_vst_plugins += toList(self.settings_db.value("Plugins/VST_native", []))
  1365. x_vst_plugins += toList(self.settings_db.value("Plugins/VST_posix32", []))
  1366. x_vst_plugins += toList(self.settings_db.value("Plugins/VST_posix64", []))
  1367. x_vst_plugins += toList(self.settings_db.value("Plugins/VST_win32", []))
  1368. x_vst_plugins += toList(self.settings_db.value("Plugins/VST_win64", []))
  1369. x_plugins = x_vst_plugins
  1370. elif ptype == "GIG":
  1371. if not x_gig_plugins: x_gig_plugins = toList(self.settings_db.value("Plugins/GIG", []))
  1372. x_plugins = x_gig_plugins
  1373. elif ptype == "SF2":
  1374. if not x_sf2_plugins: x_sf2_plugins = toList(self.settings_db.value("Plugins/SF2", []))
  1375. x_plugins = x_sf2_plugins
  1376. elif ptype == "SFZ":
  1377. if not x_sfz_plugins: x_sfz_plugins = toList(self.settings_db.value("Plugins/SFZ", []))
  1378. x_plugins = x_sfz_plugins
  1379. else:
  1380. print("load_project() - ptype '%s' not recognized" % ptype)
  1381. x_failedPlugins.append(x_saveState['Name'])
  1382. continue
  1383. # Try UniqueID -> Label -> Binary (full) -> Binary (short)
  1384. plugin_ulB = None
  1385. plugin_ulb = None
  1386. plugin_ul = None
  1387. plugin_uB = None
  1388. plugin_ub = None
  1389. plugin_lB = None
  1390. plugin_lb = None
  1391. plugin_u = None
  1392. plugin_l = None
  1393. plugin_B = None
  1394. for _plugins in x_plugins:
  1395. for x_plugin in _plugins:
  1396. if unique_id == x_plugin['unique_id'] and label == x_plugin['label'] and binary == x_plugin['binary']:
  1397. plugin_ulB = x_plugin
  1398. break
  1399. elif unique_id == x_plugin['unique_id'] and label == x_plugin['label'] and binaryS == os.path.basename(x_plugin['binary']):
  1400. plugin_ulb = x_plugin
  1401. elif unique_id == x_plugin['unique_id'] and label == x_plugin['label']:
  1402. plugin_ul = x_plugin
  1403. elif unique_id == x_plugin['unique_id'] and binary == x_plugin['binary']:
  1404. plugin_uB = x_plugin
  1405. elif unique_id == x_plugin['unique_id'] and binaryS == os.path.basename(x_plugin['binary']):
  1406. plugin_ub = x_plugin
  1407. elif label == x_plugin['label'] and binary == x_plugin['binary']:
  1408. plugin_lB = x_plugin
  1409. elif label == x_plugin['label'] and binaryS == os.path.basename(x_plugin['binary']):
  1410. plugin_lb = x_plugin
  1411. elif unique_id == x_plugin['unique_id']:
  1412. plugin_u = x_plugin
  1413. elif label == x_plugin['label']:
  1414. plugin_l = x_plugin
  1415. elif binary == x_plugin['binary']:
  1416. plugin_B = x_plugin
  1417. # LADSPA uses UniqueID or binary+label
  1418. if ptype == "LADSPA":
  1419. plugin_l = None
  1420. plugin_B = None
  1421. # DSSI uses binary+label (UniqueID ignored)
  1422. elif ptype == "DSSI":
  1423. plugin_ul = None
  1424. plugin_uB = None
  1425. plugin_ub = None
  1426. plugin_u = None
  1427. plugin_l = None
  1428. plugin_B = None
  1429. # LV2 uses URIs (label in this case)
  1430. elif ptype == "LV2":
  1431. plugin_uB = None
  1432. plugin_ub = None
  1433. plugin_u = None
  1434. plugin_B = None
  1435. # VST uses UniqueID
  1436. elif ptype == "VST":
  1437. plugin_lB = None
  1438. plugin_lb = None
  1439. plugin_l = None
  1440. plugin_B = None
  1441. # Sound Kits use binaries
  1442. elif ptype in ("GIG", "SF2", "SFZ"):
  1443. plugin_ul = None
  1444. plugin_u = None
  1445. plugin_l = None
  1446. plugin_B = binary
  1447. if plugin_ulB:
  1448. plugin = plugin_ulB
  1449. elif plugin_ulb:
  1450. plugin = plugin_ulb
  1451. elif plugin_ul:
  1452. plugin = plugin_ul
  1453. elif plugin_uB:
  1454. plugin = plugin_uB
  1455. elif plugin_ub:
  1456. plugin = plugin_ub
  1457. elif plugin_lB:
  1458. plugin = plugin_lB
  1459. elif plugin_lb:
  1460. plugin = plugin_lb
  1461. elif plugin_u:
  1462. plugin = plugin_u
  1463. elif plugin_l:
  1464. plugin = plugin_l
  1465. elif plugin_B:
  1466. plugin = plugin_B
  1467. else:
  1468. plugin = None
  1469. if plugin:
  1470. btype = plugin['build']
  1471. ptype = plugin['type']
  1472. filename = plugin['binary']
  1473. name = x_saveState['Name']
  1474. label = plugin['label']
  1475. extra_stuff = self.get_extra_stuff(plugin)
  1476. new_plugin_id = self.add_plugin(btype, ptype, filename, name, label, extra_stuff, False)
  1477. if new_plugin_id >= 0:
  1478. pwidget = self.m_plugin_list[new_plugin_id]
  1479. pwidget.loadStateDict(x_saveState)
  1480. else:
  1481. x_failedPlugins.append(x_saveState['Name'])
  1482. else:
  1483. x_failedPlugins.append(x_saveState['Name'])
  1484. if len(x_failedPlugins) > 0:
  1485. text = self.tr("The following plugins were not found or failed to initialize:\n")
  1486. for plugin in x_failedPlugins:
  1487. text += " - %s\n" % plugin
  1488. self.statusBar().showMessage("State file loaded with errors")
  1489. QMessageBox.critical(self, self.tr("Error"), text)
  1490. else:
  1491. self.statusBar().showMessage("State file loaded sucessfully!")
  1492. def loadRDFs(self):
  1493. # Save RDF info for later
  1494. if haveLRDF:
  1495. SettingsDir = os.path.join(HOME, ".config", "Cadence")
  1496. fr_ladspa_file = os.path.join(SettingsDir, "ladspa_rdf.db")
  1497. if os.path.exists(fr_ladspa_file):
  1498. fr_ladspa = open(fr_ladspa_file, 'r')
  1499. try:
  1500. self.ladspa_rdf_list = ladspa_rdf.get_c_ladspa_rdfs(json.load(fr_ladspa))
  1501. except:
  1502. self.ladspa_rdf_list = []
  1503. fr_ladspa.close()
  1504. return
  1505. self.ladspa_rdf_list = []
  1506. @pyqtSlot()
  1507. def slot_file_new(self):
  1508. self.slot_remove_all()
  1509. self.m_project_filename = None
  1510. self.setWindowTitle("Carla")
  1511. @pyqtSlot()
  1512. def slot_file_open(self):
  1513. fileFilter = self.tr("Carla Project File (*.carxp)")
  1514. filenameTry = QFileDialog.getOpenFileName(self, self.tr("Open Carla Project File"), self.m_savedSettings["Main/DefaultProjectFolder"], filter=fileFilter)
  1515. if filenameTry:
  1516. self.m_project_filename = filenameTry
  1517. self.slot_remove_all()
  1518. self.load_project()
  1519. self.setWindowTitle("Carla - %s" % os.path.basename(self.m_project_filename))
  1520. @pyqtSlot()
  1521. def slot_file_save(self, saveAs=False):
  1522. if self.m_project_filename == None or saveAs:
  1523. fileFilter = self.tr("Carla Project File (*.carxp)")
  1524. filenameTry = QFileDialog.getSaveFileName(self, self.tr("Save Carla Project File"), self.m_savedSettings["Main/DefaultProjectFolder"], filter=fileFilter)
  1525. if filenameTry:
  1526. if not filenameTry.endswith(".carxp"):
  1527. filenameTry += ".carxp"
  1528. self.m_project_filename = filenameTry
  1529. self.save_project()
  1530. self.setWindowTitle("Carla - %s" % os.path.basename(self.m_project_filename))
  1531. else:
  1532. self.save_project()
  1533. @pyqtSlot()
  1534. def slot_file_save_as(self):
  1535. self.slot_file_save(True)
  1536. @pyqtSlot()
  1537. def slot_plugin_add(self):
  1538. dialog = PluginDatabaseW(self)
  1539. if dialog.exec_():
  1540. btype = dialog.ret_plugin['build']
  1541. ptype = dialog.ret_plugin['type']
  1542. filename = dialog.ret_plugin['binary']
  1543. label = dialog.ret_plugin['label']
  1544. extra_stuff = self.get_extra_stuff(dialog.ret_plugin)
  1545. self.add_plugin(btype, ptype, filename, None, label, extra_stuff, True)
  1546. @pyqtSlot()
  1547. def slot_remove_all(self):
  1548. h = 0
  1549. for i in range(MAX_DEFAULT_PLUGINS):
  1550. pwidget = self.m_plugin_list[i]
  1551. if not pwidget:
  1552. continue
  1553. pwidget.setId(i-h)
  1554. pwidget.edit_dialog.close()
  1555. if pwidget.gui_dialog:
  1556. pwidget.gui_dialog.close()
  1557. if Carla.host.remove_plugin(i-h):
  1558. pwidget.close()
  1559. pwidget.deleteLater()
  1560. self.w_plugins.layout().removeWidget(pwidget)
  1561. self.m_plugin_list[i] = None
  1562. if Carla.processMode == PROCESS_MODE_CONTINUOUS_RACK:
  1563. h += 1
  1564. self.m_pluginCount = 0
  1565. self.act_plugin_remove_all.setEnabled(False)
  1566. @pyqtSlot()
  1567. def slot_configureCarla(self):
  1568. dialog = SettingsW(self, "carla")
  1569. if dialog.exec_():
  1570. self.loadSettings(False)
  1571. for pwidget in self.m_plugin_list:
  1572. if pwidget:
  1573. pwidget.peak_in.setRefreshRate(self.m_savedSettings["Main/RefreshInterval"])
  1574. pwidget.peak_out.setRefreshRate(self.m_savedSettings["Main/RefreshInterval"])
  1575. @pyqtSlot()
  1576. def slot_aboutCarla(self):
  1577. CarlaAboutW(self).exec_()
  1578. def saveSettings(self):
  1579. self.settings.setValue("Geometry", self.saveGeometry())
  1580. self.settings.setValue("ShowToolbar", self.toolBar.isVisible())
  1581. def loadSettings(self, geometry):
  1582. if geometry:
  1583. self.restoreGeometry(self.settings.value("Geometry", ""))
  1584. show_toolbar = self.settings.value("ShowToolbar", True, type=bool)
  1585. self.act_settings_show_toolbar.setChecked(show_toolbar)
  1586. self.toolBar.setVisible(show_toolbar)
  1587. self.m_savedSettings = {
  1588. "Main/DefaultProjectFolder": self.settings.value("Main/DefaultProjectFolder", DEFAULT_PROJECT_FOLDER, type=str),
  1589. "Main/RefreshInterval": self.settings.value("Main/RefreshInterval", 120, type=int)
  1590. }
  1591. # ---------------------------------------------
  1592. # plugin checks
  1593. disableChecks = self.settings.value("Engine/DisableChecks", False, type=bool)
  1594. if disableChecks:
  1595. os.environ["CARLA_DISCOVERY_NO_PROCESSING_CHECKS"] = "true"
  1596. elif os.getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS"):
  1597. os.environ.pop("CARLA_DISCOVERY_NO_PROCESSING_CHECKS")
  1598. # ---------------------------------------------
  1599. # plugin paths
  1600. global LADSPA_PATH, DSSI_PATH, LV2_PATH, VST_PATH, GIG_PATH, SF2_PATH, SFZ_PATH
  1601. LADSPA_PATH = toList(self.settings.value("Paths/LADSPA", LADSPA_PATH))
  1602. DSSI_PATH = toList(self.settings.value("Paths/DSSI", DSSI_PATH))
  1603. LV2_PATH = toList(self.settings.value("Paths/LV2", LV2_PATH))
  1604. VST_PATH = toList(self.settings.value("Paths/VST", VST_PATH))
  1605. GIG_PATH = toList(self.settings.value("Paths/GIG", GIG_PATH))
  1606. SF2_PATH = toList(self.settings.value("Paths/SF2", SF2_PATH))
  1607. SFZ_PATH = toList(self.settings.value("Paths/SFZ", SFZ_PATH))
  1608. os.environ["LADSPA_PATH"] = splitter.join(LADSPA_PATH)
  1609. os.environ["DSSI_PATH"] = splitter.join(DSSI_PATH)
  1610. os.environ["LV2_PATH"] = splitter.join(LV2_PATH)
  1611. os.environ["VST_PATH"] = splitter.join(VST_PATH)
  1612. os.environ["GIG_PATH"] = splitter.join(GIG_PATH)
  1613. os.environ["SF2_PATH"] = splitter.join(SF2_PATH)
  1614. os.environ["SFZ_PATH"] = splitter.join(SFZ_PATH)
  1615. #def resizeEvent(self, event):
  1616. #self.m_scene.resize()
  1617. #QMainWindow.resizeEvent(self, event)
  1618. def timerEvent(self, event):
  1619. if event.timerId() == self.TIMER_GUI_STUFF:
  1620. for pwidget in self.m_plugin_list:
  1621. if pwidget: pwidget.check_gui_stuff()
  1622. if self.m_engine_started and self.m_pluginCount > 0:
  1623. Carla.host.idle_guis()
  1624. elif event.timerId() == self.TIMER_GUI_STUFF2:
  1625. for pwidget in self.m_plugin_list:
  1626. if pwidget: pwidget.check_gui_stuff2()
  1627. QMainWindow.timerEvent(self, event)
  1628. def closeEvent(self, event):
  1629. if self.nsm_server:
  1630. self.nsm_server.stop()
  1631. self.saveSettings()
  1632. self.slot_remove_all()
  1633. QMainWindow.closeEvent(self, event)
  1634. # ------------------------------------------------------------------------------------------------
  1635. def callback_function(ptr, action, pluginId, value1, value2, value3, valueStr):
  1636. if pluginId< 0 or pluginId >= MAX_DEFAULT_PLUGINS or not Carla.gui:
  1637. return
  1638. if action == CALLBACK_DEBUG:
  1639. Carla.gui.emit(SIGNAL("DebugCallback(int, int, int, double, QString)"), pluginId, value1, value2, value3, cString(valueStr))
  1640. elif action == CALLBACK_PARAMETER_VALUE_CHANGED:
  1641. Carla.gui.emit(SIGNAL("ParameterValueCallback(int, int, double)"), pluginId, value1, value3)
  1642. elif action == CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED:
  1643. Carla.gui.emit(SIGNAL("ParameterMidiChannelCallback(int, int, int)"), pluginId, value1, value2)
  1644. elif action == CALLBACK_PARAMETER_MIDI_CC_CHANGED:
  1645. Carla.gui.emit(SIGNAL("ParameterMidiCcCallback(int, int, int)"), pluginId, value1, value2)
  1646. elif action == CALLBACK_PROGRAM_CHANGED:
  1647. Carla.gui.emit(SIGNAL("ProgramCallback(int, int)"), pluginId, value1)
  1648. elif action == CALLBACK_MIDI_PROGRAM_CHANGED:
  1649. Carla.gui.emit(SIGNAL("MidiProgramCallback(int, int)"), pluginId, value1)
  1650. elif action == CALLBACK_NOTE_ON:
  1651. Carla.gui.emit(SIGNAL("NoteOnCallback(int, int, int, int)"), pluginId, value1, value2, value3)
  1652. elif action == CALLBACK_NOTE_OFF:
  1653. Carla.gui.emit(SIGNAL("NoteOffCallback(int, int, int)"), pluginId, value1, value2)
  1654. elif action == CALLBACK_SHOW_GUI:
  1655. Carla.gui.emit(SIGNAL("ShowGuiCallback(int, int)"), pluginId, value1)
  1656. elif action == CALLBACK_UPDATE:
  1657. Carla.gui.emit(SIGNAL("UpdateCallback(int)"), pluginId)
  1658. elif action == CALLBACK_RELOAD_INFO:
  1659. Carla.gui.emit(SIGNAL("ReloadInfoCallback(int)"), pluginId)
  1660. elif action == CALLBACK_RELOAD_PARAMETERS:
  1661. Carla.gui.emit(SIGNAL("ReloadParametersCallback(int)"), pluginId)
  1662. elif action == CALLBACK_RELOAD_PROGRAMS:
  1663. Carla.gui.emit(SIGNAL("ReloadProgramsCallback(int)"), pluginId)
  1664. elif action == CALLBACK_RELOAD_ALL:
  1665. Carla.gui.emit(SIGNAL("ReloadAllCallback(int)"), pluginId)
  1666. elif action == CALLBACK_NSM_ANNOUNCE:
  1667. Carla.gui._nsmAnnounce2str = cString(Carla.host.get_last_error())
  1668. Carla.gui.emit(SIGNAL("NSM_AnnounceCallback()"))
  1669. elif action == CALLBACK_NSM_OPEN1:
  1670. Carla.gui._nsmOpen1str = cString(valueStr)
  1671. Carla.gui.emit(SIGNAL("NSM_Open1Callback()"))
  1672. elif action == CALLBACK_NSM_OPEN2:
  1673. Carla.gui._nsmOpen2str = cString(valueStr)
  1674. Carla.gui.emit(SIGNAL("NSM_Open2Callback()"))
  1675. elif action == CALLBACK_NSM_SAVE:
  1676. Carla.gui.emit(SIGNAL("NSM_SaveCallback()"))
  1677. elif action == CALLBACK_ERROR:
  1678. Carla.gui.emit(SIGNAL("ErrorCallback(QString)"), cString(Carla.host.get_last_error()))
  1679. elif action == CALLBACK_QUIT:
  1680. Carla.gui.emit(SIGNAL("QuitCallback()"))
  1681. #--------------- main ------------------
  1682. if __name__ == '__main__':
  1683. # App initialization
  1684. app = QApplication(sys.argv)
  1685. app.setApplicationName("Carla")
  1686. app.setApplicationVersion(VERSION)
  1687. app.setOrganizationName("Cadence")
  1688. app.setWindowIcon(QIcon(":/scalable/carla.svg"))
  1689. libPrefix = None
  1690. projectFilename = None
  1691. for i in range(len(app.arguments())):
  1692. if i == 0: continue
  1693. argument = app.arguments()[i]
  1694. if argument.startswith("--with-libprefix="):
  1695. libPrefix = argument.replace("--with-libprefix=", "")
  1696. elif os.path.exists(argument):
  1697. projectFilename = argument
  1698. # Init backend
  1699. Carla.host = Host(libPrefix)
  1700. #Carla.host.set_callback_function(callback_function)
  1701. #Carla.host.set_option(OPTION_PROCESS_NAME, 0, "carla")
  1702. # Set bridge paths
  1703. #if carla_bridge_posix32:
  1704. #Carla.host.set_option(OPTION_PATH_BRIDGE_POSIX32, 0, carla_bridge_posix32)
  1705. #if carla_bridge_posix64:
  1706. #Carla.host.set_option(OPTION_PATH_BRIDGE_POSIX64, 0, carla_bridge_posix64)
  1707. #if carla_bridge_win32:
  1708. #Carla.host.set_option(OPTION_PATH_BRIDGE_WIN32, 0, carla_bridge_win32)
  1709. #if carla_bridge_win64:
  1710. #Carla.host.set_option(OPTION_PATH_BRIDGE_WIN64, 0, carla_bridge_win64)
  1711. #if WINDOWS:
  1712. #if carla_bridge_lv2_windows:
  1713. #Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_WINDOWS, 0, carla_bridge_lv2_windows)
  1714. #if carla_bridge_vst_hwnd:
  1715. #Carla.host.set_option(OPTION_PATH_BRIDGE_VST_HWND, 0, carla_bridge_vst_hwnd)
  1716. #elif MACOS:
  1717. #if carla_bridge_lv2_cocoa:
  1718. #Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_COCOA, 0, carla_bridge_lv2_cocoa)
  1719. #if carla_bridge_vst_cocoa:
  1720. #Carla.host.set_option(OPTION_PATH_BRIDGE_VST_COCOA, 0, carla_bridge_vst_cocoa)
  1721. #else:
  1722. #if carla_bridge_lv2_gtk2:
  1723. #Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_GTK2, 0, carla_bridge_lv2_gtk2)
  1724. #if carla_bridge_lv2_gtk3:
  1725. #Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_GTK3, 0, carla_bridge_lv2_gtk3)
  1726. #if carla_bridge_lv2_qt4:
  1727. #Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_QT4, 0, carla_bridge_lv2_qt4)
  1728. #if carla_bridge_lv2_qt5:
  1729. #Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_QT5, 0, carla_bridge_lv2_qt5)
  1730. #if carla_bridge_lv2_x11:
  1731. #Carla.host.set_option(OPTION_PATH_BRIDGE_LV2_X11, 0, carla_bridge_lv2_x11)
  1732. #if carla_bridge_vst_x11:
  1733. #Carla.host.set_option(OPTION_PATH_BRIDGE_VST_X11, 0, carla_bridge_vst_x11)
  1734. # Set available drivers
  1735. driverCount = Carla.host.get_engine_driver_count()
  1736. driverList = []
  1737. for i in range(driverCount):
  1738. driver = cString(Carla.host.get_engine_driver_name(i))
  1739. if driver:
  1740. driverList.append(driver)
  1741. #setAvailableEngineDrivers(driverList)
  1742. # Create GUI and start engine
  1743. Carla.gui = CarlaMainW()
  1744. # Set-up custom signal handling
  1745. #setUpSignals(Carla.gui)
  1746. # Show GUI
  1747. Carla.gui.show()
  1748. # Load project file if set
  1749. if projectFilename:
  1750. Carla.gui.m_project_filename = projectFilename
  1751. Carla.gui.loadProjectLater()
  1752. Carla.gui.setWindowTitle("Carla - %s" % os.path.basename(projectFilename)) # FIXME - put in loadProject
  1753. # App-Loop
  1754. ret = app.exec_()
  1755. # Close Host
  1756. Carla.gui.stopEngine()
  1757. # Exit properly
  1758. sys.exit(ret)