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.

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