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.

629 lines
19KB

  1. /*
  2. * JackBridge (Part 3, Export)
  3. * Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "JackBridgeExport.hpp"
  17. #include "CarlaLibUtils.hpp"
  18. #include "CarlaUtils.h"
  19. // #include <cstdio>
  20. // --------------------------------------------------------------------------------------------------------------------
  21. class JackBridgeExported
  22. {
  23. public:
  24. JackBridgeExported() noexcept
  25. : lib(nullptr),
  26. func(nullptr)
  27. {
  28. #ifdef CARLA_OS_WIN64
  29. lib = lib_open("jackbridge-wine64.dll");
  30. #else
  31. lib = lib_open("jackbridge-wine32.dll");
  32. #endif
  33. CARLA_SAFE_ASSERT_RETURN(lib != nullptr,);
  34. func = lib_symbol<jackbridge_exported_function_type>(lib, "jackbridge_get_exported_functions");
  35. CARLA_SAFE_ASSERT_RETURN(func != nullptr,);
  36. }
  37. ~JackBridgeExported() noexcept
  38. {
  39. if (lib == nullptr)
  40. return;
  41. lib_close(lib);
  42. lib = nullptr;
  43. func = nullptr;
  44. }
  45. static const JackBridgeExportedFunctions& getFunctions() noexcept
  46. {
  47. static JackBridgeExportedFunctions fallback;
  48. carla_zeroStruct(fallback);
  49. fallback.unique1 = 1;
  50. fallback.unique2 = 2;
  51. fallback.unique3 = 3;
  52. static const JackBridgeExported bridge;
  53. CARLA_SAFE_ASSERT_RETURN(bridge.func != nullptr, fallback);
  54. const JackBridgeExportedFunctions* const funcs = bridge.func();
  55. CARLA_SAFE_ASSERT_RETURN(funcs != nullptr, fallback);
  56. CARLA_SAFE_ASSERT_RETURN(funcs->unique1 != 0, fallback);
  57. CARLA_SAFE_ASSERT_RETURN(funcs->unique1 == funcs->unique2, fallback);
  58. CARLA_SAFE_ASSERT_RETURN(funcs->unique2 == funcs->unique3, fallback);
  59. CARLA_SAFE_ASSERT_RETURN(funcs->discovery_pipe_destroy_ptr != nullptr, fallback);
  60. return *funcs;
  61. }
  62. private:
  63. lib_t lib;
  64. jackbridge_exported_function_type func;
  65. CARLA_PREVENT_HEAP_ALLOCATION
  66. CARLA_DECLARE_NON_COPYABLE(JackBridgeExported);
  67. };
  68. // --------------------------------------------------------------------------------------------------------------------
  69. static const JackBridgeExportedFunctions& getBridgeInstance() noexcept
  70. {
  71. static const JackBridgeExportedFunctions& funcs(JackBridgeExported::getFunctions());
  72. return funcs;
  73. }
  74. // --------------------------------------------------------------------------------------------------------------------
  75. bool jackbridge_is_ok() noexcept
  76. {
  77. const JackBridgeExportedFunctions& instance(getBridgeInstance());
  78. return (instance.unique1 != 0 && instance.unique1 == instance.unique2 && instance.init_ptr != nullptr);
  79. }
  80. void jackbridge_init()
  81. {
  82. return getBridgeInstance().init_ptr();
  83. }
  84. void jackbridge_get_version(int* major_ptr, int* minor_ptr, int* micro_ptr, int* proto_ptr)
  85. {
  86. return getBridgeInstance().get_version_ptr(major_ptr, minor_ptr, micro_ptr, proto_ptr);
  87. }
  88. const char* jackbridge_get_version_string()
  89. {
  90. return getBridgeInstance().get_version_string_ptr();
  91. }
  92. jack_client_t* jackbridge_client_open(const char* client_name, uint32_t options, jack_status_t* status)
  93. {
  94. return getBridgeInstance().client_open_ptr(client_name, options, status);
  95. }
  96. bool jackbridge_client_close(jack_client_t* client)
  97. {
  98. return getBridgeInstance().client_close_ptr(client);
  99. }
  100. int jackbridge_client_name_size()
  101. {
  102. return getBridgeInstance().client_name_size_ptr();
  103. }
  104. char* jackbridge_get_client_name(jack_client_t* client)
  105. {
  106. return getBridgeInstance().get_client_name_ptr(client);
  107. }
  108. char* jackbridge_client_get_uuid(jack_client_t* client)
  109. {
  110. return getBridgeInstance().client_get_uuid_ptr(client);
  111. }
  112. char* jackbridge_get_uuid_for_client_name(jack_client_t* client, const char* name)
  113. {
  114. return getBridgeInstance().get_uuid_for_client_name_ptr(client, name);
  115. }
  116. char* jackbridge_get_client_name_by_uuid(jack_client_t* client, const char* uuid)
  117. {
  118. return getBridgeInstance().get_client_name_by_uuid_ptr(client, uuid);
  119. }
  120. bool jackbridge_uuid_parse(const char* buf, jack_uuid_t* uuid)
  121. {
  122. return getBridgeInstance().uuid_parse_ptr(buf, uuid);
  123. }
  124. bool jackbridge_activate(jack_client_t* client)
  125. {
  126. return getBridgeInstance().activate_ptr(client);
  127. }
  128. bool jackbridge_deactivate(jack_client_t* client)
  129. {
  130. return getBridgeInstance().deactivate_ptr(client);
  131. }
  132. bool jackbridge_is_realtime(jack_client_t* client)
  133. {
  134. return getBridgeInstance().is_realtime_ptr(client);
  135. }
  136. bool jackbridge_set_thread_init_callback(jack_client_t* client, JackThreadInitCallback thread_init_callback, void* arg)
  137. {
  138. return getBridgeInstance().set_thread_init_callback_ptr(client, thread_init_callback, arg);
  139. }
  140. void jackbridge_on_shutdown(jack_client_t* client, JackShutdownCallback shutdown_callback, void* arg)
  141. {
  142. return getBridgeInstance().on_shutdown_ptr(client, shutdown_callback, arg);
  143. }
  144. void jackbridge_on_info_shutdown(jack_client_t* client, JackInfoShutdownCallback shutdown_callback, void* arg)
  145. {
  146. return getBridgeInstance().on_info_shutdown_ptr(client, shutdown_callback, arg);
  147. }
  148. bool jackbridge_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg)
  149. {
  150. return getBridgeInstance().set_process_callback_ptr(client, process_callback, arg);
  151. }
  152. bool jackbridge_set_freewheel_callback(jack_client_t* client, JackFreewheelCallback freewheel_callback, void* arg)
  153. {
  154. return getBridgeInstance().set_freewheel_callback_ptr(client, freewheel_callback, arg);
  155. }
  156. bool jackbridge_set_buffer_size_callback(jack_client_t* client, JackBufferSizeCallback bufsize_callback, void* arg)
  157. {
  158. return getBridgeInstance().set_buffer_size_callback_ptr(client, bufsize_callback, arg);
  159. }
  160. bool jackbridge_set_sample_rate_callback(jack_client_t* client, JackSampleRateCallback srate_callback, void* arg)
  161. {
  162. return getBridgeInstance().set_sample_rate_callback_ptr(client, srate_callback, arg);
  163. }
  164. bool jackbridge_set_client_registration_callback(jack_client_t* client, JackClientRegistrationCallback registration_callback, void* arg)
  165. {
  166. return getBridgeInstance().set_client_registration_callback_ptr(client, registration_callback, arg);
  167. }
  168. bool jackbridge_set_port_registration_callback(jack_client_t* client, JackPortRegistrationCallback registration_callback, void *arg)
  169. {
  170. return getBridgeInstance().set_port_registration_callback_ptr(client, registration_callback, arg);
  171. }
  172. bool jackbridge_set_port_rename_callback(jack_client_t* client, JackPortRenameCallback rename_callback, void* arg)
  173. {
  174. return getBridgeInstance().set_port_rename_callback_ptr(client, rename_callback, arg);
  175. }
  176. bool jackbridge_set_port_connect_callback(jack_client_t* client, JackPortConnectCallback connect_callback, void* arg)
  177. {
  178. return getBridgeInstance().set_port_connect_callback_ptr(client, connect_callback, arg);
  179. }
  180. bool jackbridge_set_xrun_callback(jack_client_t* client, JackXRunCallback xrun_callback, void* arg)
  181. {
  182. return getBridgeInstance().set_xrun_callback_ptr(client, xrun_callback, arg);
  183. }
  184. bool jackbridge_set_latency_callback(jack_client_t* client, JackLatencyCallback latency_callback, void* arg)
  185. {
  186. return getBridgeInstance().set_latency_callback_ptr(client, latency_callback, arg);
  187. }
  188. bool jackbridge_set_freewheel(jack_client_t* client, bool onoff)
  189. {
  190. return getBridgeInstance().set_freewheel_ptr(client, onoff);
  191. }
  192. bool jackbridge_set_buffer_size(jack_client_t* client, jack_nframes_t nframes)
  193. {
  194. return getBridgeInstance().set_buffer_size_ptr(client, nframes);
  195. }
  196. jack_nframes_t jackbridge_get_sample_rate(jack_client_t* client)
  197. {
  198. return getBridgeInstance().get_sample_rate_ptr(client);
  199. }
  200. jack_nframes_t jackbridge_get_buffer_size(jack_client_t* client)
  201. {
  202. return getBridgeInstance().get_buffer_size_ptr(client);
  203. }
  204. float jackbridge_cpu_load(jack_client_t* client)
  205. {
  206. return getBridgeInstance().cpu_load_ptr(client);
  207. }
  208. jack_port_t* jackbridge_port_register(jack_client_t* client, const char* port_name, const char* port_type, uint64_t flags, uint64_t buffer_size)
  209. {
  210. return getBridgeInstance().port_register_ptr(client, port_name, port_type, flags, buffer_size);
  211. }
  212. bool jackbridge_port_unregister(jack_client_t* client, jack_port_t* port)
  213. {
  214. return getBridgeInstance().port_unregister_ptr(client, port);
  215. }
  216. void* jackbridge_port_get_buffer(jack_port_t* port, jack_nframes_t nframes)
  217. {
  218. return getBridgeInstance().port_get_buffer_ptr(port, nframes);
  219. }
  220. const char* jackbridge_port_name(const jack_port_t* port)
  221. {
  222. return getBridgeInstance().port_name_ptr(port);
  223. }
  224. jack_uuid_t jackbridge_port_uuid(const jack_port_t* port)
  225. {
  226. return getBridgeInstance().port_uuid_ptr(port);
  227. }
  228. const char* jackbridge_port_short_name(const jack_port_t* port)
  229. {
  230. return getBridgeInstance().port_short_name_ptr(port);
  231. }
  232. int jackbridge_port_flags(const jack_port_t* port)
  233. {
  234. return getBridgeInstance().port_flags_ptr(port);
  235. }
  236. const char* jackbridge_port_type(const jack_port_t* port)
  237. {
  238. return getBridgeInstance().port_type_ptr(port);
  239. }
  240. bool jackbridge_port_is_mine(const jack_client_t* client, const jack_port_t* port)
  241. {
  242. return getBridgeInstance().port_is_mine_ptr(client, port);
  243. }
  244. int jackbridge_port_connected(const jack_port_t* port)
  245. {
  246. return getBridgeInstance().port_connected_ptr(port);
  247. }
  248. bool jackbridge_port_connected_to(const jack_port_t* port, const char* port_name)
  249. {
  250. return getBridgeInstance().port_connected_to_ptr(port, port_name);
  251. }
  252. const char** jackbridge_port_get_connections(const jack_port_t* port)
  253. {
  254. return getBridgeInstance().port_get_connections_ptr(port);
  255. }
  256. const char** jackbridge_port_get_all_connections(const jack_client_t* client, const jack_port_t* port)
  257. {
  258. return getBridgeInstance().port_get_all_connections_ptr(client, port);
  259. }
  260. bool jackbridge_port_rename(jack_client_t* client, jack_port_t* port, const char* port_name)
  261. {
  262. return getBridgeInstance().port_rename_ptr(client, port, port_name);
  263. }
  264. bool jackbridge_port_set_alias(jack_port_t* port, const char* alias)
  265. {
  266. return getBridgeInstance().port_set_alias_ptr(port, alias);
  267. }
  268. bool jackbridge_port_unset_alias(jack_port_t* port, const char* alias)
  269. {
  270. return getBridgeInstance().port_unset_alias_ptr(port, alias);
  271. }
  272. int jackbridge_port_get_aliases(const jack_port_t* port, char* const aliases[2])
  273. {
  274. return getBridgeInstance().port_get_aliases_ptr(port, aliases);
  275. }
  276. bool jackbridge_port_request_monitor(jack_port_t* port, bool onoff)
  277. {
  278. return getBridgeInstance().port_request_monitor_ptr(port, onoff);
  279. }
  280. bool jackbridge_port_request_monitor_by_name(jack_client_t* client, const char* port_name, bool onoff)
  281. {
  282. return getBridgeInstance().port_request_monitor_by_name_ptr(client, port_name, onoff);
  283. }
  284. bool jackbridge_port_ensure_monitor(jack_port_t* port, bool onoff)
  285. {
  286. return getBridgeInstance().port_ensure_monitor_ptr(port, onoff);
  287. }
  288. bool jackbridge_port_monitoring_input(jack_port_t* port)
  289. {
  290. return getBridgeInstance().port_monitoring_input_ptr(port);
  291. }
  292. bool jackbridge_connect(jack_client_t* client, const char* source_port, const char* destination_port)
  293. {
  294. return getBridgeInstance().connect_ptr(client, source_port, destination_port);
  295. }
  296. bool jackbridge_disconnect(jack_client_t* client, const char* source_port, const char* destination_port)
  297. {
  298. return getBridgeInstance().disconnect_ptr(client, source_port, destination_port);
  299. }
  300. bool jackbridge_port_disconnect(jack_client_t* client, jack_port_t* port)
  301. {
  302. return getBridgeInstance().port_disconnect_ptr(client, port);
  303. }
  304. int jackbridge_port_name_size()
  305. {
  306. return getBridgeInstance().port_name_size_ptr();
  307. }
  308. int jackbridge_port_type_size()
  309. {
  310. return getBridgeInstance().port_type_size_ptr();
  311. }
  312. uint32_t jackbridge_port_type_get_buffer_size(jack_client_t* client, const char* port_type)
  313. {
  314. return getBridgeInstance().port_type_get_buffer_size_ptr(client, port_type);
  315. }
  316. void jackbridge_port_get_latency_range(jack_port_t* port, uint32_t mode, jack_latency_range_t* range)
  317. {
  318. return getBridgeInstance().port_get_latency_range_ptr(port, mode, range);
  319. }
  320. void jackbridge_port_set_latency_range(jack_port_t* port, uint32_t mode, jack_latency_range_t* range)
  321. {
  322. return getBridgeInstance().port_set_latency_range_ptr(port, mode, range);
  323. }
  324. bool jackbridge_recompute_total_latencies(jack_client_t* client)
  325. {
  326. return getBridgeInstance().recompute_total_latencies_ptr(client);
  327. }
  328. const char** jackbridge_get_ports(jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, uint64_t flags)
  329. {
  330. return getBridgeInstance().get_ports_ptr(client, port_name_pattern, type_name_pattern, flags);
  331. }
  332. jack_port_t* jackbridge_port_by_name(jack_client_t* client, const char* port_name)
  333. {
  334. return getBridgeInstance().port_by_name_ptr(client, port_name);
  335. }
  336. jack_port_t* jackbridge_port_by_id(jack_client_t* client, jack_port_id_t port_id)
  337. {
  338. return getBridgeInstance().port_by_id_ptr(client, port_id);
  339. }
  340. void jackbridge_free(void* ptr)
  341. {
  342. return getBridgeInstance().free_ptr(ptr);
  343. }
  344. uint32_t jackbridge_midi_get_event_count(void* port_buffer)
  345. {
  346. return getBridgeInstance().midi_get_event_count_ptr(port_buffer);
  347. }
  348. bool jackbridge_midi_event_get(jack_midi_event_t* event, void* port_buffer, uint32_t event_index)
  349. {
  350. return getBridgeInstance().midi_event_get_ptr(event, port_buffer, event_index);
  351. }
  352. void jackbridge_midi_clear_buffer(void* port_buffer)
  353. {
  354. return getBridgeInstance().midi_clear_buffer_ptr(port_buffer);
  355. }
  356. bool jackbridge_midi_event_write(void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, uint32_t data_size)
  357. {
  358. return getBridgeInstance().midi_event_write_ptr(port_buffer, time, data, data_size);
  359. }
  360. jack_midi_data_t* jackbridge_midi_event_reserve(void* port_buffer, jack_nframes_t time, uint32_t data_size)
  361. {
  362. return getBridgeInstance().midi_event_reserve_ptr(port_buffer, time, data_size);
  363. }
  364. bool jackbridge_release_timebase(jack_client_t* client)
  365. {
  366. return getBridgeInstance().release_timebase_ptr(client);
  367. }
  368. bool jackbridge_set_sync_callback(jack_client_t* client, JackSyncCallback sync_callback, void* arg)
  369. {
  370. return getBridgeInstance().set_sync_callback_ptr(client, sync_callback, arg);
  371. }
  372. bool jackbridge_set_sync_timeout(jack_client_t* client, jack_time_t timeout)
  373. {
  374. return getBridgeInstance().set_sync_timeout_ptr(client, timeout);
  375. }
  376. bool jackbridge_set_timebase_callback(jack_client_t* client, bool conditional, JackTimebaseCallback timebase_callback, void* arg)
  377. {
  378. return getBridgeInstance().set_timebase_callback_ptr(client, conditional, timebase_callback, arg);
  379. }
  380. bool jackbridge_transport_locate(jack_client_t* client, jack_nframes_t frame)
  381. {
  382. return getBridgeInstance().transport_locate_ptr(client, frame);
  383. }
  384. uint32_t jackbridge_transport_query(const jack_client_t* client, jack_position_t* pos)
  385. {
  386. return getBridgeInstance().transport_query_ptr(client, pos);
  387. }
  388. jack_nframes_t jackbridge_get_current_transport_frame(const jack_client_t* client)
  389. {
  390. return getBridgeInstance().get_current_transport_frame_ptr(client);
  391. }
  392. bool jackbridge_transport_reposition(jack_client_t* client, const jack_position_t* pos)
  393. {
  394. return getBridgeInstance().transport_reposition_ptr(client, pos);
  395. }
  396. void jackbridge_transport_start(jack_client_t* client)
  397. {
  398. return getBridgeInstance().transport_start_ptr(client);
  399. }
  400. void jackbridge_transport_stop(jack_client_t* client)
  401. {
  402. return getBridgeInstance().transport_stop_ptr(client);
  403. }
  404. bool jackbridge_set_property(jack_client_t* client, jack_uuid_t subject, const char* key, const char* value, const char* type)
  405. {
  406. return getBridgeInstance().set_property_ptr(client, subject, key, value, type);
  407. }
  408. bool jackbridge_get_property(jack_uuid_t subject, const char* key, char** value, char** type)
  409. {
  410. return getBridgeInstance().get_property_ptr(subject, key, value, type);
  411. }
  412. void jackbridge_free_description(jack_description_t* desc, bool free_description_itself)
  413. {
  414. return getBridgeInstance().free_description_ptr(desc, free_description_itself);
  415. }
  416. bool jackbridge_get_properties(jack_uuid_t subject, jack_description_t* desc)
  417. {
  418. return getBridgeInstance().get_properties_ptr(subject, desc);
  419. }
  420. bool jackbridge_get_all_properties(jack_description_t** descs)
  421. {
  422. return getBridgeInstance().get_all_properties_ptr(descs);
  423. }
  424. bool jackbridge_remove_property(jack_client_t* client, jack_uuid_t subject, const char* key)
  425. {
  426. return getBridgeInstance().remove_property_ptr(client, subject, key);
  427. }
  428. int jackbridge_remove_properties(jack_client_t* client, jack_uuid_t subject)
  429. {
  430. return getBridgeInstance().remove_properties_ptr(client, subject);
  431. }
  432. bool jackbridge_remove_all_properties(jack_client_t* client)
  433. {
  434. return getBridgeInstance().remove_all_properties_ptr(client);
  435. }
  436. bool jackbridge_set_property_change_callback(jack_client_t* client, JackPropertyChangeCallback callback, void* arg)
  437. {
  438. return getBridgeInstance().set_property_change_callback_ptr(client, callback, arg);
  439. }
  440. bool jackbridge_sem_init(void* sem) noexcept
  441. {
  442. return getBridgeInstance().sem_init_ptr(sem);
  443. }
  444. void jackbridge_sem_destroy(void* sem) noexcept
  445. {
  446. getBridgeInstance().sem_destroy_ptr(sem);
  447. }
  448. bool jackbridge_sem_connect(void* sem) noexcept
  449. {
  450. return getBridgeInstance().sem_connect_ptr(sem);
  451. }
  452. void jackbridge_sem_post(void* sem, bool server) noexcept
  453. {
  454. getBridgeInstance().sem_post_ptr(sem, server);
  455. }
  456. bool jackbridge_sem_timedwait(void* sem, uint msecs, bool server) noexcept
  457. {
  458. return getBridgeInstance().sem_timedwait_ptr(sem, msecs, server);
  459. }
  460. bool jackbridge_shm_is_valid(const void* shm) noexcept
  461. {
  462. return getBridgeInstance().shm_is_valid_ptr(shm);
  463. }
  464. void jackbridge_shm_init(void* shm) noexcept
  465. {
  466. return getBridgeInstance().shm_init_ptr(shm);
  467. }
  468. void jackbridge_shm_attach(void* shm, const char* name) noexcept
  469. {
  470. return getBridgeInstance().shm_attach_ptr(shm, name);
  471. }
  472. void jackbridge_shm_close(void* shm) noexcept
  473. {
  474. return getBridgeInstance().shm_close_ptr(shm);
  475. }
  476. void* jackbridge_shm_map(void* shm, uint64_t size) noexcept
  477. {
  478. return getBridgeInstance().shm_map_ptr(shm, size);
  479. }
  480. void jackbridge_shm_unmap(void* shm, void* ptr) noexcept
  481. {
  482. return getBridgeInstance().shm_unmap_ptr(shm, ptr);
  483. }
  484. // --------------------------------------------------------------------------------------------------------------------
  485. void* jackbridge_discovery_pipe_create(const char* argv[])
  486. {
  487. return getBridgeInstance().discovery_pipe_create_ptr(argv);
  488. }
  489. void jackbridge_discovery_pipe_message(void* pipe, const char* key, const char* value)
  490. {
  491. return getBridgeInstance().discovery_pipe_message_ptr(pipe, key, value);
  492. }
  493. void jackbridge_discovery_pipe_destroy(void* pipe)
  494. {
  495. return getBridgeInstance().discovery_pipe_destroy_ptr(pipe);
  496. }
  497. // --------------------------------------------------------------------------------------------------------------------
  498. void jackbridge_parent_deathsig(bool kill) noexcept
  499. {
  500. return getBridgeInstance().parent_deathsig_ptr(kill);
  501. }
  502. // --------------------------------------------------------------------------------------------------------------------