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.

539 lines
20KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla Backend 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 GPL.txt file
  17. # ------------------------------------------------------------------------------------------------------------
  18. # Imports (Global)
  19. from ctypes import *
  20. # ------------------------------------------------------------------------------------------------------------
  21. # Imports (Custom)
  22. from carla_shared import *
  23. # ------------------------------------------------------------------------------------------------------------
  24. # Convert a ctypes struct into a python dict
  25. def structToDict(struct):
  26. return dict((attr, getattr(struct, attr)) for attr, value in struct._fields_)
  27. # ------------------------------------------------------------------------------------------------------------
  28. # Backend C++ -> Python variables
  29. c_enum = c_int
  30. c_nullptr = None
  31. #if kIs64bit:
  32. #c_uintptr = c_uint64
  33. #else:
  34. #c_uintptr = c_uint32
  35. CallbackFunc = CFUNCTYPE(None, c_void_p, c_enum, c_int, c_int, c_int, c_double, c_char_p)
  36. class ParameterData(Structure):
  37. _fields_ = [
  38. ("type", c_enum),
  39. ("index", c_int32),
  40. ("rindex", c_int32),
  41. ("hints", c_int32),
  42. ("midiChannel", c_uint8),
  43. ("midiCC", c_int16)
  44. ]
  45. class ParameterRanges(Structure):
  46. _fields_ = [
  47. ("def", c_float),
  48. ("min", c_float),
  49. ("max", c_float),
  50. ("step", c_float),
  51. ("stepSmall", c_float),
  52. ("stepLarge", c_float)
  53. ]
  54. class MidiProgramData(Structure):
  55. _fields_ = [
  56. ("bank", c_uint32),
  57. ("program", c_uint32),
  58. ("name", c_char_p)
  59. ]
  60. class CustomData(Structure):
  61. _fields_ = [
  62. ("type", c_char_p),
  63. ("key", c_char_p),
  64. ("value", c_char_p)
  65. ]
  66. # ------------------------------------------------------------------------------------------------------------
  67. # Standalone C++ -> Python variables
  68. class CarlaPluginInfo(Structure):
  69. _fields_ = [
  70. ("type", c_enum),
  71. ("category", c_enum),
  72. ("hints", c_uint),
  73. ("binary", c_char_p),
  74. ("name", c_char_p),
  75. ("label", c_char_p),
  76. ("maker", c_char_p),
  77. ("copyright", c_char_p),
  78. ("uniqueId", c_long)
  79. ]
  80. class CarlaNativePluginInfo(Structure):
  81. _fields_ = [
  82. ("category", c_enum),
  83. ("hints", c_uint),
  84. ("audioIns", c_uint32),
  85. ("audioOuts", c_uint32),
  86. ("midiIns", c_uint32),
  87. ("midiOuts", c_uint32),
  88. ("parameterIns", c_uint32),
  89. ("parameterOuts", c_uint32),
  90. ("name", c_char_p),
  91. ("label", c_char_p),
  92. ("maker", c_char_p),
  93. ("copyright", c_char_p)
  94. ]
  95. class CarlaPortCountInfo(Structure):
  96. _fields_ = [
  97. ("ins", c_uint32),
  98. ("outs", c_uint32),
  99. ("total", c_uint32)
  100. ]
  101. class CarlaParameterInfo(Structure):
  102. _fields_ = [
  103. ("name", c_char_p),
  104. ("symbol", c_char_p),
  105. ("unit", c_char_p),
  106. ("scalePointCount", c_uint32)
  107. ]
  108. class CarlaScalePointInfo(Structure):
  109. _fields_ = [
  110. ("value", c_float),
  111. ("label", c_char_p)
  112. ]
  113. # ------------------------------------------------------------------------------------------------------------
  114. # Standalone Python object
  115. class Host(object):
  116. def __init__(self, lib_prefix_arg):
  117. object.__init__(self)
  118. global carla_library_path
  119. if lib_prefix_arg:
  120. carla_library_path = os.path.join(lib_prefix_arg, "lib", "carla", carla_libname)
  121. if not carla_library_path:
  122. self.lib = None
  123. return
  124. self.lib = cdll.LoadLibrary(carla_library_path)
  125. self.lib.carla_get_extended_license_text.argtypes = None
  126. self.lib.carla_get_extended_license_text.restype = c_char_p
  127. self.lib.carla_get_engine_driver_count.argtypes = None
  128. self.lib.carla_get_engine_driver_count.restype = c_uint
  129. self.lib.carla_get_engine_driver_name.argtypes = [c_uint]
  130. self.lib.carla_get_engine_driver_name.restype = c_char_p
  131. self.lib.carla_get_internal_plugin_count.argtypes = None
  132. self.lib.carla_get_internal_plugin_count.restype = c_uint
  133. self.lib.carla_get_internal_plugin_info.argtypes = [c_uint]
  134. self.lib.carla_get_internal_plugin_info.restype = POINTER(CarlaNativePluginInfo)
  135. self.lib.carla_engine_init.argtypes = [c_char_p, c_char_p]
  136. self.lib.carla_engine_init.restype = c_bool
  137. self.lib.carla_engine_close.argtypes = None
  138. self.lib.carla_engine_close.restype = c_bool
  139. self.lib.carla_engine_idle.argtypes = None
  140. self.lib.carla_engine_idle.restype = None
  141. self.lib.carla_is_engine_running.argtypes = None
  142. self.lib.carla_is_engine_running.restype = c_bool
  143. self.lib.carla_add_plugin.argtypes = [c_enum, c_enum, c_char_p, c_char_p, c_char_p, c_void_p]
  144. self.lib.carla_add_plugin.restype = c_bool
  145. self.lib.carla_remove_plugin.argtypes = [c_uint]
  146. self.lib.carla_remove_plugin.restype = c_bool
  147. self.lib.carla_get_plugin_info.argtypes = [c_uint]
  148. self.lib.carla_get_plugin_info.restype = POINTER(CarlaPluginInfo)
  149. self.lib.carla_get_audio_port_count_info.argtypes = [c_uint]
  150. self.lib.carla_get_audio_port_count_info.restype = POINTER(CarlaPortCountInfo)
  151. self.lib.carla_get_midi_port_count_info.argtypes = [c_uint]
  152. self.lib.carla_get_midi_port_count_info.restype = POINTER(CarlaPortCountInfo)
  153. self.lib.carla_get_parameter_count_info.argtypes = [c_uint]
  154. self.lib.carla_get_parameter_count_info.restype = POINTER(CarlaPortCountInfo)
  155. self.lib.carla_get_parameter_info.argtypes = [c_uint, c_uint32]
  156. self.lib.carla_get_parameter_info.restype = POINTER(CarlaParameterInfo)
  157. self.lib.carla_get_parameter_scalepoint_info.argtypes = [c_uint, c_uint32, c_uint32]
  158. self.lib.carla_get_parameter_scalepoint_info.restype = POINTER(CarlaScalePointInfo)
  159. self.lib.carla_get_parameter_data.argtypes = [c_uint, c_uint32]
  160. self.lib.carla_get_parameter_data.restype = POINTER(ParameterData)
  161. self.lib.carla_get_parameter_ranges.argtypes = [c_uint, c_uint32]
  162. self.lib.carla_get_parameter_ranges.restype = POINTER(ParameterRanges)
  163. self.lib.carla_get_midi_program_data.argtypes = [c_uint, c_uint32]
  164. self.lib.carla_get_midi_program_data.restype = POINTER(MidiProgramData)
  165. self.lib.carla_get_custom_data.argtypes = [c_uint, c_uint32]
  166. self.lib.carla_get_custom_data.restype = POINTER(CustomData)
  167. self.lib.carla_get_chunk_data.argtypes = [c_uint]
  168. self.lib.carla_get_chunk_data.restype = c_char_p
  169. self.lib.carla_get_parameter_count.argtypes = [c_uint]
  170. self.lib.carla_get_parameter_count.restype = c_uint32
  171. self.lib.carla_get_program_count.argtypes = [c_uint]
  172. self.lib.carla_get_program_count.restype = c_uint32
  173. self.lib.carla_get_midi_program_count.argtypes = [c_uint]
  174. self.lib.carla_get_midi_program_count.restype = c_uint32
  175. self.lib.carla_get_custom_data_count.argtypes = [c_uint]
  176. self.lib.carla_get_custom_data_count.restype = c_uint32
  177. self.lib.carla_get_parameter_text.argtypes = [c_uint, c_uint32]
  178. self.lib.carla_get_parameter_text.restype = c_char_p
  179. self.lib.carla_get_program_name.argtypes = [c_uint, c_uint32]
  180. self.lib.carla_get_program_name.restype = c_char_p
  181. self.lib.carla_get_midi_program_name.argtypes = [c_uint, c_uint32]
  182. self.lib.carla_get_midi_program_name.restype = c_char_p
  183. self.lib.carla_get_real_plugin_name.argtypes = [c_uint]
  184. self.lib.carla_get_real_plugin_name.restype = c_char_p
  185. self.lib.carla_get_current_program_index.argtypes = [c_uint]
  186. self.lib.carla_get_current_program_index.restype = c_int32
  187. self.lib.carla_get_current_midi_program_index.argtypes = [c_uint]
  188. self.lib.carla_get_current_midi_program_index.restype = c_int32
  189. # TODO - consider removal
  190. self.lib.carla_get_default_parameter_value.argtypes = [c_uint, c_uint32]
  191. self.lib.carla_get_default_parameter_value.restype = c_float
  192. # TODO - consider removal
  193. self.lib.carla_get_current_parameter_value.argtypes = [c_uint, c_uint32]
  194. self.lib.carla_get_current_parameter_value.restype = c_float
  195. self.lib.carla_get_input_peak_value.argtypes = [c_uint, c_ushort]
  196. self.lib.carla_get_input_peak_value.restype = c_float
  197. self.lib.carla_get_output_peak_value.argtypes = [c_uint, c_ushort]
  198. self.lib.carla_get_output_peak_value.restype = c_float
  199. self.lib.carla_set_active.argtypes = [c_uint, c_bool]
  200. self.lib.carla_set_active.restype = None
  201. self.lib.carla_set_drywet.argtypes = [c_uint, c_float]
  202. self.lib.carla_set_drywet.restype = None
  203. self.lib.carla_set_volume.argtypes = [c_uint, c_float]
  204. self.lib.carla_set_volume.restype = None
  205. self.lib.carla_set_balance_left.argtypes = [c_uint, c_float]
  206. self.lib.carla_set_balance_left.restype = None
  207. self.lib.carla_set_balance_right.argtypes = [c_uint, c_float]
  208. self.lib.carla_set_balance_right.restype = None
  209. self.lib.carla_set_panning.argtypes = [c_uint, c_float]
  210. self.lib.carla_set_panning.restype = None
  211. self.lib.carla_set_parameter_value.argtypes = [c_uint, c_uint32, c_float]
  212. self.lib.carla_set_parameter_value.restype = None
  213. self.lib.carla_set_parameter_midi_cc.argtypes = [c_uint, c_uint32, c_int16]
  214. self.lib.carla_set_parameter_midi_cc.restype = None
  215. self.lib.carla_set_parameter_midi_channel.argtypes = [c_uint, c_uint32, c_uint8]
  216. self.lib.carla_set_parameter_midi_channel.restype = None
  217. self.lib.carla_set_program.argtypes = [c_uint, c_uint32]
  218. self.lib.carla_set_program.restype = None
  219. self.lib.carla_set_midi_program.argtypes = [c_uint, c_uint32]
  220. self.lib.carla_set_midi_program.restype = None
  221. self.lib.carla_set_custom_data.argtypes = [c_uint, c_char_p, c_char_p, c_char_p]
  222. self.lib.carla_set_custom_data.restype = None
  223. self.lib.carla_set_chunk_data.argtypes = [c_uint, c_char_p]
  224. self.lib.carla_set_chunk_data.restype = None
  225. self.lib.carla_prepare_for_save.argtypes = [c_uint]
  226. self.lib.carla_prepare_for_save.restype = None
  227. self.lib.carla_send_midi_note.argtypes = [c_uint, c_uint8, c_uint8, c_uint8]
  228. self.lib.carla_send_midi_note.restype = None
  229. self.lib.carla_show_gui.argtypes = [c_uint, c_bool]
  230. self.lib.carla_show_gui.restype = None
  231. self.lib.carla_get_buffer_size.argtypes = None
  232. self.lib.carla_get_buffer_size.restype = c_uint32
  233. self.lib.carla_get_sample_rate.argtypes = None
  234. self.lib.carla_get_sample_rate.restype = c_double
  235. self.lib.carla_get_last_error.argtypes = None
  236. self.lib.carla_get_last_error.restype = c_char_p
  237. self.lib.carla_get_host_osc_url.argtypes = None
  238. self.lib.carla_get_host_osc_url.restype = c_char_p
  239. self.lib.carla_set_callback_function.argtypes = [CallbackFunc]
  240. self.lib.carla_set_callback_function.restype = None
  241. self.lib.carla_set_option.argtypes = [c_enum, c_int, c_char_p]
  242. self.lib.carla_set_option.restype = None
  243. #self.lib.nsm_announce.argtypes = [c_char_p, c_int]
  244. #self.lib.nsm_announce.restype = None
  245. #self.lib.nsm_reply_open.argtypes = None
  246. #self.lib.nsm_reply_open.restype = None
  247. #self.lib.nsm_reply_save.argtypes = None
  248. #self.lib.nsm_reply_save.restype = None
  249. def get_extended_license_text(self):
  250. return self.lib.carla_get_extended_license_text()
  251. def get_engine_driver_count(self):
  252. return self.lib.carla_get_engine_driver_count()
  253. def get_engine_driver_name(self, index):
  254. return self.lib.carla_get_engine_driver_name(index)
  255. def get_internal_plugin_count(self):
  256. return self.lib.carla_get_internal_plugin_count()
  257. def get_internal_plugin_info(self, internalPluginId):
  258. return structToDict(self.lib.carla_get_internal_plugin_info(internalPluginId).contents)
  259. def engine_init(self, driverName, clientName):
  260. return self.lib.carla_engine_init(driverName.encode("utf-8"), clientName.encode("utf-8"))
  261. def engine_close(self):
  262. return self.lib.carla_engine_close()
  263. def engine_idle(self):
  264. return self.lib.carla_engine_idle()
  265. def is_engine_running(self):
  266. return self.lib.carla_is_engine_running()
  267. def add_plugin(self, btype, ptype, filename, name, label, extraStuff):
  268. cname = name.encode("utf-8") if name else c_nullptr
  269. return self.lib.carla_add_plugin(btype, ptype, filename.encode("utf-8"), cname, label.encode("utf-8"), cast(extraStuff, c_void_p))
  270. def remove_plugin(self, pluginId):
  271. return self.lib.carla_remove_plugin(pluginId)
  272. def get_plugin_info(self, pluginId):
  273. return structToDict(self.lib.carla_get_plugin_info(pluginId).contents)
  274. def get_audio_port_count_info(self, pluginId):
  275. return structToDict(self.lib.carla_get_audio_port_count_info(pluginId).contents)
  276. def get_midi_port_count_info(self, pluginId):
  277. return structToDict(self.lib.carla_get_midi_port_count_info(pluginId).contents)
  278. def get_parameter_count_info(self, pluginId):
  279. return structToDict(self.lib.carla_get_parameter_count_info(pluginId).contents)
  280. def get_parameter_info(self, pluginId, parameterId):
  281. return structToDict(self.lib.carla_get_parameter_info(pluginId, parameterId).contents)
  282. def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId):
  283. return structToDict(self.lib.carla_get_parameter_scalepoint_info(pluginId, parameterId, scalePointId).contents)
  284. def get_parameter_data(self, pluginId, parameterId):
  285. return structToDict(self.lib.carla_get_parameter_data(pluginId, parameterId).contents)
  286. def get_parameter_ranges(self, pluginId, parameterId):
  287. return structToDict(self.lib.carla_get_parameter_ranges(pluginId, parameterId).contents)
  288. def get_midi_program_data(self, pluginId, midiProgramId):
  289. return structToDict(self.lib.carla_get_midi_program_data(pluginId, midiProgramId).contents)
  290. def get_custom_data(self, pluginId, customDataId):
  291. return structToDict(self.lib.carla_get_custom_data(pluginId, customDataId).contents)
  292. def get_chunk_data(self, pluginId):
  293. return self.lib.carla_get_chunk_data(pluginId)
  294. def get_parameter_count(self, pluginId):
  295. return self.lib.carla_get_parameter_count(pluginId)
  296. def get_program_count(self, pluginId):
  297. return self.lib.carla_get_program_count(pluginId)
  298. def get_midi_program_count(self, pluginId):
  299. return self.lib.carla_get_midi_program_count(pluginId)
  300. def get_custom_data_count(self, pluginId):
  301. return self.lib.carla_get_custom_data_count(pluginId)
  302. def get_parameter_text(self, pluginId, parameterId):
  303. return self.lib.carla_get_parameter_text(pluginId, parameterId)
  304. def get_program_name(self, pluginId, programId):
  305. return self.lib.carla_get_program_name(pluginId, programId)
  306. def get_midi_program_name(self, pluginId, midiProgramId):
  307. return self.lib.carla_get_midi_program_name(pluginId, midiProgramId)
  308. def get_real_plugin_name(self, pluginId):
  309. return self.lib.carla_get_real_plugin_name(pluginId)
  310. def get_current_program_index(self, pluginId):
  311. return self.lib.carla_get_current_program_index(pluginId)
  312. def get_current_midi_program_index(self, pluginId):
  313. return self.lib.carla_get_current_midi_program_index(pluginId)
  314. def get_default_parameter_value(self, pluginId, parameterId):
  315. return self.lib.carla_get_default_parameter_value(pluginId, parameterId)
  316. def get_current_parameter_value(self, pluginId, parameterId):
  317. return self.lib.carla_get_current_parameter_value(pluginId, parameterId)
  318. def get_input_peak_value(self, pluginId, portId):
  319. return self.lib.carla_get_input_peak_value(pluginId, portId)
  320. def get_output_peak_value(self, pluginId, portId):
  321. return self.lib.carla_get_output_peak_value(pluginId, portId)
  322. def set_active(self, pluginId, onOff):
  323. self.lib.carla_set_active(pluginId, onOff)
  324. def set_drywet(self, pluginId, value):
  325. self.lib.carla_set_drywet(pluginId, value)
  326. def set_volume(self, pluginId, value):
  327. self.lib.carla_set_volume(pluginId, value)
  328. def set_balance_left(self, pluginId, value):
  329. self.lib.carla_set_balance_left(pluginId, value)
  330. def set_balance_right(self, pluginId, value):
  331. self.lib.carla_set_balance_right(pluginId, value)
  332. def set_panning(self, pluginId, value):
  333. self.lib.carla_set_panning(pluginId, value)
  334. def set_parameter_value(self, pluginId, parameterId, value):
  335. self.lib.carla_set_parameter_value(pluginId, parameterId, value)
  336. def set_parameter_midi_cc(self, pluginId, parameterId, cc):
  337. self.lib.carla_set_parameter_midi_cc(pluginId, parameterId, cc)
  338. def set_parameter_midi_channel(self, pluginId, parameterId, channel):
  339. self.lib.carla_set_parameter_midi_channel(pluginId, parameterId, channel)
  340. def set_program(self, pluginId, programId):
  341. self.lib.carla_set_program(pluginId, programId)
  342. def set_midi_program(self, pluginId, midiProgramId):
  343. self.lib.carla_set_midi_program(pluginId, midiProgramId)
  344. def set_custom_data(self, pluginId, type_, key, value):
  345. self.lib.carla_set_custom_data(pluginId, type_.encode("utf-8"), key.encode("utf-8"), value.encode("utf-8"))
  346. def set_chunk_data(self, pluginId, chunkData):
  347. self.lib.carla_set_chunk_data(pluginId, chunkData.encode("utf-8"))
  348. def prepare_for_save(self, pluginId):
  349. self.lib.carla_prepare_for_save(pluginId)
  350. def send_midi_note(self, pluginId, channel, note, velocity):
  351. self.lib.carla_send_midi_note(pluginId, channel, note, velocity)
  352. def show_gui(self, pluginId, yesNo):
  353. self.lib.carla_show_gui(pluginId, yesNo)
  354. def get_last_error(self):
  355. return self.lib.carla_get_last_error()
  356. def get_host_osc_url(self):
  357. return self.lib.carla_get_host_osc_url()
  358. def get_buffer_size(self):
  359. return self.lib.carla_get_buffer_size()
  360. def get_sample_rate(self):
  361. return self.lib.carla_get_sample_rate()
  362. def set_callback_function(self, func):
  363. self._callback = CallbackFunc(func)
  364. self.lib.carla_set_callback_function(self._callback)
  365. def set_option(self, option, value, valueStr):
  366. self.lib.carla_set_option(option, value, valueStr.encode("utf-8"))
  367. #def nsm_announce(self, url, pid):
  368. #self.lib.nsm_announce(url.encode("utf-8"), pid)
  369. #def nsm_reply_open(self):
  370. #self.lib.nsm_reply_open()
  371. #def nsm_reply_save(self):
  372. #self.lib.nsm_reply_save()
  373. #Carla.host = Host(None)
  374. ## Test available drivers
  375. #driverCount = Carla.host.get_engine_driver_count()
  376. #driverList = []
  377. #for i in range(driverCount):
  378. #driver = cString(Carla.host.get_engine_driver_name(i))
  379. #if driver:
  380. #driverList.append(driver)
  381. #print(i, driver)
  382. ## Test available internal plugins
  383. #pluginCount = Carla.host.get_internal_plugin_count()
  384. #for i in range(pluginCount):
  385. #plugin = Carla.host.get_internal_plugin_info(i)
  386. #print(plugin)