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.

317 lines
10KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla Backend utils
  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 (Global)
  19. from sys import argv
  20. # ------------------------------------------------------------------------------------------------------------
  21. # Imports (Custom)
  22. from carla_backend import *
  23. # ------------------------------------------------------------------------------------------------------------
  24. def getPluginTypeAsString(ptype):
  25. if ptype == PLUGIN_NONE:
  26. return "NONE"
  27. if ptype == PLUGIN_INTERNAL:
  28. return "Internal"
  29. if ptype == PLUGIN_LADSPA:
  30. return "LADSPA"
  31. if ptype == PLUGIN_DSSI:
  32. return "DSSI"
  33. if ptype == PLUGIN_LV2:
  34. return "LV2"
  35. if ptype == PLUGIN_VST2:
  36. return "VST2"
  37. if ptype == PLUGIN_VST3:
  38. return "VST3"
  39. if ptype == PLUGIN_AU:
  40. return "AU"
  41. if ptype == PLUGIN_GIG:
  42. return "GIG"
  43. if ptype == PLUGIN_SF2:
  44. return "SF2"
  45. if ptype == PLUGIN_SFZ:
  46. return "SFZ"
  47. print("getPluginTypeAsString(%i) - invalid type" % ptype);
  48. return "Unknown"
  49. def getPluginTypeFromString(stype):
  50. if not stype:
  51. return PLUGIN_NONE
  52. stype = stype.lower()
  53. if stype == "none":
  54. return PLUGIN_NONE
  55. if stype in ("internal", "native"):
  56. return PLUGIN_INTERNAL
  57. if stype == "ladspa":
  58. return PLUGIN_LADSPA
  59. if stype == "dssi":
  60. return PLUGIN_DSSI
  61. if stype == "lv2":
  62. return PLUGIN_LV2
  63. if stype in ("vst2", "vst"):
  64. return PLUGIN_VST2
  65. if stype == "vst3":
  66. return PLUGIN_VST3
  67. if stype in ("au", "audiounit"):
  68. return PLUGIN_AU
  69. if stype == "gig":
  70. return PLUGIN_GIG
  71. if stype == "sf2":
  72. return PLUGIN_SF2
  73. if stype == "sfz":
  74. return PLUGIN_SFZ
  75. print("getPluginTypeFromString(\"%s\") - invalid string type" % stype)
  76. return PLUGIN_NONE
  77. # ------------------------------------------------------------------------------------------------------------
  78. # Carla Utils API (C stuff)
  79. CarlaPipeClientHandle = c_void_p
  80. CarlaPipeCallbackFunc = CFUNCTYPE(None, c_void_p, c_char_p)
  81. # Information about an internal Carla plugin.
  82. # @see carla_get_cached_plugin_info()
  83. class CarlaCachedPluginInfo(Structure):
  84. _fields_ = [
  85. # Plugin category.
  86. ("category", c_enum),
  87. # Plugin hints.
  88. # @see PluginHints
  89. ("hints", c_uint),
  90. # Number of audio inputs.
  91. ("audioIns", c_uint32),
  92. # Number of audio outputs.
  93. ("audioOuts", c_uint32),
  94. # Number of MIDI inputs.
  95. ("midiIns", c_uint32),
  96. # Number of MIDI outputs.
  97. ("midiOuts", c_uint32),
  98. # Number of input parameters.
  99. ("parameterIns", c_uint32),
  100. # Number of output parameters.
  101. ("parameterOuts", c_uint32),
  102. # Plugin name.
  103. ("name", c_char_p),
  104. # Plugin label.
  105. ("label", c_char_p),
  106. # Plugin author/maker.
  107. ("maker", c_char_p),
  108. # Plugin copyright/license.
  109. ("copyright", c_char_p)
  110. ]
  111. # ------------------------------------------------------------------------------------------------------------
  112. # Carla Utils API (Python compatible stuff)
  113. # @see CarlaCachedPluginInfo
  114. PyCarlaCachedPluginInfo = {
  115. 'category': PLUGIN_CATEGORY_NONE,
  116. 'hints': 0x0,
  117. 'audioIns': 0,
  118. 'audioOuts': 0,
  119. 'midiIns': 0,
  120. 'midiOuts': 0,
  121. 'parameterIns': 0,
  122. 'parameterOuts': 0,
  123. 'name': "",
  124. 'label': "",
  125. 'maker': "",
  126. 'copyright': ""
  127. }
  128. # ------------------------------------------------------------------------------------------------------------
  129. # Carla Utils object using a DLL
  130. class CarlaUtils(object):
  131. def __init__(self, filename):
  132. object.__init__(self)
  133. self.lib = cdll.LoadLibrary(filename)
  134. self.lib.carla_get_complete_license_text.argtypes = None
  135. self.lib.carla_get_complete_license_text.restype = c_char_p
  136. self.lib.carla_get_juce_version.argtypes = None
  137. self.lib.carla_get_juce_version.restype = c_char_p
  138. self.lib.carla_get_supported_file_extensions.argtypes = None
  139. self.lib.carla_get_supported_file_extensions.restype = c_char_p
  140. self.lib.carla_get_cached_plugin_count.argtypes = [c_enum, c_char_p]
  141. self.lib.carla_get_cached_plugin_count.restype = c_uint
  142. self.lib.carla_get_cached_plugin_info.argtypes = [c_enum, c_uint]
  143. self.lib.carla_get_cached_plugin_info.restype = POINTER(CarlaCachedPluginInfo)
  144. self.lib.carla_set_process_name.argtypes = [c_char_p]
  145. self.lib.carla_set_process_name.restype = None
  146. self.lib.carla_pipe_client_new.argtypes = [POINTER(c_char_p), CarlaPipeCallbackFunc, c_void_p]
  147. self.lib.carla_pipe_client_new.restype = CarlaPipeClientHandle
  148. self.lib.carla_pipe_client_idle.argtypes = [CarlaPipeClientHandle]
  149. self.lib.carla_pipe_client_idle.restype = None
  150. self.lib.carla_pipe_client_is_running.argtypes = [CarlaPipeClientHandle]
  151. self.lib.carla_pipe_client_is_running.restype = c_bool
  152. self.lib.carla_pipe_client_lock.argtypes = [CarlaPipeClientHandle]
  153. self.lib.carla_pipe_client_lock.restype = None
  154. self.lib.carla_pipe_client_unlock.argtypes = [CarlaPipeClientHandle]
  155. self.lib.carla_pipe_client_unlock.restype = None
  156. self.lib.carla_pipe_client_readlineblock.argtypes = [CarlaPipeClientHandle, c_uint]
  157. self.lib.carla_pipe_client_readlineblock.restype = c_char_p
  158. self.lib.carla_pipe_client_write_msg.argtypes = [CarlaPipeClientHandle, c_char_p]
  159. self.lib.carla_pipe_client_write_msg.restype = c_bool
  160. self.lib.carla_pipe_client_write_and_fix_msg.argtypes = [CarlaPipeClientHandle, c_char_p]
  161. self.lib.carla_pipe_client_write_and_fix_msg.restype = c_bool
  162. self.lib.carla_pipe_client_flush.argtypes = [CarlaPipeClientHandle]
  163. self.lib.carla_pipe_client_flush.restype = c_bool
  164. self.lib.carla_pipe_client_flush_and_unlock.argtypes = [CarlaPipeClientHandle]
  165. self.lib.carla_pipe_client_flush_and_unlock.restype = c_bool
  166. self.lib.carla_pipe_client_destroy.argtypes = [CarlaPipeClientHandle]
  167. self.lib.carla_pipe_client_destroy.restype = None
  168. # use _putenv on windows
  169. if not WINDOWS:
  170. self.msvcrt = None
  171. return
  172. self.msvcrt = cdll.msvcrt
  173. self.msvcrt._putenv.argtypes = [c_char_p]
  174. self.msvcrt._putenv.restype = None
  175. # --------------------------------------------------------------------------------------------------------
  176. # set environment variable
  177. def setenv(self, key, value):
  178. environ[key] = value
  179. if WINDOWS:
  180. keyvalue = "%s=%s" % (key, value)
  181. self.msvcrt._putenv(keyvalue.encode("utf-8"))
  182. # unset environment variable
  183. def unsetenv(self, key):
  184. if environ.get(key) is not None:
  185. environ.pop(key)
  186. if WINDOWS:
  187. keyrm = "%s=" % key
  188. self.msvcrt._putenv(keyrm.encode("utf-8"))
  189. # --------------------------------------------------------------------------------------------------------
  190. # Get the complete license text of used third-party code and features.
  191. # Returned string is in basic html format.
  192. def get_complete_license_text(self):
  193. return charPtrToString(self.lib.carla_get_complete_license_text())
  194. # Get the juce version used in the current Carla build.
  195. def get_juce_version(self):
  196. return charPtrToString(self.lib.carla_get_juce_version())
  197. # Get all the supported file extensions in carla_load_file().
  198. # Returned string uses this syntax:
  199. # @code
  200. # "*.ext1;*.ext2;*.ext3"
  201. # @endcode
  202. def get_supported_file_extensions(self):
  203. return charPtrToString(self.lib.carla_get_supported_file_extensions())
  204. # Get how many internal plugins are available.
  205. def get_cached_plugin_count(self, ptype, pluginPath):
  206. return int(self.lib.carla_get_cached_plugin_count(ptype, pluginPath.encode("utf-8")))
  207. # Get information about a cached plugin.
  208. def get_cached_plugin_info(self, ptype, index):
  209. return structToDict(self.lib.carla_get_cached_plugin_info(ptype, index).contents)
  210. def set_process_name(self, name):
  211. self.lib.carla_set_process_name(name.encode("utf-8"))
  212. def pipe_client_new(self, func):
  213. argc = len(argv)
  214. cagrvtype = c_char_p * argc
  215. cargv = cagrvtype()
  216. for i in range(argc):
  217. cargv[i] = c_char_p(argv[i].encode("utf-8"))
  218. self._pipeClientCallback = CarlaPipeCallbackFunc(func)
  219. return self.lib.carla_pipe_client_new(cargv, self._pipeClientCallback, None)
  220. def pipe_client_idle(self, handle):
  221. self.lib.carla_pipe_client_idle(handle)
  222. def pipe_client_is_running(self, handle):
  223. return bool(self.lib.carla_pipe_client_is_running(handle))
  224. def pipe_client_lock(self, handle):
  225. self.lib.carla_pipe_client_lock(handle)
  226. def pipe_client_unlock(self, handle):
  227. self.lib.carla_pipe_client_unlock(handle)
  228. def pipe_client_readlineblock(self, handle, timeout):
  229. return charPtrToString(self.lib.carla_pipe_client_readlineblock(handle, timeout))
  230. def pipe_client_write_msg(self, handle, msg):
  231. return bool(self.lib.carla_pipe_client_write_msg(handle, msg.encode("utf-8")))
  232. def pipe_client_write_and_fix_msg(self, handle, msg):
  233. return bool(self.lib.carla_pipe_client_write_and_fix_msg(handle, msg.encode("utf-8")))
  234. def pipe_client_flush(self, handle):
  235. return bool(self.lib.carla_pipe_client_flush(handle))
  236. def pipe_client_flush_and_unlock(self, handle):
  237. return bool(self.lib.carla_pipe_client_flush_and_unlock(handle))
  238. def pipe_client_destroy(self, handle):
  239. self.lib.carla_pipe_client_destroy(handle)
  240. # ------------------------------------------------------------------------------------------------------------