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.

602 lines
18KB

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