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.

666 lines
23KB

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