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.

1507 lines
48KB

  1. /*
  2. Copyright (C) 2001-2003 Paul Davis
  3. Copyright (C) 2004-2006 Grame
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 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 General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 "JackExports.h"
  24. #include "JackAPI.h"
  25. #ifdef __APPLE__
  26. #include "JackMachThread.h"
  27. #elif WIN32
  28. #include "JackWinThread.h"
  29. #else
  30. #include "JackPosixThread.h"
  31. #endif
  32. #include <math.h>
  33. #ifdef __CLIENTDEBUG__
  34. #include "JackLibGlobals.h"
  35. #endif
  36. using namespace Jack;
  37. #ifdef __cplusplus
  38. extern "C"
  39. {
  40. #endif
  41. EXPORT int jack_client_name_size (void);
  42. EXPORT char* jack_get_client_name (jack_client_t *client);
  43. EXPORT int jack_internal_client_new (const char *client_name,
  44. const char *load_name,
  45. const char *load_init);
  46. EXPORT jack_client_t* my_jack_internal_client_new(const char* client_name);
  47. EXPORT void jack_internal_client_close (const char *client_name);
  48. EXPORT void my_jack_internal_client_close (jack_client_t* client);
  49. EXPORT int jack_is_realtime (jack_client_t *client);
  50. EXPORT void jack_on_shutdown (jack_client_t *client,
  51. void (*function)(void *arg), void *arg);
  52. EXPORT int jack_set_process_callback (jack_client_t *client,
  53. JackProcessCallback process_callback,
  54. void *arg);
  55. EXPORT int jack_set_thread_init_callback (jack_client_t *client,
  56. JackThreadInitCallback thread_init_callback,
  57. void *arg);
  58. EXPORT int jack_set_freewheel_callback (jack_client_t *client,
  59. JackFreewheelCallback freewheel_callback,
  60. void *arg);
  61. EXPORT int jack_set_freewheel(jack_client_t* client, int onoff);
  62. EXPORT int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes);
  63. EXPORT int jack_set_buffer_size_callback (jack_client_t *client,
  64. JackBufferSizeCallback bufsize_callback,
  65. void *arg);
  66. EXPORT int jack_set_sample_rate_callback (jack_client_t *client,
  67. JackSampleRateCallback srate_callback,
  68. void *arg);
  69. EXPORT int jack_set_client_registration_callback (jack_client_t *,
  70. JackClientRegistrationCallback
  71. registration_callback, void *arg);
  72. EXPORT int jack_set_port_registration_callback (jack_client_t *,
  73. JackPortRegistrationCallback
  74. registration_callback, void *arg);
  75. EXPORT int jack_set_graph_order_callback (jack_client_t *,
  76. JackGraphOrderCallback graph_callback,
  77. void *);
  78. EXPORT int jack_set_xrun_callback (jack_client_t *,
  79. JackXRunCallback xrun_callback, void *arg);
  80. EXPORT int jack_activate (jack_client_t *client);
  81. EXPORT int jack_deactivate (jack_client_t *client);
  82. EXPORT jack_port_t * jack_port_register (jack_client_t *client,
  83. const char *port_name,
  84. const char *port_type,
  85. unsigned long flags,
  86. unsigned long buffer_size);
  87. EXPORT int jack_port_unregister (jack_client_t *, jack_port_t *);
  88. EXPORT void * jack_port_get_buffer (jack_port_t *, jack_nframes_t);
  89. EXPORT const char * jack_port_name (const jack_port_t *port);
  90. EXPORT const char * jack_port_short_name (const jack_port_t *port);
  91. EXPORT int jack_port_flags (const jack_port_t *port);
  92. EXPORT const char * jack_port_type (const jack_port_t *port);
  93. EXPORT int jack_port_is_mine (const jack_client_t *, const jack_port_t *port);
  94. EXPORT int jack_port_connected (const jack_port_t *port);
  95. EXPORT int jack_port_connected_to (const jack_port_t *port,
  96. const char *port_name);
  97. EXPORT const char ** jack_port_get_connections (const jack_port_t *port);
  98. EXPORT const char ** jack_port_get_all_connections (const jack_client_t *client,
  99. const jack_port_t *port);
  100. EXPORT int jack_port_tie (jack_port_t *src, jack_port_t *dst);
  101. EXPORT int jack_port_untie (jack_port_t *port);
  102. EXPORT int jack_port_lock (jack_client_t *, jack_port_t *);
  103. EXPORT int jack_port_unlock (jack_client_t *, jack_port_t *);
  104. EXPORT jack_nframes_t jack_port_get_latency (jack_port_t *port);
  105. EXPORT jack_nframes_t jack_port_get_total_latency (jack_client_t *,
  106. jack_port_t *port);
  107. EXPORT void jack_port_set_latency (jack_port_t *, jack_nframes_t);
  108. EXPORT int jack_recompute_total_latencies (jack_client_t*);
  109. EXPORT int jack_port_set_name (jack_port_t *port, const char *port_name);
  110. EXPORT int jack_port_set_alias (jack_port_t *port, const char *alias);
  111. EXPORT int jack_port_unset_alias (jack_port_t *port, const char *alias);
  112. EXPORT int jack_port_get_aliases (const jack_port_t *port, char* const aliases[2]);
  113. EXPORT int jack_port_request_monitor (jack_port_t *port, int onoff);
  114. EXPORT int jack_port_request_monitor_by_name (jack_client_t *client,
  115. const char *port_name, int onoff);
  116. EXPORT int jack_port_ensure_monitor (jack_port_t *port, int onoff);
  117. EXPORT int jack_port_monitoring_input (jack_port_t *port);
  118. EXPORT int jack_connect (jack_client_t *,
  119. const char *source_port,
  120. const char *destination_port);
  121. EXPORT int jack_disconnect (jack_client_t *,
  122. const char *source_port,
  123. const char *destination_port);
  124. EXPORT int jack_port_disconnect (jack_client_t *, jack_port_t *);
  125. EXPORT int jack_port_name_size(void);
  126. EXPORT int jack_port_type_size(void);
  127. EXPORT jack_nframes_t jack_get_sample_rate (jack_client_t *);
  128. EXPORT jack_nframes_t jack_get_buffer_size (jack_client_t *);
  129. EXPORT const char ** jack_get_ports (jack_client_t *,
  130. const char *port_name_pattern,
  131. const char *type_name_pattern,
  132. unsigned long flags);
  133. EXPORT jack_port_t * jack_port_by_name (jack_client_t *, const char *port_name);
  134. EXPORT jack_port_t * jack_port_by_id (jack_client_t *client,
  135. jack_port_id_t port_id);
  136. EXPORT int jack_engine_takeover_timebase (jack_client_t *);
  137. EXPORT jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *);
  138. EXPORT jack_time_t jack_get_time(const jack_client_t *client);
  139. EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t time);
  140. EXPORT jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t frames);
  141. EXPORT jack_nframes_t jack_frame_time (const jack_client_t *);
  142. EXPORT jack_nframes_t jack_last_frame_time (const jack_client_t *client);
  143. EXPORT float jack_cpu_load (jack_client_t *client);
  144. EXPORT pthread_t jack_client_thread_id (jack_client_t *);
  145. EXPORT void jack_set_error_function (void (*func)(const char *));
  146. EXPORT float jack_get_max_delayed_usecs (jack_client_t *client);
  147. EXPORT float jack_get_xrun_delayed_usecs (jack_client_t *client);
  148. EXPORT void jack_reset_max_delayed_usecs (jack_client_t *client);
  149. EXPORT int jack_release_timebase (jack_client_t *client);
  150. EXPORT int jack_set_sync_callback (jack_client_t *client,
  151. JackSyncCallback sync_callback,
  152. void *arg);
  153. EXPORT int jack_set_sync_timeout (jack_client_t *client,
  154. jack_time_t timeout);
  155. EXPORT int jack_set_timebase_callback (jack_client_t *client,
  156. int conditional,
  157. JackTimebaseCallback timebase_callback,
  158. void *arg);
  159. EXPORT int jack_transport_locate (jack_client_t *client,
  160. jack_nframes_t frame);
  161. EXPORT jack_transport_state_t jack_transport_query (const jack_client_t *client,
  162. jack_position_t *pos);
  163. EXPORT jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client);
  164. EXPORT int jack_transport_reposition (jack_client_t *client,
  165. jack_position_t *pos);
  166. EXPORT void jack_transport_start (jack_client_t *client);
  167. EXPORT void jack_transport_stop (jack_client_t *client);
  168. EXPORT void jack_get_transport_info (jack_client_t *client,
  169. jack_transport_info_t *tinfo);
  170. EXPORT void jack_set_transport_info (jack_client_t *client,
  171. jack_transport_info_t *tinfo);
  172. EXPORT int jack_acquire_real_time_scheduling (pthread_t thread, int priority);
  173. EXPORT int jack_client_create_thread (jack_client_t* client,
  174. pthread_t *thread,
  175. int priority,
  176. int realtime, // boolean
  177. void *(*start_routine)(void*),
  178. void *arg);
  179. EXPORT int jack_drop_real_time_scheduling (pthread_t thread);
  180. EXPORT char * jack_get_internal_client_name (jack_client_t *client,
  181. jack_intclient_t intclient);
  182. EXPORT jack_intclient_t jack_internal_client_handle (jack_client_t *client,
  183. const char *client_name,
  184. jack_status_t *status);
  185. EXPORT jack_intclient_t jack_internal_client_load (jack_client_t *client,
  186. const char *client_name,
  187. jack_options_t options,
  188. jack_status_t *status, ...);
  189. EXPORT jack_status_t jack_internal_client_unload (jack_client_t *client,
  190. jack_intclient_t intclient);
  191. #ifdef __cplusplus
  192. }
  193. #endif
  194. #ifdef WIN32
  195. /* missing on Windows : see http://bugs.mysql.com/bug.php?id=15936 */
  196. inline double rint(double nr)
  197. {
  198. double f = floor(nr);
  199. double c = ceil(nr);
  200. return (((c -nr) >= (nr - f)) ? f : c);
  201. }
  202. #endif
  203. static inline bool CheckPort(jack_port_id_t port_index)
  204. {
  205. return (port_index < PORT_NUM);
  206. }
  207. static inline bool CheckBufferSize(jack_nframes_t buffer_size)
  208. {
  209. return (buffer_size <= BUFFER_SIZE_MAX);
  210. }
  211. static inline void WaitGraphChange()
  212. {
  213. if (GetGraphManager()->IsPendingChange()) {
  214. JackLog("WaitGraphChange...\n");
  215. JackSleep(GetEngineControl()->fPeriodUsecs * 2);
  216. }
  217. }
  218. static void default_jack_error_callback(const char *desc)
  219. {
  220. fprintf(stderr, "%s\n", desc);
  221. }
  222. void (*jack_error_callback)(const char *desc) = &default_jack_error_callback;
  223. EXPORT void jack_set_error_function (void (*func)(const char *))
  224. {
  225. jack_error_callback = func;
  226. }
  227. EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
  228. {
  229. #ifdef __CLIENTDEBUG__
  230. JackLibGlobals::CheckContext();
  231. #endif
  232. jack_port_id_t myport = (jack_port_id_t)port;
  233. if (!CheckPort(myport)) {
  234. jack_error("jack_port_get_buffer called with an incorrect port %ld", myport);
  235. return NULL;
  236. } else {
  237. return GetGraphManager()->GetBuffer(myport, frames);
  238. }
  239. }
  240. EXPORT const char* jack_port_name(const jack_port_t* port)
  241. {
  242. #ifdef __CLIENTDEBUG__
  243. JackLibGlobals::CheckContext();
  244. #endif
  245. jack_port_id_t myport = (jack_port_id_t)port;
  246. if (!CheckPort(myport)) {
  247. jack_error("jack_port_name called with an incorrect port %ld", myport);
  248. return NULL;
  249. } else {
  250. return GetGraphManager()->GetPort(myport)->GetName();
  251. }
  252. }
  253. EXPORT const char* jack_port_short_name(const jack_port_t* port)
  254. {
  255. #ifdef __CLIENTDEBUG__
  256. JackLibGlobals::CheckContext();
  257. #endif
  258. jack_port_id_t myport = (jack_port_id_t)port;
  259. if (!CheckPort(myport)) {
  260. jack_error("jack_port_short_name called with an incorrect port %ld", myport);
  261. return NULL;
  262. } else {
  263. return GetGraphManager()->GetPort(myport)->GetShortName();
  264. }
  265. }
  266. EXPORT int jack_port_flags(const jack_port_t* port)
  267. {
  268. #ifdef __CLIENTDEBUG__
  269. JackLibGlobals::CheckContext();
  270. #endif
  271. jack_port_id_t myport = (jack_port_id_t)port;
  272. if (!CheckPort(myport)) {
  273. jack_error("jack_port_flags called with an incorrect port %ld", myport);
  274. return -1;
  275. } else {
  276. return GetGraphManager()->GetPort(myport)->Flags();
  277. }
  278. }
  279. EXPORT const char* jack_port_type(const jack_port_t* port)
  280. {
  281. #ifdef __CLIENTDEBUG__
  282. JackLibGlobals::CheckContext();
  283. #endif
  284. jack_port_id_t myport = (jack_port_id_t)port;
  285. if (!CheckPort(myport)) {
  286. jack_error("jack_port_flags called an incorrect port %ld", myport);
  287. return NULL;
  288. } else {
  289. return GetGraphManager()->GetPort(myport)->Type();
  290. }
  291. }
  292. EXPORT int jack_port_connected(const jack_port_t* port)
  293. {
  294. #ifdef __CLIENTDEBUG__
  295. JackLibGlobals::CheckContext();
  296. #endif
  297. jack_port_id_t myport = (jack_port_id_t)port;
  298. if (!CheckPort(myport)) {
  299. jack_error("jack_port_connected called with an incorrect port %ld", myport);
  300. return -1;
  301. } else {
  302. WaitGraphChange();
  303. return GetGraphManager()->GetConnectionsNum(myport);
  304. }
  305. }
  306. EXPORT int jack_port_connected_to(const jack_port_t* port, const char* portname)
  307. {
  308. #ifdef __CLIENTDEBUG__
  309. JackLibGlobals::CheckContext();
  310. #endif
  311. jack_port_id_t myport = (jack_port_id_t)port;
  312. if (!CheckPort(myport)) {
  313. jack_error("jack_port_connected_to called with an incorrect port %ld", myport);
  314. return -1;
  315. } else if (portname == NULL) {
  316. jack_error("jack_port_connected_to called with a NULL port name");
  317. return -1;
  318. } else {
  319. WaitGraphChange();
  320. return GetGraphManager()->ConnectedTo(myport, portname);
  321. }
  322. }
  323. EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst)
  324. {
  325. #ifdef __CLIENTDEBUG__
  326. JackLibGlobals::CheckContext();
  327. #endif
  328. jack_port_id_t mysrc = (jack_port_id_t)src;
  329. if (!CheckPort(mysrc)) {
  330. jack_error("jack_port_tie called with a NULL src port");
  331. return -1;
  332. }
  333. jack_port_id_t mydst = (jack_port_id_t)dst;
  334. if (!CheckPort(mydst)) {
  335. jack_error("jack_port_tie called with a NULL dst port");
  336. return -1;
  337. }
  338. if (GetGraphManager()->GetPort(mysrc)->GetRefNum() != GetGraphManager()->GetPort(mydst)->GetRefNum()) {
  339. jack_error("jack_port_tie called with ports not belonging to the same client");
  340. return -1;
  341. }
  342. return GetGraphManager()->GetPort(mydst)->Tie(mysrc);
  343. }
  344. EXPORT int jack_port_untie(jack_port_t* port)
  345. {
  346. #ifdef __CLIENTDEBUG__
  347. JackLibGlobals::CheckContext();
  348. #endif
  349. jack_port_id_t myport = (jack_port_id_t)port;
  350. if (!CheckPort(myport)) {
  351. jack_error("jack_port_untie called with an incorrect port %ld", myport);
  352. return -1;
  353. } else {
  354. return GetGraphManager()->GetPort(myport)->UnTie();
  355. }
  356. }
  357. EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port)
  358. {
  359. #ifdef __CLIENTDEBUG__
  360. JackLibGlobals::CheckContext();
  361. #endif
  362. jack_port_id_t myport = (jack_port_id_t)port;
  363. if (!CheckPort(myport)) {
  364. jack_error("jack_port_get_latency called with an incorrect port %ld", myport);
  365. return 0;
  366. } else {
  367. WaitGraphChange();
  368. return GetGraphManager()->GetPort(myport)->GetLatency();
  369. }
  370. }
  371. EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames)
  372. {
  373. #ifdef __CLIENTDEBUG__
  374. JackLibGlobals::CheckContext();
  375. #endif
  376. jack_port_id_t myport = (jack_port_id_t)port;
  377. if (!CheckPort(myport)) {
  378. jack_error("jack_port_set_latency called with an incorrect port %ld", myport);
  379. } else {
  380. GetGraphManager()->GetPort(myport)->SetLatency(frames);
  381. }
  382. }
  383. EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client)
  384. {
  385. // The latency computation is done each time jack_port_get_total_latency is called
  386. return 0;
  387. }
  388. EXPORT int jack_port_set_name(jack_port_t* port, const char* name)
  389. {
  390. #ifdef __CLIENTDEBUG__
  391. JackLibGlobals::CheckContext();
  392. #endif
  393. jack_port_id_t myport = (jack_port_id_t)port;
  394. if (!CheckPort(myport)) {
  395. jack_error("jack_port_set_name called with an incorrect port %ld", myport);
  396. return -1;
  397. } else if (name == NULL) {
  398. jack_error("jack_port_set_name called with a NULL port name");
  399. return -1;
  400. } else {
  401. return GetGraphManager()->GetPort(myport)->SetName(name);
  402. }
  403. }
  404. EXPORT int jack_port_set_alias(jack_port_t* port, const char* name)
  405. {
  406. #ifdef __CLIENTDEBUG__
  407. JackLibGlobals::CheckContext();
  408. #endif
  409. jack_port_id_t myport = (jack_port_id_t)port;
  410. if (!CheckPort(myport)) {
  411. jack_error("jack_port_set_alias called with an incorrect port %ld", myport);
  412. return -1;
  413. } else if (name == NULL) {
  414. jack_error("jack_port_set_alias called with a NULL port name");
  415. return -1;
  416. } else {
  417. return GetGraphManager()->GetPort(myport)->SetAlias(name);
  418. }
  419. }
  420. EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name)
  421. {
  422. #ifdef __CLIENTDEBUG__
  423. JackLibGlobals::CheckContext();
  424. #endif
  425. jack_port_id_t myport = (jack_port_id_t)port;
  426. if (!CheckPort(myport)) {
  427. jack_error("jack_port_unset_alias called with an incorrect port %ld", myport);
  428. return -1;
  429. } else if (name == NULL) {
  430. jack_error("jack_port_unset_alias called with a NULL port name");
  431. return -1;
  432. } else {
  433. return GetGraphManager()->GetPort(myport)->UnsetAlias(name);
  434. }
  435. }
  436. EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2])
  437. {
  438. #ifdef __CLIENTDEBUG__
  439. JackLibGlobals::CheckContext();
  440. #endif
  441. jack_port_id_t myport = (jack_port_id_t)port;
  442. if (!CheckPort(myport)) {
  443. jack_error("jack_port_get_aliases called with an incorrect port %ld", myport);
  444. return -1;
  445. } else {
  446. return GetGraphManager()->GetPort(myport)->GetAliases(aliases);
  447. }
  448. }
  449. EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff)
  450. {
  451. #ifdef __CLIENTDEBUG__
  452. JackLibGlobals::CheckContext();
  453. #endif
  454. jack_port_id_t myport = (jack_port_id_t)port;
  455. if (!CheckPort(myport)) {
  456. jack_error("jack_port_request_monitor called with an incorrect port %ld", myport);
  457. return -1;
  458. } else {
  459. return GetGraphManager()->RequestMonitor(myport, onoff);
  460. }
  461. }
  462. EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff)
  463. {
  464. #ifdef __CLIENTDEBUG__
  465. JackLibGlobals::CheckContext();
  466. #endif
  467. JackClient* client = (JackClient*)ext_client;
  468. if (client == NULL) {
  469. jack_error("jack_port_request_monitor_by_name called with a NULL client");
  470. return -1;
  471. } else {
  472. jack_port_id_t myport = GetGraphManager()->GetPort(port_name);
  473. if (!CheckPort(myport)) {
  474. jack_error("jack_port_request_monitor_by_name called with an incorrect port %s", port_name);
  475. return -1;
  476. } else {
  477. return GetGraphManager()->RequestMonitor(myport, onoff);
  478. }
  479. }
  480. }
  481. EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff)
  482. {
  483. #ifdef __CLIENTDEBUG__
  484. JackLibGlobals::CheckContext();
  485. #endif
  486. jack_port_id_t myport = (jack_port_id_t)port;
  487. if (!CheckPort(myport)) {
  488. jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport);
  489. return -1;
  490. } else {
  491. return GetGraphManager()->GetPort(myport)->EnsureMonitor(onoff);
  492. }
  493. }
  494. EXPORT int jack_port_monitoring_input(jack_port_t* port)
  495. {
  496. #ifdef __CLIENTDEBUG__
  497. JackLibGlobals::CheckContext();
  498. #endif
  499. jack_port_id_t myport = (jack_port_id_t)port;
  500. if (!CheckPort(myport)) {
  501. jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport);
  502. return -1;
  503. } else {
  504. return GetGraphManager()->GetPort(myport)->MonitoringInput();
  505. }
  506. }
  507. EXPORT int jack_is_realtime(jack_client_t* ext_client)
  508. {
  509. #ifdef __CLIENTDEBUG__
  510. JackLibGlobals::CheckContext();
  511. #endif
  512. JackClient* client = (JackClient*)ext_client;
  513. if (client == NULL) {
  514. jack_error("jack_is_realtime called with a NULL client");
  515. return -1;
  516. } else {
  517. return GetEngineControl()->fRealTime;
  518. }
  519. }
  520. EXPORT void jack_on_shutdown(jack_client_t* ext_client, void (*function)(void* arg), void* arg)
  521. {
  522. #ifdef __CLIENTDEBUG__
  523. JackLibGlobals::CheckContext();
  524. #endif
  525. JackClient* client = (JackClient*)ext_client;
  526. if (client == NULL) {
  527. jack_error("jack_on_shutdown called with a NULL client");
  528. } else {
  529. client->OnShutdown(function, arg);
  530. }
  531. }
  532. EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg)
  533. {
  534. #ifdef __CLIENTDEBUG__
  535. JackLibGlobals::CheckContext();
  536. #endif
  537. JackClient* client = (JackClient*)ext_client;
  538. if (client == NULL) {
  539. jack_error("jack_set_process_callback called with a NULL client");
  540. return -1;
  541. } else {
  542. return client->SetProcessCallback(callback, arg);
  543. }
  544. }
  545. EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg)
  546. {
  547. #ifdef __CLIENTDEBUG__
  548. JackLibGlobals::CheckContext();
  549. #endif
  550. JackClient* client = (JackClient*)ext_client;
  551. if (client == NULL) {
  552. jack_error("jack_set_freewheel_callback called with a NULL client");
  553. return -1;
  554. } else {
  555. return client->SetFreewheelCallback(freewheel_callback, arg);
  556. }
  557. }
  558. EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff)
  559. {
  560. #ifdef __CLIENTDEBUG__
  561. JackLibGlobals::CheckContext();
  562. #endif
  563. JackClient* client = (JackClient*)ext_client;
  564. if (client == NULL) {
  565. jack_error("jack_set_freewheel called with a NULL client");
  566. return -1;
  567. } else {
  568. return client->SetFreeWheel(onoff);
  569. }
  570. }
  571. EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size)
  572. {
  573. #ifdef __CLIENTDEBUG__
  574. JackLibGlobals::CheckContext();
  575. #endif
  576. JackClient* client = (JackClient*)ext_client;
  577. if (client == NULL) {
  578. jack_error("jack_set_buffer_size called with a NULL client");
  579. return -1;
  580. } else if (!CheckBufferSize(buffer_size)) {
  581. return -1;
  582. } else {
  583. return client->SetBufferSize(buffer_size);
  584. }
  585. }
  586. EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg)
  587. {
  588. #ifdef __CLIENTDEBUG__
  589. JackLibGlobals::CheckContext();
  590. #endif
  591. JackClient* client = (JackClient*)ext_client;
  592. if (client == NULL) {
  593. jack_error("jack_set_buffer_size_callback called with a NULL client");
  594. return -1;
  595. } else {
  596. return client->SetBufferSizeCallback(bufsize_callback, arg);
  597. }
  598. }
  599. EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg)
  600. {
  601. #ifdef __CLIENTDEBUG__
  602. JackLibGlobals::CheckContext();
  603. #endif
  604. JackClient* client = (JackClient*)ext_client;
  605. if (client == NULL) {
  606. jack_error("jack_set_sample_rate_callback called with a NULL client");
  607. return -1;
  608. } else {
  609. jack_error("jack_set_sample_rate_callback: deprecated");
  610. return 0;
  611. }
  612. }
  613. EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, JackClientRegistrationCallback registration_callback, void* arg)
  614. {
  615. #ifdef __CLIENTDEBUG__
  616. JackLibGlobals::CheckContext();
  617. #endif
  618. JackClient* client = (JackClient*)ext_client;
  619. if (client == NULL) {
  620. jack_error("jack_set_client_registration_callback called with a NULL client");
  621. return -1;
  622. } else {
  623. return client->SetClientRegistrationCallback(registration_callback, arg);
  624. }
  625. }
  626. EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg)
  627. {
  628. #ifdef __CLIENTDEBUG__
  629. JackLibGlobals::CheckContext();
  630. #endif
  631. JackClient* client = (JackClient*)ext_client;
  632. if (client == NULL) {
  633. jack_error("jack_set_port_registration_callback called with a NULL client");
  634. return -1;
  635. } else {
  636. return client->SetPortRegistrationCallback(registration_callback, arg);
  637. }
  638. }
  639. EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrderCallback graph_callback, void* arg)
  640. {
  641. #ifdef __CLIENTDEBUG__
  642. JackLibGlobals::CheckContext();
  643. #endif
  644. JackClient* client = (JackClient*)ext_client;
  645. JackLog("jack_set_graph_order_callback ext_client %x client %x \n", ext_client, client);
  646. if (client == NULL) {
  647. jack_error("jack_set_graph_order_callback called with a NULL client");
  648. return -1;
  649. } else {
  650. return client->SetGraphOrderCallback(graph_callback, arg);
  651. }
  652. }
  653. EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xrun_callback, void* arg)
  654. {
  655. #ifdef __CLIENTDEBUG__
  656. JackLibGlobals::CheckContext();
  657. #endif
  658. JackClient* client = (JackClient*)ext_client;
  659. if (client == NULL) {
  660. jack_error("jack_set_xrun_callback called with a NULL client");
  661. return -1;
  662. } else {
  663. return client->SetXRunCallback(xrun_callback, arg);
  664. }
  665. }
  666. EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg)
  667. {
  668. #ifdef __CLIENTDEBUG__
  669. JackLibGlobals::CheckContext();
  670. #endif
  671. JackClient* client = (JackClient*)ext_client;
  672. JackLog("jack_set_thread_init_callback ext_client %x client %x \n", ext_client, client);
  673. if (client == NULL) {
  674. jack_error("jack_set_thread_init_callback called with a NULL client");
  675. return -1;
  676. } else {
  677. return client->SetInitCallback(init_callback, arg);
  678. }
  679. }
  680. EXPORT int jack_activate(jack_client_t* ext_client)
  681. {
  682. #ifdef __CLIENTDEBUG__
  683. JackLibGlobals::CheckContext();
  684. #endif
  685. JackClient* client = (JackClient*)ext_client;
  686. if (client == NULL) {
  687. jack_error("jack_activate called with a NULL client");
  688. return -1;
  689. } else {
  690. return client->Activate();
  691. }
  692. }
  693. EXPORT int jack_deactivate(jack_client_t* ext_client)
  694. {
  695. #ifdef __CLIENTDEBUG__
  696. JackLibGlobals::CheckContext();
  697. #endif
  698. JackClient* client = (JackClient*)ext_client;
  699. if (client == NULL) {
  700. jack_error("jack_deactivate called with a NULL client");
  701. return -1;
  702. } else {
  703. return client->Deactivate();
  704. }
  705. }
  706. 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)
  707. {
  708. #ifdef __CLIENTDEBUG__
  709. JackLibGlobals::CheckContext();
  710. #endif
  711. JackClient* client = (JackClient*)ext_client;
  712. if (client == NULL) {
  713. jack_error("jack_port_register called with a NULL client");
  714. return NULL;
  715. } else if ((port_name == NULL) || (port_type == NULL)) {
  716. jack_error("jack_port_register called with a NULL port name or a NULL port_type");
  717. return NULL;
  718. } else {
  719. return (jack_port_t *)client->PortRegister(port_name, port_type, flags, buffer_size);
  720. }
  721. }
  722. EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port)
  723. {
  724. #ifdef __CLIENTDEBUG__
  725. JackLibGlobals::CheckContext();
  726. #endif
  727. JackClient* client = (JackClient*)ext_client;
  728. if (client == NULL) {
  729. jack_error("jack_port_unregister called with a NULL client");
  730. return -1;
  731. }
  732. jack_port_id_t myport = (jack_port_id_t)port;
  733. if (!CheckPort(myport)) {
  734. jack_error("jack_port_unregister called with an incorrect port %ld", myport);
  735. return -1;
  736. }
  737. return client->PortUnRegister(myport);
  738. }
  739. EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* port)
  740. {
  741. #ifdef __CLIENTDEBUG__
  742. JackLibGlobals::CheckContext();
  743. #endif
  744. JackClient* client = (JackClient*)ext_client;
  745. if (client == NULL) {
  746. jack_error("jack_port_is_mine called with a NULL client");
  747. return -1;
  748. }
  749. jack_port_id_t myport = (jack_port_id_t)port;
  750. if (!CheckPort(myport)) {
  751. jack_error("jack_port_is_mine called with an incorrect port %ld", myport);
  752. return -1;
  753. }
  754. return client->PortIsMine(myport);
  755. }
  756. EXPORT const char** jack_port_get_connections(const jack_port_t* port)
  757. {
  758. #ifdef __CLIENTDEBUG__
  759. JackLibGlobals::CheckContext();
  760. #endif
  761. jack_port_id_t myport = (jack_port_id_t)port;
  762. if (!CheckPort(myport)) {
  763. jack_error("jack_port_get_connections called with an incorrect port %ld", myport);
  764. return NULL;
  765. } else {
  766. WaitGraphChange();
  767. return GetGraphManager()->GetConnections(myport);
  768. }
  769. }
  770. // Calling client does not need to "own" the port
  771. EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_client, const jack_port_t* port)
  772. {
  773. #ifdef __CLIENTDEBUG__
  774. JackLibGlobals::CheckContext();
  775. #endif
  776. JackClient* client = (JackClient*)ext_client;
  777. if (client == NULL) {
  778. jack_error("jack_port_get_all_connections called with a NULL client");
  779. return NULL;
  780. }
  781. jack_port_id_t myport = (jack_port_id_t)port;
  782. if (!CheckPort(myport)) {
  783. jack_error("jack_port_get_all_connections called with an incorrect port %ld", myport);
  784. return NULL;
  785. } else {
  786. WaitGraphChange();
  787. return GetGraphManager()->GetConnections(myport);
  788. }
  789. }
  790. // Does not use the client parameter
  791. EXPORT int jack_port_lock(jack_client_t* ext_client, jack_port_t* port)
  792. {
  793. #ifdef __CLIENTDEBUG__
  794. JackLibGlobals::CheckContext();
  795. #endif
  796. JackClient* client = (JackClient*)ext_client;
  797. if (client == NULL) {
  798. jack_error("jack_port_lock called with a NULL client");
  799. return -1;
  800. }
  801. jack_port_id_t myport = (jack_port_id_t)port;
  802. if (!CheckPort(myport)) {
  803. jack_error("jack_port_lock called with an incorrect port %ld", myport);
  804. return -1;
  805. } else {
  806. return (myport && client->PortIsMine(myport)) ? GetGraphManager()->GetPort(myport)->Lock() : -1;
  807. }
  808. }
  809. // Does not use the client parameter
  810. EXPORT int jack_port_unlock(jack_client_t* ext_client, jack_port_t* port)
  811. {
  812. #ifdef __CLIENTDEBUG__
  813. JackLibGlobals::CheckContext();
  814. #endif
  815. JackClient* client = (JackClient*)ext_client;
  816. if (client == NULL) {
  817. jack_error("jack_port_unlock called with a NULL client");
  818. return -1;
  819. }
  820. jack_port_id_t myport = (jack_port_id_t)port;
  821. if (!CheckPort(myport)) {
  822. jack_error("jack_port_unlock called with an incorrect port %ld", myport);
  823. return -1;
  824. } else {
  825. return (myport && client->PortIsMine(myport)) ? GetGraphManager()->GetPort(myport)->Unlock() : -1;
  826. }
  827. }
  828. EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jack_port_t* port)
  829. {
  830. #ifdef __CLIENTDEBUG__
  831. JackLibGlobals::CheckContext();
  832. #endif
  833. JackClient* client = (JackClient*)ext_client;
  834. if (client == NULL) {
  835. jack_error("jack_port_get_total_latency called with a NULL client");
  836. return 0;
  837. }
  838. jack_port_id_t myport = (jack_port_id_t)port;
  839. if (!CheckPort(myport)) {
  840. jack_error("jack_port_get_total_latency called with an incorrect port %ld", myport);
  841. return 0;
  842. } else {
  843. // The latency computation is done each time
  844. WaitGraphChange();
  845. return GetGraphManager()->GetTotalLatency(myport);
  846. }
  847. }
  848. EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* dst)
  849. {
  850. #ifdef __CLIENTDEBUG__
  851. JackLibGlobals::CheckContext();
  852. #endif
  853. JackClient* client = (JackClient*)ext_client;
  854. if (client == NULL) {
  855. jack_error("jack_connect called with a NULL client");
  856. return -1;
  857. } else if ((src == NULL) || (dst == NULL)) {
  858. jack_error("jack_connect called with a NULL port name");
  859. return -1;
  860. } else {
  861. return client->PortConnect(src, dst);
  862. }
  863. }
  864. EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const char* dst)
  865. {
  866. #ifdef __CLIENTDEBUG__
  867. JackLibGlobals::CheckContext();
  868. #endif
  869. JackClient* client = (JackClient*)ext_client;
  870. if (client == NULL) {
  871. jack_error("jack_disconnect called with a NULL client");
  872. return -1;
  873. } else if ((src == NULL) || (dst == NULL)) {
  874. jack_error("jack_connect called with a NULL port name");
  875. return -1;
  876. } else {
  877. return client->PortDisconnect(src, dst);
  878. }
  879. }
  880. EXPORT int jack_port_connect(jack_client_t* ext_client, jack_port_t* src, jack_port_t* dst)
  881. {
  882. #ifdef __CLIENTDEBUG__
  883. JackLibGlobals::CheckContext();
  884. #endif
  885. JackClient* client = (JackClient*)ext_client;
  886. if (client == NULL) {
  887. jack_error("jack_port_connect called with a NULL client");
  888. return -1;
  889. }
  890. jack_port_id_t mysrc = (jack_port_id_t)src;
  891. if (!CheckPort(mysrc)) {
  892. jack_error("jack_port_connect called with a NULL src port");
  893. return -1;
  894. }
  895. jack_port_id_t mydst = (jack_port_id_t)dst;
  896. if (!CheckPort(mydst)) {
  897. jack_error("jack_port_connect called with a NULL dst port");
  898. return -1;
  899. }
  900. return client->PortConnect(mysrc, mydst);
  901. }
  902. EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src)
  903. {
  904. #ifdef __CLIENTDEBUG__
  905. JackLibGlobals::CheckContext();
  906. #endif
  907. JackClient* client = (JackClient*)ext_client;
  908. if (client == NULL) {
  909. jack_error("jack_port_disconnect called with a NULL client");
  910. return -1;
  911. }
  912. jack_port_id_t myport = (jack_port_id_t)src;
  913. if (!CheckPort(myport)) {
  914. jack_error("jack_port_disconnect called with an incorrect port %ld", myport);
  915. return -1;
  916. }
  917. return client->PortDisconnect(myport);
  918. }
  919. EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client)
  920. {
  921. #ifdef __CLIENTDEBUG__
  922. JackLibGlobals::CheckContext();
  923. #endif
  924. JackClient* client = (JackClient*)ext_client;
  925. if (client == NULL) {
  926. jack_error("jack_get_sample_rate called with a NULL client");
  927. return 0;
  928. } else {
  929. return GetEngineControl()->fSampleRate;
  930. }
  931. }
  932. EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client)
  933. {
  934. #ifdef __CLIENTDEBUG__
  935. JackLibGlobals::CheckContext();
  936. #endif
  937. JackClient* client = (JackClient*)ext_client;
  938. if (client == NULL) {
  939. jack_error("jack_get_buffer_size called with a NULL client");
  940. return 0;
  941. } else {
  942. return GetEngineControl()->fBufferSize;
  943. }
  944. }
  945. EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
  946. {
  947. #ifdef __CLIENTDEBUG__
  948. JackLibGlobals::CheckContext();
  949. #endif
  950. JackClient* client = (JackClient*)ext_client;
  951. if (client == NULL) {
  952. jack_error("jack_get_ports called with a NULL client");
  953. return NULL;
  954. }
  955. return GetGraphManager()->GetPorts(port_name_pattern, type_name_pattern, flags);
  956. }
  957. EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* portname)
  958. {
  959. #ifdef __CLIENTDEBUG__
  960. JackLibGlobals::CheckContext();
  961. #endif
  962. JackClient* client = (JackClient*)ext_client;
  963. if (client == NULL) {
  964. jack_error("jack_get_ports called with a NULL client");
  965. return 0;
  966. }
  967. if (portname == NULL) {
  968. jack_error("jack_port_by_name called with a NULL port name");
  969. return NULL;
  970. } else {
  971. int res = GetGraphManager()->GetPort(portname); // returns a port index at least > 1
  972. return (res == NO_PORT) ? NULL : (jack_port_t*)res;
  973. }
  974. }
  975. EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id)
  976. {
  977. #ifdef __CLIENTDEBUG__
  978. JackLibGlobals::CheckContext();
  979. #endif
  980. /* jack_port_t* type is actually the port index */
  981. return (jack_port_t*)id;
  982. }
  983. EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client)
  984. {
  985. #ifdef __CLIENTDEBUG__
  986. JackLibGlobals::CheckContext();
  987. #endif
  988. JackClient* client = (JackClient*)ext_client;
  989. if (client == NULL) {
  990. jack_error("jack_engine_takeover_timebase called with a NULL client");
  991. return -1;
  992. } else {
  993. jack_error("jack_engine_takeover_timebase: deprecated\n");
  994. return 0;
  995. }
  996. }
  997. EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_client)
  998. {
  999. #ifdef __CLIENTDEBUG__
  1000. JackLibGlobals::CheckContext();
  1001. #endif
  1002. JackTimer timer;
  1003. GetEngineControl()->ReadFrameTime(&timer);
  1004. return (jack_nframes_t) floor((((float)GetEngineControl()->fSampleRate) / 1000000.0f) * (GetMicroSeconds() - timer.fCurrentCallback));
  1005. }
  1006. EXPORT jack_time_t jack_get_time(jack_client_t *client)
  1007. {
  1008. return GetMicroSeconds();
  1009. }
  1010. EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nframes_t frames)
  1011. {
  1012. #ifdef __CLIENTDEBUG__
  1013. JackLibGlobals::CheckContext();
  1014. #endif
  1015. JackClient* client = (JackClient*)ext_client;
  1016. if (client == NULL) {
  1017. jack_error("jack_frames_to_time called with a NULL client");
  1018. return 0;
  1019. } else {
  1020. JackTimer timer;
  1021. GetEngineControl()->ReadFrameTime(&timer);
  1022. if (timer.fInitialized) {
  1023. return timer.fCurrentWakeup +
  1024. (long) rint(((double) ((frames - timer.fFrames)) *
  1025. ((jack_time_t)(timer.fNextWakeUp - timer.fCurrentWakeup))) / GetEngineControl()->fBufferSize);
  1026. } else {
  1027. return 0;
  1028. }
  1029. }
  1030. }
  1031. EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_time_t time)
  1032. {
  1033. #ifdef __CLIENTDEBUG__
  1034. JackLibGlobals::CheckContext();
  1035. #endif
  1036. JackClient* client = (JackClient*)ext_client;
  1037. if (client == NULL) {
  1038. jack_error("jack_time_to_frames called with a NULL client");
  1039. return 0;
  1040. } else {
  1041. JackTimer timer;
  1042. GetEngineControl()->ReadFrameTime(&timer);
  1043. if (timer.fInitialized) {
  1044. return timer.fFrames +
  1045. (long) rint(((double) ((time - timer.fCurrentWakeup)) /
  1046. ((jack_time_t)(timer.fNextWakeUp - timer.fCurrentWakeup))) * GetEngineControl()->fBufferSize);
  1047. } else {
  1048. return 0;
  1049. }
  1050. }
  1051. }
  1052. EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client)
  1053. {
  1054. return jack_time_to_frames(ext_client, GetMicroSeconds());
  1055. }
  1056. EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client)
  1057. {
  1058. #ifdef __CLIENTDEBUG__
  1059. JackLibGlobals::CheckContext();
  1060. #endif
  1061. JackTimer timer;
  1062. GetEngineControl()->ReadFrameTime(&timer);
  1063. return timer.fFrames;
  1064. }
  1065. EXPORT float jack_cpu_load(jack_client_t* ext_client)
  1066. {
  1067. #ifdef __CLIENTDEBUG__
  1068. JackLibGlobals::CheckContext();
  1069. #endif
  1070. JackClient* client = (JackClient*)ext_client;
  1071. if (client == NULL) {
  1072. jack_error("jack_cpu_load called with a NULL client");
  1073. return 0.0f;
  1074. } else {
  1075. return GetEngineControl()->fCPULoad;
  1076. }
  1077. }
  1078. EXPORT pthread_t jack_client_thread_id(jack_client_t* ext_client)
  1079. {
  1080. #ifdef __CLIENTDEBUG__
  1081. JackLibGlobals::CheckContext();
  1082. #endif
  1083. JackClient* client = (JackClient*)ext_client;
  1084. if (client == NULL) {
  1085. jack_error("jack_client_thread_id called with a NULL client");
  1086. return (pthread_t)NULL;
  1087. } else {
  1088. return client->GetThreadID();
  1089. }
  1090. }
  1091. EXPORT char* jack_get_client_name (jack_client_t* ext_client)
  1092. {
  1093. #ifdef __CLIENTDEBUG__
  1094. JackLibGlobals::CheckContext();
  1095. #endif
  1096. JackClient* client = (JackClient*)ext_client;
  1097. if (client == NULL) {
  1098. jack_error("jack_get_client_name called with a NULL client");
  1099. return NULL;
  1100. } else {
  1101. return client->GetClientControl()->fName;
  1102. }
  1103. }
  1104. EXPORT int jack_client_name_size(void)
  1105. {
  1106. return JACK_CLIENT_NAME_SIZE;
  1107. }
  1108. EXPORT int jack_port_name_size(void)
  1109. {
  1110. return JACK_PORT_NAME_SIZE;
  1111. }
  1112. // transport.h
  1113. EXPORT int jack_release_timebase(jack_client_t* ext_client)
  1114. {
  1115. #ifdef __CLIENTDEBUG__
  1116. JackLibGlobals::CheckContext();
  1117. #endif
  1118. JackClient* client = (JackClient*)ext_client;
  1119. if (client == NULL) {
  1120. jack_error("jack_release_timebase called with a NULL client");
  1121. return -1;
  1122. } else {
  1123. return client->ReleaseTimebase();
  1124. }
  1125. }
  1126. EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg)
  1127. {
  1128. #ifdef __CLIENTDEBUG__
  1129. JackLibGlobals::CheckContext();
  1130. #endif
  1131. JackClient* client = (JackClient*)ext_client;
  1132. if (client == NULL) {
  1133. jack_error("jack_set_sync_callback called with a NULL client");
  1134. return -1;
  1135. } else {
  1136. return client->SetSyncCallback(sync_callback, arg);
  1137. }
  1138. }
  1139. EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout)
  1140. {
  1141. #ifdef __CLIENTDEBUG__
  1142. JackLibGlobals::CheckContext();
  1143. #endif
  1144. JackClient* client = (JackClient*)ext_client;
  1145. if (client == NULL) {
  1146. jack_error("jack_set_sync_timeout called with a NULL client");
  1147. return -1;
  1148. } else {
  1149. return client->SetSyncTimeout(timeout);
  1150. }
  1151. }
  1152. EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg)
  1153. {
  1154. #ifdef __CLIENTDEBUG__
  1155. JackLibGlobals::CheckContext();
  1156. #endif
  1157. JackClient* client = (JackClient*)ext_client;
  1158. if (client == NULL) {
  1159. jack_error("jack_set_timebase_callback called with a NULL client");
  1160. return -1;
  1161. } else {
  1162. return client->SetTimebaseCallback(conditional, timebase_callback, arg);
  1163. }
  1164. }
  1165. EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame)
  1166. {
  1167. #ifdef __CLIENTDEBUG__
  1168. JackLibGlobals::CheckContext();
  1169. #endif
  1170. JackClient* client = (JackClient*)ext_client;
  1171. if (client == NULL) {
  1172. jack_error("jack_transport_locate called with a NULL client");
  1173. return -1;
  1174. } else {
  1175. return client->TransportLocate(frame);
  1176. }
  1177. }
  1178. EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos)
  1179. {
  1180. #ifdef __CLIENTDEBUG__
  1181. JackLibGlobals::CheckContext();
  1182. #endif
  1183. JackClient* client = (JackClient*)ext_client;
  1184. if (client == NULL) {
  1185. jack_error("jack_transport_query called with a NULL client");
  1186. return JackTransportStopped;
  1187. } else {
  1188. return client->TransportQuery(pos);
  1189. }
  1190. }
  1191. EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client)
  1192. {
  1193. #ifdef __CLIENTDEBUG__
  1194. JackLibGlobals::CheckContext();
  1195. #endif
  1196. JackClient* client = (JackClient*)ext_client;
  1197. if (client == NULL) {
  1198. jack_error("jack_get_current_transport_frame called with a NULL client");
  1199. return 0;
  1200. } else {
  1201. return client->GetCurrentTransportFrame();
  1202. }
  1203. }
  1204. EXPORT int jack_transport_reposition(jack_client_t* ext_client, jack_position_t* pos)
  1205. {
  1206. #ifdef __CLIENTDEBUG__
  1207. JackLibGlobals::CheckContext();
  1208. #endif
  1209. JackClient* client = (JackClient*)ext_client;
  1210. if (client == NULL) {
  1211. jack_error("jack_transport_reposition called with a NULL client");
  1212. return -1;
  1213. } else {
  1214. return client->TransportReposition(pos);
  1215. }
  1216. }
  1217. EXPORT void jack_transport_start(jack_client_t* ext_client)
  1218. {
  1219. #ifdef __CLIENTDEBUG__
  1220. JackLibGlobals::CheckContext();
  1221. #endif
  1222. JackClient* client = (JackClient*)ext_client;
  1223. if (client == NULL) {
  1224. jack_error("jack_transport_start called with a NULL client");
  1225. } else {
  1226. client->TransportStart();
  1227. }
  1228. }
  1229. EXPORT void jack_transport_stop(jack_client_t* ext_client)
  1230. {
  1231. #ifdef __CLIENTDEBUG__
  1232. JackLibGlobals::CheckContext();
  1233. #endif
  1234. JackClient* client = (JackClient*)ext_client;
  1235. if (client == NULL) {
  1236. jack_error("jack_transport_stop called with a NULL client");
  1237. } else {
  1238. client->TransportStop();
  1239. }
  1240. }
  1241. // deprecated
  1242. EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
  1243. {
  1244. jack_error("jack_get_transport_info: deprecated");
  1245. if (tinfo)
  1246. memset(tinfo, 0, sizeof(jack_transport_info_t));
  1247. }
  1248. EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
  1249. {
  1250. jack_error("jack_set_transport_info: deprecated");
  1251. if (tinfo)
  1252. memset(tinfo, 0, sizeof(jack_transport_info_t));
  1253. }
  1254. // statistics.h
  1255. EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client)
  1256. {
  1257. #ifdef __CLIENTDEBUG__
  1258. JackLibGlobals::CheckContext();
  1259. #endif
  1260. JackLog("jack_get_max_delayed_usecs: not yet implemented\n");
  1261. return 0.f;
  1262. }
  1263. EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client)
  1264. {
  1265. #ifdef __CLIENTDEBUG__
  1266. JackLibGlobals::CheckContext();
  1267. #endif
  1268. JackLog("jack_get_xrun_delayed_usecs: not yet implemented\n");
  1269. return 0.f;
  1270. }
  1271. EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client)
  1272. {
  1273. #ifdef __CLIENTDEBUG__
  1274. JackLibGlobals::CheckContext();
  1275. #endif
  1276. JackLog("jack_reset_max_delayed_usecs: not yet implemented\n");
  1277. }
  1278. // thread.h
  1279. EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority)
  1280. {
  1281. #ifdef __APPLE__
  1282. return JackMachThread::AcquireRealTimeImp(thread, 0, 500 * 1000, 500 * 1000);
  1283. #elif WIN32
  1284. return JackWinThread::AcquireRealTimeImp(thread, priority);
  1285. #else
  1286. return JackPosixThread::AcquireRealTimeImp(thread, priority);
  1287. #endif
  1288. }
  1289. EXPORT int jack_client_create_thread(jack_client_t* client,
  1290. pthread_t *thread,
  1291. int priority,
  1292. int realtime, /* boolean */
  1293. void *(*start_routine)(void*),
  1294. void *arg)
  1295. {
  1296. #ifdef __APPLE__
  1297. return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg);
  1298. #elif WIN32
  1299. return JackWinThread::StartImp(thread, priority, realtime, (ThreadCallback)start_routine, arg);
  1300. #else
  1301. return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg);
  1302. #endif
  1303. }
  1304. EXPORT int jack_drop_real_time_scheduling(pthread_t thread)
  1305. {
  1306. #ifdef __APPLE__
  1307. return JackMachThread::DropRealTimeImp(thread);
  1308. #elif WIN32
  1309. return JackWinThread::DropRealTimeImp(thread);
  1310. #else
  1311. return JackPosixThread::DropRealTimeImp(thread);
  1312. #endif
  1313. }
  1314. // intclient.h
  1315. EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient)
  1316. {
  1317. #ifdef __CLIENTDEBUG__
  1318. JackLibGlobals::CheckContext();
  1319. #endif
  1320. JackClient* client = (JackClient*)ext_client;
  1321. if (client == NULL) {
  1322. jack_error("jack_get_internal_client_name called with a NULL client");
  1323. return "";
  1324. } else {
  1325. return client->GetInternalClientName(intclient);
  1326. }
  1327. }
  1328. EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, const char* client_name, jack_status_t* status)
  1329. {
  1330. #ifdef __CLIENTDEBUG__
  1331. JackLibGlobals::CheckContext();
  1332. #endif
  1333. JackClient* client = (JackClient*)ext_client;
  1334. if (client == NULL) {
  1335. jack_error("jack_internal_client_handle called with a NULL client");
  1336. return 0;
  1337. } else {
  1338. jack_status_t my_status;
  1339. if (status == NULL) /* no status from caller? */
  1340. status = &my_status; /* use local status word */
  1341. *status = (jack_status_t)0;
  1342. return client->InternalClientHandle(client_name, status);
  1343. }
  1344. }
  1345. EXPORT jack_intclient_t jack_internal_client_load(jack_client_t* ext_client, const char* client_name, jack_options_t options, jack_status_t* status, ...)
  1346. {
  1347. #ifdef __CLIENTDEBUG__
  1348. JackLibGlobals::CheckContext();
  1349. #endif
  1350. JackClient* client = (JackClient*)ext_client;
  1351. if (client == NULL) {
  1352. jack_error("jack_internal_client_load called with a NULL client");
  1353. return 0;
  1354. } else {
  1355. va_list ap;
  1356. jack_varargs_t va;
  1357. jack_status_t my_status;
  1358. if (status == NULL) /* no status from caller? */
  1359. status = &my_status; /* use local status word */
  1360. *status = (jack_status_t)0;
  1361. /* validate parameters */
  1362. if ((options & ~JackLoadOptions)) {
  1363. int my_status1 = *status | (JackFailure | JackInvalidOption);
  1364. *status = (jack_status_t)my_status1;
  1365. return 0;
  1366. }
  1367. /* parse variable arguments */
  1368. va_start(ap, status);
  1369. jack_varargs_parse(options, ap, &va);
  1370. va_end(ap);
  1371. return client->InternalClientLoad(client_name, options, status, &va);
  1372. }
  1373. }
  1374. EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack_intclient_t intclient)
  1375. {
  1376. #ifdef __CLIENTDEBUG__
  1377. JackLibGlobals::CheckContext();
  1378. #endif
  1379. JackClient* client = (JackClient*)ext_client;
  1380. if (client == NULL) {
  1381. jack_error("jack_internal_client_unload called with a NULL client");
  1382. return (jack_status_t)(JackNoSuchClient | JackFailure);
  1383. } else {
  1384. jack_status_t my_status;
  1385. client->InternalClientUnload(intclient, &my_status);
  1386. return my_status;
  1387. }
  1388. }