jack2 codebase
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.

2129 lines
73KB

  1. /*
  2. Copyright (C) 2001-2003 Paul Davis
  3. Copyright (C) 2004-2008 Grame
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include "JackClient.h"
  17. #include "JackError.h"
  18. #include "JackGraphManager.h"
  19. #include "JackEngineControl.h"
  20. #include "JackClientControl.h"
  21. #include "JackGlobals.h"
  22. #include "JackTime.h"
  23. #include "JackCompilerDeps.h"
  24. #include "JackPortType.h"
  25. #include "JackPlatformPlug.h"
  26. #include <math.h>
  27. #ifdef __CLIENTDEBUG__
  28. #include "JackLibGlobals.h"
  29. #endif
  30. using namespace Jack;
  31. #ifdef __cplusplus
  32. extern "C"
  33. {
  34. #endif
  35. typedef void (*print_function)(const char*);
  36. typedef void *(*thread_routine)(void*);
  37. LIB_EXPORT
  38. void
  39. jack_get_version(
  40. int *major_ptr,
  41. int *minor_ptr,
  42. int *micro_ptr,
  43. int *proto_ptr);
  44. LIB_EXPORT
  45. const char*
  46. jack_get_version_string();
  47. jack_client_t * jack_client_new_aux(const char* client_name,
  48. jack_options_t options,
  49. jack_status_t *status);
  50. LIB_EXPORT jack_client_t * jack_client_open(const char* client_name,
  51. jack_options_t options,
  52. jack_status_t *status, ...);
  53. LIB_EXPORT jack_client_t * jack_client_new(const char* client_name);
  54. LIB_EXPORT int jack_client_name_size(void);
  55. LIB_EXPORT char* jack_get_client_name(jack_client_t *client);
  56. LIB_EXPORT int jack_internal_client_new(const char* client_name,
  57. const char* load_name,
  58. const char* load_init);
  59. LIB_EXPORT void jack_internal_client_close(const char* client_name);
  60. LIB_EXPORT int jack_is_realtime(jack_client_t *client);
  61. LIB_EXPORT void jack_on_shutdown(jack_client_t *client,
  62. JackShutdownCallback shutdown_callback, void *arg);
  63. LIB_EXPORT void jack_on_info_shutdown(jack_client_t *client,
  64. JackInfoShutdownCallback shutdown_callback, void *arg);
  65. LIB_EXPORT int jack_set_process_callback(jack_client_t *client,
  66. JackProcessCallback process_callback,
  67. void *arg);
  68. LIB_EXPORT jack_nframes_t jack_thread_wait(jack_client_t *client, int status);
  69. // new
  70. LIB_EXPORT jack_nframes_t jack_cycle_wait(jack_client_t*);
  71. LIB_EXPORT void jack_cycle_signal(jack_client_t*, int status);
  72. LIB_EXPORT int jack_set_process_thread(jack_client_t* client, JackThreadCallback fun, void *arg);
  73. LIB_EXPORT int jack_set_thread_init_callback(jack_client_t *client,
  74. JackThreadInitCallback thread_init_callback,
  75. void *arg);
  76. LIB_EXPORT int jack_set_freewheel_callback(jack_client_t *client,
  77. JackFreewheelCallback freewheel_callback,
  78. void *arg);
  79. LIB_EXPORT int jack_set_freewheel(jack_client_t* client, int onoff);
  80. LIB_EXPORT int jack_set_buffer_size(jack_client_t *client, jack_nframes_t nframes);
  81. LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t *client,
  82. JackBufferSizeCallback bufsize_callback,
  83. void *arg);
  84. LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t *client,
  85. JackSampleRateCallback srate_callback,
  86. void *arg);
  87. LIB_EXPORT int jack_set_client_registration_callback(jack_client_t *,
  88. JackClientRegistrationCallback
  89. registration_callback, void *arg);
  90. LIB_EXPORT int jack_set_port_registration_callback(jack_client_t *,
  91. JackPortRegistrationCallback
  92. registration_callback, void *arg);
  93. LIB_EXPORT int jack_set_port_connect_callback(jack_client_t *,
  94. JackPortConnectCallback
  95. connect_callback, void *arg);
  96. LIB_EXPORT int jack_set_port_rename_callback(jack_client_t *,
  97. JackPortRenameCallback
  98. rename_callback, void *arg);
  99. LIB_EXPORT int jack_set_graph_order_callback(jack_client_t *,
  100. JackGraphOrderCallback graph_callback,
  101. void *);
  102. LIB_EXPORT int jack_set_xrun_callback(jack_client_t *,
  103. JackXRunCallback xrun_callback, void *arg);
  104. LIB_EXPORT int jack_set_latency_callback(jack_client_t *client,
  105. JackLatencyCallback latency_callback, void *arg);
  106. LIB_EXPORT int jack_activate(jack_client_t *client);
  107. LIB_EXPORT int jack_deactivate(jack_client_t *client);
  108. LIB_EXPORT jack_port_t * jack_port_register(jack_client_t *client,
  109. const char* port_name,
  110. const char* port_type,
  111. unsigned long flags,
  112. unsigned long buffer_size);
  113. LIB_EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *);
  114. LIB_EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t);
  115. LIB_EXPORT const char* jack_port_name(const jack_port_t *port);
  116. LIB_EXPORT const char* jack_port_short_name(const jack_port_t *port);
  117. LIB_EXPORT int jack_port_flags(const jack_port_t *port);
  118. LIB_EXPORT const char* jack_port_type(const jack_port_t *port);
  119. LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port);
  120. LIB_EXPORT int jack_port_is_mine(const jack_client_t *, const jack_port_t *port);
  121. LIB_EXPORT int jack_port_connected(const jack_port_t *port);
  122. LIB_EXPORT int jack_port_connected_to(const jack_port_t *port,
  123. const char* port_name);
  124. LIB_EXPORT const char* * jack_port_get_connections(const jack_port_t *port);
  125. LIB_EXPORT const char* * jack_port_get_all_connections(const jack_client_t *client,
  126. const jack_port_t *port);
  127. LIB_EXPORT int jack_port_tie(jack_port_t *src, jack_port_t *dst);
  128. LIB_EXPORT int jack_port_untie(jack_port_t *port);
  129. // Old latency API
  130. LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t *port);
  131. LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t *,
  132. jack_port_t *port);
  133. LIB_EXPORT void jack_port_set_latency(jack_port_t *, jack_nframes_t);
  134. LIB_EXPORT int jack_recompute_total_latency(jack_client_t*, jack_port_t* port);
  135. // New latency API
  136. LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range);
  137. LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range);
  138. LIB_EXPORT int jack_recompute_total_latencies(jack_client_t*);
  139. LIB_EXPORT int jack_port_set_name(jack_port_t *port, const char* port_name);
  140. LIB_EXPORT int jack_port_set_alias(jack_port_t *port, const char* alias);
  141. LIB_EXPORT int jack_port_unset_alias(jack_port_t *port, const char* alias);
  142. LIB_EXPORT int jack_port_get_aliases(const jack_port_t *port, char* const aliases[2]);
  143. LIB_EXPORT int jack_port_request_monitor(jack_port_t *port, int onoff);
  144. LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t *client,
  145. const char* port_name, int onoff);
  146. LIB_EXPORT int jack_port_ensure_monitor(jack_port_t *port, int onoff);
  147. LIB_EXPORT int jack_port_monitoring_input(jack_port_t *port);
  148. LIB_EXPORT int jack_connect(jack_client_t *,
  149. const char* source_port,
  150. const char* destination_port);
  151. LIB_EXPORT int jack_disconnect(jack_client_t *,
  152. const char* source_port,
  153. const char* destination_port);
  154. LIB_EXPORT int jack_port_disconnect(jack_client_t *, jack_port_t *);
  155. LIB_EXPORT int jack_port_name_size(void);
  156. LIB_EXPORT int jack_port_type_size(void);
  157. LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t *client, const char* port_type);
  158. LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t *);
  159. LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t *);
  160. LIB_EXPORT const char* * jack_get_ports(jack_client_t *,
  161. const char* port_name_pattern,
  162. const char* type_name_pattern,
  163. unsigned long flags);
  164. LIB_EXPORT jack_port_t * jack_port_by_name(jack_client_t *, const char* port_name);
  165. LIB_EXPORT jack_port_t * jack_port_by_id(jack_client_t *client,
  166. jack_port_id_t port_id);
  167. LIB_EXPORT int jack_engine_takeover_timebase(jack_client_t *);
  168. LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t *);
  169. LIB_EXPORT jack_time_t jack_get_time();
  170. LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t time);
  171. LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t frames);
  172. LIB_EXPORT jack_nframes_t jack_frame_time(const jack_client_t *);
  173. LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t *client);
  174. LIB_EXPORT float jack_cpu_load(jack_client_t *client);
  175. LIB_EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t *);
  176. LIB_EXPORT void jack_set_error_function(print_function);
  177. LIB_EXPORT void jack_set_info_function(print_function);
  178. LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t *client);
  179. LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t *client);
  180. LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t *client);
  181. LIB_EXPORT int jack_release_timebase(jack_client_t *client);
  182. LIB_EXPORT int jack_set_sync_callback(jack_client_t *client,
  183. JackSyncCallback sync_callback,
  184. void *arg);
  185. LIB_EXPORT int jack_set_sync_timeout(jack_client_t *client,
  186. jack_time_t timeout);
  187. LIB_EXPORT int jack_set_timebase_callback(jack_client_t *client,
  188. int conditional,
  189. JackTimebaseCallback timebase_callback,
  190. void *arg);
  191. LIB_EXPORT int jack_transport_locate(jack_client_t *client,
  192. jack_nframes_t frame);
  193. LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t *client,
  194. jack_position_t *pos);
  195. LIB_EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t *client);
  196. LIB_EXPORT int jack_transport_reposition(jack_client_t *client,
  197. const jack_position_t *pos);
  198. LIB_EXPORT void jack_transport_start(jack_client_t *client);
  199. LIB_EXPORT void jack_transport_stop(jack_client_t *client);
  200. LIB_EXPORT void jack_get_transport_info(jack_client_t *client,
  201. jack_transport_info_t *tinfo);
  202. LIB_EXPORT void jack_set_transport_info(jack_client_t *client,
  203. jack_transport_info_t *tinfo);
  204. LIB_EXPORT int jack_client_real_time_priority(jack_client_t*);
  205. LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t*);
  206. LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority);
  207. LIB_EXPORT int jack_client_create_thread(jack_client_t* client,
  208. jack_native_thread_t *thread,
  209. int priority,
  210. int realtime, // boolean
  211. thread_routine routine,
  212. void *arg);
  213. LIB_EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread);
  214. LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread);
  215. LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread);
  216. #ifndef WIN32
  217. LIB_EXPORT void jack_set_thread_creator(jack_thread_creator_t jtc);
  218. #endif
  219. LIB_EXPORT char * jack_get_internal_client_name(jack_client_t *client,
  220. jack_intclient_t intclient);
  221. LIB_EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t *client,
  222. const char* client_name,
  223. jack_status_t *status);
  224. LIB_EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client,
  225. const char* client_name,
  226. jack_options_t options,
  227. jack_status_t *status, ...);
  228. LIB_EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t *client,
  229. const char* client_name,
  230. jack_options_t options,
  231. jack_status_t *status, va_list ap);
  232. LIB_EXPORT jack_status_t jack_internal_client_unload(jack_client_t *client,
  233. jack_intclient_t intclient);
  234. LIB_EXPORT void jack_free(void* ptr);
  235. LIB_EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg);
  236. LIB_EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path);
  237. LIB_EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event);
  238. LIB_EXPORT void jack_session_event_free(jack_session_event_t* ev);
  239. LIB_EXPORT char* jack_client_get_uuid (jack_client_t *client);
  240. LIB_EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name);
  241. LIB_EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid);
  242. LIB_EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* name, const char* uuid);
  243. LIB_EXPORT void jack_session_commands_free(jack_session_command_t *cmds);
  244. LIB_EXPORT int jack_client_has_session_callback(jack_client_t *client, const char* client_name);
  245. #ifdef __cplusplus
  246. }
  247. #endif
  248. static inline bool CheckPort(jack_port_id_t port_index)
  249. {
  250. return (port_index > 0 && port_index < PORT_NUM_MAX);
  251. }
  252. static inline bool CheckBufferSize(jack_nframes_t buffer_size)
  253. {
  254. return (buffer_size >= 1 && buffer_size <= BUFFER_SIZE_MAX);
  255. }
  256. static inline void WaitGraphChange()
  257. {
  258. /*
  259. TLS key that is set only in RT thread, so never waits for pending
  260. graph change in RT context (just read the current graph state).
  261. */
  262. if (jack_tls_get(JackGlobals::fRealTime) == NULL) {
  263. JackGraphManager* manager = GetGraphManager();
  264. JackEngineControl* control = GetEngineControl();
  265. assert(manager);
  266. assert(control);
  267. if (manager->IsPendingChange()) {
  268. jack_log("WaitGraphChange...");
  269. JackSleep(int(control->fPeriodUsecs * 1.1f));
  270. }
  271. }
  272. }
  273. LIB_EXPORT void jack_set_error_function(print_function func)
  274. {
  275. jack_error_callback = (func == NULL) ? &default_jack_error_callback : func;
  276. }
  277. LIB_EXPORT void jack_set_info_function(print_function func)
  278. {
  279. jack_info_callback = (func == NULL) ? &default_jack_info_callback : func;
  280. }
  281. LIB_EXPORT jack_client_t* jack_client_new(const char* client_name)
  282. {
  283. #ifdef __CLIENTDEBUG__
  284. JackGlobals::CheckContext("jack_client_new");
  285. #endif
  286. try {
  287. assert(JackGlobals::fOpenMutex);
  288. JackGlobals::fOpenMutex->Lock();
  289. jack_error("jack_client_new: deprecated");
  290. int options = JackUseExactName;
  291. if (getenv("JACK_START_SERVER") == NULL)
  292. options |= JackNoStartServer;
  293. jack_client_t* res = jack_client_new_aux(client_name, (jack_options_t)options, NULL);
  294. JackGlobals::fOpenMutex->Unlock();
  295. return res;
  296. } catch (std::bad_alloc& e) {
  297. jack_error("Memory allocation error...");
  298. return NULL;
  299. } catch (...) {
  300. jack_error("Unknown error...");
  301. return NULL;
  302. }
  303. }
  304. LIB_EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
  305. {
  306. #ifdef __CLIENTDEBUG__
  307. JackGlobals::CheckContext("jack_port_get_buffer");
  308. #endif
  309. uintptr_t port_aux = (uintptr_t)port;
  310. jack_port_id_t myport = (jack_port_id_t)port_aux;
  311. if (!CheckPort(myport)) {
  312. jack_error("jack_port_get_buffer called with an incorrect port %ld", myport);
  313. return NULL;
  314. } else {
  315. JackGraphManager* manager = GetGraphManager();
  316. return (manager ? manager->GetBuffer(myport, frames) : NULL);
  317. }
  318. }
  319. LIB_EXPORT const char* jack_port_name(const jack_port_t* port)
  320. {
  321. #ifdef __CLIENTDEBUG__
  322. JackGlobals::CheckContext("jack_port_name");
  323. #endif
  324. uintptr_t port_aux = (uintptr_t)port;
  325. jack_port_id_t myport = (jack_port_id_t)port_aux;
  326. if (!CheckPort(myport)) {
  327. jack_error("jack_port_name called with an incorrect port %ld", myport);
  328. return NULL;
  329. } else {
  330. JackGraphManager* manager = GetGraphManager();
  331. return (manager ? manager->GetPort(myport)->GetName() : NULL);
  332. }
  333. }
  334. LIB_EXPORT const char* jack_port_short_name(const jack_port_t* port)
  335. {
  336. #ifdef __CLIENTDEBUG__
  337. JackGlobals::CheckContext("jack_port_short_name");
  338. #endif
  339. uintptr_t port_aux = (uintptr_t)port;
  340. jack_port_id_t myport = (jack_port_id_t)port_aux;
  341. if (!CheckPort(myport)) {
  342. jack_error("jack_port_short_name called with an incorrect port %ld", myport);
  343. return NULL;
  344. } else {
  345. JackGraphManager* manager = GetGraphManager();
  346. return (manager ? manager->GetPort(myport)->GetShortName() : NULL);
  347. }
  348. }
  349. LIB_EXPORT int jack_port_flags(const jack_port_t* port)
  350. {
  351. #ifdef __CLIENTDEBUG__
  352. JackGlobals::CheckContext("jack_port_flags");
  353. #endif
  354. uintptr_t port_aux = (uintptr_t)port;
  355. jack_port_id_t myport = (jack_port_id_t)port_aux;
  356. if (!CheckPort(myport)) {
  357. jack_error("jack_port_flags called with an incorrect port %ld", myport);
  358. return -1;
  359. } else {
  360. JackGraphManager* manager = GetGraphManager();
  361. return (manager ? manager->GetPort(myport)->GetFlags() : -1);
  362. }
  363. }
  364. LIB_EXPORT const char* jack_port_type(const jack_port_t* port)
  365. {
  366. #ifdef __CLIENTDEBUG__
  367. JackGlobals::CheckContext("jack_port_type");
  368. #endif
  369. uintptr_t port_aux = (uintptr_t)port;
  370. jack_port_id_t myport = (jack_port_id_t)port_aux;
  371. if (!CheckPort(myport)) {
  372. jack_error("jack_port_flags called an incorrect port %ld", myport);
  373. return NULL;
  374. } else {
  375. JackGraphManager* manager = GetGraphManager();
  376. return (manager ? manager->GetPort(myport)->GetType() : NULL);
  377. }
  378. }
  379. LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port)
  380. {
  381. #ifdef __CLIENTDEBUG__
  382. JackGlobals::CheckContext("jack_port_type_id");
  383. #endif
  384. uintptr_t port_aux = (uintptr_t)port;
  385. jack_port_id_t myport = (jack_port_id_t)port_aux;
  386. if (!CheckPort(myport)) {
  387. jack_error("jack_port_type_id called an incorrect port %ld", myport);
  388. return 0;
  389. } else {
  390. JackGraphManager* manager = GetGraphManager();
  391. return (manager ? GetPortTypeId(manager->GetPort(myport)->GetType()) : 0);
  392. }
  393. }
  394. LIB_EXPORT int jack_port_connected(const jack_port_t* port)
  395. {
  396. #ifdef __CLIENTDEBUG__
  397. JackGlobals::CheckContext("jack_port_connected");
  398. #endif
  399. uintptr_t port_aux = (uintptr_t)port;
  400. jack_port_id_t myport = (jack_port_id_t)port_aux;
  401. if (!CheckPort(myport)) {
  402. jack_error("jack_port_connected called with an incorrect port %ld", myport);
  403. return -1;
  404. } else {
  405. WaitGraphChange();
  406. JackGraphManager* manager = GetGraphManager();
  407. return (manager ? manager->GetConnectionsNum(myport) : -1);
  408. }
  409. }
  410. LIB_EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name)
  411. {
  412. #ifdef __CLIENTDEBUG__
  413. JackGlobals::CheckContext("jack_port_connected_to");
  414. #endif
  415. uintptr_t port_aux = (uintptr_t)port;
  416. jack_port_id_t src = (jack_port_id_t)port_aux;
  417. if (!CheckPort(src)) {
  418. jack_error("jack_port_connected_to called with an incorrect port %ld", src);
  419. return -1;
  420. } else if (port_name == NULL) {
  421. jack_error("jack_port_connected_to called with a NULL port name");
  422. return -1;
  423. } else {
  424. WaitGraphChange();
  425. JackGraphManager* manager = GetGraphManager();
  426. jack_port_id_t dst = (manager ? manager->GetPort(port_name) : NO_PORT);
  427. if (dst == NO_PORT) {
  428. jack_error("Unknown destination port port_name = %s", port_name);
  429. return 0;
  430. } else {
  431. return manager->IsConnected(src, dst);
  432. }
  433. }
  434. }
  435. LIB_EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst)
  436. {
  437. #ifdef __CLIENTDEBUG__
  438. JackGlobals::CheckContext("jack_port_tie");
  439. #endif
  440. uintptr_t src_aux = (uintptr_t)src;
  441. jack_port_id_t mysrc = (jack_port_id_t)src_aux;
  442. if (!CheckPort(mysrc)) {
  443. jack_error("jack_port_tie called with a NULL src port");
  444. return -1;
  445. }
  446. uintptr_t dst_aux = (uintptr_t)dst;
  447. jack_port_id_t mydst = (jack_port_id_t)dst_aux;
  448. if (!CheckPort(mydst)) {
  449. jack_error("jack_port_tie called with a NULL dst port");
  450. return -1;
  451. }
  452. JackGraphManager* manager = GetGraphManager();
  453. if (manager && manager->GetPort(mysrc)->GetRefNum() != manager->GetPort(mydst)->GetRefNum()) {
  454. jack_error("jack_port_tie called with ports not belonging to the same client");
  455. return -1;
  456. } else {
  457. return manager->GetPort(mydst)->Tie(mysrc);
  458. }
  459. }
  460. LIB_EXPORT int jack_port_untie(jack_port_t* port)
  461. {
  462. #ifdef __CLIENTDEBUG__
  463. JackGlobals::CheckContext("jack_port_untie");
  464. #endif
  465. uintptr_t port_aux = (uintptr_t)port;
  466. jack_port_id_t myport = (jack_port_id_t)port_aux;
  467. if (!CheckPort(myport)) {
  468. jack_error("jack_port_untie called with an incorrect port %ld", myport);
  469. return -1;
  470. } else {
  471. JackGraphManager* manager = GetGraphManager();
  472. return (manager ? manager->GetPort(myport)->UnTie() : -1);
  473. }
  474. }
  475. LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port)
  476. {
  477. #ifdef __CLIENTDEBUG__
  478. JackGlobals::CheckContext("jack_port_get_latency");
  479. #endif
  480. uintptr_t port_aux = (uintptr_t)port;
  481. jack_port_id_t myport = (jack_port_id_t)port_aux;
  482. if (!CheckPort(myport)) {
  483. jack_error("jack_port_get_latency called with an incorrect port %ld", myport);
  484. return 0;
  485. } else {
  486. WaitGraphChange();
  487. JackGraphManager* manager = GetGraphManager();
  488. return (manager ? manager->GetPort(myport)->GetLatency() : 0);
  489. }
  490. }
  491. LIB_EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames)
  492. {
  493. #ifdef __CLIENTDEBUG__
  494. JackGlobals::CheckContext("jack_port_set_latency");
  495. #endif
  496. uintptr_t port_aux = (uintptr_t)port;
  497. jack_port_id_t myport = (jack_port_id_t)port_aux;
  498. if (!CheckPort(myport)) {
  499. jack_error("jack_port_set_latency called with an incorrect port %ld", myport);
  500. } else {
  501. JackGraphManager* manager = GetGraphManager();
  502. if (manager)
  503. manager->GetPort(myport)->SetLatency(frames);
  504. }
  505. }
  506. LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
  507. {
  508. #ifdef __CLIENTDEBUG__
  509. JackGlobals::CheckContext("jack_port_get_latency_range");
  510. #endif
  511. uintptr_t port_aux = (uintptr_t)port;
  512. jack_port_id_t myport = (jack_port_id_t)port_aux;
  513. if (!CheckPort(myport)) {
  514. jack_error("jack_port_get_latency_range called with an incorrect port %ld", myport);
  515. } else {
  516. WaitGraphChange();
  517. JackGraphManager* manager = GetGraphManager();
  518. if (manager)
  519. manager->GetPort(myport)->GetLatencyRange(mode, range);
  520. }
  521. }
  522. LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
  523. {
  524. #ifdef __CLIENTDEBUG__
  525. JackGlobals::CheckContext("jack_port_set_latency_range");
  526. #endif
  527. uintptr_t port_aux = (uintptr_t)port;
  528. jack_port_id_t myport = (jack_port_id_t)port_aux;
  529. if (!CheckPort(myport)) {
  530. jack_error("jack_port_set_latency_range called with an incorrect port %ld", myport);
  531. } else {
  532. WaitGraphChange();
  533. JackGraphManager* manager = GetGraphManager();
  534. if (manager)
  535. manager->GetPort(myport)->SetLatencyRange(mode, range);
  536. }
  537. }
  538. LIB_EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port)
  539. {
  540. #ifdef __CLIENTDEBUG__
  541. JackGlobals::CheckContext("jack_recompute_total_latency");
  542. #endif
  543. JackClient* client = (JackClient*)ext_client;
  544. uintptr_t port_aux = (uintptr_t)port;
  545. jack_port_id_t myport = (jack_port_id_t)port_aux;
  546. if (client == NULL) {
  547. jack_error("jack_recompute_total_latency called with a NULL client");
  548. return -1;
  549. } else if (!CheckPort(myport)) {
  550. jack_error("jack_recompute_total_latency called with a NULL port");
  551. return -1;
  552. } else {
  553. WaitGraphChange();
  554. JackGraphManager* manager = GetGraphManager();
  555. return (manager ? manager->ComputeTotalLatency(myport) : -1);
  556. }
  557. }
  558. LIB_EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client)
  559. {
  560. #ifdef __CLIENTDEBUG__
  561. JackGlobals::CheckContext("jack_recompute_total_latencies");
  562. #endif
  563. JackClient* client = (JackClient*)ext_client;
  564. if (client == NULL) {
  565. jack_error("jack_recompute_total_latencies called with a NULL client");
  566. return -1;
  567. } else {
  568. return client->ComputeTotalLatencies();
  569. }
  570. }
  571. LIB_EXPORT int jack_port_set_name(jack_port_t* port, const char* name)
  572. {
  573. #ifdef __CLIENTDEBUG__
  574. JackGlobals::CheckContext("jack_port_set_name");
  575. #endif
  576. uintptr_t port_aux = (uintptr_t)port;
  577. jack_port_id_t myport = (jack_port_id_t)port_aux;
  578. if (!CheckPort(myport)) {
  579. jack_error("jack_port_set_name called with an incorrect port %ld", myport);
  580. return -1;
  581. } else if (name == NULL) {
  582. jack_error("jack_port_set_name called with a NULL port name");
  583. return -1;
  584. } else {
  585. JackClient* client = NULL;
  586. for (int i = 0; i < CLIENT_NUM; i++) {
  587. // Find a valid client
  588. if ((client = JackGlobals::fClientTable[i])) {
  589. break;
  590. }
  591. }
  592. return (client) ? client->PortRename(myport, name) : -1;
  593. }
  594. }
  595. LIB_EXPORT int jack_port_set_alias(jack_port_t* port, const char* name)
  596. {
  597. #ifdef __CLIENTDEBUG__
  598. JackGlobals::CheckContext("jack_port_set_alias");
  599. #endif
  600. uintptr_t port_aux = (uintptr_t)port;
  601. jack_port_id_t myport = (jack_port_id_t)port_aux;
  602. if (!CheckPort(myport)) {
  603. jack_error("jack_port_set_alias called with an incorrect port %ld", myport);
  604. return -1;
  605. } else if (name == NULL) {
  606. jack_error("jack_port_set_alias called with a NULL port name");
  607. return -1;
  608. } else {
  609. JackGraphManager* manager = GetGraphManager();
  610. return (manager ? manager->GetPort(myport)->SetAlias(name) : -1);
  611. }
  612. }
  613. LIB_EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name)
  614. {
  615. #ifdef __CLIENTDEBUG__
  616. JackGlobals::CheckContext("jack_port_unset_alias");
  617. #endif
  618. uintptr_t port_aux = (uintptr_t)port;
  619. jack_port_id_t myport = (jack_port_id_t)port_aux;
  620. if (!CheckPort(myport)) {
  621. jack_error("jack_port_unset_alias called with an incorrect port %ld", myport);
  622. return -1;
  623. } else if (name == NULL) {
  624. jack_error("jack_port_unset_alias called with a NULL port name");
  625. return -1;
  626. } else {
  627. JackGraphManager* manager = GetGraphManager();
  628. return (manager ? manager->GetPort(myport)->UnsetAlias(name) : -1);
  629. }
  630. }
  631. LIB_EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2])
  632. {
  633. #ifdef __CLIENTDEBUG__
  634. JackGlobals::CheckContext("jack_port_get_aliases");
  635. #endif
  636. uintptr_t port_aux = (uintptr_t)port;
  637. jack_port_id_t myport = (jack_port_id_t)port_aux;
  638. if (!CheckPort(myport)) {
  639. jack_error("jack_port_get_aliases called with an incorrect port %ld", myport);
  640. return -1;
  641. } else {
  642. JackGraphManager* manager = GetGraphManager();
  643. return (manager ? manager->GetPort(myport)->GetAliases(aliases) : -1);
  644. }
  645. }
  646. LIB_EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff)
  647. {
  648. #ifdef __CLIENTDEBUG__
  649. JackGlobals::CheckContext("jack_port_request_monitor");
  650. #endif
  651. uintptr_t port_aux = (uintptr_t)port;
  652. jack_port_id_t myport = (jack_port_id_t)port_aux;
  653. if (!CheckPort(myport)) {
  654. jack_error("jack_port_request_monitor called with an incorrect port %ld", myport);
  655. return -1;
  656. } else {
  657. JackGraphManager* manager = GetGraphManager();
  658. return (manager ? manager->RequestMonitor(myport, onoff) : -1);
  659. }
  660. }
  661. LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff)
  662. {
  663. #ifdef __CLIENTDEBUG__
  664. JackGlobals::CheckContext("jack_port_request_monitor_by_name");
  665. #endif
  666. JackClient* client = (JackClient*)ext_client;
  667. if (client == NULL) {
  668. jack_error("jack_port_request_monitor_by_name called with a NULL client");
  669. return -1;
  670. } else {
  671. JackGraphManager* manager = GetGraphManager();
  672. if (!manager)
  673. return -1;
  674. jack_port_id_t myport = manager->GetPort(port_name);
  675. if (!CheckPort(myport)) {
  676. jack_error("jack_port_request_monitor_by_name called with an incorrect port %s", port_name);
  677. return -1;
  678. } else {
  679. return manager->RequestMonitor(myport, onoff);
  680. }
  681. }
  682. }
  683. LIB_EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff)
  684. {
  685. #ifdef __CLIENTDEBUG__
  686. JackGlobals::CheckContext("jack_port_ensure_monitor");
  687. #endif
  688. uintptr_t port_aux = (uintptr_t)port;
  689. jack_port_id_t myport = (jack_port_id_t)port_aux;
  690. if (!CheckPort(myport)) {
  691. jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport);
  692. return -1;
  693. } else {
  694. JackGraphManager* manager = GetGraphManager();
  695. return (manager ? manager->GetPort(myport)->EnsureMonitor(onoff) : -1);
  696. }
  697. }
  698. LIB_EXPORT int jack_port_monitoring_input(jack_port_t* port)
  699. {
  700. #ifdef __CLIENTDEBUG__
  701. JackGlobals::CheckContext("jack_port_monitoring_input");
  702. #endif
  703. uintptr_t port_aux = (uintptr_t)port;
  704. jack_port_id_t myport = (jack_port_id_t)port_aux;
  705. if (!CheckPort(myport)) {
  706. jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport);
  707. return -1;
  708. } else {
  709. JackGraphManager* manager = GetGraphManager();
  710. return (manager ? manager->GetPort(myport)->MonitoringInput() : -1);
  711. }
  712. }
  713. LIB_EXPORT int jack_is_realtime(jack_client_t* ext_client)
  714. {
  715. #ifdef __CLIENTDEBUG__
  716. JackGlobals::CheckContext("jack_is_realtime");
  717. #endif
  718. JackClient* client = (JackClient*)ext_client;
  719. if (client == NULL) {
  720. jack_error("jack_is_realtime called with a NULL client");
  721. return -1;
  722. } else {
  723. JackEngineControl* control = GetEngineControl();
  724. return (control ? control->fRealTime : -1);
  725. }
  726. }
  727. LIB_EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback callback, void* arg)
  728. {
  729. #ifdef __CLIENTDEBUG__
  730. JackGlobals::CheckContext("jack_on_shutdown");
  731. #endif
  732. JackClient* client = (JackClient*)ext_client;
  733. if (client == NULL) {
  734. jack_error("jack_on_shutdown called with a NULL client");
  735. } else {
  736. client->OnShutdown(callback, arg);
  737. }
  738. }
  739. LIB_EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg)
  740. {
  741. #ifdef __CLIENTDEBUG__
  742. JackGlobals::CheckContext("jack_on_info_shutdown");
  743. #endif
  744. JackClient* client = (JackClient*)ext_client;
  745. if (client == NULL) {
  746. jack_error("jack_on_info_shutdown called with a NULL client");
  747. } else {
  748. client->OnInfoShutdown(callback, arg);
  749. }
  750. }
  751. LIB_EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg)
  752. {
  753. #ifdef __CLIENTDEBUG__
  754. JackGlobals::CheckContext("jack_set_process_callback");
  755. #endif
  756. JackClient* client = (JackClient*)ext_client;
  757. if (client == NULL) {
  758. jack_error("jack_set_process_callback called with a NULL client");
  759. return -1;
  760. } else {
  761. return client->SetProcessCallback(callback, arg);
  762. }
  763. }
  764. LIB_EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status)
  765. {
  766. #ifdef __CLIENTDEBUG__
  767. JackGlobals::CheckContext("jack_thread_wait");
  768. #endif
  769. JackClient* client = (JackClient*)ext_client;
  770. if (client == NULL) {
  771. jack_error("jack_thread_wait called with a NULL client");
  772. return 0;
  773. } else {
  774. jack_error("jack_thread_wait: deprecated, use jack_cycle_wait/jack_cycle_signal");
  775. return 0;
  776. }
  777. }
  778. LIB_EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client)
  779. {
  780. #ifdef __CLIENTDEBUG__
  781. JackGlobals::CheckContext("jack_cycle_wait");
  782. #endif
  783. JackClient* client = (JackClient*)ext_client;
  784. if (client == NULL) {
  785. jack_error("jack_cycle_wait called with a NULL client");
  786. return 0;
  787. } else {
  788. return client->CycleWait();
  789. }
  790. }
  791. LIB_EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status)
  792. {
  793. #ifdef __CLIENTDEBUG__
  794. JackGlobals::CheckContext("jack_cycle_signal");
  795. #endif
  796. JackClient* client = (JackClient*)ext_client;
  797. if (client == NULL) {
  798. jack_error("jack_cycle_signal called with a NULL client");
  799. } else {
  800. client->CycleSignal(status);
  801. }
  802. }
  803. LIB_EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback fun, void *arg)
  804. {
  805. #ifdef __CLIENTDEBUG__
  806. JackGlobals::CheckContext("jack_set_process_thread");
  807. #endif
  808. JackClient* client = (JackClient*)ext_client;
  809. if (client == NULL) {
  810. jack_error("jack_set_process_thread called with a NULL client");
  811. return -1;
  812. } else {
  813. return client->SetProcessThread(fun, arg);
  814. }
  815. }
  816. LIB_EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg)
  817. {
  818. #ifdef __CLIENTDEBUG__
  819. JackGlobals::CheckContext("jack_set_freewheel_callback");
  820. #endif
  821. JackClient* client = (JackClient*)ext_client;
  822. if (client == NULL) {
  823. jack_error("jack_set_freewheel_callback called with a NULL client");
  824. return -1;
  825. } else {
  826. return client->SetFreewheelCallback(freewheel_callback, arg);
  827. }
  828. }
  829. LIB_EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff)
  830. {
  831. #ifdef __CLIENTDEBUG__
  832. JackGlobals::CheckContext("jack_set_freewheel");
  833. #endif
  834. JackClient* client = (JackClient*)ext_client;
  835. if (client == NULL) {
  836. jack_error("jack_set_freewheel called with a NULL client");
  837. return -1;
  838. } else {
  839. return client->SetFreeWheel(onoff);
  840. }
  841. }
  842. LIB_EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size)
  843. {
  844. #ifdef __CLIENTDEBUG__
  845. JackGlobals::CheckContext("jack_set_buffer_size");
  846. #endif
  847. JackClient* client = (JackClient*)ext_client;
  848. if (client == NULL) {
  849. jack_error("jack_set_buffer_size called with a NULL client");
  850. return -1;
  851. } else if (!CheckBufferSize(buffer_size)) {
  852. return -1;
  853. } else {
  854. return client->SetBufferSize(buffer_size);
  855. }
  856. }
  857. LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg)
  858. {
  859. #ifdef __CLIENTDEBUG__
  860. JackGlobals::CheckContext("jack_set_buffer_size_callback");
  861. #endif
  862. JackClient* client = (JackClient*)ext_client;
  863. if (client == NULL) {
  864. jack_error("jack_set_buffer_size_callback called with a NULL client");
  865. return -1;
  866. } else {
  867. return client->SetBufferSizeCallback(bufsize_callback, arg);
  868. }
  869. }
  870. LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg)
  871. {
  872. #ifdef __CLIENTDEBUG__
  873. JackGlobals::CheckContext("jack_set_sample_rate_callback");
  874. #endif
  875. JackClient* client = (JackClient*)ext_client;
  876. if (client == NULL) {
  877. jack_error("jack_set_sample_rate_callback called with a NULL client");
  878. return -1;
  879. } else {
  880. return client->SetSampleRateCallback(srate_callback, arg);
  881. }
  882. }
  883. LIB_EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, JackClientRegistrationCallback registration_callback, void* arg)
  884. {
  885. #ifdef __CLIENTDEBUG__
  886. JackGlobals::CheckContext("jack_set_client_registration_callback");
  887. #endif
  888. JackClient* client = (JackClient*)ext_client;
  889. if (client == NULL) {
  890. jack_error("jack_set_client_registration_callback called with a NULL client");
  891. return -1;
  892. } else {
  893. return client->SetClientRegistrationCallback(registration_callback, arg);
  894. }
  895. }
  896. LIB_EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg)
  897. {
  898. #ifdef __CLIENTDEBUG__
  899. JackGlobals::CheckContext("jack_set_port_registration_callback");
  900. #endif
  901. JackClient* client = (JackClient*)ext_client;
  902. if (client == NULL) {
  903. jack_error("jack_set_port_registration_callback called with a NULL client");
  904. return -1;
  905. } else {
  906. return client->SetPortRegistrationCallback(registration_callback, arg);
  907. }
  908. }
  909. LIB_EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortConnectCallback portconnect_callback, void* arg)
  910. {
  911. #ifdef __CLIENTDEBUG__
  912. JackGlobals::CheckContext("jack_set_port_connect_callback");
  913. #endif
  914. JackClient* client = (JackClient*)ext_client;
  915. if (client == NULL) {
  916. jack_error("jack_set_port_connect_callback called with a NULL client");
  917. return -1;
  918. } else {
  919. return client->SetPortConnectCallback(portconnect_callback, arg);
  920. }
  921. }
  922. LIB_EXPORT int jack_set_port_rename_callback(jack_client_t* ext_client, JackPortRenameCallback rename_callback, void* arg)
  923. {
  924. #ifdef __CLIENTDEBUG__
  925. JackGlobals::CheckContext("jack_set_port_rename_callback");
  926. #endif
  927. JackClient* client = (JackClient*)ext_client;
  928. if (client == NULL) {
  929. jack_error("jack_set_port_rename_callback called with a NULL client");
  930. return -1;
  931. } else {
  932. return client->SetPortRenameCallback(rename_callback, arg);
  933. }
  934. }
  935. LIB_EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrderCallback graph_callback, void* arg)
  936. {
  937. #ifdef __CLIENTDEBUG__
  938. JackGlobals::CheckContext("jack_set_graph_order_callback");
  939. #endif
  940. JackClient* client = (JackClient*)ext_client;
  941. jack_log("jack_set_graph_order_callback ext_client %x client %x ", ext_client, client);
  942. if (client == NULL) {
  943. jack_error("jack_set_graph_order_callback called with a NULL client");
  944. return -1;
  945. } else {
  946. return client->SetGraphOrderCallback(graph_callback, arg);
  947. }
  948. }
  949. LIB_EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xrun_callback, void* arg)
  950. {
  951. #ifdef __CLIENTDEBUG__
  952. JackGlobals::CheckContext("jack_set_xrun_callback");
  953. #endif
  954. JackClient* client = (JackClient*)ext_client;
  955. if (client == NULL) {
  956. jack_error("jack_set_xrun_callback called with a NULL client");
  957. return -1;
  958. } else {
  959. return client->SetXRunCallback(xrun_callback, arg);
  960. }
  961. }
  962. LIB_EXPORT int jack_set_latency_callback(jack_client_t* ext_client, JackLatencyCallback latency_callback, void *arg)
  963. {
  964. #ifdef __CLIENTDEBUG__
  965. JackGlobals::CheckContext("jack_set_latency_callback");
  966. #endif
  967. JackClient* client = (JackClient*)ext_client;
  968. if (client == NULL) {
  969. jack_error("jack_set_latency_callback called with a NULL client");
  970. return -1;
  971. } else {
  972. return client->SetLatencyCallback(latency_callback, arg);
  973. }
  974. }
  975. LIB_EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg)
  976. {
  977. #ifdef __CLIENTDEBUG__
  978. JackGlobals::CheckContext("jack_set_thread_init_callback");
  979. #endif
  980. JackClient* client = (JackClient*)ext_client;
  981. jack_log("jack_set_thread_init_callback ext_client %x client %x ", ext_client, client);
  982. if (client == NULL) {
  983. jack_error("jack_set_thread_init_callback called with a NULL client");
  984. return -1;
  985. } else {
  986. return client->SetInitCallback(init_callback, arg);
  987. }
  988. }
  989. LIB_EXPORT int jack_activate(jack_client_t* ext_client)
  990. {
  991. #ifdef __CLIENTDEBUG__
  992. JackGlobals::CheckContext("jack_activate");
  993. #endif
  994. JackClient* client = (JackClient*)ext_client;
  995. if (client == NULL) {
  996. jack_error("jack_activate called with a NULL client");
  997. return -1;
  998. } else {
  999. return client->Activate();
  1000. }
  1001. }
  1002. LIB_EXPORT int jack_deactivate(jack_client_t* ext_client)
  1003. {
  1004. #ifdef __CLIENTDEBUG__
  1005. JackGlobals::CheckContext("jack_deactivate");
  1006. #endif
  1007. JackClient* client = (JackClient*)ext_client;
  1008. if (client == NULL) {
  1009. jack_error("jack_deactivate called with a NULL client");
  1010. return -1;
  1011. } else {
  1012. return client->Deactivate();
  1013. }
  1014. }
  1015. LIB_EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size)
  1016. {
  1017. #ifdef __CLIENTDEBUG__
  1018. JackGlobals::CheckContext("jack_port_register");
  1019. #endif
  1020. JackClient* client = (JackClient*)ext_client;
  1021. if (client == NULL) {
  1022. jack_error("jack_port_register called with a NULL client");
  1023. return NULL;
  1024. } else if ((port_name == NULL) || (port_type == NULL)) {
  1025. jack_error("jack_port_register called with a NULL port name or a NULL port_type");
  1026. return NULL;
  1027. } else {
  1028. return (jack_port_t *)((uintptr_t)client->PortRegister(port_name, port_type, flags, buffer_size));
  1029. }
  1030. }
  1031. LIB_EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port)
  1032. {
  1033. #ifdef __CLIENTDEBUG__
  1034. JackGlobals::CheckContext("jack_port_unregister");
  1035. #endif
  1036. JackClient* client = (JackClient*)ext_client;
  1037. if (client == NULL) {
  1038. jack_error("jack_port_unregister called with a NULL client");
  1039. return -1;
  1040. }
  1041. uintptr_t port_aux = (uintptr_t)port;
  1042. jack_port_id_t myport = (jack_port_id_t)port_aux;
  1043. if (!CheckPort(myport)) {
  1044. jack_error("jack_port_unregister called with an incorrect port %ld", myport);
  1045. return -1;
  1046. }
  1047. return client->PortUnRegister(myport);
  1048. }
  1049. LIB_EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* port)
  1050. {
  1051. #ifdef __CLIENTDEBUG__
  1052. JackGlobals::CheckContext("jack_port_is_mine");
  1053. #endif
  1054. JackClient* client = (JackClient*)ext_client;
  1055. if (client == NULL) {
  1056. jack_error("jack_port_is_mine called with a NULL client");
  1057. return -1;
  1058. }
  1059. uintptr_t port_aux = (uintptr_t)port;
  1060. jack_port_id_t myport = (jack_port_id_t)port_aux;
  1061. if (!CheckPort(myport)) {
  1062. jack_error("jack_port_is_mine called with an incorrect port %ld", myport);
  1063. return -1;
  1064. }
  1065. return client->PortIsMine(myport);
  1066. }
  1067. LIB_EXPORT const char** jack_port_get_connections(const jack_port_t* port)
  1068. {
  1069. #ifdef __CLIENTDEBUG__
  1070. JackGlobals::CheckContext("jack_port_get_connections");
  1071. #endif
  1072. uintptr_t port_aux = (uintptr_t)port;
  1073. jack_port_id_t myport = (jack_port_id_t)port_aux;
  1074. if (!CheckPort(myport)) {
  1075. jack_error("jack_port_get_connections called with an incorrect port %ld", myport);
  1076. return NULL;
  1077. } else {
  1078. WaitGraphChange();
  1079. JackGraphManager* manager = GetGraphManager();
  1080. return (manager ? manager->GetConnections(myport) : NULL);
  1081. }
  1082. }
  1083. // Calling client does not need to "own" the port
  1084. LIB_EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_client, const jack_port_t* port)
  1085. {
  1086. #ifdef __CLIENTDEBUG__
  1087. JackGlobals::CheckContext("jack_port_get_all_connections");
  1088. #endif
  1089. JackClient* client = (JackClient*)ext_client;
  1090. if (client == NULL) {
  1091. jack_error("jack_port_get_all_connections called with a NULL client");
  1092. return NULL;
  1093. }
  1094. uintptr_t port_aux = (uintptr_t)port;
  1095. jack_port_id_t myport = (jack_port_id_t)port_aux;
  1096. if (!CheckPort(myport)) {
  1097. jack_error("jack_port_get_all_connections called with an incorrect port %ld", myport);
  1098. return NULL;
  1099. } else {
  1100. WaitGraphChange();
  1101. JackGraphManager* manager = GetGraphManager();
  1102. return (manager ? manager->GetConnections(myport) : NULL);
  1103. }
  1104. }
  1105. LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jack_port_t* port)
  1106. {
  1107. #ifdef __CLIENTDEBUG__
  1108. JackGlobals::CheckContext("jack_port_get_total_latency");
  1109. #endif
  1110. JackClient* client = (JackClient*)ext_client;
  1111. if (client == NULL) {
  1112. jack_error("jack_port_get_total_latency called with a NULL client");
  1113. return 0;
  1114. }
  1115. uintptr_t port_aux = (uintptr_t)port;
  1116. jack_port_id_t myport = (jack_port_id_t)port_aux;
  1117. if (!CheckPort(myport)) {
  1118. jack_error("jack_port_get_total_latency called with an incorrect port %ld", myport);
  1119. return 0;
  1120. } else {
  1121. WaitGraphChange();
  1122. JackGraphManager* manager = GetGraphManager();
  1123. if (manager) {
  1124. manager->ComputeTotalLatency(myport);
  1125. return manager->GetPort(myport)->GetTotalLatency();
  1126. } else {
  1127. return 0;
  1128. }
  1129. }
  1130. }
  1131. LIB_EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* dst)
  1132. {
  1133. #ifdef __CLIENTDEBUG__
  1134. JackGlobals::CheckContext("jack_connect");
  1135. #endif
  1136. JackClient* client = (JackClient*)ext_client;
  1137. if (client == NULL) {
  1138. jack_error("jack_connect called with a NULL client");
  1139. return -1;
  1140. } else if ((src == NULL) || (dst == NULL)) {
  1141. jack_error("jack_connect called with a NULL port name");
  1142. return -1;
  1143. } else {
  1144. return client->PortConnect(src, dst);
  1145. }
  1146. }
  1147. LIB_EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const char* dst)
  1148. {
  1149. #ifdef __CLIENTDEBUG__
  1150. JackGlobals::CheckContext("jack_disconnect");
  1151. #endif
  1152. JackClient* client = (JackClient*)ext_client;
  1153. if (client == NULL) {
  1154. jack_error("jack_disconnect called with a NULL client");
  1155. return -1;
  1156. } else if ((src == NULL) || (dst == NULL)) {
  1157. jack_error("jack_connect called with a NULL port name");
  1158. return -1;
  1159. } else {
  1160. return client->PortDisconnect(src, dst);
  1161. }
  1162. }
  1163. LIB_EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src)
  1164. {
  1165. #ifdef __CLIENTDEBUG__
  1166. JackGlobals::CheckContext("jack_port_disconnect");
  1167. #endif
  1168. JackClient* client = (JackClient*)ext_client;
  1169. if (client == NULL) {
  1170. jack_error("jack_port_disconnect called with a NULL client");
  1171. return -1;
  1172. }
  1173. uintptr_t port_aux = (uintptr_t)src;
  1174. jack_port_id_t myport = (jack_port_id_t)port_aux;
  1175. if (!CheckPort(myport)) {
  1176. jack_error("jack_port_disconnect called with an incorrect port %ld", myport);
  1177. return -1;
  1178. }
  1179. return client->PortDisconnect(myport);
  1180. }
  1181. LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client)
  1182. {
  1183. #ifdef __CLIENTDEBUG__
  1184. JackGlobals::CheckContext("jack_get_sample_rate");
  1185. #endif
  1186. JackClient* client = (JackClient*)ext_client;
  1187. if (client == NULL) {
  1188. jack_error("jack_get_sample_rate called with a NULL client");
  1189. return 0;
  1190. } else {
  1191. JackEngineControl* control = GetEngineControl();
  1192. return (control ? control->fSampleRate : 0);
  1193. }
  1194. }
  1195. LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client)
  1196. {
  1197. #ifdef __CLIENTDEBUG__
  1198. JackGlobals::CheckContext("jack_get_buffer_size");
  1199. #endif
  1200. JackClient* client = (JackClient*)ext_client;
  1201. if (client == NULL) {
  1202. jack_error("jack_get_buffer_size called with a NULL client");
  1203. return 0;
  1204. } else {
  1205. JackEngineControl* control = GetEngineControl();
  1206. return (control ? control->fBufferSize : 0);
  1207. }
  1208. }
  1209. LIB_EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
  1210. {
  1211. #ifdef __CLIENTDEBUG__
  1212. JackGlobals::CheckContext("jack_get_ports");
  1213. #endif
  1214. JackClient* client = (JackClient*)ext_client;
  1215. if (client == NULL) {
  1216. jack_error("jack_get_ports called with a NULL client");
  1217. return NULL;
  1218. }
  1219. JackGraphManager* manager = GetGraphManager();
  1220. return (manager ? manager->GetPorts(port_name_pattern, type_name_pattern, flags) : NULL);
  1221. }
  1222. LIB_EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* portname)
  1223. {
  1224. #ifdef __CLIENTDEBUG__
  1225. JackGlobals::CheckContext("jack_port_by_name");
  1226. #endif
  1227. JackClient* client = (JackClient*)ext_client;
  1228. if (client == NULL) {
  1229. jack_error("jack_get_ports called with a NULL client");
  1230. return 0;
  1231. }
  1232. if (portname == NULL) {
  1233. jack_error("jack_port_by_name called with a NULL port name");
  1234. return NULL;
  1235. } else {
  1236. JackGraphManager* manager = GetGraphManager();
  1237. if (!manager)
  1238. return NULL;
  1239. int res = manager->GetPort(portname); // returns a port index at least > 1
  1240. return (res == NO_PORT) ? NULL : (jack_port_t*)((uintptr_t)res);
  1241. }
  1242. }
  1243. LIB_EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id)
  1244. {
  1245. #ifdef __CLIENTDEBUG__
  1246. JackGlobals::CheckContext("jack_port_by_id");
  1247. #endif
  1248. /* jack_port_t* type is actually the port index */
  1249. return (jack_port_t*)((uintptr_t)id);
  1250. }
  1251. LIB_EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client)
  1252. {
  1253. #ifdef __CLIENTDEBUG__
  1254. JackGlobals::CheckContext("jack_engine_takeover_timebase");
  1255. #endif
  1256. JackClient* client = (JackClient*)ext_client;
  1257. if (client == NULL) {
  1258. jack_error("jack_engine_takeover_timebase called with a NULL client");
  1259. return -1;
  1260. } else {
  1261. jack_error("jack_engine_takeover_timebase: deprecated\n");
  1262. return 0;
  1263. }
  1264. }
  1265. LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_client)
  1266. {
  1267. #ifdef __CLIENTDEBUG__
  1268. JackGlobals::CheckContext("jack_frames_since_cycle_start");
  1269. #endif
  1270. JackTimer timer;
  1271. JackEngineControl* control = GetEngineControl();
  1272. if (control) {
  1273. control->ReadFrameTime(&timer);
  1274. return timer.FramesSinceCycleStart(GetMicroSeconds(), control->fSampleRate);
  1275. } else {
  1276. return 0;
  1277. }
  1278. }
  1279. LIB_EXPORT jack_time_t jack_get_time()
  1280. {
  1281. #ifdef __CLIENTDEBUG__
  1282. JackGlobals::CheckContext("jack_get_time");
  1283. #endif
  1284. return GetMicroSeconds();
  1285. }
  1286. LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nframes_t frames)
  1287. {
  1288. #ifdef __CLIENTDEBUG__
  1289. JackGlobals::CheckContext("jack_frames_to_time");
  1290. #endif
  1291. JackClient* client = (JackClient*)ext_client;
  1292. if (client == NULL) {
  1293. jack_error("jack_frames_to_time called with a NULL client");
  1294. return 0;
  1295. } else {
  1296. JackTimer timer;
  1297. JackEngineControl* control = GetEngineControl();
  1298. if (control) {
  1299. control->ReadFrameTime(&timer);
  1300. return timer.Frames2Time(frames, control->fBufferSize);
  1301. } else {
  1302. return 0;
  1303. }
  1304. }
  1305. }
  1306. LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_time_t time)
  1307. {
  1308. #ifdef __CLIENTDEBUG__
  1309. JackGlobals::CheckContext("jack_time_to_frames");
  1310. #endif
  1311. JackClient* client = (JackClient*)ext_client;
  1312. if (client == NULL) {
  1313. jack_error("jack_time_to_frames called with a NULL client");
  1314. return 0;
  1315. } else {
  1316. JackTimer timer;
  1317. JackEngineControl* control = GetEngineControl();
  1318. if (control) {
  1319. control->ReadFrameTime(&timer);
  1320. return timer.Time2Frames(time, control->fBufferSize);
  1321. } else {
  1322. return 0;
  1323. }
  1324. }
  1325. }
  1326. LIB_EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client)
  1327. {
  1328. #ifdef __CLIENTDEBUG__
  1329. JackGlobals::CheckContext("jack_frame_time");
  1330. #endif
  1331. return jack_time_to_frames(ext_client, GetMicroSeconds());
  1332. }
  1333. LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client)
  1334. {
  1335. #ifdef __CLIENTDEBUG__
  1336. JackGlobals::CheckContext("jack_last_frame_time");
  1337. #endif
  1338. JackEngineControl* control = GetEngineControl();
  1339. return (control) ? control->fFrameTimer.ReadCurrentState()->CurFrame() : 0;
  1340. }
  1341. LIB_EXPORT float jack_cpu_load(jack_client_t* ext_client)
  1342. {
  1343. #ifdef __CLIENTDEBUG__
  1344. JackGlobals::CheckContext("jack_cpu_load");
  1345. #endif
  1346. JackClient* client = (JackClient*)ext_client;
  1347. if (client == NULL) {
  1348. jack_error("jack_cpu_load called with a NULL client");
  1349. return 0.0f;
  1350. } else {
  1351. JackEngineControl* control = GetEngineControl();
  1352. return (control ? control->fCPULoad : 0.0f);
  1353. }
  1354. }
  1355. LIB_EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t* ext_client)
  1356. {
  1357. #ifdef __CLIENTDEBUG__
  1358. JackGlobals::CheckContext("jack_client_thread_id");
  1359. #endif
  1360. JackClient* client = (JackClient*)ext_client;
  1361. if (client == NULL) {
  1362. jack_error("jack_client_thread_id called with a NULL client");
  1363. return (jack_native_thread_t)NULL;
  1364. } else {
  1365. return client->GetThreadID();
  1366. }
  1367. }
  1368. LIB_EXPORT char* jack_get_client_name(jack_client_t* ext_client)
  1369. {
  1370. #ifdef __CLIENTDEBUG__
  1371. JackGlobals::CheckContext("jack_get_client_name");
  1372. #endif
  1373. JackClient* client = (JackClient*)ext_client;
  1374. if (client == NULL) {
  1375. jack_error("jack_get_client_name called with a NULL client");
  1376. return NULL;
  1377. } else {
  1378. return client->GetClientControl()->fName;
  1379. }
  1380. }
  1381. LIB_EXPORT int jack_client_name_size(void)
  1382. {
  1383. return JACK_CLIENT_NAME_SIZE;
  1384. }
  1385. LIB_EXPORT int jack_port_name_size(void)
  1386. {
  1387. return REAL_JACK_PORT_NAME_SIZE;
  1388. }
  1389. LIB_EXPORT int jack_port_type_size(void)
  1390. {
  1391. return JACK_PORT_TYPE_SIZE;
  1392. }
  1393. LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t* ext_client, const char* port_type)
  1394. {
  1395. #ifdef __CLIENTDEBUG__
  1396. JackGlobals::CheckContext("jack_port_type_get_buffer_size");
  1397. #endif
  1398. JackClient* client = (JackClient*)ext_client;
  1399. if (client == NULL) {
  1400. jack_error("jack_port_type_get_buffer_size called with a NULL client");
  1401. return 0;
  1402. } else {
  1403. jack_port_type_id_t port_id = GetPortTypeId(port_type);
  1404. if (port_id == PORT_TYPES_MAX) {
  1405. jack_error("jack_port_type_get_buffer_size called with an unknown port type = %s", port_type);
  1406. return 0;
  1407. } else {
  1408. return GetPortType(port_id)->size();
  1409. }
  1410. }
  1411. }
  1412. // transport.h
  1413. LIB_EXPORT int jack_release_timebase(jack_client_t* ext_client)
  1414. {
  1415. #ifdef __CLIENTDEBUG__
  1416. JackGlobals::CheckContext("jack_release_timebase");
  1417. #endif
  1418. JackClient* client = (JackClient*)ext_client;
  1419. if (client == NULL) {
  1420. jack_error("jack_release_timebase called with a NULL client");
  1421. return -1;
  1422. } else {
  1423. return client->ReleaseTimebase();
  1424. }
  1425. }
  1426. LIB_EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg)
  1427. {
  1428. #ifdef __CLIENTDEBUG__
  1429. JackGlobals::CheckContext("jack_set_sync_callback");
  1430. #endif
  1431. JackClient* client = (JackClient*)ext_client;
  1432. if (client == NULL) {
  1433. jack_error("jack_set_sync_callback called with a NULL client");
  1434. return -1;
  1435. } else {
  1436. return client->SetSyncCallback(sync_callback, arg);
  1437. }
  1438. }
  1439. LIB_EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout)
  1440. {
  1441. #ifdef __CLIENTDEBUG__
  1442. JackGlobals::CheckContext("jack_set_sync_timeout");
  1443. #endif
  1444. JackClient* client = (JackClient*)ext_client;
  1445. if (client == NULL) {
  1446. jack_error("jack_set_sync_timeout called with a NULL client");
  1447. return -1;
  1448. } else {
  1449. return client->SetSyncTimeout(timeout);
  1450. }
  1451. }
  1452. LIB_EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg)
  1453. {
  1454. #ifdef __CLIENTDEBUG__
  1455. JackGlobals::CheckContext("jack_set_timebase_callback");
  1456. #endif
  1457. JackClient* client = (JackClient*)ext_client;
  1458. if (client == NULL) {
  1459. jack_error("jack_set_timebase_callback called with a NULL client");
  1460. return -1;
  1461. } else {
  1462. return client->SetTimebaseCallback(conditional, timebase_callback, arg);
  1463. }
  1464. }
  1465. LIB_EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame)
  1466. {
  1467. #ifdef __CLIENTDEBUG__
  1468. JackGlobals::CheckContext("jack_transport_locate");
  1469. #endif
  1470. JackClient* client = (JackClient*)ext_client;
  1471. if (client == NULL) {
  1472. jack_error("jack_transport_locate called with a NULL client");
  1473. return -1;
  1474. } else {
  1475. client->TransportLocate(frame);
  1476. return 0;
  1477. }
  1478. }
  1479. LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos)
  1480. {
  1481. #ifdef __CLIENTDEBUG__
  1482. JackGlobals::CheckContext("jack_transport_query");
  1483. #endif
  1484. JackClient* client = (JackClient*)ext_client;
  1485. if (client == NULL) {
  1486. jack_error("jack_transport_query called with a NULL client");
  1487. return JackTransportStopped;
  1488. } else {
  1489. return client->TransportQuery(pos);
  1490. }
  1491. }
  1492. LIB_EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client)
  1493. {
  1494. #ifdef __CLIENTDEBUG__
  1495. JackGlobals::CheckContext("jack_get_current_transport_frame");
  1496. #endif
  1497. JackClient* client = (JackClient*)ext_client;
  1498. if (client == NULL) {
  1499. jack_error("jack_get_current_transport_frame called with a NULL client");
  1500. return 0;
  1501. } else {
  1502. return client->GetCurrentTransportFrame();
  1503. }
  1504. }
  1505. LIB_EXPORT int jack_transport_reposition(jack_client_t* ext_client, const jack_position_t* pos)
  1506. {
  1507. #ifdef __CLIENTDEBUG__
  1508. JackGlobals::CheckContext("jack_transport_reposition");
  1509. #endif
  1510. JackClient* client = (JackClient*)ext_client;
  1511. if (client == NULL) {
  1512. jack_error("jack_transport_reposition called with a NULL client");
  1513. return -1;
  1514. } else {
  1515. client->TransportReposition(pos);
  1516. return 0;
  1517. }
  1518. }
  1519. LIB_EXPORT void jack_transport_start(jack_client_t* ext_client)
  1520. {
  1521. #ifdef __CLIENTDEBUG__
  1522. JackGlobals::CheckContext("jack_transport_start");
  1523. #endif
  1524. JackClient* client = (JackClient*)ext_client;
  1525. if (client == NULL) {
  1526. jack_error("jack_transport_start called with a NULL client");
  1527. } else {
  1528. client->TransportStart();
  1529. }
  1530. }
  1531. LIB_EXPORT void jack_transport_stop(jack_client_t* ext_client)
  1532. {
  1533. #ifdef __CLIENTDEBUG__
  1534. JackGlobals::CheckContext("jack_transport_stop");
  1535. #endif
  1536. JackClient* client = (JackClient*)ext_client;
  1537. if (client == NULL) {
  1538. jack_error("jack_transport_stop called with a NULL client");
  1539. } else {
  1540. client->TransportStop();
  1541. }
  1542. }
  1543. // deprecated
  1544. LIB_EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
  1545. {
  1546. #ifdef __CLIENTDEBUG__
  1547. JackGlobals::CheckContext("jack_get_transport_info");
  1548. #endif
  1549. jack_error("jack_get_transport_info: deprecated");
  1550. if (tinfo)
  1551. memset(tinfo, 0, sizeof(jack_transport_info_t));
  1552. }
  1553. LIB_EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
  1554. {
  1555. #ifdef __CLIENTDEBUG__
  1556. JackGlobals::CheckContext("jack_set_transport_info");
  1557. #endif
  1558. jack_error("jack_set_transport_info: deprecated");
  1559. if (tinfo)
  1560. memset(tinfo, 0, sizeof(jack_transport_info_t));
  1561. }
  1562. // statistics.h
  1563. LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client)
  1564. {
  1565. #ifdef __CLIENTDEBUG__
  1566. JackGlobals::CheckContext("jack_get_max_delayed_usecs");
  1567. #endif
  1568. JackClient* client = (JackClient*)ext_client;
  1569. if (client == NULL) {
  1570. jack_error("jack_get_max_delayed_usecs called with a NULL client");
  1571. return 0.f;
  1572. } else {
  1573. JackEngineControl* control = GetEngineControl();
  1574. return (control ? control->fMaxDelayedUsecs : 0.f);
  1575. }
  1576. }
  1577. LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client)
  1578. {
  1579. #ifdef __CLIENTDEBUG__
  1580. JackGlobals::CheckContext("jack_get_xrun_delayed_usecs");
  1581. #endif
  1582. JackClient* client = (JackClient*)ext_client;
  1583. if (client == NULL) {
  1584. jack_error("jack_get_xrun_delayed_usecs called with a NULL client");
  1585. return 0.f;
  1586. } else {
  1587. JackEngineControl* control = GetEngineControl();
  1588. return (control ? control->fXrunDelayedUsecs : 0.f);
  1589. }
  1590. }
  1591. LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client)
  1592. {
  1593. #ifdef __CLIENTDEBUG__
  1594. JackGlobals::CheckContext("jack_reset_max_delayed_usecs");
  1595. #endif
  1596. JackClient* client = (JackClient*)ext_client;
  1597. if (client == NULL) {
  1598. jack_error("jack_reset_max_delayed_usecs called with a NULL client");
  1599. } else {
  1600. JackEngineControl* control = GetEngineControl();
  1601. control->ResetXRun();
  1602. }
  1603. }
  1604. // thread.h
  1605. LIB_EXPORT int jack_client_real_time_priority(jack_client_t* ext_client)
  1606. {
  1607. #ifdef __CLIENTDEBUG__
  1608. JackGlobals::CheckContext("jack_client_real_time_priority");
  1609. #endif
  1610. JackClient* client = (JackClient*)ext_client;
  1611. if (client == NULL) {
  1612. jack_error("jack_client_real_time_priority called with a NULL client");
  1613. return -1;
  1614. } else {
  1615. JackEngineControl* control = GetEngineControl();
  1616. return (control->fRealTime) ? control->fClientPriority : -1;
  1617. }
  1618. }
  1619. LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client)
  1620. {
  1621. #ifdef __CLIENTDEBUG__
  1622. JackGlobals::CheckContext("jack_client_max_real_time_priority");
  1623. #endif
  1624. JackClient* client = (JackClient*)ext_client;
  1625. if (client == NULL) {
  1626. jack_error("jack_client_max_real_time_priority called with a NULL client");
  1627. return -1;
  1628. } else {
  1629. JackEngineControl* control = GetEngineControl();
  1630. return (control->fRealTime) ? control->fMaxClientPriority : -1;
  1631. }
  1632. }
  1633. LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority)
  1634. {
  1635. JackEngineControl* control = GetEngineControl();
  1636. return (control ? JackThread::AcquireRealTimeImp(thread, priority, GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint) : -1);
  1637. }
  1638. LIB_EXPORT int jack_client_create_thread(jack_client_t* client,
  1639. jack_native_thread_t *thread,
  1640. int priority,
  1641. int realtime, /* boolean */
  1642. thread_routine routine,
  1643. void *arg)
  1644. {
  1645. #ifdef __CLIENTDEBUG__
  1646. JackGlobals::CheckContext("jack_client_create_thread");
  1647. #endif
  1648. JackEngineControl* control = GetEngineControl();
  1649. int res = JackThread::StartImp(thread, priority, realtime, routine, arg);
  1650. return (res == 0)
  1651. ? ((realtime ? JackThread::AcquireRealTimeImp(*thread, priority,
  1652. GetEngineControl()->fPeriod,
  1653. GetEngineControl()->fComputation,
  1654. GetEngineControl()->fConstraint) : res))
  1655. : res;
  1656. }
  1657. LIB_EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread)
  1658. {
  1659. return JackThread::DropRealTimeImp(thread);
  1660. }
  1661. LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread)
  1662. {
  1663. #ifdef __CLIENTDEBUG__
  1664. JackGlobals::CheckContext("jack_client_stop_thread");
  1665. #endif
  1666. return JackThread::StopImp(thread);
  1667. }
  1668. LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread)
  1669. {
  1670. #ifdef __CLIENTDEBUG__
  1671. JackGlobals::CheckContext("jack_client_kill_thread");
  1672. #endif
  1673. return JackThread::KillImp(thread);
  1674. }
  1675. #ifndef WIN32
  1676. LIB_EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc)
  1677. {
  1678. JackGlobals::fJackThreadCreator = (jtc == NULL) ? pthread_create : jtc;
  1679. }
  1680. #endif
  1681. // intclient.h
  1682. LIB_EXPORT int jack_internal_client_new (const char* client_name,
  1683. const char* load_name,
  1684. const char* load_init)
  1685. {
  1686. #ifdef __CLIENTDEBUG__
  1687. JackGlobals::CheckContext("jack_internal_client_new");
  1688. #endif
  1689. jack_error("jack_internal_client_new: deprecated");
  1690. return -1;
  1691. }
  1692. LIB_EXPORT void jack_internal_client_close (const char* client_name)
  1693. {
  1694. #ifdef __CLIENTDEBUG__
  1695. JackGlobals::CheckContext("jack_internal_client_close");
  1696. #endif
  1697. jack_error("jack_internal_client_close: deprecated");
  1698. }
  1699. LIB_EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient)
  1700. {
  1701. #ifdef __CLIENTDEBUG__
  1702. JackGlobals::CheckContext("jack_get_internal_client_name");
  1703. #endif
  1704. JackClient* client = (JackClient*)ext_client;
  1705. if (client == NULL) {
  1706. jack_error("jack_get_internal_client_name called with a NULL client");
  1707. return NULL;
  1708. } else if (intclient >= CLIENT_NUM) {
  1709. jack_error("jack_get_internal_client_name: incorrect client");
  1710. return NULL;
  1711. } else {
  1712. return client->GetInternalClientName(intclient);
  1713. }
  1714. }
  1715. LIB_EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, const char* client_name, jack_status_t* status)
  1716. {
  1717. #ifdef __CLIENTDEBUG__
  1718. JackGlobals::CheckContext("jack_internal_client_handle");
  1719. #endif
  1720. JackClient* client = (JackClient*)ext_client;
  1721. if (client == NULL) {
  1722. jack_error("jack_internal_client_handle called with a NULL client");
  1723. return 0;
  1724. } else {
  1725. jack_status_t my_status;
  1726. if (status == NULL) /* no status from caller? */
  1727. status = &my_status; /* use local status word */
  1728. *status = (jack_status_t)0;
  1729. return client->InternalClientHandle(client_name, status);
  1730. }
  1731. }
  1732. LIB_EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t* ext_client, const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
  1733. {
  1734. #ifdef __CLIENTDEBUG__
  1735. JackGlobals::CheckContext("jack_internal_client_load_aux");
  1736. #endif
  1737. JackClient* client = (JackClient*)ext_client;
  1738. if (client == NULL) {
  1739. jack_error("jack_internal_client_load called with a NULL client");
  1740. return 0;
  1741. } else {
  1742. jack_varargs_t va;
  1743. jack_status_t my_status;
  1744. if (status == NULL) /* no status from caller? */
  1745. status = &my_status; /* use local status word */
  1746. *status = (jack_status_t)0;
  1747. /* validate parameters */
  1748. if ((options & ~JackLoadOptions)) {
  1749. int my_status1 = *status | (JackFailure | JackInvalidOption);
  1750. *status = (jack_status_t)my_status1;
  1751. return 0;
  1752. }
  1753. /* parse variable arguments */
  1754. jack_varargs_parse(options, ap, &va);
  1755. return client->InternalClientLoad(client_name, options, status, &va);
  1756. }
  1757. }
  1758. LIB_EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const char* client_name, jack_options_t options, jack_status_t *status, ...)
  1759. {
  1760. #ifdef __CLIENTDEBUG__
  1761. JackGlobals::CheckContext("jack_internal_client_load");
  1762. #endif
  1763. va_list ap;
  1764. va_start(ap, status);
  1765. jack_intclient_t res = jack_internal_client_load_aux(client, client_name, options, status, ap);
  1766. va_end(ap);
  1767. return res;
  1768. }
  1769. LIB_EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack_intclient_t intclient)
  1770. {
  1771. #ifdef __CLIENTDEBUG__
  1772. JackGlobals::CheckContext("jack_internal_client_load");
  1773. #endif
  1774. JackClient* client = (JackClient*)ext_client;
  1775. if (client == NULL) {
  1776. jack_error("jack_internal_client_unload called with a NULL client");
  1777. return (jack_status_t)(JackNoSuchClient | JackFailure);
  1778. } else if (intclient >= CLIENT_NUM) {
  1779. jack_error("jack_internal_client_unload: incorrect client");
  1780. return (jack_status_t)(JackNoSuchClient | JackFailure);
  1781. } else {
  1782. jack_status_t my_status;
  1783. client->InternalClientUnload(intclient, &my_status);
  1784. return my_status;
  1785. }
  1786. }
  1787. LIB_EXPORT void jack_get_version(int *major_ptr,
  1788. int *minor_ptr,
  1789. int *micro_ptr,
  1790. int *proto_ptr)
  1791. {
  1792. #ifdef __CLIENTDEBUG__
  1793. JackGlobals::CheckContext("jack_get_version");
  1794. #endif
  1795. // FIXME: We need these comming from build system
  1796. *major_ptr = 0;
  1797. *minor_ptr = 0;
  1798. *micro_ptr = 0;
  1799. *proto_ptr = 0;
  1800. }
  1801. LIB_EXPORT const char* jack_get_version_string()
  1802. {
  1803. #ifdef __CLIENTDEBUG__
  1804. JackGlobals::CheckContext("jack_get_version_string");
  1805. #endif
  1806. return VERSION;
  1807. }
  1808. LIB_EXPORT void jack_free(void* ptr)
  1809. {
  1810. #ifdef __CLIENTDEBUG__
  1811. JackGlobals::CheckContext("jack_free");
  1812. #endif
  1813. if (ptr) {
  1814. free(ptr);
  1815. }
  1816. }
  1817. // session.h
  1818. LIB_EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg)
  1819. {
  1820. #ifdef __CLIENTDEBUG__
  1821. JackGlobals::CheckContext("jack_set_session_callback");
  1822. #endif
  1823. JackClient* client = (JackClient*)ext_client;
  1824. jack_log("jack_set_session_callback ext_client %x client %x ", ext_client, client);
  1825. if (client == NULL) {
  1826. jack_error("jack_set_session_callback called with a NULL client");
  1827. return -1;
  1828. } else {
  1829. return client->SetSessionCallback(session_callback, arg);
  1830. }
  1831. }
  1832. LIB_EXPORT jack_session_command_t* jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path)
  1833. {
  1834. #ifdef __CLIENTDEBUG__
  1835. JackGlobals::CheckContext("jack_session_notify");
  1836. #endif
  1837. JackClient* client = (JackClient*)ext_client;
  1838. jack_log("jack_session_notify ext_client %x client %x ", ext_client, client);
  1839. if (client == NULL) {
  1840. jack_error("jack_session_notify called with a NULL client");
  1841. return NULL;
  1842. } else {
  1843. return client->SessionNotify(target, ev_type, path);
  1844. }
  1845. }
  1846. LIB_EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event)
  1847. {
  1848. #ifdef __CLIENTDEBUG__
  1849. JackGlobals::CheckContext("jack_session_reply");
  1850. #endif
  1851. JackClient* client = (JackClient*)ext_client;
  1852. jack_log("jack_session_reply ext_client %x client %x ", ext_client, client);
  1853. if (client == NULL) {
  1854. jack_error("jack_session_reply called with a NULL client");
  1855. return -1;
  1856. } else {
  1857. return client->SessionReply(event);
  1858. }
  1859. }
  1860. LIB_EXPORT void jack_session_event_free(jack_session_event_t* ev)
  1861. {
  1862. #ifdef __CLIENTDEBUG__
  1863. JackGlobals::CheckContext("jack_session_event_free");
  1864. #endif
  1865. if (ev) {
  1866. if (ev->session_dir)
  1867. free((void *)ev->session_dir);
  1868. if (ev->client_uuid)
  1869. free((void *)ev->client_uuid);
  1870. if (ev->command_line)
  1871. free(ev->command_line);
  1872. free(ev);
  1873. }
  1874. }
  1875. LIB_EXPORT char *jack_client_get_uuid(jack_client_t* ext_client)
  1876. {
  1877. #ifdef __CLIENTDEBUG__
  1878. JackGlobals::CheckContext("jack_client_get_uuid");
  1879. #endif
  1880. JackClient* client = (JackClient*)ext_client;
  1881. if (client == NULL) {
  1882. jack_error("jack_client_get_uuid called with a NULL client");
  1883. return NULL;
  1884. } else {
  1885. char retval[16];
  1886. snprintf(retval, sizeof(retval), "%d", client->GetClientControl()->fSessionID);
  1887. return strdup(retval);
  1888. }
  1889. }
  1890. LIB_EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name)
  1891. {
  1892. #ifdef __CLIENTDEBUG__
  1893. JackGlobals::CheckContext("jack_get_uuid_for_client_name");
  1894. #endif
  1895. JackClient* client = (JackClient*)ext_client;
  1896. jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client);
  1897. if (client == NULL) {
  1898. jack_error("jack_get_uuid_for_client_name called with a NULL client");
  1899. return NULL;
  1900. } else {
  1901. return client->GetUUIDForClientName(client_name);
  1902. }
  1903. }
  1904. LIB_EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid)
  1905. {
  1906. #ifdef __CLIENTDEBUG__
  1907. JackGlobals::CheckContext("jack_get_client_name_by_uuid");
  1908. #endif
  1909. JackClient* client = (JackClient*)ext_client;
  1910. jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client);
  1911. if (client == NULL) {
  1912. jack_error("jack_get_client_name_by_uuid called with a NULL client");
  1913. return NULL;
  1914. } else {
  1915. return client->GetClientNameByUUID(client_uuid);
  1916. }
  1917. }
  1918. LIB_EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* client_name, const char* uuid)
  1919. {
  1920. #ifdef __CLIENTDEBUG__
  1921. JackGlobals::CheckContext("jack_reserve_client_name");
  1922. #endif
  1923. JackClient* client = (JackClient*)ext_client;
  1924. jack_log("jack_reserve_client_name ext_client %x client %x ", ext_client, client);
  1925. if (client == NULL) {
  1926. jack_error("jack_reserve_client_name called with a NULL client");
  1927. return -1;
  1928. } else {
  1929. return client->ReserveClientName(client_name, uuid);
  1930. }
  1931. }
  1932. LIB_EXPORT void jack_session_commands_free(jack_session_command_t *cmds)
  1933. {
  1934. #ifdef __CLIENTDEBUG__
  1935. JackGlobals::CheckContext("jack_session_commands_free");
  1936. #endif
  1937. if (!cmds)
  1938. return;
  1939. int i = 0;
  1940. while (1) {
  1941. if (cmds[i].client_name)
  1942. free ((char *)cmds[i].client_name);
  1943. if (cmds[i].command)
  1944. free ((char *)cmds[i].command);
  1945. if (cmds[i].uuid)
  1946. free ((char *)cmds[i].uuid);
  1947. else
  1948. break;
  1949. i += 1;
  1950. }
  1951. free(cmds);
  1952. }
  1953. LIB_EXPORT int jack_client_has_session_callback(jack_client_t* ext_client, const char* client_name)
  1954. {
  1955. #ifdef __CLIENTDEBUG__
  1956. JackGlobals::CheckContext("jack_client_has_session_callback");
  1957. #endif
  1958. JackClient* client = (JackClient*)ext_client;
  1959. jack_log("jack_client_has_session_callback ext_client %x client %x ", ext_client, client);
  1960. if (client == NULL) {
  1961. jack_error("jack_client_has_session_callback called with a NULL client");
  1962. return -1;
  1963. } else {
  1964. return client->ClientHasSessionCallback(client_name);
  1965. }
  1966. }