Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

carla_shared.py 23KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Common Carla code
  4. # Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
  5. #
  6. # This program is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU General Public License as
  8. # published by the Free Software Foundation; either version 2 of
  9. # the License, or any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # For a full copy of the GNU General Public License see the doc/GPL.txt file.
  17. # ------------------------------------------------------------------------------------------------------------
  18. # Imports (Config)
  19. from carla_config import *
  20. # ------------------------------------------------------------------------------------------------------------
  21. # Imports (Global)
  22. import os
  23. import sys
  24. if config_UseQt5:
  25. from PyQt5.QtCore import qFatal, qWarning, QDir
  26. from PyQt5.QtGui import QIcon
  27. from PyQt5.QtWidgets import QFileDialog, QMessageBox
  28. else:
  29. from PyQt4.QtCore import qFatal, qWarning, QDir
  30. from PyQt4.QtGui import QFileDialog, QIcon, QMessageBox
  31. # ------------------------------------------------------------------------------------------------------------
  32. # Import Signal
  33. from signal import signal, SIGINT, SIGTERM
  34. try:
  35. from signal import SIGUSR1
  36. haveSIGUSR1 = True
  37. except:
  38. haveSIGUSR1 = False
  39. # ------------------------------------------------------------------------------------------------------------
  40. # Imports (Custom)
  41. from carla_backend import *
  42. # ------------------------------------------------------------------------------------------------------------
  43. # Platform specific stuff
  44. if MACOS:
  45. if config_UseQt5:
  46. pass
  47. #from PyQt5.QtGui import qt_mac_set_menubar_icons
  48. else:
  49. from PyQt4.QtGui import qt_mac_set_menubar_icons
  50. qt_mac_set_menubar_icons(False)
  51. elif WINDOWS:
  52. WINDIR = os.getenv("WINDIR")
  53. # ------------------------------------------------------------------------------------------------------------
  54. # Set Version
  55. VERSION = "1.9.3 (2.0-beta1)"
  56. # ------------------------------------------------------------------------------------------------------------
  57. # Set TMP
  58. envTMP = os.getenv("TMP")
  59. if envTMP is None:
  60. if WINDOWS:
  61. qWarning("TMP variable not set")
  62. TMP = QDir.tempPath()
  63. else:
  64. TMP = envTMP
  65. if not os.path.exists(TMP):
  66. qWarning("TMP does not exist")
  67. TMP = "/"
  68. del envTMP
  69. # ------------------------------------------------------------------------------------------------------------
  70. # Set HOME
  71. envHOME = os.getenv("HOME")
  72. if envHOME is None:
  73. if LINUX or MACOS:
  74. qWarning("HOME variable not set")
  75. HOME = QDir.homePath()
  76. else:
  77. HOME = envHOME
  78. if not os.path.exists(HOME):
  79. qWarning("HOME does not exist")
  80. HOME = TMP
  81. del envHOME
  82. # ------------------------------------------------------------------------------------------------------------
  83. # Set PATH
  84. envPATH = os.getenv("PATH")
  85. if envPATH is None:
  86. qWarning("PATH variable not set")
  87. if MACOS:
  88. PATH = ("/opt/local/bin", "/usr/local/bin", "/usr/bin", "/bin")
  89. elif WINDOWS:
  90. PATH = (os.path.join(WINDIR, "system32"), WINDIR)
  91. else:
  92. PATH = ("/usr/local/bin", "/usr/bin", "/bin")
  93. else:
  94. PATH = envPATH.split(os.pathsep)
  95. del envPATH
  96. # ------------------------------------------------------------------------------------------------------------
  97. # Static MIDI CC list
  98. MIDI_CC_LIST = (
  99. "0x01 Modulation",
  100. "0x02 Breath",
  101. "0x03 (Undefined)",
  102. "0x04 Foot",
  103. "0x05 Portamento",
  104. "0x07 Volume",
  105. "0x08 Balance",
  106. "0x09 (Undefined)",
  107. "0x0A Pan",
  108. "0x0B Expression",
  109. "0x0C FX Control 1",
  110. "0x0D FX Control 2",
  111. "0x0E (Undefined)",
  112. "0x0F (Undefined)",
  113. "0x10 General Purpose 1",
  114. "0x11 General Purpose 2",
  115. "0x12 General Purpose 3",
  116. "0x13 General Purpose 4",
  117. "0x14 (Undefined)",
  118. "0x15 (Undefined)",
  119. "0x16 (Undefined)",
  120. "0x17 (Undefined)",
  121. "0x18 (Undefined)",
  122. "0x19 (Undefined)",
  123. "0x1A (Undefined)",
  124. "0x1B (Undefined)",
  125. "0x1C (Undefined)",
  126. "0x1D (Undefined)",
  127. "0x1E (Undefined)",
  128. "0x1F (Undefined)",
  129. "0x46 Control 1 [Variation]",
  130. "0x47 Control 2 [Timbre]",
  131. "0x48 Control 3 [Release]",
  132. "0x49 Control 4 [Attack]",
  133. "0x4A Control 5 [Brightness]",
  134. "0x4B Control 6 [Decay]",
  135. "0x4C Control 7 [Vib Rate]",
  136. "0x4D Control 8 [Vib Depth]",
  137. "0x4E Control 9 [Vib Delay]",
  138. "0x4F Control 10 [Undefined]",
  139. "0x50 General Purpose 5",
  140. "0x51 General Purpose 6",
  141. "0x52 General Purpose 7",
  142. "0x53 General Purpose 8",
  143. "0x54 Portamento Control",
  144. "0x5B FX 1 Depth [Reverb]",
  145. "0x5C FX 2 Depth [Tremolo]",
  146. "0x5D FX 3 Depth [Chorus]",
  147. "0x5E FX 4 Depth [Detune]",
  148. "0x5F FX 5 Depth [Phaser]"
  149. )
  150. # ------------------------------------------------------------------------------------------------------------
  151. # Carla Settings keys
  152. CARLA_KEY_MAIN_PROJECT_FOLDER = "Main/ProjectFolder" # str
  153. CARLA_KEY_MAIN_USE_PRO_THEME = "Main/UseProTheme" # bool
  154. CARLA_KEY_MAIN_PRO_THEME_COLOR = "Main/ProThemeColor" # str
  155. CARLA_KEY_MAIN_REFRESH_INTERVAL = "Main/RefreshInterval" # int
  156. CARLA_KEY_CANVAS_THEME = "Canvas/Theme" # str
  157. CARLA_KEY_CANVAS_SIZE = "Canvas/Size" # str "NxN"
  158. CARLA_KEY_CANVAS_USE_BEZIER_LINES = "Canvas/UseBezierLines" # bool
  159. CARLA_KEY_CANVAS_AUTO_HIDE_GROUPS = "Canvas/AutoHideGroups" # bool
  160. CARLA_KEY_CANVAS_EYE_CANDY = "Canvas/EyeCandy" # enum
  161. CARLA_KEY_CANVAS_USE_OPENGL = "Canvas/UseOpenGL" # bool
  162. CARLA_KEY_CANVAS_ANTIALIASING = "Canvas/Antialiasing" # enum
  163. CARLA_KEY_CANVAS_HQ_ANTIALIASING = "Canvas/HQAntialiasing" # bool
  164. CARLA_KEY_CUSTOM_PAINTING = "UseCustomPainting" # bool
  165. CARLA_KEY_ENGINE_DRIVER_PREFIX = "Engine/Driver-"
  166. CARLA_KEY_ENGINE_AUDIO_DRIVER = "Engine/AudioDriver" # str
  167. CARLA_KEY_ENGINE_PROCESS_MODE = "Engine/ProcessMode" # enum
  168. CARLA_KEY_ENGINE_TRANSPORT_MODE = "Engine/TransportMode" # enum
  169. CARLA_KEY_ENGINE_FORCE_STEREO = "Engine/ForceStereo" # bool
  170. CARLA_KEY_ENGINE_PREFER_PLUGIN_BRIDGES = "Engine/PreferPluginBridges" # bool
  171. CARLA_KEY_ENGINE_PREFER_UI_BRIDGES = "Engine/PreferUiBridges" # bool
  172. CARLA_KEY_ENGINE_UIS_ALWAYS_ON_TOP = "Engine/UIsAlwaysOnTop" # bool
  173. CARLA_KEY_ENGINE_MAX_PARAMETERS = "Engine/MaxParameters" # int
  174. CARLA_KEY_ENGINE_UI_BRIDGES_TIMEOUT = "Engine/UiBridgesTimeout" # int
  175. CARLA_KEY_PATHS_LADSPA = "Paths/LADSPA"
  176. CARLA_KEY_PATHS_DSSI = "Paths/DSSI"
  177. CARLA_KEY_PATHS_LV2 = "Paths/LV2"
  178. CARLA_KEY_PATHS_VST = "Paths/VST"
  179. CARLA_KEY_PATHS_VST3 = "Paths/VST3"
  180. CARLA_KEY_PATHS_AU = "Paths/AU"
  181. CARLA_KEY_PATHS_CSD = "Paths/CSD"
  182. CARLA_KEY_PATHS_GIG = "Paths/GIG"
  183. CARLA_KEY_PATHS_SF2 = "Paths/SF2"
  184. CARLA_KEY_PATHS_SFZ = "Paths/SFZ"
  185. # ------------------------------------------------------------------------------------------------------------
  186. # Global Carla object
  187. class CarlaObject(object):
  188. __slots__ = [
  189. # Host library object
  190. 'host',
  191. # Host Window
  192. 'gui',
  193. # bool, is controller
  194. 'isControl',
  195. # bool, is running local
  196. 'isLocal',
  197. # bool, is plugin
  198. 'isPlugin',
  199. # current buffer size
  200. 'bufferSize',
  201. # current sample rate
  202. 'sampleRate',
  203. # current process mode
  204. 'processMode',
  205. # check if process mode is forced (rack/patchbay)
  206. 'processModeForced',
  207. # current transport mode
  208. 'transportMode',
  209. # current max parameters
  210. 'maxParameters',
  211. # discovery tools
  212. 'discovery_native',
  213. 'discovery_posix32',
  214. 'discovery_posix64',
  215. 'discovery_win32',
  216. 'discovery_win64',
  217. # default paths
  218. 'DEFAULT_LADSPA_PATH',
  219. 'DEFAULT_DSSI_PATH',
  220. 'DEFAULT_LV2_PATH',
  221. 'DEFAULT_VST_PATH',
  222. 'DEFAULT_VST3_PATH',
  223. 'DEFAULT_AU_PATH',
  224. 'DEFAULT_CSOUND_PATH',
  225. 'DEFAULT_GIG_PATH',
  226. 'DEFAULT_SF2_PATH',
  227. 'DEFAULT_SFZ_PATH'
  228. ]
  229. gCarla = CarlaObject()
  230. gCarla.host = None
  231. gCarla.gui = None
  232. gCarla.isControl = False
  233. gCarla.isLocal = True
  234. gCarla.isPlugin = False
  235. gCarla.bufferSize = 0
  236. gCarla.sampleRate = 0.0
  237. gCarla.processMode = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS if LINUX else ENGINE_PROCESS_MODE_CONTINUOUS_RACK
  238. gCarla.processModeForced = False
  239. gCarla.transportMode = ENGINE_TRANSPORT_MODE_JACK if LINUX else ENGINE_TRANSPORT_MODE_INTERNAL
  240. gCarla.maxParameters = MAX_DEFAULT_PARAMETERS
  241. gCarla.discovery_native = ""
  242. gCarla.discovery_posix32 = ""
  243. gCarla.discovery_posix64 = ""
  244. gCarla.discovery_win32 = ""
  245. gCarla.discovery_win64 = ""
  246. # ------------------------------------------------------------------------------------------------------------
  247. # Default Plugin Folders (get)
  248. DEFAULT_LADSPA_PATH = ""
  249. DEFAULT_DSSI_PATH = ""
  250. DEFAULT_LV2_PATH = ""
  251. DEFAULT_VST_PATH = ""
  252. DEFAULT_VST3_PATH = ""
  253. DEFAULT_AU_PATH = ""
  254. DEFAULT_CSOUND_PATH = ""
  255. DEFAULT_GIG_PATH = ""
  256. DEFAULT_SF2_PATH = ""
  257. DEFAULT_SFZ_PATH = ""
  258. if WINDOWS:
  259. splitter = ";"
  260. APPDATA = os.getenv("APPDATA")
  261. PROGRAMFILES = os.getenv("PROGRAMFILES")
  262. PROGRAMFILESx86 = os.getenv("PROGRAMFILES(x86)")
  263. COMMONPROGRAMFILES = os.getenv("COMMONPROGRAMFILES")
  264. COMMONPROGRAMFILESx86 = os.getenv("COMMONPROGRAMFILES(x86)")
  265. # Small integrity tests
  266. if not APPDATA:
  267. qFatal("APPDATA variable not set, cannot continue")
  268. sys.exit(1)
  269. if not PROGRAMFILES:
  270. qFatal("PROGRAMFILES variable not set, cannot continue")
  271. sys.exit(1)
  272. if not COMMONPROGRAMFILES:
  273. qFatal("COMMONPROGRAMFILES variable not set, cannot continue")
  274. sys.exit(1)
  275. DEFAULT_LADSPA_PATH = APPDATA + "\\LADSPA"
  276. DEFAULT_LADSPA_PATH += ";" + PROGRAMFILES + "\\LADSPA"
  277. DEFAULT_DSSI_PATH = APPDATA + "\\DSSI"
  278. DEFAULT_DSSI_PATH += ";" + PROGRAMFILES + "\\DSSI"
  279. DEFAULT_LV2_PATH = APPDATA + "\\LV2"
  280. DEFAULT_LV2_PATH += ";" + COMMONPROGRAMFILES + "\\LV2"
  281. DEFAULT_VST_PATH = PROGRAMFILES + "\\VstPlugins"
  282. DEFAULT_VST_PATH += ";" + PROGRAMFILES + "\\Steinberg\\VstPlugins"
  283. DEFAULT_VST3_PATH = COMMONPROGRAMFILES + "\\VST3"
  284. DEFAULT_GIG_PATH = APPDATA + "\\GIG"
  285. DEFAULT_SF2_PATH = APPDATA + "\\SF2"
  286. DEFAULT_SFZ_PATH = APPDATA + "\\SFZ"
  287. if PROGRAMFILESx86:
  288. DEFAULT_LADSPA_PATH += ";" + PROGRAMFILESx86 + "\\LADSPA"
  289. DEFAULT_DSSI_PATH += ";" + PROGRAMFILESx86 + "\\DSSI"
  290. DEFAULT_VST_PATH += ";" + PROGRAMFILESx86 + "\\VstPlugins"
  291. DEFAULT_VST_PATH += ";" + PROGRAMFILESx86 + "\\Steinberg\\VstPlugins"
  292. if COMMONPROGRAMFILESx86:
  293. DEFAULT_VST3_PATH += COMMONPROGRAMFILESx86 + "\\VST3"
  294. elif HAIKU:
  295. splitter = ":"
  296. DEFAULT_LADSPA_PATH = HOME + "/.ladspa"
  297. DEFAULT_LADSPA_PATH += ":/boot/common/add-ons/ladspa"
  298. DEFAULT_DSSI_PATH = HOME + "/.dssi"
  299. DEFAULT_DSSI_PATH += ":/boot/common/add-ons/dssi"
  300. DEFAULT_LV2_PATH = HOME + "/.lv2"
  301. DEFAULT_LV2_PATH += ":/boot/common/add-ons/lv2"
  302. DEFAULT_VST_PATH = HOME + "/.vst"
  303. DEFAULT_VST_PATH += ":/boot/common/add-ons/vst"
  304. DEFAULT_VST3_PATH = HOME + "/.vst3"
  305. DEFAULT_VST3_PATH += ":/boot/common/add-ons/vst3"
  306. elif MACOS:
  307. splitter = ":"
  308. DEFAULT_LADSPA_PATH = HOME + "/Library/Audio/Plug-Ins/LADSPA"
  309. DEFAULT_LADSPA_PATH += ":/Library/Audio/Plug-Ins/LADSPA"
  310. DEFAULT_DSSI_PATH = HOME + "/Library/Audio/Plug-Ins/DSSI"
  311. DEFAULT_DSSI_PATH += ":/Library/Audio/Plug-Ins/DSSI"
  312. DEFAULT_LV2_PATH = HOME + "/Library/Audio/Plug-Ins/LV2"
  313. DEFAULT_LV2_PATH += ":/Library/Audio/Plug-Ins/LV2"
  314. DEFAULT_VST_PATH = HOME + "/Library/Audio/Plug-Ins/VST"
  315. DEFAULT_VST_PATH += ":/Library/Audio/Plug-Ins/VST"
  316. DEFAULT_VST3_PATH = HOME + "/Library/Audio/Plug-Ins/VST3"
  317. DEFAULT_VST3_PATH += ":/Library/Audio/Plug-Ins/VST3"
  318. DEFAULT_AU_PATH = HOME + "/Library/Audio/Plug-Ins/Components"
  319. DEFAULT_AU_PATH += ":/Library/Audio/Plug-Ins/Components"
  320. else:
  321. splitter = ":"
  322. DEFAULT_LADSPA_PATH = HOME + "/.ladspa"
  323. DEFAULT_LADSPA_PATH += ":/usr/lib/ladspa"
  324. DEFAULT_LADSPA_PATH += ":/usr/local/lib/ladspa"
  325. DEFAULT_DSSI_PATH = HOME + "/.dssi"
  326. DEFAULT_DSSI_PATH += ":/usr/lib/dssi"
  327. DEFAULT_DSSI_PATH += ":/usr/local/lib/dssi"
  328. DEFAULT_LV2_PATH = HOME + "/.lv2"
  329. DEFAULT_LV2_PATH += ":/usr/lib/lv2"
  330. DEFAULT_LV2_PATH += ":/usr/local/lib/lv2"
  331. DEFAULT_VST_PATH = HOME + "/.vst"
  332. DEFAULT_VST_PATH += ":/usr/lib/vst"
  333. DEFAULT_VST_PATH += ":/usr/local/lib/vst"
  334. DEFAULT_VST3_PATH = HOME + "/.vst3"
  335. DEFAULT_VST3_PATH += ":/usr/lib/vst3"
  336. DEFAULT_VST3_PATH += ":/usr/local/lib/vst3"
  337. DEFAULT_GIG_PATH = HOME + "/.sounds/gig"
  338. DEFAULT_GIG_PATH += ":/usr/share/sounds/gig"
  339. DEFAULT_SF2_PATH = HOME + "/.sounds/sf2"
  340. DEFAULT_SF2_PATH += ":/usr/share/sounds/sf2"
  341. DEFAULT_SFZ_PATH = HOME + "/.sounds/sfz"
  342. DEFAULT_SFZ_PATH += ":/usr/share/sounds/sfz"
  343. if not WINDOWS:
  344. winePrefix = os.getenv("WINEPREFIX")
  345. if not winePrefix:
  346. winePrefix = HOME + "/.wine"
  347. if os.path.exists(winePrefix):
  348. DEFAULT_VST_PATH += ":" + winePrefix + "/drive_c/Program Files/VstPlugins"
  349. DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3"
  350. if kIs64bit and os.path.exists(winePrefix + "/drive_c/Program Files (x86)"):
  351. DEFAULT_VST_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/VstPlugins"
  352. DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/VST3"
  353. # ------------------------------------------------------------------------------------------------------------
  354. # Default Plugin Folders (set)
  355. readEnvVars = True
  356. if WINDOWS:
  357. # Check if running Wine. If yes, ignore env vars
  358. from winreg import ConnectRegistry, OpenKey, CloseKey, HKEY_CURRENT_USER
  359. reg = ConnectRegistry(None, HKEY_CURRENT_USER)
  360. try:
  361. key = OpenKey(reg, r"SOFTWARE\Wine")
  362. CloseKey(key)
  363. readEnvVars = False
  364. except:
  365. pass
  366. CloseKey(reg)
  367. del reg
  368. if readEnvVars:
  369. gCarla.DEFAULT_LADSPA_PATH = os.getenv("LADSPA_PATH", DEFAULT_LADSPA_PATH).split(splitter)
  370. gCarla.DEFAULT_DSSI_PATH = os.getenv("DSSI_PATH", DEFAULT_DSSI_PATH).split(splitter)
  371. gCarla.DEFAULT_LV2_PATH = os.getenv("LV2_PATH", DEFAULT_LV2_PATH).split(splitter)
  372. gCarla.DEFAULT_VST_PATH = os.getenv("VST_PATH", DEFAULT_VST_PATH).split(splitter)
  373. gCarla.DEFAULT_VST3_PATH = os.getenv("VST3_PATH", DEFAULT_VST3_PATH).split(splitter)
  374. gCarla.DEFAULT_AU_PATH = os.getenv("AU_PATH", DEFAULT_AU_PATH).split(splitter)
  375. gCarla.DEFAULT_CSOUND_PATH = os.getenv("CSOUND_PATH", DEFAULT_CSOUND_PATH).split(splitter)
  376. gCarla.DEFAULT_GIG_PATH = os.getenv("GIG_PATH", DEFAULT_GIG_PATH).split(splitter)
  377. gCarla.DEFAULT_SF2_PATH = os.getenv("SF2_PATH", DEFAULT_SF2_PATH).split(splitter)
  378. gCarla.DEFAULT_SFZ_PATH = os.getenv("SFZ_PATH", DEFAULT_SFZ_PATH).split(splitter)
  379. else:
  380. gCarla.DEFAULT_LADSPA_PATH = DEFAULT_LADSPA_PATH.split(splitter)
  381. gCarla.DEFAULT_DSSI_PATH = DEFAULT_DSSI_PATH.split(splitter)
  382. gCarla.DEFAULT_LV2_PATH = DEFAULT_LV2_PATH.split(splitter)
  383. gCarla.DEFAULT_VST_PATH = DEFAULT_VST_PATH.split(splitter)
  384. gCarla.DEFAULT_VST3_PATH = DEFAULT_VST3_PATH.split(splitter)
  385. gCarla.DEFAULT_AU_PATH = DEFAULT_AU_PATH.split(splitter)
  386. gCarla.DEFAULT_CSOUND_PATH = DEFAULT_CSOUND_PATH.split(splitter)
  387. gCarla.DEFAULT_GIG_PATH = DEFAULT_GIG_PATH.split(splitter)
  388. gCarla.DEFAULT_SF2_PATH = DEFAULT_SF2_PATH.split(splitter)
  389. gCarla.DEFAULT_SFZ_PATH = DEFAULT_SFZ_PATH.split(splitter)
  390. # ------------------------------------------------------------------------------------------------------------
  391. # Search for Carla tools
  392. CWD = sys.path[0]
  393. # make it work with cxfreeze
  394. if WINDOWS and CWD.endswith(".exe"):
  395. CWD = CWD.rsplit("\\", 1)[0]
  396. elif CWD.endswith(("/carla", "/carla-plugin", "/carla-patchbay", "/carla-rack")):
  397. CWD = CWD.rsplit("/", 1)[0]
  398. # find tool
  399. def findTool(toolDir, toolName):
  400. path = os.path.join(CWD, toolName)
  401. if os.path.exists(path):
  402. return path
  403. path = os.path.join(CWD, toolDir, toolName)
  404. if os.path.exists(path):
  405. return path
  406. for p in PATH:
  407. path = os.path.join(p, toolName)
  408. if os.path.exists(path):
  409. return path
  410. return ""
  411. # ------------------------------------------------------------------------------------------------------------
  412. # Init host
  413. def initHost(initName, libPrefix = None, failError = True):
  414. # -------------------------------------------------------------
  415. # Set Carla library name
  416. libname = "libcarla_"
  417. if gCarla.isControl:
  418. libname += "control2"
  419. else:
  420. libname += "standalone2"
  421. if WINDOWS:
  422. libname += ".dll"
  423. elif MACOS:
  424. libname += ".dylib"
  425. else:
  426. libname += ".so"
  427. # -------------------------------------------------------------
  428. # Search for the Carla library
  429. libfilename = ""
  430. if libPrefix is not None:
  431. libfilename = os.path.join(libPrefix, "lib", "carla", libname)
  432. else:
  433. path = os.path.join(CWD, "backend", libname)
  434. if os.path.exists(path):
  435. libfilename = path
  436. else:
  437. path = os.getenv("CARLA_LIB_PATH")
  438. if path and os.path.exists(path):
  439. CARLA_LIB_PATH = (path,)
  440. elif WINDOWS:
  441. CARLA_LIB_PATH = (os.path.join(PROGRAMFILES, "Carla"),)
  442. elif MACOS:
  443. CARLA_LIB_PATH = ("/opt/local/lib", "/usr/local/lib/", "/usr/lib")
  444. else:
  445. CARLA_LIB_PATH = ("/usr/local/lib/", "/usr/lib")
  446. for libpath in CARLA_LIB_PATH:
  447. path = os.path.join(libpath, "carla", libname)
  448. if os.path.exists(path):
  449. libfilename = path
  450. break
  451. # -------------------------------------------------------------
  452. # find windows tools
  453. gCarla.discovery_win32 = findTool("discovery", "carla-discovery-win32.exe")
  454. gCarla.discovery_win64 = findTool("discovery", "carla-discovery-win64.exe")
  455. # -------------------------------------------------------------
  456. # find native and posix tools
  457. if not WINDOWS:
  458. gCarla.discovery_native = findTool("discovery", "carla-discovery-native")
  459. gCarla.discovery_posix32 = findTool("discovery", "carla-discovery-posix32")
  460. gCarla.discovery_posix64 = findTool("discovery", "carla-discovery-posix64")
  461. # -------------------------------------------------------------
  462. if not (libfilename or gCarla.isPlugin):
  463. if failError:
  464. QMessageBox.critical(None, "Error", "Failed to find the carla library, cannot continue")
  465. sys.exit(1)
  466. return
  467. # -------------------------------------------------------------
  468. # Init host
  469. if gCarla.host is None:
  470. gCarla.host = Host(libfilename)
  471. if not (gCarla.isControl or gCarla.isPlugin):
  472. gCarla.host.set_engine_option(ENGINE_OPTION_NSM_INIT, os.getpid(), initName)
  473. # -------------------------------------------------------------
  474. # Set binary path
  475. libfolder = libfilename.replace(libname, "")
  476. localBinaries = os.path.join(libfolder, "..", "bridges")
  477. systemBinaries = os.path.join(libfolder, "bridges")
  478. if os.path.exists(libfolder):
  479. gCarla.host.set_engine_option(ENGINE_OPTION_PATH_BINARIES, 0, libfolder)
  480. elif os.path.exists(localBinaries):
  481. gCarla.host.set_engine_option(ENGINE_OPTION_PATH_BINARIES, 0, localBinaries)
  482. elif os.path.exists(systemBinaries):
  483. gCarla.host.set_engine_option(ENGINE_OPTION_PATH_BINARIES, 0, systemBinaries)
  484. # -------------------------------------------------------------
  485. # Set resource path
  486. localResources = os.path.join(libfolder, "..", "modules", "native-plugins", "resources")
  487. systemResources = os.path.join(libfolder, "resources")
  488. if os.path.exists(localResources):
  489. gCarla.host.set_engine_option(ENGINE_OPTION_PATH_RESOURCES, 0, localResources)
  490. elif os.path.exists(systemResources):
  491. gCarla.host.set_engine_option(ENGINE_OPTION_PATH_RESOURCES, 0, systemResources)
  492. # ------------------------------------------------------------------------------------------------------------
  493. # Check if a value is a number (float support)
  494. def isNumber(value):
  495. try:
  496. float(value)
  497. return True
  498. except:
  499. return False
  500. # ------------------------------------------------------------------------------------------------------------
  501. # Convert a value to a list
  502. def toList(value):
  503. if value is None:
  504. return []
  505. elif not isinstance(value, list):
  506. return [value]
  507. else:
  508. return value
  509. # ------------------------------------------------------------------------------------------------------------
  510. # Get Icon from user theme, using our own as backup (Oxygen)
  511. def getIcon(icon, size=16):
  512. return QIcon.fromTheme(icon, QIcon(":/%ix%i/%s.png" % (size, size, icon)))
  513. # ------------------------------------------------------------------------------------------------------------
  514. # Signal handler
  515. def signalHandler(sig, frame):
  516. if gCarla.gui is None:
  517. return
  518. if sig in (SIGINT, SIGTERM):
  519. gCarla.gui.SIGTERM.emit()
  520. elif haveSIGUSR1 and sig == SIGUSR1:
  521. gCarla.gui.SIGUSR1.emit()
  522. def setUpSignals():
  523. signal(SIGINT, signalHandler)
  524. signal(SIGTERM, signalHandler)
  525. if not haveSIGUSR1:
  526. return
  527. signal(SIGUSR1, signalHandler)
  528. # ------------------------------------------------------------------------------------------------------------
  529. # QLineEdit and QPushButton combo
  530. def getAndSetPath(parent, currentPath, lineEdit):
  531. newPath = QFileDialog.getExistingDirectory(parent, parent.tr("Set Path"), currentPath, QFileDialog.ShowDirsOnly)
  532. if newPath:
  533. lineEdit.setText(newPath)
  534. return newPath
  535. # ------------------------------------------------------------------------------------------------------------
  536. # Get plugin type as string
  537. def getPluginTypeAsString(ptype):
  538. if ptype == PLUGIN_INTERNAL:
  539. return "Internal"
  540. if ptype == PLUGIN_LADSPA:
  541. return "LADSPA"
  542. if ptype == PLUGIN_DSSI:
  543. return "DSSI"
  544. if ptype == PLUGIN_LV2:
  545. return "LV2"
  546. if ptype == PLUGIN_VST:
  547. return "VST"
  548. if ptype == PLUGIN_VST3:
  549. return "VST3"
  550. if ptype == PLUGIN_AU:
  551. return "AU"
  552. if ptype == PLUGIN_JACK:
  553. return "JACK"
  554. if ptype == PLUGIN_REWIRE:
  555. return "ReWire"
  556. if ptype == PLUGIN_FILE_CSD:
  557. return "CSD"
  558. if ptype == PLUGIN_FILE_GIG:
  559. return "GIG"
  560. if ptype == PLUGIN_FILE_SF2:
  561. return "SF2"
  562. if ptype == PLUGIN_FILE_SFZ:
  563. return "SFZ"
  564. return "Unknown"
  565. # ------------------------------------------------------------------------------------------------------------
  566. # Custom MessageBox
  567. def CustomMessageBox(parent, icon, title, text, extraText="", buttons=QMessageBox.Yes|QMessageBox.No, defButton=QMessageBox.No):
  568. msgBox = QMessageBox(parent)
  569. msgBox.setIcon(icon)
  570. msgBox.setWindowTitle(title)
  571. msgBox.setText(text)
  572. msgBox.setInformativeText(extraText)
  573. msgBox.setStandardButtons(buttons)
  574. msgBox.setDefaultButton(defButton)
  575. return msgBox.exec_()