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.

JackBridge.cpp 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. /*
  2. * JackBridge
  3. * Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * For a full copy of the license see the LGPL.txt file
  15. */
  16. #include "JackBridge.hpp"
  17. #ifdef __WINE__
  18. # define __CARLA_UTILS_HPP__
  19. # undef CARLA_ASSERT
  20. # define CARLA_ASSERT(...)
  21. #endif
  22. #include "CarlaLibUtils.hpp"
  23. #include <stdio.h>
  24. #ifndef JACKBRIDGE_DUMMY
  25. # include <time.h>
  26. # include <semaphore.h>
  27. #endif
  28. // -----------------------------------------------------------------------------
  29. typedef const char* (*jacksym_get_version_string)();
  30. typedef jack_client_t* (*jacksym_client_open)(const char*, jack_options_t, jack_status_t*, ...);
  31. typedef const char* (*jacksym_client_rename)(jack_client_t* client, const char* new_name);
  32. typedef int (*jacksym_client_close)(jack_client_t*);
  33. typedef int (*jacksym_client_name_size)();
  34. typedef char* (*jacksym_get_client_name)(jack_client_t*);
  35. typedef int (*jacksym_activate)(jack_client_t*);
  36. typedef int (*jacksym_deactivate)(jack_client_t*);
  37. typedef void (*jacksym_on_shutdown)(jack_client_t*, JackShutdownCallback, void*);
  38. typedef int (*jacksym_set_process_callback)(jack_client_t*, JackProcessCallback, void*);
  39. typedef int (*jacksym_set_freewheel_callback)(jack_client_t*, JackFreewheelCallback, void*);
  40. typedef int (*jacksym_set_buffer_size_callback)(jack_client_t*, JackBufferSizeCallback, void*);
  41. typedef int (*jacksym_set_sample_rate_callback)(jack_client_t*, JackSampleRateCallback, void*);
  42. typedef int (*jacksym_set_client_registration_callback)(jack_client_t*, JackClientRegistrationCallback, void*);
  43. typedef int (*jacksym_set_port_registration_callback)(jack_client_t*, JackPortRegistrationCallback, void*);
  44. typedef int (*jacksym_set_port_connect_callback)(jack_client_t*, JackPortConnectCallback, void*);
  45. typedef int (*jacksym_set_port_rename_callback)(jack_client_t*, JackPortRenameCallback, void*);
  46. typedef int (*jacksym_set_latency_callback)(jack_client_t*, JackLatencyCallback, void*);
  47. typedef jack_nframes_t (*jacksym_get_sample_rate)(jack_client_t*);
  48. typedef jack_nframes_t (*jacksym_get_buffer_size)(jack_client_t*);
  49. typedef jack_port_t* (*jacksym_port_register)(jack_client_t*, const char*, const char*, unsigned long, unsigned long);
  50. typedef int (*jacksym_port_unregister)(jack_client_t*, jack_port_t*);
  51. typedef void* (*jacksym_port_get_buffer)(jack_port_t*, jack_nframes_t);
  52. typedef const char* (*jacksym_port_name)(const jack_port_t*);
  53. typedef const char* (*jacksym_port_short_name)(const jack_port_t*);
  54. typedef int (*jacksym_port_flags)(const jack_port_t*);
  55. typedef const char* (*jacksym_port_type)(const jack_port_t*);
  56. typedef const char** (*jacksym_port_get_connections)(const jack_port_t*);
  57. typedef int (*jacksym_port_set_name)(jack_port_t*, const char*);
  58. typedef int (*jacksym_connect)(jack_client_t*, const char*, const char*);
  59. typedef int (*jacksym_disconnect)(jack_client_t*, const char*, const char*);
  60. typedef int (*jacksym_port_name_size)();
  61. typedef void (*jacksym_port_get_latency_range)(jack_port_t*, jack_latency_callback_mode_t, jack_latency_range_t*);
  62. typedef void (*jacksym_port_set_latency_range)(jack_port_t*, jack_latency_callback_mode_t, jack_latency_range_t*);
  63. typedef int (*jacksym_recompute_total_latencies)(jack_client_t*);
  64. typedef const char** (*jacksym_get_ports)(jack_client_t*, const char*, const char*, unsigned long);
  65. typedef jack_port_t* (*jacksym_port_by_name)(jack_client_t*, const char*);
  66. typedef jack_port_t* (*jacksym_port_by_id)(jack_client_t*, jack_port_id_t);
  67. typedef void (*jacksym_free)(void*);
  68. typedef uint32_t (*jacksym_midi_get_event_count)(void*);
  69. typedef int (*jacksym_midi_event_get)(jack_midi_event_t*, void*, uint32_t);
  70. typedef void (*jacksym_midi_clear_buffer)(void*);
  71. typedef int (*jacksym_midi_event_write)(void*, jack_nframes_t, const jack_midi_data_t*, size_t);
  72. typedef jack_midi_data_t* (*jacksym_midi_event_reserve)(void*, jack_nframes_t, size_t);
  73. typedef int (*jacksym_transport_locate)(jack_client_t*, jack_nframes_t);
  74. typedef void (*jacksym_transport_start)(jack_client_t*);
  75. typedef void (*jacksym_transport_stop)(jack_client_t*);
  76. typedef jack_transport_state_t (*jacksym_transport_query)(const jack_client_t*, jack_position_t*);
  77. // -----------------------------------------------------------------------------
  78. struct JackBridge {
  79. void* lib;
  80. jacksym_get_version_string get_version_string_ptr;
  81. jacksym_client_open client_open_ptr;
  82. jacksym_client_rename client_rename_ptr;
  83. jacksym_client_close client_close_ptr;
  84. jacksym_client_name_size client_name_size_ptr;
  85. jacksym_get_client_name get_client_name_ptr;
  86. jacksym_activate activate_ptr;
  87. jacksym_deactivate deactivate_ptr;
  88. jacksym_on_shutdown on_shutdown_ptr;
  89. jacksym_set_process_callback set_process_callback_ptr;
  90. jacksym_set_freewheel_callback set_freewheel_callback_ptr;
  91. jacksym_set_buffer_size_callback set_buffer_size_callback_ptr;
  92. jacksym_set_sample_rate_callback set_sample_rate_callback_ptr;
  93. jacksym_set_client_registration_callback set_client_registration_callback_ptr;
  94. jacksym_set_port_registration_callback set_port_registration_callback_ptr;
  95. jacksym_set_port_connect_callback set_port_connect_callback_ptr;
  96. jacksym_set_port_rename_callback set_port_rename_callback_ptr;
  97. jacksym_set_latency_callback set_latency_callback_ptr;
  98. jacksym_get_sample_rate get_sample_rate_ptr;
  99. jacksym_get_buffer_size get_buffer_size_ptr;
  100. jacksym_port_register port_register_ptr;
  101. jacksym_port_unregister port_unregister_ptr;
  102. jacksym_port_get_buffer port_get_buffer_ptr;
  103. jacksym_port_name port_name_ptr;
  104. jacksym_port_short_name port_short_name_ptr;
  105. jacksym_port_flags port_flags_ptr;
  106. jacksym_port_type port_type_ptr;
  107. jacksym_port_get_connections port_get_connections_ptr;
  108. jacksym_port_set_name port_set_name_ptr;
  109. jacksym_connect connect_ptr;
  110. jacksym_disconnect disconnect_ptr;
  111. jacksym_port_name_size port_name_size_ptr;
  112. jacksym_port_get_latency_range port_get_latency_range_ptr;
  113. jacksym_port_set_latency_range port_set_latency_range_ptr;
  114. jacksym_recompute_total_latencies recompute_total_latencies_ptr;
  115. jacksym_get_ports get_ports_ptr;
  116. jacksym_port_by_name port_by_name_ptr;
  117. jacksym_port_by_id port_by_id_ptr;
  118. jacksym_free free_ptr;
  119. jacksym_midi_get_event_count midi_get_event_count_ptr;
  120. jacksym_midi_event_get midi_event_get_ptr;
  121. jacksym_midi_clear_buffer midi_clear_buffer_ptr;
  122. jacksym_midi_event_write midi_event_write_ptr;
  123. jacksym_midi_event_reserve midi_event_reserve_ptr;
  124. jacksym_transport_locate transport_locate_ptr;
  125. jacksym_transport_start transport_start_ptr;
  126. jacksym_transport_stop transport_stop_ptr;
  127. jacksym_transport_query transport_query_ptr;
  128. JackBridge()
  129. : lib(nullptr),
  130. get_version_string_ptr(nullptr),
  131. client_open_ptr(nullptr),
  132. client_rename_ptr(nullptr),
  133. client_close_ptr(nullptr),
  134. client_name_size_ptr(nullptr),
  135. get_client_name_ptr(nullptr),
  136. activate_ptr(nullptr),
  137. deactivate_ptr(nullptr),
  138. on_shutdown_ptr(nullptr),
  139. set_process_callback_ptr(nullptr),
  140. set_freewheel_callback_ptr(nullptr),
  141. set_buffer_size_callback_ptr(nullptr),
  142. set_sample_rate_callback_ptr(nullptr),
  143. set_client_registration_callback_ptr(nullptr),
  144. set_port_registration_callback_ptr(nullptr),
  145. set_port_connect_callback_ptr(nullptr),
  146. set_port_rename_callback_ptr(nullptr),
  147. set_latency_callback_ptr(nullptr),
  148. get_sample_rate_ptr(nullptr),
  149. get_buffer_size_ptr(nullptr),
  150. port_register_ptr(nullptr),
  151. port_unregister_ptr(nullptr),
  152. port_get_buffer_ptr(nullptr),
  153. port_name_ptr(nullptr),
  154. port_short_name_ptr(nullptr),
  155. port_flags_ptr(nullptr),
  156. port_type_ptr(nullptr),
  157. port_get_connections_ptr(nullptr),
  158. port_set_name_ptr(nullptr),
  159. connect_ptr(nullptr),
  160. disconnect_ptr(nullptr),
  161. port_name_size_ptr(nullptr),
  162. port_get_latency_range_ptr(nullptr),
  163. port_set_latency_range_ptr(nullptr),
  164. recompute_total_latencies_ptr(nullptr),
  165. get_ports_ptr(nullptr),
  166. port_by_name_ptr(nullptr),
  167. port_by_id_ptr(nullptr),
  168. free_ptr(nullptr),
  169. midi_get_event_count_ptr(nullptr),
  170. midi_event_get_ptr(nullptr),
  171. midi_clear_buffer_ptr(nullptr),
  172. midi_event_write_ptr(nullptr),
  173. midi_event_reserve_ptr(nullptr),
  174. transport_locate_ptr(nullptr),
  175. transport_start_ptr(nullptr),
  176. transport_stop_ptr(nullptr),
  177. transport_query_ptr(nullptr)
  178. {
  179. #if defined(CARLA_OS_MAC)
  180. const char* const filename = "libjack.dylib";
  181. #elif defined(CARLA_OS_WIN) && ! defined(__WINE__)
  182. const char* const filename = "libjack.dll";
  183. #else
  184. const char* const filename = "libjack.so.0";
  185. #endif
  186. lib = lib_open(filename);
  187. if (lib == nullptr)
  188. {
  189. fprintf(stderr, "Failed to load JACK DLL, reason:\n%s\n", lib_error(filename));
  190. return;
  191. }
  192. #define JOIN(a, b) a ## b
  193. #define LIB_SYMBOL(NAME) JOIN(NAME, _ptr) = (jacksym_##NAME)lib_symbol(lib, "jack_" #NAME);
  194. LIB_SYMBOL(get_version_string)
  195. LIB_SYMBOL(client_open)
  196. LIB_SYMBOL(client_rename)
  197. LIB_SYMBOL(client_close)
  198. LIB_SYMBOL(client_name_size)
  199. LIB_SYMBOL(get_client_name)
  200. LIB_SYMBOL(activate)
  201. LIB_SYMBOL(deactivate)
  202. LIB_SYMBOL(on_shutdown)
  203. LIB_SYMBOL(set_process_callback)
  204. LIB_SYMBOL(set_freewheel_callback)
  205. LIB_SYMBOL(set_buffer_size_callback)
  206. LIB_SYMBOL(set_sample_rate_callback)
  207. LIB_SYMBOL(set_client_registration_callback)
  208. LIB_SYMBOL(set_port_registration_callback)
  209. LIB_SYMBOL(set_port_connect_callback)
  210. LIB_SYMBOL(set_port_rename_callback)
  211. LIB_SYMBOL(set_latency_callback)
  212. LIB_SYMBOL(get_sample_rate)
  213. LIB_SYMBOL(get_buffer_size)
  214. LIB_SYMBOL(port_register)
  215. LIB_SYMBOL(port_unregister)
  216. LIB_SYMBOL(port_get_buffer)
  217. LIB_SYMBOL(port_name)
  218. LIB_SYMBOL(port_short_name)
  219. LIB_SYMBOL(port_flags)
  220. LIB_SYMBOL(port_type)
  221. LIB_SYMBOL(port_get_connections)
  222. LIB_SYMBOL(port_set_name)
  223. LIB_SYMBOL(connect)
  224. LIB_SYMBOL(disconnect)
  225. LIB_SYMBOL(port_name_size)
  226. LIB_SYMBOL(port_get_latency_range)
  227. LIB_SYMBOL(port_set_latency_range)
  228. LIB_SYMBOL(recompute_total_latencies)
  229. LIB_SYMBOL(get_ports)
  230. LIB_SYMBOL(port_by_name)
  231. LIB_SYMBOL(port_by_id)
  232. LIB_SYMBOL(free)
  233. LIB_SYMBOL(midi_get_event_count)
  234. LIB_SYMBOL(midi_event_get)
  235. LIB_SYMBOL(midi_clear_buffer)
  236. LIB_SYMBOL(midi_event_write)
  237. LIB_SYMBOL(midi_event_reserve)
  238. LIB_SYMBOL(transport_locate)
  239. LIB_SYMBOL(transport_start)
  240. LIB_SYMBOL(transport_stop)
  241. LIB_SYMBOL(transport_query)
  242. #undef JOIN
  243. #undef LIB_SYMBOL
  244. }
  245. ~JackBridge()
  246. {
  247. if (lib != nullptr)
  248. lib_close(lib);
  249. }
  250. };
  251. static JackBridge bridge;
  252. // -----------------------------------------------------------------------------
  253. const char* jackbridge_get_version_string()
  254. {
  255. if (bridge.get_version_string_ptr != nullptr)
  256. return bridge.get_version_string_ptr();
  257. return nullptr;
  258. }
  259. jack_client_t* jackbridge_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...)
  260. {
  261. if (bridge.client_open_ptr != nullptr)
  262. return bridge.client_open_ptr(client_name, options, status);
  263. return nullptr;
  264. }
  265. const char* jackbridge_client_rename(jack_client_t* client, const char* new_name)
  266. {
  267. if (bridge.client_rename_ptr != nullptr)
  268. return bridge.client_rename_ptr(client, new_name);
  269. return nullptr;
  270. }
  271. // -----------------------------------------------------------------------------
  272. bool jackbridge_client_close(jack_client_t* client)
  273. {
  274. if (bridge.client_close_ptr != nullptr)
  275. return (bridge.client_close_ptr(client) == 0);
  276. return false;
  277. }
  278. int jackbridge_client_name_size()
  279. {
  280. if (bridge.client_name_size_ptr != nullptr)
  281. return bridge.client_name_size_ptr();
  282. return 0;
  283. }
  284. char* jackbridge_get_client_name(jack_client_t* client)
  285. {
  286. if (bridge.get_client_name_ptr != nullptr)
  287. return bridge.get_client_name_ptr(client);
  288. return nullptr;
  289. }
  290. // -----------------------------------------------------------------------------
  291. bool jackbridge_activate(jack_client_t* client)
  292. {
  293. if (bridge.activate_ptr != nullptr)
  294. return (bridge.activate_ptr(client) == 0);
  295. return false;
  296. }
  297. bool jackbridge_deactivate(jack_client_t* client)
  298. {
  299. if (bridge.deactivate_ptr != nullptr)
  300. return (bridge.deactivate_ptr(client) == 0);
  301. return false;
  302. }
  303. void jackbridge_on_shutdown(jack_client_t* client, JackShutdownCallback shutdown_callback, void* arg)
  304. {
  305. if (bridge.on_shutdown_ptr != nullptr)
  306. bridge.on_shutdown_ptr(client, shutdown_callback, arg);
  307. }
  308. bool jackbridge_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg)
  309. {
  310. if (bridge.set_process_callback_ptr != nullptr)
  311. return (bridge.set_process_callback_ptr(client, process_callback, arg) == 0);
  312. return false;
  313. }
  314. bool jackbridge_set_freewheel_callback(jack_client_t* client, JackFreewheelCallback freewheel_callback, void* arg)
  315. {
  316. if (bridge.set_freewheel_callback_ptr != nullptr)
  317. return (bridge.set_freewheel_callback_ptr(client, freewheel_callback, arg) == 0);
  318. return false;
  319. }
  320. bool jackbridge_set_buffer_size_callback(jack_client_t* client, JackBufferSizeCallback bufsize_callback, void* arg)
  321. {
  322. if (bridge.set_buffer_size_callback_ptr != nullptr)
  323. return (bridge.set_buffer_size_callback_ptr(client, bufsize_callback, arg) == 0);
  324. return false;
  325. }
  326. bool jackbridge_set_sample_rate_callback(jack_client_t* client, JackSampleRateCallback srate_callback, void* arg)
  327. {
  328. if (bridge.set_sample_rate_callback_ptr != nullptr)
  329. return (bridge.set_sample_rate_callback_ptr(client, srate_callback, arg) == 0);
  330. return false;
  331. }
  332. bool jackbridge_set_client_registration_callback(jack_client_t* client, JackClientRegistrationCallback registration_callback, void* arg)
  333. {
  334. if (bridge.set_client_registration_callback_ptr != nullptr)
  335. return (bridge.set_client_registration_callback_ptr(client, registration_callback, arg) == 0);
  336. return false;
  337. }
  338. bool jackbridge_set_port_registration_callback (jack_client_t* client, JackPortRegistrationCallback registration_callback, void *arg)
  339. {
  340. if (bridge.set_port_registration_callback_ptr != nullptr)
  341. return (bridge.set_port_registration_callback_ptr(client, registration_callback, arg) == 0);
  342. return false;
  343. }
  344. bool jackbridge_set_port_connect_callback (jack_client_t* client, JackPortConnectCallback connect_callback, void* arg)
  345. {
  346. if (bridge.set_port_connect_callback_ptr != nullptr)
  347. return (bridge.set_port_connect_callback_ptr(client, connect_callback, arg) == 0);
  348. return false;
  349. }
  350. bool jackbridge_set_port_rename_callback (jack_client_t* client, JackPortRenameCallback rename_callback, void* arg)
  351. {
  352. if (bridge.set_port_rename_callback_ptr != nullptr)
  353. return (bridge.set_port_rename_callback_ptr(client, rename_callback, arg) == 0);
  354. return false;
  355. }
  356. bool jackbridge_set_latency_callback(jack_client_t* client, JackLatencyCallback latency_callback, void* arg)
  357. {
  358. if (bridge.set_latency_callback_ptr != nullptr)
  359. return (bridge.set_latency_callback_ptr(client, latency_callback, arg) == 0);
  360. return false;
  361. }
  362. // -----------------------------------------------------------------------------
  363. jack_nframes_t jackbridge_get_sample_rate(jack_client_t* client)
  364. {
  365. if (bridge.get_sample_rate_ptr != nullptr)
  366. return bridge.get_sample_rate_ptr(client);
  367. return 0;
  368. }
  369. jack_nframes_t jackbridge_get_buffer_size(jack_client_t* client)
  370. {
  371. if (bridge.get_buffer_size_ptr != nullptr)
  372. return bridge.get_buffer_size_ptr(client);
  373. return 0;
  374. }
  375. jack_port_t* jackbridge_port_register(jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size)
  376. {
  377. if (bridge.port_register_ptr != nullptr)
  378. return bridge.port_register_ptr(client, port_name, port_type, flags, buffer_size);
  379. return nullptr;
  380. }
  381. bool jackbridge_port_unregister(jack_client_t* client, jack_port_t* port)
  382. {
  383. if (bridge.port_unregister_ptr != nullptr)
  384. return (bridge.port_unregister_ptr(client, port) == 0);
  385. return false;
  386. }
  387. void* jackbridge_port_get_buffer(jack_port_t* port, jack_nframes_t nframes)
  388. {
  389. if (bridge.port_get_buffer_ptr != nullptr)
  390. return bridge.port_get_buffer_ptr(port, nframes);
  391. return nullptr;
  392. }
  393. // -----------------------------------------------------------------------------
  394. const char* jackbridge_port_name(const jack_port_t* port)
  395. {
  396. if (bridge.port_name_ptr != nullptr)
  397. return bridge.port_name_ptr(port);
  398. return nullptr;
  399. }
  400. const char* jackbridge_port_short_name(const jack_port_t* port)
  401. {
  402. if (bridge.port_short_name_ptr != nullptr)
  403. return bridge.port_short_name_ptr(port);
  404. return nullptr;
  405. }
  406. int jackbridge_port_flags(const jack_port_t* port)
  407. {
  408. if (bridge.port_flags_ptr != nullptr)
  409. return bridge.port_flags_ptr(port);
  410. return 0;
  411. }
  412. const char* jackbridge_port_type(const jack_port_t* port)
  413. {
  414. if (bridge.port_type_ptr != nullptr)
  415. return bridge.port_type_ptr(port);
  416. return nullptr;
  417. }
  418. const char** jackbridge_port_get_connections(const jack_port_t* port)
  419. {
  420. if (bridge.port_get_connections_ptr != nullptr)
  421. return bridge.port_get_connections_ptr(port);
  422. return nullptr;
  423. }
  424. // -----------------------------------------------------------------------------
  425. bool jackbridge_port_set_name(jack_port_t* port, const char* port_name)
  426. {
  427. if (bridge.port_set_name_ptr != nullptr)
  428. return (bridge.port_set_name_ptr(port, port_name) == 0);
  429. return false;
  430. }
  431. bool jackbridge_connect(jack_client_t* client, const char* source_port, const char* destination_port)
  432. {
  433. if (bridge.connect_ptr != nullptr)
  434. return (bridge.connect_ptr(client, source_port, destination_port) == 0);
  435. return false;
  436. }
  437. bool jackbridge_disconnect(jack_client_t* client, const char* source_port, const char* destination_port)
  438. {
  439. if (bridge.disconnect_ptr != nullptr)
  440. return (bridge.disconnect_ptr(client, source_port, destination_port) == 0);
  441. return false;
  442. }
  443. int jackbridge_port_name_size()
  444. {
  445. if (bridge.port_name_size_ptr != nullptr)
  446. return bridge.port_name_size_ptr();
  447. return 0;
  448. }
  449. void jackbridge_port_get_latency_range(jack_port_t* port, jack_latency_callback_mode_t mode, jack_latency_range_t* range)
  450. {
  451. if (bridge.port_get_latency_range_ptr != nullptr)
  452. bridge.port_get_latency_range_ptr(port, mode, range);
  453. }
  454. void jackbridge_port_set_latency_range(jack_port_t* port, jack_latency_callback_mode_t mode, jack_latency_range_t* range)
  455. {
  456. if (bridge.port_set_latency_range_ptr != nullptr)
  457. bridge.port_set_latency_range_ptr(port, mode, range);
  458. }
  459. bool jackbridge_recompute_total_latencies(jack_client_t* client)
  460. {
  461. if (bridge.recompute_total_latencies_ptr != nullptr)
  462. return (bridge.recompute_total_latencies_ptr(client) == 0);
  463. return false;
  464. }
  465. const char** jackbridge_get_ports(jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
  466. {
  467. if (bridge.get_ports_ptr != nullptr)
  468. return bridge.get_ports_ptr(client, port_name_pattern, type_name_pattern, flags);
  469. return nullptr;
  470. }
  471. jack_port_t* jackbridge_port_by_name(jack_client_t* client, const char* port_name)
  472. {
  473. if (bridge.port_by_name_ptr != nullptr)
  474. return bridge.port_by_name_ptr(client, port_name);
  475. return nullptr;
  476. }
  477. jack_port_t* jackbridge_port_by_id(jack_client_t* client, jack_port_id_t port_id)
  478. {
  479. if (bridge.port_by_id_ptr != nullptr)
  480. return bridge.port_by_id_ptr(client, port_id);
  481. return nullptr;
  482. }
  483. // -----------------------------------------------------------------------------
  484. void jackbridge_free(void* ptr)
  485. {
  486. if (bridge.free_ptr != nullptr)
  487. return bridge.free_ptr(ptr);
  488. // just in case
  489. free(ptr);
  490. }
  491. // -----------------------------------------------------------------------------
  492. uint32_t jackbridge_midi_get_event_count(void* port_buffer)
  493. {
  494. if (bridge.midi_get_event_count_ptr != nullptr)
  495. return bridge.midi_get_event_count_ptr(port_buffer);
  496. return 0;
  497. }
  498. bool jackbridge_midi_event_get(jack_midi_event_t* event, void* port_buffer, uint32_t event_index)
  499. {
  500. if (bridge.midi_event_get_ptr != nullptr)
  501. return (bridge.midi_event_get_ptr(event, port_buffer, event_index) == 0);
  502. return false;
  503. }
  504. void jackbridge_midi_clear_buffer(void* port_buffer)
  505. {
  506. if (bridge.midi_clear_buffer_ptr != nullptr)
  507. bridge.midi_clear_buffer_ptr(port_buffer);
  508. }
  509. bool jackbridge_midi_event_write(void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, size_t data_size)
  510. {
  511. if (bridge.midi_event_write_ptr != nullptr)
  512. return (bridge.midi_event_write_ptr(port_buffer, time, data, data_size) == 0);
  513. return false;
  514. }
  515. jack_midi_data_t* jackbridge_midi_event_reserve(void* port_buffer, jack_nframes_t time, size_t data_size)
  516. {
  517. if (bridge.midi_event_reserve_ptr != nullptr)
  518. return bridge.midi_event_reserve_ptr(port_buffer, time, data_size);
  519. return nullptr;
  520. }
  521. // -----------------------------------------------------------------------------
  522. int jackbridge_transport_locate(jack_client_t* client, jack_nframes_t frame)
  523. {
  524. if (bridge.transport_locate_ptr != nullptr)
  525. return (bridge.transport_locate_ptr(client, frame) == 0);
  526. return false;
  527. }
  528. void jackbridge_transport_start(jack_client_t* client)
  529. {
  530. if (bridge.transport_start_ptr != nullptr)
  531. bridge.transport_start_ptr(client);
  532. }
  533. void jackbridge_transport_stop(jack_client_t* client)
  534. {
  535. if (bridge.transport_stop_ptr != nullptr)
  536. bridge.transport_stop_ptr(client);
  537. }
  538. jack_transport_state_t jackbridge_transport_query(const jack_client_t* client, jack_position_t* pos)
  539. {
  540. if (bridge.transport_query_ptr != nullptr)
  541. return bridge.transport_query_ptr(client, pos);
  542. return JackTransportStopped;
  543. }
  544. // -----------------------------------------------------------------------------
  545. #ifdef JACKBRIDGE_DUMMY
  546. bool jackbridge_sem_post(void* sem)
  547. {
  548. return false;
  549. }
  550. bool jackbridge_sem_timedwait(void* sem, int secs)
  551. {
  552. return false;
  553. }
  554. #else
  555. bool jackbridge_sem_post(void* sem)
  556. {
  557. return (sem_post((sem_t*)sem) == 0);
  558. }
  559. bool jackbridge_sem_timedwait(void* sem, int secs)
  560. {
  561. # ifdef CARLA_OS_MAC
  562. alarm(secs);
  563. return (sem_wait((sem_t*)sem) == 0);
  564. # else
  565. timespec timeout;
  566. # ifdef CARLA_LIB_WINDOWS
  567. timeval now;
  568. gettimeofday(&now, nullptr);
  569. timeout.tv_sec = now.tv_sec;
  570. timeout.tv_nsec = now.tv_usec * 1000;
  571. # else
  572. clock_gettime(CLOCK_REALTIME, &timeout);
  573. # endif
  574. timeout.tv_sec += secs;
  575. return (sem_timedwait((sem_t*)sem, &timeout) == 0);
  576. # endif
  577. }
  578. #endif