Collection of tools useful for audio production
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.

2141 lines
91KB

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