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.

JackBridgeExport.cpp 18KB

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