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 25KB

11 years ago
7 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
7 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
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
7 years ago
7 years ago
10 years ago
7 years ago
7 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
9 years ago
10 years ago
9 years ago
11 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
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Common Carla code
  4. # Copyright (C) 2011-2017 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. # These will be modified during install
  21. X_LIBDIR_X = None
  22. X_DATADIR_X = None
  23. # ------------------------------------------------------------------------------------------------------------
  24. # Imports (Global)
  25. import os
  26. import sys
  27. if config_UseQt5:
  28. from PyQt5.Qt import PYQT_VERSION_STR
  29. from PyQt5.QtCore import qFatal, qVersion, qWarning, QDir
  30. from PyQt5.QtGui import QIcon
  31. from PyQt5.QtWidgets import QFileDialog, QMessageBox
  32. else:
  33. from PyQt4.Qt import PYQT_VERSION_STR
  34. from PyQt4.QtCore import qFatal, qVersion, qWarning, QDir
  35. from PyQt4.QtGui import QFileDialog, QIcon, QMessageBox
  36. # ------------------------------------------------------------------------------------------------------------
  37. # Import Signal
  38. from signal import signal, SIGINT, SIGTERM
  39. try:
  40. from signal import SIGUSR1
  41. haveSIGUSR1 = True
  42. except:
  43. haveSIGUSR1 = False
  44. # ------------------------------------------------------------------------------------------------------------
  45. # Imports (Custom)
  46. from carla_backend_qt import *
  47. # ------------------------------------------------------------------------------------------------------------
  48. # Platform specific stuff
  49. if WINDOWS:
  50. WINDIR = os.getenv("WINDIR")
  51. # ------------------------------------------------------------------------------------------------------------
  52. # Set Version
  53. VERSION = "1.9.7 (2.0-beta5)"
  54. # ------------------------------------------------------------------------------------------------------------
  55. # Set TMP
  56. envTMP = os.getenv("TMP")
  57. if envTMP is None:
  58. if WINDOWS:
  59. qWarning("TMP variable not set")
  60. TMP = QDir.tempPath()
  61. else:
  62. TMP = envTMP
  63. if not os.path.exists(TMP):
  64. qWarning("TMP does not exist")
  65. TMP = "/"
  66. del envTMP
  67. # ------------------------------------------------------------------------------------------------------------
  68. # Set HOME
  69. envHOME = os.getenv("HOME")
  70. if envHOME is None:
  71. if LINUX or MACOS:
  72. qWarning("HOME variable not set")
  73. HOME = QDir.toNativeSeparators(QDir.homePath())
  74. else:
  75. HOME = envHOME
  76. if not os.path.exists(HOME):
  77. qWarning("HOME does not exist")
  78. HOME = TMP
  79. del envHOME
  80. # ------------------------------------------------------------------------------------------------------------
  81. # Set PATH
  82. envPATH = os.getenv("PATH")
  83. if envPATH is None:
  84. qWarning("PATH variable not set")
  85. if MACOS:
  86. PATH = ("/opt/local/bin", "/usr/local/bin", "/usr/bin", "/bin")
  87. elif WINDOWS:
  88. PATH = (os.path.join(WINDIR, "system32"), WINDIR)
  89. else:
  90. PATH = ("/usr/local/bin", "/usr/bin", "/bin")
  91. else:
  92. PATH = envPATH.split(os.pathsep)
  93. del envPATH
  94. # ------------------------------------------------------------------------------------------------------------
  95. # Static MIDI CC list
  96. MIDI_CC_LIST = (
  97. "0x01 Modulation",
  98. "0x02 Breath",
  99. "0x03 (Undefined)",
  100. "0x04 Foot",
  101. "0x05 Portamento",
  102. "0x07 Volume",
  103. "0x08 Balance",
  104. "0x09 (Undefined)",
  105. "0x0A Pan",
  106. "0x0B Expression",
  107. "0x0C FX Control 1",
  108. "0x0D FX Control 2",
  109. "0x0E (Undefined)",
  110. "0x0F (Undefined)",
  111. "0x10 General Purpose 1",
  112. "0x11 General Purpose 2",
  113. "0x12 General Purpose 3",
  114. "0x13 General Purpose 4",
  115. "0x14 (Undefined)",
  116. "0x15 (Undefined)",
  117. "0x16 (Undefined)",
  118. "0x17 (Undefined)",
  119. "0x18 (Undefined)",
  120. "0x19 (Undefined)",
  121. "0x1A (Undefined)",
  122. "0x1B (Undefined)",
  123. "0x1C (Undefined)",
  124. "0x1D (Undefined)",
  125. "0x1E (Undefined)",
  126. "0x1F (Undefined)",
  127. "0x46 Control 1 [Variation]",
  128. "0x47 Control 2 [Timbre]",
  129. "0x48 Control 3 [Release]",
  130. "0x49 Control 4 [Attack]",
  131. "0x4A Control 5 [Brightness]",
  132. "0x4B Control 6 [Decay]",
  133. "0x4C Control 7 [Vib Rate]",
  134. "0x4D Control 8 [Vib Depth]",
  135. "0x4E Control 9 [Vib Delay]",
  136. "0x4F Control 10 [Undefined]",
  137. "0x50 General Purpose 5",
  138. "0x51 General Purpose 6",
  139. "0x52 General Purpose 7",
  140. "0x53 General Purpose 8",
  141. "0x54 Portamento Control",
  142. "0x5B FX 1 Depth [Reverb]",
  143. "0x5C FX 2 Depth [Tremolo]",
  144. "0x5D FX 3 Depth [Chorus]",
  145. "0x5E FX 4 Depth [Detune]",
  146. "0x5F FX 5 Depth [Phaser]"
  147. )
  148. # ------------------------------------------------------------------------------------------------------------
  149. # PatchCanvas defines
  150. CANVAS_ANTIALIASING_SMALL = 1
  151. CANVAS_EYECANDY_SMALL = 1
  152. # ------------------------------------------------------------------------------------------------------------
  153. # Carla Settings keys
  154. CARLA_KEY_MAIN_PROJECT_FOLDER = "Main/ProjectFolder" # str
  155. CARLA_KEY_MAIN_USE_PRO_THEME = "Main/UseProTheme" # bool
  156. CARLA_KEY_MAIN_PRO_THEME_COLOR = "Main/ProThemeColor" # str
  157. CARLA_KEY_MAIN_REFRESH_INTERVAL = "Main/RefreshInterval" # int
  158. CARLA_KEY_MAIN_USE_CUSTOM_SKINS = "Main/UseCustomSkins" # bool
  159. CARLA_KEY_MAIN_SHOW_LOGS = "Main/ShowLogs" # bool
  160. CARLA_KEY_MAIN_EXPERIMENTAL = "Main/Experimental" # bool
  161. CARLA_KEY_CANVAS_THEME = "Canvas/Theme" # str
  162. CARLA_KEY_CANVAS_SIZE = "Canvas/Size" # str "NxN"
  163. CARLA_KEY_CANVAS_USE_BEZIER_LINES = "Canvas/UseBezierLines" # bool
  164. CARLA_KEY_CANVAS_AUTO_HIDE_GROUPS = "Canvas/AutoHideGroups" # bool
  165. CARLA_KEY_CANVAS_AUTO_SELECT_ITEMS = "Canvas/AutoSelectItems" # bool
  166. CARLA_KEY_CANVAS_EYE_CANDY = "Canvas/EyeCandy2" # bool
  167. CARLA_KEY_CANVAS_FANCY_EYE_CANDY = "Canvas/FancyEyeCandy" # bool
  168. CARLA_KEY_CANVAS_USE_OPENGL = "Canvas/UseOpenGL" # bool
  169. CARLA_KEY_CANVAS_ANTIALIASING = "Canvas/Antialiasing" # enum
  170. CARLA_KEY_CANVAS_HQ_ANTIALIASING = "Canvas/HQAntialiasing" # bool
  171. CARLA_KEY_ENGINE_DRIVER_PREFIX = "Engine/Driver-"
  172. CARLA_KEY_ENGINE_AUDIO_DRIVER = "Engine/AudioDriver" # str
  173. CARLA_KEY_ENGINE_PROCESS_MODE = "Engine/ProcessMode" # enum
  174. CARLA_KEY_ENGINE_TRANSPORT_MODE = "Engine/TransportMode" # enum
  175. CARLA_KEY_ENGINE_FORCE_STEREO = "Engine/ForceStereo" # bool
  176. CARLA_KEY_ENGINE_PREFER_PLUGIN_BRIDGES = "Engine/PreferPluginBridges" # bool
  177. CARLA_KEY_ENGINE_PREFER_UI_BRIDGES = "Engine/PreferUiBridges" # bool
  178. CARLA_KEY_ENGINE_MANAGE_UIS = "Engine/ManageUIs" # bool
  179. CARLA_KEY_ENGINE_UIS_ALWAYS_ON_TOP = "Engine/UIsAlwaysOnTop" # bool
  180. CARLA_KEY_ENGINE_MAX_PARAMETERS = "Engine/MaxParameters" # int
  181. CARLA_KEY_ENGINE_UI_BRIDGES_TIMEOUT = "Engine/UiBridgesTimeout" # int
  182. CARLA_KEY_PATHS_LADSPA = "Paths/LADSPA"
  183. CARLA_KEY_PATHS_DSSI = "Paths/DSSI"
  184. CARLA_KEY_PATHS_LV2 = "Paths/LV2"
  185. CARLA_KEY_PATHS_VST2 = "Paths/VST2"
  186. CARLA_KEY_PATHS_VST3 = "Paths/VST3"
  187. CARLA_KEY_PATHS_GIG = "Paths/GIG"
  188. CARLA_KEY_PATHS_SF2 = "Paths/SF2"
  189. CARLA_KEY_PATHS_SFZ = "Paths/SFZ"
  190. CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES = "Experimental/PluginBridges" # bool
  191. CARLA_KEY_EXPERIMENTAL_JACK_APPS = "Experimental/JackApplications" # bool
  192. CARLA_KEY_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR = "Experimental/PreventBadBehaviour" # bool
  193. CARLA_KEY_EXPERIMENTAL_LOAD_LIB_GLOBAL = "Experimental/LoadLibGlobal" # bool
  194. # if pro theme is on and color is black
  195. CARLA_KEY_CUSTOM_PAINTING = "UseCustomPainting" # bool
  196. # ------------------------------------------------------------------------------------------------------------
  197. # Carla Settings defaults
  198. # Main
  199. CARLA_DEFAULT_MAIN_PROJECT_FOLDER = HOME
  200. CARLA_DEFAULT_MAIN_USE_PRO_THEME = True
  201. CARLA_DEFAULT_MAIN_PRO_THEME_COLOR = "Black"
  202. CARLA_DEFAULT_MAIN_REFRESH_INTERVAL = 20
  203. CARLA_DEFAULT_MAIN_USE_CUSTOM_SKINS = True
  204. CARLA_DEFAULT_MAIN_SHOW_LOGS = bool(not WINDOWS)
  205. CARLA_DEFAULT_MAIN_EXPERIMENTAL = False
  206. # Canvas
  207. CARLA_DEFAULT_CANVAS_THEME = "Modern Dark"
  208. CARLA_DEFAULT_CANVAS_SIZE = "3100x2400"
  209. CARLA_DEFAULT_CANVAS_SIZE_WIDTH = 3100
  210. CARLA_DEFAULT_CANVAS_SIZE_HEIGHT = 2400
  211. CARLA_DEFAULT_CANVAS_USE_BEZIER_LINES = True
  212. CARLA_DEFAULT_CANVAS_AUTO_HIDE_GROUPS = True
  213. CARLA_DEFAULT_CANVAS_AUTO_SELECT_ITEMS = False
  214. CARLA_DEFAULT_CANVAS_EYE_CANDY = True
  215. CARLA_DEFAULT_CANVAS_FANCY_EYE_CANDY = False
  216. CARLA_DEFAULT_CANVAS_USE_OPENGL = False
  217. CARLA_DEFAULT_CANVAS_ANTIALIASING = CANVAS_ANTIALIASING_SMALL
  218. CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING = False
  219. # Engine
  220. CARLA_DEFAULT_FORCE_STEREO = False
  221. CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES = False
  222. CARLA_DEFAULT_PREFER_UI_BRIDGES = bool(not WINDOWS)
  223. CARLA_DEFAULT_MANAGE_UIS = True
  224. CARLA_DEFAULT_UIS_ALWAYS_ON_TOP = False
  225. CARLA_DEFAULT_MAX_PARAMETERS = MAX_DEFAULT_PARAMETERS
  226. CARLA_DEFAULT_UI_BRIDGES_TIMEOUT = 4000
  227. CARLA_DEFAULT_AUDIO_NUM_PERIODS = 2
  228. CARLA_DEFAULT_AUDIO_BUFFER_SIZE = 512
  229. CARLA_DEFAULT_AUDIO_SAMPLE_RATE = 44100
  230. if WINDOWS:
  231. CARLA_DEFAULT_AUDIO_DRIVER = "DirectSound"
  232. elif MACOS:
  233. CARLA_DEFAULT_AUDIO_DRIVER = "CoreAudio"
  234. else:
  235. CARLA_DEFAULT_AUDIO_DRIVER = "JACK"
  236. if LINUX:
  237. CARLA_DEFAULT_PROCESS_MODE = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS
  238. CARLA_DEFAULT_TRANSPORT_MODE = ENGINE_TRANSPORT_MODE_JACK
  239. else:
  240. CARLA_DEFAULT_PROCESS_MODE = ENGINE_PROCESS_MODE_PATCHBAY
  241. CARLA_DEFAULT_TRANSPORT_MODE = ENGINE_TRANSPORT_MODE_INTERNAL
  242. CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES = False
  243. CARLA_DEFAULT_EXPERIMENTAL_JACK_APPS = False
  244. CARLA_DEFAULT_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR = False
  245. CARLA_DEFAULT_EXPERIMENTAL_LOAD_LIB_GLOBAL = False
  246. # ------------------------------------------------------------------------------------------------------------
  247. # Default Plugin Folders (get)
  248. DEFAULT_LADSPA_PATH = ""
  249. DEFAULT_DSSI_PATH = ""
  250. DEFAULT_LV2_PATH = ""
  251. DEFAULT_VST2_PATH = ""
  252. DEFAULT_VST3_PATH = ""
  253. DEFAULT_GIG_PATH = ""
  254. DEFAULT_SF2_PATH = ""
  255. DEFAULT_SFZ_PATH = ""
  256. if WINDOWS:
  257. splitter = ";"
  258. APPDATA = os.getenv("APPDATA")
  259. PROGRAMFILES = os.getenv("PROGRAMFILES")
  260. PROGRAMFILESx86 = os.getenv("PROGRAMFILES(x86)")
  261. COMMONPROGRAMFILES = os.getenv("COMMONPROGRAMFILES")
  262. COMMONPROGRAMFILESx86 = os.getenv("COMMONPROGRAMFILES(x86)")
  263. # Small integrity tests
  264. if not APPDATA:
  265. qFatal("APPDATA variable not set, cannot continue")
  266. sys.exit(1)
  267. if not PROGRAMFILES:
  268. qFatal("PROGRAMFILES variable not set, cannot continue")
  269. sys.exit(1)
  270. if not COMMONPROGRAMFILES:
  271. qFatal("COMMONPROGRAMFILES variable not set, cannot continue")
  272. sys.exit(1)
  273. DEFAULT_LADSPA_PATH = APPDATA + "\\LADSPA"
  274. DEFAULT_LADSPA_PATH += ";" + PROGRAMFILES + "\\LADSPA"
  275. DEFAULT_DSSI_PATH = APPDATA + "\\DSSI"
  276. DEFAULT_DSSI_PATH += ";" + PROGRAMFILES + "\\DSSI"
  277. DEFAULT_LV2_PATH = APPDATA + "\\LV2"
  278. DEFAULT_LV2_PATH += ";" + COMMONPROGRAMFILES + "\\LV2"
  279. DEFAULT_VST2_PATH = PROGRAMFILES + "\\VstPlugins"
  280. DEFAULT_VST2_PATH += ";" + PROGRAMFILES + "\\Steinberg\\VstPlugins"
  281. if kIs64bit:
  282. DEFAULT_VST2_PATH += ";" + COMMONPROGRAMFILES + "\\VST2"
  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_VST2_PATH += ";" + PROGRAMFILESx86 + "\\VstPlugins"
  291. DEFAULT_VST2_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_VST2_PATH = HOME + "/.vst"
  303. DEFAULT_VST2_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_VST2_PATH = HOME + "/Library/Audio/Plug-Ins/VST"
  315. DEFAULT_VST2_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. else:
  319. splitter = ":"
  320. DEFAULT_LADSPA_PATH = HOME + "/.ladspa"
  321. DEFAULT_LADSPA_PATH += ":/usr/lib/ladspa"
  322. DEFAULT_LADSPA_PATH += ":/usr/local/lib/ladspa"
  323. DEFAULT_DSSI_PATH = HOME + "/.dssi"
  324. DEFAULT_DSSI_PATH += ":/usr/lib/dssi"
  325. DEFAULT_DSSI_PATH += ":/usr/local/lib/dssi"
  326. DEFAULT_LV2_PATH = HOME + "/.lv2"
  327. DEFAULT_LV2_PATH += ":/usr/lib/lv2"
  328. DEFAULT_LV2_PATH += ":/usr/local/lib/lv2"
  329. DEFAULT_VST2_PATH = HOME + "/.vst"
  330. DEFAULT_VST2_PATH += ":/usr/lib/vst"
  331. DEFAULT_VST2_PATH += ":/usr/local/lib/vst"
  332. DEFAULT_VST3_PATH = HOME + "/.vst3"
  333. DEFAULT_VST3_PATH += ":/usr/lib/vst3"
  334. DEFAULT_VST3_PATH += ":/usr/local/lib/vst3"
  335. DEFAULT_GIG_PATH = HOME + "/.sounds/gig"
  336. DEFAULT_GIG_PATH += ":/usr/share/sounds/gig"
  337. DEFAULT_SF2_PATH = HOME + "/.sounds/sf2"
  338. DEFAULT_SF2_PATH += ":/usr/share/sounds/sf2"
  339. DEFAULT_SFZ_PATH = HOME + "/.sounds/sfz"
  340. DEFAULT_SFZ_PATH += ":/usr/share/sounds/sfz"
  341. if not WINDOWS:
  342. winePrefix = os.getenv("WINEPREFIX")
  343. if not winePrefix:
  344. winePrefix = HOME + "/.wine"
  345. if os.path.exists(winePrefix):
  346. DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files/VstPlugins"
  347. DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3"
  348. if kIs64bit and os.path.exists(winePrefix + "/drive_c/Program Files (x86)"):
  349. DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/VstPlugins"
  350. DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/VST3"
  351. del winePrefix
  352. # ------------------------------------------------------------------------------------------------------------
  353. # Default Plugin Folders (set)
  354. readEnvVars = True
  355. if WINDOWS:
  356. # Check if running Wine. If yes, ignore env vars
  357. from winreg import ConnectRegistry, OpenKey, CloseKey, HKEY_CURRENT_USER
  358. reg = ConnectRegistry(None, HKEY_CURRENT_USER)
  359. try:
  360. key = OpenKey(reg, r"SOFTWARE\Wine")
  361. CloseKey(key)
  362. del key
  363. readEnvVars = False
  364. except:
  365. pass
  366. CloseKey(reg)
  367. del reg
  368. if readEnvVars:
  369. CARLA_DEFAULT_LADSPA_PATH = os.getenv("LADSPA_PATH", DEFAULT_LADSPA_PATH).split(splitter)
  370. CARLA_DEFAULT_DSSI_PATH = os.getenv("DSSI_PATH", DEFAULT_DSSI_PATH).split(splitter)
  371. CARLA_DEFAULT_LV2_PATH = os.getenv("LV2_PATH", DEFAULT_LV2_PATH).split(splitter)
  372. CARLA_DEFAULT_VST2_PATH = os.getenv("VST_PATH", DEFAULT_VST2_PATH).split(splitter)
  373. CARLA_DEFAULT_VST3_PATH = os.getenv("VST3_PATH", DEFAULT_VST3_PATH).split(splitter)
  374. CARLA_DEFAULT_GIG_PATH = os.getenv("GIG_PATH", DEFAULT_GIG_PATH).split(splitter)
  375. CARLA_DEFAULT_SF2_PATH = os.getenv("SF2_PATH", DEFAULT_SF2_PATH).split(splitter)
  376. CARLA_DEFAULT_SFZ_PATH = os.getenv("SFZ_PATH", DEFAULT_SFZ_PATH).split(splitter)
  377. else:
  378. CARLA_DEFAULT_LADSPA_PATH = DEFAULT_LADSPA_PATH.split(splitter)
  379. CARLA_DEFAULT_DSSI_PATH = DEFAULT_DSSI_PATH.split(splitter)
  380. CARLA_DEFAULT_LV2_PATH = DEFAULT_LV2_PATH.split(splitter)
  381. CARLA_DEFAULT_VST2_PATH = DEFAULT_VST2_PATH.split(splitter)
  382. CARLA_DEFAULT_VST3_PATH = DEFAULT_VST3_PATH.split(splitter)
  383. CARLA_DEFAULT_GIG_PATH = DEFAULT_GIG_PATH.split(splitter)
  384. CARLA_DEFAULT_SF2_PATH = DEFAULT_SF2_PATH.split(splitter)
  385. CARLA_DEFAULT_SFZ_PATH = DEFAULT_SFZ_PATH.split(splitter)
  386. # ------------------------------------------------------------------------------------------------------------
  387. # Default Plugin Folders (cleanup)
  388. del DEFAULT_LADSPA_PATH
  389. del DEFAULT_DSSI_PATH
  390. del DEFAULT_LV2_PATH
  391. del DEFAULT_VST2_PATH
  392. del DEFAULT_VST3_PATH
  393. del DEFAULT_GIG_PATH
  394. del DEFAULT_SF2_PATH
  395. del DEFAULT_SFZ_PATH
  396. # ------------------------------------------------------------------------------------------------------------
  397. # Global Carla object
  398. class CarlaObject(object):
  399. __slots__ = [
  400. 'gui', # Host Window
  401. 'nogui', # Skip UI
  402. 'term', # Terminated by OS signal
  403. 'utils' # Utils object
  404. ]
  405. gCarla = CarlaObject()
  406. gCarla.gui = None
  407. gCarla.nogui = False
  408. gCarla.term = False
  409. gCarla.utils = None
  410. # ------------------------------------------------------------------------------------------------------------
  411. # Set CWD
  412. CWD = sys.path[0]
  413. if not CWD:
  414. CWD = os.path.dirname(sys.argv[0])
  415. # make it work with cxfreeze
  416. if os.path.isfile(CWD):
  417. CWD = os.path.dirname(CWD)
  418. CXFREEZE = True
  419. else:
  420. CXFREEZE = False
  421. # ------------------------------------------------------------------------------------------------------------
  422. # Set DLL_EXTENSION
  423. if WINDOWS:
  424. DLL_EXTENSION = "dll"
  425. elif MACOS:
  426. DLL_EXTENSION = "dylib"
  427. else:
  428. DLL_EXTENSION = "so"
  429. # ------------------------------------------------------------------------------------------------------------
  430. # Check if a value is a number (float support)
  431. def isNumber(value):
  432. try:
  433. float(value)
  434. return True
  435. except:
  436. return False
  437. # ------------------------------------------------------------------------------------------------------------
  438. # Convert a value to a list
  439. def toList(value):
  440. if value is None:
  441. return []
  442. elif not isinstance(value, list):
  443. return [value]
  444. else:
  445. return value
  446. # ------------------------------------------------------------------------------------------------------------
  447. # Get Icon from user theme, using our own as backup (Oxygen)
  448. def getIcon(icon, size = 16):
  449. return QIcon.fromTheme(icon, QIcon(":/%ix%i/%s.png" % (size, size, icon)))
  450. # ------------------------------------------------------------------------------------------------------------
  451. # Handle some basic command-line arguments shared between all carla variants
  452. def handleInitialCommandLineArguments(file):
  453. initName = os.path.basename(file) if (file is not None and os.path.dirname(file) in PATH) else sys.argv[0]
  454. libPrefix = None
  455. for arg in sys.argv[1:]:
  456. if arg.startswith("--with-appname="):
  457. initName = os.path.basename(arg.replace("--with-initname=", ""))
  458. elif arg.startswith("--with-libprefix="):
  459. libPrefix = arg.replace("--with-libprefix=", "")
  460. elif arg == "--gdb":
  461. pass
  462. elif arg in ("-n", "--n", "-no-gui", "--no-gui", "-nogui", "--nogui"):
  463. gCarla.nogui = True
  464. elif arg in ("-h", "--h", "-help", "--help"):
  465. print("Usage: %s [OPTION]... [FILE|URL]" % initName)
  466. print("")
  467. print(" where FILE can be a Carla project or preset file to be loaded, or URL if using Carla-Control")
  468. print("")
  469. print(" and OPTION can be one or more of the following:")
  470. print("")
  471. print(" --gdb \t Run Carla inside gdb.")
  472. print(" -n,--no-gui \t Run Carla headless, don't show UI.")
  473. print("")
  474. print(" -h,--help \t Print this help text and exit.")
  475. print(" -v,--version\t Print version information and exit.")
  476. print("")
  477. sys.exit(0)
  478. elif arg in ("-v", "--v", "-version", "--version"):
  479. pathBinaries, pathResources = getPaths(libPrefix)
  480. print("Using Carla version %s" % VERSION)
  481. print(" Python version: %s" % sys.version.split(" ",1)[0])
  482. print(" Qt version: %s" % qVersion())
  483. print(" PyQt version: %s" % PYQT_VERSION_STR)
  484. print(" Binary dir: %s" % pathBinaries)
  485. print(" Resources dir: %s" % pathResources)
  486. sys.exit(0)
  487. return (initName, libPrefix)
  488. # ------------------------------------------------------------------------------------------------------------
  489. # Get initial project file (as passed in the command-line parameters)
  490. def getInitialProjectFile(app, skipExistCheck = False):
  491. # FIXME - PyQt mishandles unicode characters, we'll use direct sys.argv for now
  492. # see https://riverbankcomputing.com/pipermail/pyqt/2015-January/035395.html
  493. #args = app.arguments()[1:]
  494. args = sys.argv[1:]
  495. for arg in args:
  496. if arg.startswith("--with-appname=") or arg.startswith("--with-libprefix=") or arg == "--gdb":
  497. continue
  498. if arg in ("-n", "--n", "-no-gui", "--no-gui", "-nogui", "--nogui"):
  499. continue
  500. if skipExistCheck or os.path.exists(arg):
  501. return arg
  502. return None
  503. # ------------------------------------------------------------------------------------------------------------
  504. # Get paths (binaries, resources)
  505. def getPaths(libPrefix = None):
  506. CWDl = CWD.lower()
  507. # adjust for special distros
  508. libdir = os.path.basename(os.path.normpath(X_LIBDIR_X)) if X_LIBDIR_X else "lib"
  509. datadir = os.path.basename(os.path.normpath(X_DATADIR_X)) if X_DATADIR_X else "share"
  510. # standalone, installed system-wide linux
  511. if libPrefix is not None:
  512. pathBinaries = os.path.join(libPrefix, libdir, "carla")
  513. pathResources = os.path.join(libPrefix, datadir, "carla", "resources")
  514. # standalone, local source
  515. elif CWDl.endswith("source"):
  516. pathBinaries = os.path.abspath(os.path.join(CWD, "..", "bin"))
  517. pathResources = os.path.join(pathBinaries, "resources")
  518. # plugin
  519. elif CWDl.endswith("resources"):
  520. # installed system-wide linux
  521. if CWDl.endswith("/share/carla/resources"):
  522. pathBinaries = os.path.abspath(os.path.join(CWD, "..", "..", "..", libdir, "carla"))
  523. pathResources = CWD
  524. # local source
  525. elif CWDl.endswith("native-plugins%sresources" % os.sep):
  526. pathBinaries = os.path.abspath(os.path.join(CWD, "..", "..", "..", "bin"))
  527. pathResources = CWD
  528. # other
  529. else:
  530. pathBinaries = os.path.abspath(os.path.join(CWD, ".."))
  531. pathResources = CWD
  532. # everything else
  533. else:
  534. pathBinaries = CWD
  535. pathResources = os.path.join(pathBinaries, "resources")
  536. return (pathBinaries, pathResources)
  537. # ------------------------------------------------------------------------------------------------------------
  538. # Signal handler
  539. # TODO move to carla_host.py or something
  540. def signalHandler(sig, frame):
  541. if sig in (SIGINT, SIGTERM):
  542. gCarla.term = True
  543. if gCarla.gui is not None:
  544. gCarla.gui.SIGTERM.emit()
  545. elif haveSIGUSR1 and sig == SIGUSR1:
  546. if gCarla.gui is not None:
  547. gCarla.gui.SIGUSR1.emit()
  548. def setUpSignals():
  549. signal(SIGINT, signalHandler)
  550. signal(SIGTERM, signalHandler)
  551. if not haveSIGUSR1:
  552. return
  553. signal(SIGUSR1, signalHandler)
  554. # ------------------------------------------------------------------------------------------------------------
  555. # QLineEdit and QPushButton combo
  556. def getAndSetPath(parent, lineEdit):
  557. newPath = QFileDialog.getExistingDirectory(parent, parent.tr("Set Path"), lineEdit.text(), QFileDialog.ShowDirsOnly)
  558. if newPath:
  559. lineEdit.setText(newPath)
  560. return newPath
  561. # ------------------------------------------------------------------------------------------------------------
  562. # Custom MessageBox
  563. def CustomMessageBox(parent, icon, title, text, extraText="", buttons=QMessageBox.Yes|QMessageBox.No, defButton=QMessageBox.No):
  564. msgBox = QMessageBox(parent)
  565. msgBox.setIcon(icon)
  566. msgBox.setWindowTitle(title)
  567. msgBox.setText(text)
  568. msgBox.setInformativeText(extraText)
  569. msgBox.setStandardButtons(buttons)
  570. msgBox.setDefaultButton(defButton)
  571. return msgBox.exec_()
  572. # ------------------------------------------------------------------------------------------------------------