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.

1876 lines
60KB

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