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.

1490 lines
47KB

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