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.

809 lines
35KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla settings code
  4. # Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  5. #
  6. # This program is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU General Public License as
  8. # published by the Free Software Foundation; either version 2 of
  9. # the License, or any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # For a full copy of the GNU General Public License see the doc/GPL.txt file.
  17. # ------------------------------------------------------------------------------------------------------------
  18. # Imports (Global)
  19. from PyQt4.QtCore import pyqtSlot, QByteArray, QDir, QSettings
  20. from PyQt4.QtGui import QColor, QCursor, QFontMetrics, QPainter, QPainterPath
  21. from PyQt4.QtGui import QDialog, QDialogButtonBox, QFrame, QInputDialog, QLineEdit, QMenu, QVBoxLayout, QWidget
  22. # ------------------------------------------------------------------------------------------------------------
  23. # Imports (Custom)
  24. import ui_carla_settings
  25. import ui_carla_settings_driver
  26. from carla_style import *
  27. from patchcanvas_theme import *
  28. # ------------------------------------------------------------------------------------------------------------
  29. # PatchCanvas defines
  30. CANVAS_ANTIALIASING_SMALL = 1
  31. CANVAS_EYECANDY_SMALL = 1
  32. # ------------------------------------------------------------------------------------------------------------
  33. # Carla defaults
  34. # Main
  35. CARLA_DEFAULT_MAIN_PROJECT_FOLDER = QDir.homePath()
  36. CARLA_DEFAULT_MAIN_USE_PRO_THEME = True
  37. CARLA_DEFAULT_MAIN_PRO_THEME_COLOR = "Black"
  38. CARLA_DEFAULT_MAIN_REFRESH_INTERVAL = 20
  39. # Canvas
  40. CARLA_DEFAULT_CANVAS_THEME = "Modern Dark"
  41. CARLA_DEFAULT_CANVAS_SIZE = "3100x2400"
  42. CARLA_DEFAULT_CANVAS_SIZE_WIDTH = 3100
  43. CARLA_DEFAULT_CANVAS_SIZE_HEIGHT = 2400
  44. CARLA_DEFAULT_CANVAS_USE_BEZIER_LINES = True
  45. CARLA_DEFAULT_CANVAS_AUTO_HIDE_GROUPS = False
  46. CARLA_DEFAULT_CANVAS_EYE_CANDY = CANVAS_EYECANDY_SMALL
  47. CARLA_DEFAULT_CANVAS_USE_OPENGL = False
  48. CARLA_DEFAULT_CANVAS_ANTIALIASING = CANVAS_ANTIALIASING_SMALL
  49. CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING = False
  50. # Engine
  51. CARLA_DEFAULT_FORCE_STEREO = False
  52. CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES = False
  53. CARLA_DEFAULT_PREFER_UI_BRIDGES = True
  54. CARLA_DEFAULT_UIS_ALWAYS_ON_TOP = True
  55. CARLA_DEFAULT_MAX_PARAMETERS = MAX_DEFAULT_PARAMETERS
  56. CARLA_DEFAULT_UI_BRIDGES_TIMEOUT = 4000
  57. CARLA_DEFAULT_AUDIO_NUM_PERIODS = 2
  58. CARLA_DEFAULT_AUDIO_BUFFER_SIZE = 512
  59. CARLA_DEFAULT_AUDIO_SAMPLE_RATE = 44100
  60. if WINDOWS:
  61. CARLA_DEFAULT_AUDIO_DRIVER = "DirectSound"
  62. elif MACOS:
  63. CARLA_DEFAULT_AUDIO_DRIVER = "CoreAudio"
  64. else:
  65. CARLA_DEFAULT_AUDIO_DRIVER = "JACK"
  66. if LINUX:
  67. CARLA_DEFAULT_PROCESS_MODE = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS
  68. CARLA_DEFAULT_TRANSPORT_MODE = ENGINE_TRANSPORT_MODE_JACK
  69. else:
  70. CARLA_DEFAULT_PROCESS_MODE = ENGINE_PROCESS_MODE_CONTINUOUS_RACK
  71. CARLA_DEFAULT_TRANSPORT_MODE = ENGINE_TRANSPORT_MODE_INTERNAL
  72. # ------------------------------------------------------------------------------------------------------------
  73. # ...
  74. BUFFER_SIZE_LIST = (16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192)
  75. SAMPLE_RATE_LIST = (22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000)
  76. # ------------------------------------------------------------------------------------------------------------
  77. # Driver Settings
  78. class DriverSettingsW(QDialog):
  79. def __init__(self, parent, driverIndex, driverName):
  80. QDialog.__init__(self, parent)
  81. self.ui = ui_carla_settings_driver.Ui_DriverSettingsW()
  82. self.ui.setupUi(self)
  83. # -------------------------------------------------------------
  84. # Internal stuff
  85. self.fDriverIndex = driverIndex
  86. self.fDriverName = driverName
  87. self.fDeviceNames = gCarla.host.get_engine_driver_device_names(driverIndex) if gCarla.host is not None else []
  88. self.fBufferSizes = BUFFER_SIZE_LIST
  89. self.fSampleRates = SAMPLE_RATE_LIST
  90. # -------------------------------------------------------------
  91. # Set-up GUI
  92. for name in self.fDeviceNames:
  93. self.ui.cb_device.addItem(name)
  94. # -------------------------------------------------------------
  95. # Load settings
  96. self.loadSettings()
  97. # -------------------------------------------------------------
  98. # Set-up connections
  99. self.accepted.connect(self.slot_saveSettings)
  100. self.ui.cb_device.currentIndexChanged.connect(self.slot_updateDeviceInfo)
  101. # -------------------------------------------------------------
  102. def loadSettings(self):
  103. settings = QSettings()
  104. audioDevice = settings.value("%s%s/Device" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), "", type=str)
  105. audioNumPeriods = settings.value("%s%s/NumPeriods" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_NUM_PERIODS, type=int)
  106. audioBufferSize = settings.value("%s%s/BufferSize" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_BUFFER_SIZE, type=int)
  107. audioSampleRate = settings.value("%s%s/SampleRate" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_SAMPLE_RATE, type=int)
  108. if audioDevice and audioDevice in self.fDeviceNames:
  109. self.ui.cb_device.setCurrentIndex(self.fDeviceNames.index(audioDevice))
  110. else:
  111. self.ui.cb_device.setCurrentIndex(-1)
  112. # fill combo-boxes first
  113. self.slot_updateDeviceInfo()
  114. if audioNumPeriods in (2, 3):
  115. self.ui.sb_numperiods.setValue(audioNumPeriods)
  116. else:
  117. self.ui.sb_numperiods.setValue(CARLA_DEFAULT_AUDIO_NUM_PERIODS)
  118. if audioBufferSize and audioBufferSize in self.fBufferSizes:
  119. self.ui.cb_buffersize.setCurrentIndex(self.fBufferSizes.index(audioBufferSize))
  120. elif self.fBufferSizes == BUFFER_SIZE_LIST:
  121. self.ui.cb_buffersize.setCurrentIndex(BUFFER_SIZE_LIST.index(CARLA_DEFAULT_AUDIO_BUFFER_SIZE))
  122. else:
  123. self.ui.cb_buffersize.setCurrentIndex(len(self.fBufferSizes)/2)
  124. if audioSampleRate and audioSampleRate in self.fSampleRates:
  125. self.ui.cb_samplerate.setCurrentIndex(self.fSampleRates.index(audioSampleRate))
  126. elif self.fSampleRates == SAMPLE_RATE_LIST:
  127. self.ui.cb_samplerate.setCurrentIndex(SAMPLE_RATE_LIST.index(CARLA_DEFAULT_AUDIO_SAMPLE_RATE))
  128. else:
  129. self.ui.cb_samplerate.setCurrentIndex(len(self.fSampleRates)/2)
  130. @pyqtSlot()
  131. def slot_saveSettings(self):
  132. settings = QSettings()
  133. settings.setValue("%s%s/Device" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), self.ui.cb_device.currentText())
  134. settings.setValue("%s%s/NumPeriods" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), self.ui.sb_numperiods.value())
  135. settings.setValue("%s%s/BufferSize" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), self.ui.cb_buffersize.currentText())
  136. settings.setValue("%s%s/SampleRate" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), self.ui.cb_samplerate.currentText())
  137. @pyqtSlot()
  138. def slot_updateDeviceInfo(self):
  139. deviceName = self.ui.cb_device.currentText()
  140. oldBufferSize = self.ui.cb_buffersize.currentText()
  141. oldSampleRate = self.ui.cb_samplerate.currentText()
  142. self.ui.cb_buffersize.clear()
  143. self.ui.cb_samplerate.clear()
  144. if deviceName and gCarla.host is not None:
  145. driverDeviceInfo = gCarla.host.get_engine_driver_device_info(self.fDriverIndex, deviceName)
  146. self.fBufferSizes = driverDeviceInfo['bufferSizes']
  147. self.fSampleRates = driverDeviceInfo['sampleRates']
  148. else:
  149. self.fBufferSizes = BUFFER_SIZE_LIST
  150. self.fSampleRates = SAMPLE_RATE_LIST
  151. for bsize in self.fBufferSizes:
  152. sbsize = str(bsize)
  153. self.ui.cb_buffersize.addItem(sbsize)
  154. if oldBufferSize == sbsize:
  155. self.ui.cb_buffersize.setCurrentIndex(self.ui.cb_buffersize.count()-1)
  156. for srate in self.fSampleRates:
  157. ssrate = str(int(srate))
  158. self.ui.cb_samplerate.addItem(ssrate)
  159. if oldSampleRate == ssrate:
  160. self.ui.cb_samplerate.setCurrentIndex(self.ui.cb_samplerate.count()-1)
  161. def done(self, r):
  162. QDialog.done(self, r)
  163. self.close()
  164. # ------------------------------------------------------------------------------------------------------------
  165. # Settings Dialog
  166. class CarlaSettingsW(QDialog):
  167. # Tab indexes
  168. TAB_INDEX_MAIN = 0
  169. TAB_INDEX_CANVAS = 1
  170. TAB_INDEX_ENGINE = 2
  171. TAB_INDEX_PATHS = 3
  172. TAB_INDEX_NONE = 4
  173. # Path indexes
  174. PATH_INDEX_LADSPA = 0
  175. PATH_INDEX_DSSI = 1
  176. PATH_INDEX_LV2 = 2
  177. PATH_INDEX_VST = 3
  178. PATH_INDEX_AU = 4
  179. PATH_INDEX_CSOUND = 5
  180. PATH_INDEX_GIG = 6
  181. PATH_INDEX_SF2 = 7
  182. PATH_INDEX_SFZ = 8
  183. # Single and Multiple client mode is only for JACK,
  184. # but we still want to match QComboBox index to defines,
  185. # so add +2 pos padding if driverName != "JACK".
  186. PROCESS_MODE_NON_JACK_PADDING = 2
  187. def __init__(self, parent, hasCanvas, hasCanvasGL):
  188. QDialog.__init__(self, parent)
  189. self.ui = ui_carla_settings.Ui_CarlaSettingsW()
  190. self.ui.setupUi(self)
  191. # -------------------------------------------------------------
  192. # Set-up GUI
  193. if gCarla.host is not None:
  194. for i in range(gCarla.host.get_engine_driver_count()):
  195. self.ui.cb_engine_audio_driver.addItem(gCarla.host.get_engine_driver_name(i))
  196. else:
  197. self.ui.tb_engine_driver_config.setEnabled(False)
  198. for i in range(Theme.THEME_MAX):
  199. self.ui.cb_canvas_theme.addItem(getThemeName(i))
  200. # -------------------------------------------------------------
  201. # Load settings
  202. self.loadSettings()
  203. if not hasCanvas:
  204. self.ui.lw_page.hideRow(self.TAB_INDEX_CANVAS)
  205. if not hasCanvasGL:
  206. self.ui.cb_canvas_use_opengl.setChecked(False)
  207. self.ui.cb_canvas_use_opengl.setEnabled(False)
  208. if WINDOWS:
  209. self.ui.group_main_theme.setEnabled(False)
  210. self.ui.ch_main_theme_pro.setChecked(False)
  211. if not MACOS:
  212. self.ui.cb_paths.removeItem(self.ui.cb_paths.findText("AU"))
  213. if gCarla.isPlugin:
  214. self.ui.lw_page.hideRow(self.TAB_INDEX_ENGINE)
  215. self.ui.lw_page.hideRow(self.TAB_INDEX_PATHS)
  216. # -------------------------------------------------------------
  217. # Set-up connections
  218. self.accepted.connect(self.slot_saveSettings)
  219. self.ui.buttonBox.button(QDialogButtonBox.Reset).clicked.connect(self.slot_resetSettings)
  220. self.ui.b_main_proj_folder_open.clicked.connect(self.slot_getAndSetProjectPath)
  221. self.ui.cb_engine_audio_driver.currentIndexChanged.connect(self.slot_engineAudioDriverChanged)
  222. self.ui.tb_engine_driver_config.clicked.connect(self.slot_showAudioDriverSettings)
  223. self.ui.b_paths_add.clicked.connect(self.slot_addPluginPath)
  224. self.ui.b_paths_remove.clicked.connect(self.slot_removePluginPath)
  225. self.ui.b_paths_change.clicked.connect(self.slot_changePluginPath)
  226. self.ui.cb_paths.currentIndexChanged.connect(self.slot_pluginPathTabChanged)
  227. self.ui.lw_ladspa.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  228. self.ui.lw_dssi.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  229. self.ui.lw_lv2.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  230. self.ui.lw_vst.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  231. self.ui.lw_au.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  232. self.ui.lw_csound.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  233. self.ui.lw_gig.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  234. self.ui.lw_sf2.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  235. self.ui.lw_sfz.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  236. # -------------------------------------------------------------
  237. # Post-connect setup
  238. self.ui.lw_ladspa.setCurrentRow(0)
  239. self.ui.lw_dssi.setCurrentRow(0)
  240. self.ui.lw_lv2.setCurrentRow(0)
  241. self.ui.lw_vst.setCurrentRow(0)
  242. self.ui.lw_au.setCurrentRow(0)
  243. self.ui.lw_csound.setCurrentRow(0)
  244. self.ui.lw_gig.setCurrentRow(0)
  245. self.ui.lw_sf2.setCurrentRow(0)
  246. self.ui.lw_sfz.setCurrentRow(0)
  247. self.ui.lw_page.setCurrentCell(0, 0)
  248. def loadSettings(self):
  249. settings = QSettings()
  250. # ---------------------------------------
  251. # Main
  252. self.ui.le_main_proj_folder.setText(settings.value(CARLA_KEY_MAIN_PROJECT_FOLDER, CARLA_DEFAULT_MAIN_PROJECT_FOLDER, type=str))
  253. self.ui.ch_main_theme_pro.setChecked(settings.value(CARLA_KEY_MAIN_USE_PRO_THEME, CARLA_DEFAULT_MAIN_USE_PRO_THEME, type=bool))
  254. self.ui.cb_main_theme_color.setCurrentIndex(self.ui.cb_main_theme_color.findText(settings.value(CARLA_KEY_MAIN_PRO_THEME_COLOR, CARLA_DEFAULT_MAIN_PRO_THEME_COLOR, type=str)))
  255. self.ui.sb_main_refresh_interval.setValue(settings.value(CARLA_KEY_MAIN_REFRESH_INTERVAL, CARLA_DEFAULT_MAIN_REFRESH_INTERVAL, type=int))
  256. # ---------------------------------------
  257. # Canvas
  258. self.ui.cb_canvas_theme.setCurrentIndex(self.ui.cb_canvas_theme.findText(settings.value(CARLA_KEY_CANVAS_THEME, CARLA_DEFAULT_CANVAS_THEME, type=str)))
  259. self.ui.cb_canvas_size.setCurrentIndex(self.ui.cb_canvas_size.findText(settings.value(CARLA_KEY_CANVAS_SIZE, CARLA_DEFAULT_CANVAS_SIZE, type=str)))
  260. self.ui.cb_canvas_bezier_lines.setChecked(settings.value(CARLA_KEY_CANVAS_USE_BEZIER_LINES, CARLA_DEFAULT_CANVAS_USE_BEZIER_LINES, type=bool))
  261. self.ui.cb_canvas_hide_groups.setChecked(settings.value(CARLA_KEY_CANVAS_AUTO_HIDE_GROUPS, CARLA_DEFAULT_CANVAS_AUTO_HIDE_GROUPS, type=bool))
  262. self.ui.cb_canvas_eyecandy.setCheckState(settings.value(CARLA_KEY_CANVAS_EYE_CANDY, CARLA_DEFAULT_CANVAS_EYE_CANDY, type=int))
  263. self.ui.cb_canvas_use_opengl.setChecked(settings.value(CARLA_KEY_CANVAS_USE_OPENGL, CARLA_DEFAULT_CANVAS_USE_OPENGL, type=bool))
  264. self.ui.cb_canvas_render_aa.setCheckState(settings.value(CARLA_KEY_CANVAS_ANTIALIASING, CARLA_DEFAULT_CANVAS_ANTIALIASING, type=int))
  265. self.ui.cb_canvas_render_hq_aa.setChecked(settings.value(CARLA_KEY_CANVAS_HQ_ANTIALIASING, CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING, type=bool))
  266. # --------------------------------------------
  267. # Engine
  268. audioDriver = settings.value(CARLA_KEY_ENGINE_AUDIO_DRIVER, CARLA_DEFAULT_AUDIO_DRIVER, type=str)
  269. for i in range(self.ui.cb_engine_audio_driver.count()):
  270. if self.ui.cb_engine_audio_driver.itemText(i) == audioDriver:
  271. self.ui.cb_engine_audio_driver.setCurrentIndex(i)
  272. break
  273. else:
  274. self.ui.cb_engine_audio_driver.setCurrentIndex(-1)
  275. if audioDriver == "JACK":
  276. processModeIndex = settings.value(CARLA_KEY_ENGINE_PROCESS_MODE, ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, type=int)
  277. self.ui.cb_engine_process_mode_jack.setCurrentIndex(processModeIndex)
  278. self.ui.sw_engine_process_mode.setCurrentIndex(0)
  279. else:
  280. processModeIndex = settings.value(CARLA_KEY_ENGINE_PROCESS_MODE, ENGINE_PROCESS_MODE_CONTINUOUS_RACK, type=int)
  281. processModeIndex -= self.PROCESS_MODE_NON_JACK_PADDING
  282. self.ui.cb_engine_process_mode_other.setCurrentIndex(processModeIndex)
  283. self.ui.sw_engine_process_mode.setCurrentIndex(1)
  284. self.ui.sb_engine_max_params.setValue(settings.value(CARLA_KEY_ENGINE_MAX_PARAMETERS, CARLA_DEFAULT_MAX_PARAMETERS, type=int))
  285. self.ui.ch_engine_uis_always_on_top.setChecked(settings.value(CARLA_KEY_ENGINE_UIS_ALWAYS_ON_TOP, CARLA_DEFAULT_UIS_ALWAYS_ON_TOP, type=bool))
  286. self.ui.ch_engine_prefer_ui_bridges.setChecked(settings.value(CARLA_KEY_ENGINE_PREFER_UI_BRIDGES, CARLA_DEFAULT_PREFER_UI_BRIDGES, type=bool))
  287. self.ui.sb_engine_ui_bridges_timeout.setValue(settings.value(CARLA_KEY_ENGINE_UI_BRIDGES_TIMEOUT, CARLA_DEFAULT_UI_BRIDGES_TIMEOUT, type=int))
  288. self.ui.ch_engine_force_stereo.setChecked(settings.value(CARLA_KEY_ENGINE_FORCE_STEREO, CARLA_DEFAULT_FORCE_STEREO, type=bool))
  289. self.ui.ch_engine_prefer_plugin_bridges.setChecked(settings.value(CARLA_KEY_ENGINE_PREFER_PLUGIN_BRIDGES, CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES, type=bool))
  290. # --------------------------------------------
  291. # Paths
  292. ladspas = toList(settings.value(CARLA_KEY_PATHS_LADSPA, gCarla.DEFAULT_LADSPA_PATH))
  293. dssis = toList(settings.value(CARLA_KEY_PATHS_DSSI, gCarla.DEFAULT_DSSI_PATH))
  294. lv2s = toList(settings.value(CARLA_KEY_PATHS_LV2, gCarla.DEFAULT_LV2_PATH))
  295. vsts = toList(settings.value(CARLA_KEY_PATHS_VST, gCarla.DEFAULT_VST_PATH))
  296. aus = toList(settings.value(CARLA_KEY_PATHS_AU, gCarla.DEFAULT_AU_PATH))
  297. csds = toList(settings.value(CARLA_KEY_PATHS_CSD, gCarla.DEFAULT_CSOUND_PATH))
  298. gigs = toList(settings.value(CARLA_KEY_PATHS_GIG, gCarla.DEFAULT_GIG_PATH))
  299. sf2s = toList(settings.value(CARLA_KEY_PATHS_SF2, gCarla.DEFAULT_SF2_PATH))
  300. sfzs = toList(settings.value(CARLA_KEY_PATHS_SFZ, gCarla.DEFAULT_SFZ_PATH))
  301. ladspas.sort()
  302. dssis.sort()
  303. lv2s.sort()
  304. vsts.sort()
  305. aus.sort()
  306. csds.sort()
  307. gigs.sort()
  308. sf2s.sort()
  309. sfzs.sort()
  310. for ladspa in ladspas:
  311. if not ladspa: continue
  312. self.ui.lw_ladspa.addItem(ladspa)
  313. for dssi in dssis:
  314. if not dssi: continue
  315. self.ui.lw_dssi.addItem(dssi)
  316. for lv2 in lv2s:
  317. if not lv2: continue
  318. self.ui.lw_lv2.addItem(lv2)
  319. for vst in vsts:
  320. if not vst: continue
  321. self.ui.lw_vst.addItem(vst)
  322. for au in aus:
  323. if not au: continue
  324. self.ui.lw_au.addItem(au)
  325. for csd in csds:
  326. if not csd: continue
  327. self.ui.lw_csound.addItem(csd)
  328. for gig in gigs:
  329. if not gig: continue
  330. self.ui.lw_gig.addItem(gig)
  331. for sf2 in sf2s:
  332. if not sf2: continue
  333. self.ui.lw_sf2.addItem(sf2)
  334. for sfz in sfzs:
  335. if not sfz: continue
  336. self.ui.lw_sfz.addItem(sfz)
  337. @pyqtSlot()
  338. def slot_saveSettings(self):
  339. settings = QSettings()
  340. # ---------------------------------------
  341. settings.setValue(CARLA_KEY_MAIN_PROJECT_FOLDER, self.ui.le_main_proj_folder.text())
  342. settings.setValue(CARLA_KEY_MAIN_USE_PRO_THEME, self.ui.ch_main_theme_pro.isChecked())
  343. settings.setValue(CARLA_KEY_MAIN_PRO_THEME_COLOR, self.ui.cb_main_theme_color.currentText())
  344. settings.setValue(CARLA_KEY_MAIN_REFRESH_INTERVAL, self.ui.sb_main_refresh_interval.value())
  345. # ---------------------------------------
  346. settings.setValue(CARLA_KEY_CANVAS_THEME, self.ui.cb_canvas_theme.currentText())
  347. settings.setValue(CARLA_KEY_CANVAS_SIZE, self.ui.cb_canvas_size.currentText())
  348. settings.setValue(CARLA_KEY_CANVAS_USE_BEZIER_LINES, self.ui.cb_canvas_bezier_lines.isChecked())
  349. settings.setValue(CARLA_KEY_CANVAS_AUTO_HIDE_GROUPS, self.ui.cb_canvas_hide_groups.isChecked())
  350. settings.setValue(CARLA_KEY_CANVAS_EYE_CANDY, self.ui.cb_canvas_eyecandy.checkState()) # 0, 1, 2 match their enum variants
  351. settings.setValue(CARLA_KEY_CANVAS_USE_OPENGL, self.ui.cb_canvas_use_opengl.isChecked())
  352. settings.setValue(CARLA_KEY_CANVAS_HQ_ANTIALIASING, self.ui.cb_canvas_render_hq_aa.isChecked())
  353. settings.setValue(CARLA_KEY_CANVAS_ANTIALIASING, self.ui.cb_canvas_render_aa.checkState()) # 0, 1, 2 match their enum variants
  354. # --------------------------------------------
  355. audioDriver = self.ui.cb_engine_audio_driver.currentText()
  356. if audioDriver:
  357. settings.setValue(CARLA_KEY_ENGINE_AUDIO_DRIVER, audioDriver)
  358. if audioDriver == "JACK":
  359. settings.setValue(CARLA_KEY_ENGINE_PROCESS_MODE, self.ui.cb_engine_process_mode_jack.currentIndex())
  360. else:
  361. settings.setValue(CARLA_KEY_ENGINE_PROCESS_MODE, self.ui.cb_engine_process_mode_other.currentIndex()+self.PROCESS_MODE_NON_JACK_PADDING)
  362. settings.setValue(CARLA_KEY_ENGINE_MAX_PARAMETERS, self.ui.sb_engine_max_params.value())
  363. settings.setValue(CARLA_KEY_ENGINE_UIS_ALWAYS_ON_TOP, self.ui.ch_engine_uis_always_on_top.isChecked())
  364. settings.setValue(CARLA_KEY_ENGINE_PREFER_UI_BRIDGES, self.ui.ch_engine_prefer_ui_bridges.isChecked())
  365. settings.setValue(CARLA_KEY_ENGINE_UI_BRIDGES_TIMEOUT, self.ui.sb_engine_ui_bridges_timeout.value())
  366. settings.setValue(CARLA_KEY_ENGINE_FORCE_STEREO, self.ui.ch_engine_force_stereo.isChecked())
  367. settings.setValue(CARLA_KEY_ENGINE_PREFER_PLUGIN_BRIDGES, self.ui.ch_engine_prefer_plugin_bridges.isChecked())
  368. # --------------------------------------------
  369. ladspas = []
  370. dssis = []
  371. lv2s = []
  372. vsts = []
  373. aus = []
  374. csds = []
  375. gigs = []
  376. sf2s = []
  377. sfzs = []
  378. for i in range(self.ui.lw_ladspa.count()):
  379. ladspas.append(self.ui.lw_ladspa.item(i).text())
  380. for i in range(self.ui.lw_dssi.count()):
  381. dssis.append(self.ui.lw_dssi.item(i).text())
  382. for i in range(self.ui.lw_lv2.count()):
  383. lv2s.append(self.ui.lw_lv2.item(i).text())
  384. for i in range(self.ui.lw_vst.count()):
  385. vsts.append(self.ui.lw_vst.item(i).text())
  386. for i in range(self.ui.lw_au.count()):
  387. aus.append(self.ui.lw_au.item(i).text())
  388. for i in range(self.ui.lw_csound.count()):
  389. csds.append(self.ui.lw_csound.item(i).text())
  390. for i in range(self.ui.lw_gig.count()):
  391. gigs.append(self.ui.lw_gig.item(i).text())
  392. for i in range(self.ui.lw_sf2.count()):
  393. sf2s.append(self.ui.lw_sf2.item(i).text())
  394. for i in range(self.ui.lw_sfz.count()):
  395. sfzs.append(self.ui.lw_sfz.item(i).text())
  396. settings.setValue(CARLA_KEY_PATHS_LADSPA, ladspas)
  397. settings.setValue(CARLA_KEY_PATHS_DSSI, dssis)
  398. settings.setValue(CARLA_KEY_PATHS_LV2, lv2s)
  399. settings.setValue(CARLA_KEY_PATHS_VST, vsts)
  400. settings.setValue(CARLA_KEY_PATHS_AU, aus)
  401. settings.setValue(CARLA_KEY_PATHS_CSD, csds)
  402. settings.setValue(CARLA_KEY_PATHS_GIG, gigs)
  403. settings.setValue(CARLA_KEY_PATHS_SF2, sf2s)
  404. settings.setValue(CARLA_KEY_PATHS_SFZ, sfzs)
  405. @pyqtSlot()
  406. def slot_resetSettings(self):
  407. if self.ui.lw_page.currentRow() == self.TAB_INDEX_MAIN:
  408. self.ui.le_main_proj_folder.setText(CARLA_DEFAULT_MAIN_PROJECT_FOLDER)
  409. self.ui.ch_theme_pro.setChecked(CARLA_DEFAULT_MAIN_USE_PRO_THEME)
  410. self.ui.cb_theme_color.setCurrentIndex(self.ui.cb_theme_color.findText(CARLA_DEFAULT_MAIN_PRO_THEME_COLOR))
  411. self.ui.sb_gui_refresh.setValue(CARLA_DEFAULT_MAIN_REFRESH_INTERVAL)
  412. elif self.ui.lw_page.currentRow() == self.TAB_INDEX_CANVAS:
  413. self.ui.cb_canvas_theme.setCurrentIndex(self.ui.cb_canvas_theme.findText(CARLA_DEFAULT_CANVAS_THEME))
  414. self.ui.cb_canvas_size.setCurrentIndex(self.ui.cb_canvas_size.findText(CARLA_DEFAULT_CANVAS_SIZE))
  415. self.ui.cb_canvas_bezier_lines.setChecked(CARLA_DEFAULT_CANVAS_USE_BEZIER_LINES)
  416. self.ui.cb_canvas_hide_groups.setChecked(CARLA_DEFAULT_CANVAS_AUTO_HIDE_GROUPS)
  417. self.ui.cb_canvas_eyecandy.setCheckState(Qt.PartiallyChecked) # CARLA_DEFAULT_CANVAS_EYE_CANDY
  418. self.ui.cb_canvas_use_opengl.setChecked(CARLA_DEFAULT_CANVAS_USE_OPENGL)
  419. self.ui.cb_canvas_render_aa.setCheckState(Qt.PartiallyChecked) # CARLA_DEFAULT_CANVAS_ANTIALIASING
  420. self.ui.cb_canvas_render_hq_aa.setChecked(CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING)
  421. elif self.ui.lw_page.currentRow() == self.TAB_INDEX_ENGINE:
  422. self.ui.cb_engine_audio_driver.setCurrentIndex(0)
  423. self.ui.sb_engine_max_params.setValue(CARLA_DEFAULT_MAX_PARAMETERS)
  424. self.ui.ch_engine_uis_always_on_top.setChecked(CARLA_DEFAULT_UIS_ALWAYS_ON_TOP)
  425. self.ui.ch_engine_prefer_ui_bridges.setChecked(CARLA_DEFAULT_PREFER_UI_BRIDGES)
  426. self.ui.sb_engine_ui_bridges_timeout.setValue(CARLA_DEFAULT_UI_BRIDGES_TIMEOUT)
  427. self.ui.ch_engine_force_stereo.setChecked(CARLA_DEFAULT_FORCE_STEREO)
  428. self.ui.ch_engine_prefer_plugin_bridges.setChecked(CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES)
  429. if self.ui.cb_engine_audio_driver.currentText() == "JACK":
  430. self.ui.cb_engine_process_mode_jack.setCurrentIndex(ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  431. self.ui.sw_engine_process_mode.setCurrentIndex(0) # show all modes
  432. else:
  433. self.ui.cb_engine_process_mode_other.setCurrentIndex(ENGINE_PROCESS_MODE_CONTINUOUS_RACK-self.PROCESS_MODE_NON_JACK_PADDING)
  434. self.ui.sw_engine_process_mode.setCurrentIndex(1) # hide single+multi client modes
  435. elif self.ui.lw_page.currentRow() == self.TAB_INDEX_PATHS:
  436. curIndex = self.ui.tw_paths.currentIndex()
  437. if curIndex == self.PATH_INDEX_LADSPA:
  438. paths = DEFAULT_LADSPA_PATH.split(splitter)
  439. paths.sort()
  440. self.ui.lw_ladspa.clear()
  441. for path in paths:
  442. if not path: continue
  443. self.ui.lw_ladspa.addItem(path)
  444. elif curIndex == self.PATH_INDEX_DSSI:
  445. paths = DEFAULT_DSSI_PATH.split(splitter)
  446. paths.sort()
  447. self.ui.lw_dssi.clear()
  448. for path in paths:
  449. if not path: continue
  450. self.ui.lw_dssi.addItem(path)
  451. elif curIndex == self.PATH_INDEX_LV2:
  452. paths = DEFAULT_LV2_PATH.split(splitter)
  453. paths.sort()
  454. self.ui.lw_lv2.clear()
  455. for path in paths:
  456. if not path: continue
  457. self.ui.lw_lv2.addItem(path)
  458. elif curIndex == self.PATH_INDEX_VST:
  459. paths = DEFAULT_VST_PATH.split(splitter)
  460. paths.sort()
  461. self.ui.lw_vst.clear()
  462. for path in paths:
  463. if not path: continue
  464. self.ui.lw_vst.addItem(path)
  465. elif curIndex == self.PATH_INDEX_AU:
  466. paths = DEFAULT_AU_PATH.split(splitter)
  467. paths.sort()
  468. self.ui.lw_au.clear()
  469. for path in paths:
  470. if not path: continue
  471. self.ui.lw_au.addItem(path)
  472. elif curIndex == self.PATH_INDEX_CSOUND:
  473. paths = DEFAULT_CSOUND_PATH.split(splitter)
  474. paths.sort()
  475. self.ui.lw_csound.clear()
  476. for path in paths:
  477. if not path: continue
  478. self.ui.lw_csound.addItem(path)
  479. elif curIndex == self.PATH_INDEX_GIG:
  480. paths = DEFAULT_GIG_PATH.split(splitter)
  481. paths.sort()
  482. self.ui.lw_gig.clear()
  483. for path in paths:
  484. if not path: continue
  485. self.ui.lw_gig.addItem(path)
  486. elif curIndex == self.PATH_INDEX_SF2:
  487. paths = DEFAULT_SF2_PATH.split(splitter)
  488. paths.sort()
  489. self.ui.lw_sf2.clear()
  490. for path in paths:
  491. if not path: continue
  492. self.ui.lw_sf2.addItem(path)
  493. elif curIndex == self.PATH_INDEX_SFZ:
  494. paths = DEFAULT_SFZ_PATH.split(splitter)
  495. paths.sort()
  496. self.ui.lw_sfz.clear()
  497. for path in paths:
  498. if not path: continue
  499. self.ui.lw_sfz.addItem(path)
  500. @pyqtSlot()
  501. def slot_getAndSetProjectPath(self):
  502. getAndSetPath(self, self.ui.le_main_proj_folder.text(), self.ui.le_main_proj_folder)
  503. @pyqtSlot()
  504. def slot_engineAudioDriverChanged(self):
  505. if self.ui.cb_engine_audio_driver.currentText() == "JACK":
  506. self.ui.sw_engine_process_mode.setCurrentIndex(0)
  507. self.ui.tb_engine_driver_config.setEnabled(False)
  508. else:
  509. self.ui.sw_engine_process_mode.setCurrentIndex(1)
  510. self.ui.tb_engine_driver_config.setEnabled(True)
  511. @pyqtSlot()
  512. def slot_showAudioDriverSettings(self):
  513. driverIndex = self.ui.cb_engine_audio_driver.currentIndex()
  514. driverName = self.ui.cb_engine_audio_driver.currentText()
  515. DriverSettingsW(self, driverIndex, driverName).exec_()
  516. @pyqtSlot()
  517. def slot_addPluginPath(self):
  518. newPath = QFileDialog.getExistingDirectory(self, self.tr("Add Path"), "", QFileDialog.ShowDirsOnly)
  519. if not newPath:
  520. return
  521. curIndex = self.ui.tw_paths.currentIndex()
  522. if curIndex == self.PATH_INDEX_LADSPA:
  523. self.ui.lw_ladspa.addItem(newPath)
  524. elif curIndex == self.PATH_INDEX_DSSI:
  525. self.ui.lw_dssi.addItem(newPath)
  526. elif curIndex == self.PATH_INDEX_LV2:
  527. self.ui.lw_lv2.addItem(newPath)
  528. elif curIndex == self.PATH_INDEX_VST:
  529. self.ui.lw_vst.addItem(newPath)
  530. elif curIndex == self.PATH_INDEX_AU:
  531. self.ui.lw_au.addItem(newPath)
  532. elif curIndex == self.PATH_INDEX_CSOUND:
  533. self.ui.lw_csound.addItem(newPath)
  534. elif curIndex == self.PATH_INDEX_GIG:
  535. self.ui.lw_gig.addItem(newPath)
  536. elif curIndex == self.PATH_INDEX_SF2:
  537. self.ui.lw_sf2.addItem(newPath)
  538. elif curIndex == self.PATH_INDEX_SFZ:
  539. self.ui.lw_sfz.addItem(newPath)
  540. @pyqtSlot()
  541. def slot_removePluginPath(self):
  542. curIndex = self.ui.tw_paths.currentIndex()
  543. if curIndex == self.PATH_INDEX_LADSPA:
  544. self.ui.lw_ladspa.takeItem(self.ui.lw_ladspa.currentRow())
  545. elif curIndex == self.PATH_INDEX_DSSI:
  546. self.ui.lw_dssi.takeItem(self.ui.lw_dssi.currentRow())
  547. elif curIndex == self.PATH_INDEX_LV2:
  548. self.ui.lw_lv2.takeItem(self.ui.lw_lv2.currentRow())
  549. elif curIndex == self.PATH_INDEX_VST:
  550. self.ui.lw_vst.takeItem(self.ui.lw_vst.currentRow())
  551. elif curIndex == self.PATH_INDEX_AU:
  552. self.ui.lw_au.takeItem(self.ui.lw_au.currentRow())
  553. elif curIndex == self.PATH_INDEX_CSOUND:
  554. self.ui.lw_csound.takeItem(self.ui.lw_csound.currentRow())
  555. elif curIndex == self.PATH_INDEX_GIG:
  556. self.ui.lw_gig.takeItem(self.ui.lw_gig.currentRow())
  557. elif curIndex == self.PATH_INDEX_SF2:
  558. self.ui.lw_sf2.takeItem(self.ui.lw_sf2.currentRow())
  559. elif curIndex == self.PATH_INDEX_SFZ:
  560. self.ui.lw_sfz.takeItem(self.ui.lw_sfz.currentRow())
  561. @pyqtSlot()
  562. def slot_changePluginPath(self):
  563. curIndex = self.ui.tw_paths.currentIndex()
  564. if curIndex == self.PATH_INDEX_LADSPA:
  565. currentPath = self.ui.lw_ladspa.currentItem().text()
  566. elif curIndex == self.PATH_INDEX_DSSI:
  567. currentPath = self.ui.lw_dssi.currentItem().text()
  568. elif curIndex == self.PATH_INDEX_LV2:
  569. currentPath = self.ui.lw_lv2.currentItem().text()
  570. elif curIndex == self.PATH_INDEX_VST:
  571. currentPath = self.ui.lw_vst.currentItem().text()
  572. elif curIndex == self.PATH_INDEX_AU:
  573. currentPath = self.ui.lw_au.currentItem().text()
  574. elif curIndex == self.PATH_INDEX_CSOUND:
  575. currentPath = self.ui.lw_csound.currentItem().text()
  576. elif curIndex == self.PATH_INDEX_GIG:
  577. currentPath = self.ui.lw_gig.currentItem().text()
  578. elif curIndex == self.PATH_INDEX_SF2:
  579. currentPath = self.ui.lw_sf2.currentItem().text()
  580. elif curIndex == self.PATH_INDEX_SFZ:
  581. currentPath = self.ui.lw_sfz.currentItem().text()
  582. else:
  583. currentPath = ""
  584. newPath = QFileDialog.getExistingDirectory(self, self.tr("Add Path"), currentPath, QFileDialog.ShowDirsOnly)
  585. if not newPath:
  586. return
  587. if curIndex == self.PATH_INDEX_LADSPA:
  588. self.ui.lw_ladspa.currentItem().setText(newPath)
  589. elif curIndex == self.PATH_INDEX_DSSI:
  590. self.ui.lw_dssi.currentItem().setText(newPath)
  591. elif curIndex == self.PATH_INDEX_LV2:
  592. self.ui.lw_lv2.currentItem().setText(newPath)
  593. elif curIndex == self.PATH_INDEX_VST:
  594. self.ui.lw_vst.currentItem().setText(newPath)
  595. elif curIndex == self.PATH_INDEX_AU:
  596. self.ui.lw_au.currentItem().setText(newPath)
  597. elif curIndex == self.PATH_INDEX_CSOUND:
  598. self.ui.lw_csound.currentItem().setText(newPath)
  599. elif curIndex == self.PATH_INDEX_GIG:
  600. self.ui.lw_gig.currentItem().setText(newPath)
  601. elif curIndex == self.PATH_INDEX_SF2:
  602. self.ui.lw_sf2.currentItem().setText(newPath)
  603. elif curIndex == self.PATH_INDEX_SFZ:
  604. self.ui.lw_sfz.currentItem().setText(newPath)
  605. @pyqtSlot(int)
  606. def slot_pluginPathTabChanged(self, index):
  607. if index >= self.PATH_INDEX_AU and not MACOS:
  608. self.ui.tw_paths.setCurrentIndex(index+1)
  609. if index == self.PATH_INDEX_LADSPA:
  610. row = self.ui.lw_ladspa.currentRow()
  611. elif index == self.PATH_INDEX_DSSI:
  612. row = self.ui.lw_dssi.currentRow()
  613. elif index == self.PATH_INDEX_LV2:
  614. row = self.ui.lw_lv2.currentRow()
  615. elif index == self.PATH_INDEX_VST:
  616. row = self.ui.lw_vst.currentRow()
  617. elif index == self.PATH_INDEX_AU:
  618. row = self.ui.lw_au.currentRow()
  619. elif index == self.PATH_INDEX_CSOUND:
  620. row = self.ui.lw_csound.currentRow()
  621. elif index == self.PATH_INDEX_GIG:
  622. row = self.ui.lw_gig.currentRow()
  623. elif index == self.PATH_INDEX_SF2:
  624. row = self.ui.lw_sf2.currentRow()
  625. elif index == self.PATH_INDEX_SFZ:
  626. row = self.ui.lw_sfz.currentRow()
  627. else:
  628. row = -1
  629. check = bool(row >= 0)
  630. self.ui.b_paths_remove.setEnabled(check)
  631. self.ui.b_paths_change.setEnabled(check)
  632. @pyqtSlot(int)
  633. def slot_pluginPathRowChanged(self, row):
  634. check = bool(row >= 0)
  635. self.ui.b_paths_remove.setEnabled(check)
  636. self.ui.b_paths_change.setEnabled(check)
  637. def done(self, r):
  638. QDialog.done(self, r)
  639. self.close()
  640. # ------------------------------------------------------------------------------------------------------------
  641. # Main
  642. if __name__ == '__main__':
  643. app = CarlaApplication()
  644. initHost("Settings", None, False)
  645. gui = CarlaSettingsW(None, True, True)
  646. gui.show()
  647. sys.exit(app.exec_())