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.

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