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.

2069 lines
69KB

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