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.

1122 lines
38KB

  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 <math.h>
  25. using namespace Jack;
  26. #ifdef __cplusplus
  27. extern "C"
  28. {
  29. #endif
  30. EXPORT int jack_client_name_size (void);
  31. EXPORT char* jack_get_client_name (jack_client_t *client);
  32. EXPORT int jack_internal_client_new (const char *client_name,
  33. const char *load_name,
  34. const char *load_init);
  35. EXPORT jack_client_t* my_jack_internal_client_new(const char* client_name);
  36. EXPORT void jack_internal_client_close (const char *client_name);
  37. EXPORT void my_jack_internal_client_close (jack_client_t* client);
  38. EXPORT int jack_is_realtime (jack_client_t *client);
  39. EXPORT void jack_on_shutdown (jack_client_t *client,
  40. void (*function)(void *arg), void *arg);
  41. EXPORT int jack_set_process_callback (jack_client_t *client,
  42. JackProcessCallback process_callback,
  43. void *arg);
  44. EXPORT int jack_set_thread_init_callback (jack_client_t *client,
  45. JackThreadInitCallback thread_init_callback,
  46. void *arg);
  47. EXPORT int jack_set_freewheel_callback (jack_client_t *client,
  48. JackFreewheelCallback freewheel_callback,
  49. void *arg);
  50. EXPORT int jack_set_freewheel(jack_client_t* client, int onoff);
  51. EXPORT int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes);
  52. EXPORT int jack_set_buffer_size_callback (jack_client_t *client,
  53. JackBufferSizeCallback bufsize_callback,
  54. void *arg);
  55. EXPORT int jack_set_sample_rate_callback (jack_client_t *client,
  56. JackSampleRateCallback srate_callback,
  57. void *arg);
  58. EXPORT int jack_set_port_registration_callback (jack_client_t *,
  59. JackPortRegistrationCallback
  60. registration_callback, void *arg);
  61. EXPORT int jack_set_graph_order_callback (jack_client_t *,
  62. JackGraphOrderCallback graph_callback,
  63. void *);
  64. EXPORT int jack_set_xrun_callback (jack_client_t *,
  65. JackXRunCallback xrun_callback, void *arg);
  66. EXPORT int jack_activate (jack_client_t *client);
  67. EXPORT int jack_deactivate (jack_client_t *client);
  68. EXPORT jack_port_t * jack_port_register (jack_client_t *client,
  69. const char *port_name,
  70. const char *port_type,
  71. unsigned long flags,
  72. unsigned long buffer_size);
  73. EXPORT int jack_port_unregister (jack_client_t *, jack_port_t *);
  74. EXPORT void * jack_port_get_buffer (jack_port_t *, jack_nframes_t);
  75. EXPORT const char * jack_port_name (const jack_port_t *port);
  76. EXPORT const char * jack_port_short_name (const jack_port_t *port);
  77. EXPORT int jack_port_flags (const jack_port_t *port);
  78. EXPORT const char * jack_port_type (const jack_port_t *port);
  79. EXPORT int jack_port_is_mine (const jack_client_t *, const jack_port_t *port);
  80. EXPORT int jack_port_connected (const jack_port_t *port);
  81. EXPORT int jack_port_connected_to (const jack_port_t *port,
  82. const char *port_name);
  83. EXPORT const char ** jack_port_get_connections (const jack_port_t *port);
  84. EXPORT const char ** jack_port_get_all_connections (const jack_client_t *client,
  85. const jack_port_t *port);
  86. EXPORT int jack_port_tie (jack_port_t *src, jack_port_t *dst);
  87. EXPORT int jack_port_untie (jack_port_t *port);
  88. EXPORT int jack_port_lock (jack_client_t *, jack_port_t *);
  89. EXPORT int jack_port_unlock (jack_client_t *, jack_port_t *);
  90. EXPORT jack_nframes_t jack_port_get_latency (jack_port_t *port);
  91. EXPORT jack_nframes_t jack_port_get_total_latency (jack_client_t *,
  92. jack_port_t *port);
  93. EXPORT void jack_port_set_latency (jack_port_t *, jack_nframes_t);
  94. EXPORT int jack_recompute_total_latencies (jack_client_t*);
  95. EXPORT int jack_port_set_name (jack_port_t *port, const char *port_name);
  96. EXPORT int jack_port_request_monitor (jack_port_t *port, int onoff);
  97. EXPORT int jack_port_request_monitor_by_name (jack_client_t *client,
  98. const char *port_name, int onoff);
  99. EXPORT int jack_port_ensure_monitor (jack_port_t *port, int onoff);
  100. EXPORT int jack_port_monitoring_input (jack_port_t *port);
  101. EXPORT int jack_connect (jack_client_t *,
  102. const char *source_port,
  103. const char *destination_port);
  104. EXPORT int jack_disconnect (jack_client_t *,
  105. const char *source_port,
  106. const char *destination_port);
  107. EXPORT int jack_port_disconnect (jack_client_t *, jack_port_t *);
  108. EXPORT int jack_port_name_size(void);
  109. EXPORT int jack_port_type_size(void);
  110. EXPORT jack_nframes_t jack_get_sample_rate (jack_client_t *);
  111. EXPORT jack_nframes_t jack_get_buffer_size (jack_client_t *);
  112. EXPORT const char ** jack_get_ports (jack_client_t *,
  113. const char *port_name_pattern,
  114. const char *type_name_pattern,
  115. unsigned long flags);
  116. EXPORT jack_port_t * jack_port_by_name (jack_client_t *, const char *port_name);
  117. EXPORT jack_port_t * jack_port_by_id (jack_client_t *client,
  118. jack_port_id_t port_id);
  119. EXPORT int jack_engine_takeover_timebase (jack_client_t *);
  120. EXPORT jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *);
  121. EXPORT jack_nframes_t jack_frame_time (const jack_client_t *);
  122. EXPORT jack_nframes_t jack_last_frame_time (const jack_client_t *client);
  123. EXPORT float jack_cpu_load (jack_client_t *client);
  124. EXPORT pthread_t jack_client_thread_id (jack_client_t *);
  125. EXPORT void jack_set_error_function (void (*func)(const char *));
  126. EXPORT float jack_get_max_delayed_usecs (jack_client_t *client);
  127. EXPORT float jack_get_xrun_delayed_usecs (jack_client_t *client);
  128. EXPORT void jack_reset_max_delayed_usecs (jack_client_t *client);
  129. EXPORT int jack_release_timebase (jack_client_t *client);
  130. EXPORT int jack_set_sync_callback (jack_client_t *client,
  131. JackSyncCallback sync_callback,
  132. void *arg);
  133. EXPORT int jack_set_sync_timeout (jack_client_t *client,
  134. jack_time_t timeout);
  135. EXPORT int jack_set_timebase_callback (jack_client_t *client,
  136. int conditional,
  137. JackTimebaseCallback timebase_callback,
  138. void *arg);
  139. EXPORT int jack_transport_locate (jack_client_t *client,
  140. jack_nframes_t frame);
  141. EXPORT jack_transport_state_t jack_transport_query (const jack_client_t *client,
  142. jack_position_t *pos);
  143. EXPORT jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client);
  144. EXPORT int jack_transport_reposition (jack_client_t *client,
  145. jack_position_t *pos);
  146. EXPORT void jack_transport_start (jack_client_t *client);
  147. EXPORT void jack_transport_stop (jack_client_t *client);
  148. EXPORT void jack_get_transport_info (jack_client_t *client,
  149. jack_transport_info_t *tinfo);
  150. EXPORT void jack_set_transport_info (jack_client_t *client,
  151. jack_transport_info_t *tinfo);
  152. EXPORT int jack_acquire_real_time_scheduling (pthread_t thread, int priority);
  153. EXPORT int jack_client_create_thread (jack_client_t* client,
  154. pthread_t *thread,
  155. int priority,
  156. int realtime, // boolean
  157. void *(*start_routine)(void*),
  158. void *arg);
  159. EXPORT int jack_drop_real_time_scheduling (pthread_t thread);
  160. EXPORT char * jack_get_internal_client_name (jack_client_t *client,
  161. jack_intclient_t intclient);
  162. EXPORT jack_intclient_t jack_internal_client_handle (jack_client_t *client,
  163. const char *client_name,
  164. jack_status_t *status);
  165. EXPORT jack_intclient_t jack_internal_client_load (jack_client_t *client,
  166. const char *client_name,
  167. jack_options_t options,
  168. jack_status_t *status, ...);
  169. EXPORT jack_status_t jack_internal_client_unload (jack_client_t *client,
  170. jack_intclient_t intclient);
  171. #ifdef __cplusplus
  172. }
  173. #endif
  174. #ifdef WIN32
  175. /* missing on Windows : see http://bugs.mysql.com/bug.php?id=15936 */
  176. inline double rint(double nr)
  177. {
  178. double f = floor(nr);
  179. double c = ceil(nr);
  180. return (((c -nr) >= (nr - f)) ? f : c);
  181. }
  182. #endif
  183. static inline bool CheckPort(jack_port_id_t port_index)
  184. {
  185. return (port_index < PORT_NUM);
  186. }
  187. static inline bool CheckBufferSize(jack_nframes_t buffer_size)
  188. {
  189. return (buffer_size <= BUFFER_SIZE_MAX);
  190. }
  191. static inline void WaitGraphChange()
  192. {
  193. if (GetGraphManager()->IsPendingChange()) {
  194. JackLog("WaitGraphChange...\n");
  195. JackSleep(GetEngineControl()->fPeriodUsecs * 2);
  196. }
  197. }
  198. static void default_jack_error_callback(const char *desc)
  199. {
  200. fprintf(stderr, "%s\n", desc);
  201. }
  202. void (*jack_error_callback)(const char *desc) = &default_jack_error_callback;
  203. EXPORT void jack_set_error_function (void (*func)(const char *))
  204. {
  205. jack_error_callback = func;
  206. }
  207. EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
  208. {
  209. jack_port_id_t myport = (jack_port_id_t)port;
  210. if (!CheckPort(myport)) {
  211. jack_error("jack_port_get_buffer called with an incorrect port %ld", myport);
  212. return NULL;
  213. } else {
  214. return GetGraphManager()->GetBuffer(myport, frames);
  215. }
  216. }
  217. EXPORT const char* jack_port_name(const jack_port_t* port)
  218. {
  219. jack_port_id_t myport = (jack_port_id_t)port;
  220. if (!CheckPort(myport)) {
  221. jack_error("jack_port_name called with an incorrect port %ld", myport);
  222. return NULL;
  223. } else {
  224. return GetGraphManager()->GetPort(myport)->GetName();
  225. }
  226. }
  227. EXPORT const char* jack_port_short_name(const jack_port_t* port)
  228. {
  229. jack_port_id_t myport = (jack_port_id_t)port;
  230. if (!CheckPort(myport)) {
  231. jack_error("jack_port_short_name called with an incorrect port %ld", myport);
  232. return NULL;
  233. } else {
  234. return GetGraphManager()->GetPort(myport)->GetShortName();
  235. }
  236. }
  237. EXPORT int jack_port_flags(const jack_port_t* port)
  238. {
  239. jack_port_id_t myport = (jack_port_id_t)port;
  240. if (!CheckPort(myport)) {
  241. jack_error("jack_port_flags called with an incorrect port %ld", myport);
  242. return -1;
  243. } else {
  244. return GetGraphManager()->GetPort(myport)->Flags();
  245. }
  246. }
  247. EXPORT const char* jack_port_type(const jack_port_t* port)
  248. {
  249. jack_port_id_t myport = (jack_port_id_t)port;
  250. if (!CheckPort(myport)) {
  251. jack_error("jack_port_flags called an incorrect port %ld", myport);
  252. return NULL;
  253. } else {
  254. return GetGraphManager()->GetPort(myport)->Type();
  255. }
  256. }
  257. EXPORT int jack_port_connected(const jack_port_t* port)
  258. {
  259. jack_port_id_t myport = (jack_port_id_t)port;
  260. if (!CheckPort(myport)) {
  261. jack_error("jack_port_connected called with an incorrect port %ld", myport);
  262. return -1;
  263. } else {
  264. WaitGraphChange();
  265. return GetGraphManager()->GetConnectionsNum(myport);
  266. }
  267. }
  268. EXPORT int jack_port_connected_to(const jack_port_t* port, const char* portname)
  269. {
  270. jack_port_id_t myport = (jack_port_id_t)port;
  271. if (!CheckPort(myport)) {
  272. jack_error("jack_port_connected_to called with an incorrect port %ld", myport);
  273. return -1;
  274. } else if (portname == NULL) {
  275. jack_error("jack_port_connected_to called with a NULL port name");
  276. return -1;
  277. } else {
  278. WaitGraphChange();
  279. return GetGraphManager()->ConnectedTo(myport, portname);
  280. }
  281. }
  282. EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst)
  283. {
  284. jack_port_id_t mysrc = (jack_port_id_t)src;
  285. if (!CheckPort(mysrc)) {
  286. jack_error("jack_port_tie called with a NULL src port");
  287. return -1;
  288. }
  289. jack_port_id_t mydst = (jack_port_id_t)dst;
  290. if (!CheckPort(mydst)) {
  291. jack_error("jack_port_tie called with a NULL dst port");
  292. return -1;
  293. }
  294. if (GetGraphManager()->GetPort(mysrc)->GetRefNum() != GetGraphManager()->GetPort(mydst)->GetRefNum()) {
  295. jack_error("jack_port_tie called with ports not belonging to the same client");
  296. return -1;
  297. }
  298. return GetGraphManager()->GetPort(mydst)->Tie(mysrc);
  299. }
  300. EXPORT int jack_port_untie(jack_port_t* port)
  301. {
  302. jack_port_id_t myport = (jack_port_id_t)port;
  303. if (!CheckPort(myport)) {
  304. jack_error("jack_port_untie called with an incorrect port %ld", myport);
  305. return -1;
  306. } else {
  307. return GetGraphManager()->GetPort(myport)->UnTie();
  308. }
  309. }
  310. EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port)
  311. {
  312. jack_port_id_t myport = (jack_port_id_t)port;
  313. if (!CheckPort(myport)) {
  314. jack_error("jack_port_get_latency called with an incorrect port %ld", myport);
  315. return 0;
  316. } else {
  317. WaitGraphChange();
  318. return GetGraphManager()->GetPort(myport)->GetLatency();
  319. }
  320. }
  321. EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames)
  322. {
  323. jack_port_id_t myport = (jack_port_id_t)port;
  324. if (!CheckPort(myport)) {
  325. jack_error("jack_port_set_latency called with an incorrect port %ld", myport);
  326. } else {
  327. GetGraphManager()->GetPort(myport)->SetLatency(frames);
  328. }
  329. }
  330. EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client)
  331. {
  332. // The latency computation is done each time jack_port_get_total_latency is called
  333. return 0;
  334. }
  335. EXPORT int jack_port_set_name(jack_port_t* port, const char* name)
  336. {
  337. jack_port_id_t myport = (jack_port_id_t)port;
  338. if (!CheckPort(myport)) {
  339. jack_error("jack_port_set_name called with an incorrect port %ld", myport);
  340. return -1;
  341. } else if (name == NULL) {
  342. jack_error("jack_port_set_name called with a NULL port name");
  343. return -1;
  344. } else {
  345. return GetGraphManager()->GetPort(myport)->SetName(name);
  346. }
  347. }
  348. EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff)
  349. {
  350. jack_port_id_t myport = (jack_port_id_t)port;
  351. if (!CheckPort(myport)) {
  352. jack_error("jack_port_request_monitor called with an incorrect port %ld", myport);
  353. return -1;
  354. } else {
  355. return GetGraphManager()->RequestMonitor(myport, onoff);
  356. }
  357. }
  358. EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff)
  359. {
  360. JackClient* client = (JackClient*)ext_client;
  361. if (client == NULL) {
  362. jack_error("jack_port_request_monitor_by_name called with a NULL client");
  363. return -1;
  364. } else {
  365. jack_port_id_t myport = GetGraphManager()->GetPort(port_name);
  366. if (!CheckPort(myport)) {
  367. jack_error("jack_port_request_monitor_by_name called with an incorrect port %s", port_name);
  368. return -1;
  369. } else {
  370. return GetGraphManager()->RequestMonitor(myport, onoff);
  371. }
  372. }
  373. }
  374. EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff)
  375. {
  376. jack_port_id_t myport = (jack_port_id_t)port;
  377. if (!CheckPort(myport)) {
  378. jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport);
  379. return -1;
  380. } else {
  381. return GetGraphManager()->GetPort(myport)->EnsureMonitor(onoff);
  382. }
  383. }
  384. EXPORT int jack_port_monitoring_input(jack_port_t* port)
  385. {
  386. jack_port_id_t myport = (jack_port_id_t)port;
  387. if (!CheckPort(myport)) {
  388. jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport);
  389. return -1;
  390. } else {
  391. return GetGraphManager()->GetPort(myport)->MonitoringInput();
  392. }
  393. }
  394. EXPORT int jack_is_realtime(jack_client_t* ext_client)
  395. {
  396. JackClient* client = (JackClient*)ext_client;
  397. if (client == NULL) {
  398. jack_error("jack_is_realtime called with a NULL client");
  399. return -1;
  400. } else {
  401. return GetEngineControl()->fRealTime;
  402. }
  403. }
  404. EXPORT void jack_on_shutdown(jack_client_t* ext_client, void (*function)(void* arg), void* arg)
  405. {
  406. JackClient* client = (JackClient*)ext_client;
  407. if (client == NULL) {
  408. jack_error("jack_on_shutdown called with a NULL client");
  409. } else {
  410. client->OnShutdown(function, arg);
  411. }
  412. }
  413. EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg)
  414. {
  415. JackClient* client = (JackClient*)ext_client;
  416. if (client == NULL) {
  417. jack_error("jack_set_process_callback called with a NULL client");
  418. return -1;
  419. } else {
  420. return client->SetProcessCallback(callback, arg);
  421. }
  422. }
  423. EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg)
  424. {
  425. JackClient* client = (JackClient*)ext_client;
  426. if (client == NULL) {
  427. jack_error("jack_set_freewheel_callback called with a NULL client");
  428. return -1;
  429. } else {
  430. return client->SetFreewheelCallback(freewheel_callback, arg);
  431. }
  432. }
  433. EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff)
  434. {
  435. JackClient* client = (JackClient*)ext_client;
  436. if (client == NULL) {
  437. jack_error("jack_set_freewheel called with a NULL client");
  438. return -1;
  439. } else {
  440. return client->SetFreeWheel(onoff);
  441. }
  442. }
  443. EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size)
  444. {
  445. JackClient* client = (JackClient*)ext_client;
  446. if (client == NULL) {
  447. jack_error("jack_set_buffer_size called with a NULL client");
  448. return -1;
  449. } else if (!CheckBufferSize(buffer_size)) {
  450. return -1;
  451. } else {
  452. return client->SetBufferSize(buffer_size);
  453. }
  454. }
  455. EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg)
  456. {
  457. JackClient* client = (JackClient*)ext_client;
  458. if (client == NULL) {
  459. jack_error("jack_set_buffer_size_callback called with a NULL client");
  460. return -1;
  461. } else {
  462. return client->SetBufferSizeCallback(bufsize_callback, arg);
  463. }
  464. }
  465. EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg)
  466. {
  467. JackClient* client = (JackClient*)ext_client;
  468. JackLog("jack_set_sample_rate_callback ext_client %x client %x \n", ext_client, client);
  469. if (client == NULL) {
  470. jack_error("jack_set_sample_rate_callback called with a NULL client");
  471. return -1;
  472. } else {
  473. JackLog("jack_set_sample_rate_callback: deprecated\n");
  474. return -1;
  475. }
  476. }
  477. EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg)
  478. {
  479. JackClient* client = (JackClient*)ext_client;
  480. if (client == NULL) {
  481. jack_error("jack_set_port_registration_callback called with a NULL client");
  482. return -1;
  483. } else {
  484. return client->SetPortRegistrationCallback(registration_callback, arg);
  485. }
  486. }
  487. EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrderCallback graph_callback, void* arg)
  488. {
  489. JackClient* client = (JackClient*)ext_client;
  490. JackLog("jack_set_graph_order_callback ext_client %x client %x \n", ext_client, client);
  491. if (client == NULL) {
  492. jack_error("jack_set_graph_order_callback called with a NULL client");
  493. return -1;
  494. } else {
  495. return client->SetGraphOrderCallback(graph_callback, arg);
  496. }
  497. }
  498. EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback callback, void* arg)
  499. {
  500. JackClient* client = (JackClient*)ext_client;
  501. if (client == NULL) {
  502. jack_error("jack_set_xrun_callback called with a NULL client");
  503. return -1;
  504. } else {
  505. return client->SetXRunCallback(callback, arg);
  506. }
  507. }
  508. EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback callback, void *arg)
  509. {
  510. JackClient* client = (JackClient*)ext_client;
  511. JackLog("jack_set_thread_init_callback ext_client %x client %x \n", ext_client, client);
  512. if (client == NULL) {
  513. jack_error("jack_set_thread_init_callback called with a NULL client");
  514. return -1;
  515. } else {
  516. return client->SetInitCallback(callback, arg);
  517. }
  518. }
  519. EXPORT int jack_activate(jack_client_t* ext_client)
  520. {
  521. JackClient* client = (JackClient*)ext_client;
  522. if (client == NULL) {
  523. jack_error("jack_activate called with a NULL client");
  524. return -1;
  525. } else {
  526. return client->Activate();
  527. }
  528. }
  529. EXPORT int jack_deactivate(jack_client_t* ext_client)
  530. {
  531. JackClient* client = (JackClient*)ext_client;
  532. if (client == NULL) {
  533. jack_error("jack_deactivate called with a NULL client");
  534. return -1;
  535. } else {
  536. return client->Deactivate();
  537. }
  538. }
  539. 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)
  540. {
  541. JackClient* client = (JackClient*)ext_client;
  542. if (client == NULL) {
  543. jack_error("jack_port_register called with a NULL client");
  544. return NULL;
  545. } else if ((port_name == NULL) || (port_type == NULL)) {
  546. jack_error("jack_port_register called with a NULL port name or a NULL port_type");
  547. return NULL;
  548. } else {
  549. return (jack_port_t *)client->PortRegister(port_name, port_type, flags, buffer_size);
  550. }
  551. }
  552. EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port)
  553. {
  554. JackClient* client = (JackClient*)ext_client;
  555. if (client == NULL) {
  556. jack_error("jack_port_unregister called with a NULL client");
  557. return -1;
  558. }
  559. jack_port_id_t myport = (jack_port_id_t)port;
  560. if (!CheckPort(myport)) {
  561. jack_error("jack_port_unregister called with an incorrect port %ld", myport);
  562. return -1;
  563. }
  564. return client->PortUnRegister(myport);
  565. }
  566. EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* port)
  567. {
  568. JackClient* client = (JackClient*)ext_client;
  569. if (client == NULL) {
  570. jack_error("jack_port_is_mine called with a NULL client");
  571. return -1;
  572. }
  573. jack_port_id_t myport = (jack_port_id_t)port;
  574. if (!CheckPort(myport)) {
  575. jack_error("jack_port_is_mine called with an incorrect port %ld", myport);
  576. return -1;
  577. }
  578. return client->PortIsMine(myport);
  579. }
  580. EXPORT const char** jack_port_get_connections(const jack_port_t* port)
  581. {
  582. jack_port_id_t myport = (jack_port_id_t)port;
  583. if (!CheckPort(myport)) {
  584. jack_error("jack_port_get_connections called with an incorrect port %ld", myport);
  585. return NULL;
  586. } else {
  587. WaitGraphChange();
  588. return GetGraphManager()->GetConnections(myport);
  589. }
  590. }
  591. // Calling client does not need to "own" the port
  592. EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_client, const jack_port_t* port)
  593. {
  594. JackClient* client = (JackClient*)ext_client;
  595. if (client == NULL) {
  596. jack_error("jack_port_get_all_connections called with a NULL client");
  597. return NULL;
  598. }
  599. jack_port_id_t myport = (jack_port_id_t)port;
  600. if (!CheckPort(myport)) {
  601. jack_error("jack_port_get_all_connections called with an incorrect port %ld", myport);
  602. return NULL;
  603. } else {
  604. WaitGraphChange();
  605. return GetGraphManager()->GetConnections(myport);
  606. }
  607. }
  608. // Does not use the client parameter
  609. EXPORT int jack_port_lock(jack_client_t* ext_client, jack_port_t* port)
  610. {
  611. JackClient* client = (JackClient*)ext_client;
  612. if (client == NULL) {
  613. jack_error("jack_port_lock called with a NULL client");
  614. return -1;
  615. }
  616. jack_port_id_t myport = (jack_port_id_t)port;
  617. if (!CheckPort(myport)) {
  618. jack_error("jack_port_lock called with an incorrect port %ld", myport);
  619. return -1;
  620. } else {
  621. return (myport && client->PortIsMine(myport)) ? GetGraphManager()->GetPort(myport)->Lock() : -1;
  622. }
  623. }
  624. // Does not use the client parameter
  625. EXPORT int jack_port_unlock(jack_client_t* ext_client, jack_port_t* port)
  626. {
  627. JackClient* client = (JackClient*)ext_client;
  628. if (client == NULL) {
  629. jack_error("jack_port_unlock called with a NULL client");
  630. return -1;
  631. }
  632. jack_port_id_t myport = (jack_port_id_t)port;
  633. if (!CheckPort(myport)) {
  634. jack_error("jack_port_unlock called with an incorrect port %ld", myport);
  635. return -1;
  636. } else {
  637. return (myport && client->PortIsMine(myport)) ? GetGraphManager()->GetPort(myport)->Unlock() : -1;
  638. }
  639. }
  640. EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jack_port_t* port)
  641. {
  642. JackClient* client = (JackClient*)ext_client;
  643. if (client == NULL) {
  644. jack_error("jack_port_get_total_latency called with a NULL client");
  645. return 0;
  646. }
  647. jack_port_id_t myport = (jack_port_id_t)port;
  648. if (!CheckPort(myport)) {
  649. jack_error("jack_port_get_total_latency called with an incorrect port %ld", myport);
  650. return 0;
  651. } else {
  652. // The latency computation is done each time
  653. WaitGraphChange();
  654. return GetGraphManager()->GetTotalLatency(myport);
  655. }
  656. }
  657. EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* dst)
  658. {
  659. JackClient* client = (JackClient*)ext_client;
  660. if (client == NULL) {
  661. jack_error("jack_connect called with a NULL client");
  662. return -1;
  663. } else if ((src == NULL) || (dst == NULL)) {
  664. jack_error("jack_connect called with a NULL port name");
  665. return -1;
  666. } else {
  667. return client->PortConnect(src, dst);
  668. }
  669. }
  670. EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const char* dst)
  671. {
  672. JackClient* client = (JackClient*)ext_client;
  673. if (client == NULL) {
  674. jack_error("jack_disconnect called with a NULL client");
  675. return -1;
  676. } else if ((src == NULL) || (dst == NULL)) {
  677. jack_error("jack_connect called with a NULL port name");
  678. return -1;
  679. } else {
  680. return client->PortDisconnect(src, dst);
  681. }
  682. }
  683. EXPORT int jack_port_connect(jack_client_t* ext_client, jack_port_t* src, jack_port_t* dst)
  684. {
  685. JackClient* client = (JackClient*)ext_client;
  686. if (client == NULL) {
  687. jack_error("jack_port_connect called with a NULL client");
  688. return -1;
  689. }
  690. jack_port_id_t mysrc = (jack_port_id_t)src;
  691. if (!CheckPort(mysrc)) {
  692. jack_error("jack_port_connect called with a NULL src port");
  693. return -1;
  694. }
  695. jack_port_id_t mydst = (jack_port_id_t)dst;
  696. if (!CheckPort(mydst)) {
  697. jack_error("jack_port_connect called with a NULL dst port");
  698. return -1;
  699. }
  700. return client->PortConnect(mysrc, mydst);
  701. }
  702. EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src)
  703. {
  704. JackClient* client = (JackClient*)ext_client;
  705. if (client == NULL) {
  706. jack_error("jack_port_disconnect called with a NULL client");
  707. return -1;
  708. }
  709. jack_port_id_t myport = (jack_port_id_t)src;
  710. if (!CheckPort(myport)) {
  711. jack_error("jack_port_disconnect called with an incorrect port %ld", myport);
  712. return -1;
  713. }
  714. return client->PortDisconnect(myport);
  715. }
  716. EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client)
  717. {
  718. JackClient* client = (JackClient*)ext_client;
  719. if (client == NULL) {
  720. jack_error("jack_get_sample_rate called with a NULL client");
  721. return 0;
  722. } else {
  723. return GetEngineControl()->fSampleRate;
  724. }
  725. }
  726. EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client)
  727. {
  728. JackClient* client = (JackClient*)ext_client;
  729. if (client == NULL) {
  730. jack_error("jack_get_buffer_size called with a NULL client");
  731. return 0;
  732. } else {
  733. return GetEngineControl()->fBufferSize;
  734. }
  735. }
  736. EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
  737. {
  738. JackClient* client = (JackClient*)ext_client;
  739. if (client == NULL) {
  740. jack_error("jack_get_ports called with a NULL client");
  741. return NULL;
  742. }
  743. return GetGraphManager()->GetPorts(port_name_pattern, type_name_pattern, flags);
  744. }
  745. EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* portname)
  746. {
  747. JackClient* client = (JackClient*)ext_client;
  748. if (client == NULL) {
  749. jack_error("jack_get_ports called with a NULL client");
  750. return 0;
  751. }
  752. if (portname == NULL) {
  753. jack_error("jack_port_by_name called with a NULL port name");
  754. return NULL;
  755. } else {
  756. int res = GetGraphManager()->GetPort(portname); // returns a port index at least > 1
  757. return (res == NO_PORT) ? NULL : (jack_port_t*)res;
  758. }
  759. }
  760. EXPORT jack_port_t* jack_port_by_id(const jack_client_t* ext_client, jack_port_id_t id)
  761. {
  762. /* jack_port_t* type is actually the port index */
  763. return (jack_port_t*)id;
  764. }
  765. EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client)
  766. {
  767. JackClient* client = (JackClient*)ext_client;
  768. if (client == NULL) {
  769. jack_error("jack_engine_takeover_timebase called with a NULL client");
  770. return -1;
  771. } else {
  772. jack_error("jack_engine_takeover_timebase : not yet implemented\n");
  773. return 0;
  774. }
  775. }
  776. EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_client)
  777. {
  778. JackTimer timer;
  779. GetEngineControl()->fFrameTimer.ReadFrameTime(&timer);
  780. return (jack_nframes_t) floor((((float)GetEngineControl()->fSampleRate) / 1000000.0f) * (GetMicroSeconds() - timer.fCurrentCallback));
  781. }
  782. EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client)
  783. {
  784. JackClient* client = (JackClient*)ext_client;
  785. if (client == NULL) {
  786. jack_error("jack_frame_time called with a NULL client");
  787. return 0;
  788. } else {
  789. JackTimer timer;
  790. GetEngineControl()->fFrameTimer.ReadFrameTime(&timer);
  791. if (timer.fInitialized) {
  792. return timer.fFrames +
  793. (long) rint(((double) ((jack_time_t)(GetMicroSeconds() - timer.fCurrentWakeup)) /
  794. ((jack_time_t)(timer.fNextWakeUp - timer.fCurrentWakeup))) * GetEngineControl()->fBufferSize);
  795. } else {
  796. return 0;
  797. }
  798. }
  799. }
  800. EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client)
  801. {
  802. JackTimer timer;
  803. GetEngineControl()->fFrameTimer.ReadFrameTime(&timer);
  804. return timer.fFrames;
  805. }
  806. EXPORT float jack_cpu_load(jack_client_t* ext_client)
  807. {
  808. JackClient* client = (JackClient*)ext_client;
  809. if (client == NULL) {
  810. jack_error("jack_cpu_load called with a NULL client");
  811. return 0.0f;
  812. } else {
  813. return GetEngineControl()->fCPULoad;
  814. }
  815. }
  816. pthread_t EXPORT jack_client_thread_id(jack_client_t* ext_client)
  817. {
  818. JackClient* client = (JackClient*)ext_client;
  819. if (client == NULL) {
  820. jack_error("jack_client_thread_id called with a NULL client");
  821. return (pthread_t)NULL;
  822. } else {
  823. return client->GetThreadID();
  824. }
  825. }
  826. EXPORT char* jack_get_client_name (jack_client_t* ext_client)
  827. {
  828. JackClient* client = (JackClient*)ext_client;
  829. if (client == NULL) {
  830. jack_error("jack_get_client_name called with a NULL client");
  831. return NULL;
  832. } else {
  833. return client->GetClientControl()->fName;
  834. }
  835. }
  836. EXPORT int jack_client_name_size(void)
  837. {
  838. return JACK_CLIENT_NAME_SIZE;
  839. }
  840. EXPORT int jack_port_name_size(void)
  841. {
  842. return JACK_PORT_NAME_SIZE;
  843. }
  844. // transport.h
  845. EXPORT int jack_release_timebase(jack_client_t* ext_client)
  846. {
  847. JackClient* client = (JackClient*)ext_client;
  848. if (client == NULL) {
  849. jack_error("jack_release_timebase called with a NULL client");
  850. return -1;
  851. } else {
  852. return client->ReleaseTimebase();
  853. }
  854. }
  855. EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg)
  856. {
  857. JackClient* client = (JackClient*)ext_client;
  858. if (client == NULL) {
  859. jack_error("jack_set_sync_callback called with a NULL client");
  860. return -1;
  861. } else {
  862. return client->SetSyncCallback(sync_callback, arg);
  863. }
  864. }
  865. EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout)
  866. {
  867. JackClient* client = (JackClient*)ext_client;
  868. if (client == NULL) {
  869. jack_error("jack_set_sync_timeout called with a NULL client");
  870. return -1;
  871. } else {
  872. return client->SetSyncTimeout(timeout);
  873. }
  874. }
  875. EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg)
  876. {
  877. JackClient* client = (JackClient*)ext_client;
  878. if (client == NULL) {
  879. jack_error("jack_set_timebase_callback called with a NULL client");
  880. return -1;
  881. } else {
  882. return client->SetTimebaseCallback(conditional, timebase_callback, arg);
  883. }
  884. }
  885. EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame)
  886. {
  887. JackClient* client = (JackClient*)ext_client;
  888. if (client == NULL) {
  889. jack_error("jack_transport_locate called with a NULL client");
  890. return -1;
  891. } else {
  892. return client->TransportLocate(frame);
  893. }
  894. }
  895. EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos)
  896. {
  897. JackClient* client = (JackClient*)ext_client;
  898. if (client == NULL) {
  899. jack_error("jack_transport_query called with a NULL client");
  900. return JackTransportStopped;
  901. } else {
  902. return client->TransportQuery(pos);
  903. }
  904. }
  905. EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client)
  906. {
  907. JackClient* client = (JackClient*)ext_client;
  908. if (client == NULL) {
  909. jack_error("jack_get_current_transport_frame called with a NULL client");
  910. return 0;
  911. } else {
  912. return client->GetCurrentTransportFrame();
  913. }
  914. }
  915. EXPORT int jack_transport_reposition(jack_client_t* ext_client, jack_position_t* pos)
  916. {
  917. JackClient* client = (JackClient*)ext_client;
  918. if (client == NULL) {
  919. jack_error("jack_transport_reposition called with a NULL client");
  920. return -1;
  921. } else {
  922. return client->TransportReposition(pos);
  923. }
  924. }
  925. EXPORT void jack_transport_start(jack_client_t* ext_client)
  926. {
  927. JackClient* client = (JackClient*)ext_client;
  928. if (client == NULL) {
  929. jack_error("jack_transport_start called with a NULL client");
  930. } else {
  931. client->TransportStart();
  932. }
  933. }
  934. EXPORT void jack_transport_stop(jack_client_t* ext_client)
  935. {
  936. JackClient* client = (JackClient*)ext_client;
  937. if (client == NULL) {
  938. jack_error("jack_transport_stop called with a NULL client");
  939. } else {
  940. client->TransportStop();
  941. }
  942. }
  943. // deprecated
  944. EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
  945. {
  946. JackLog("jack_get_transport_info : deprecated");
  947. if (tinfo)
  948. memset(tinfo, 0, sizeof(jack_transport_info_t));
  949. }
  950. EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
  951. {
  952. JackLog("jack_set_transport_info : deprecated");
  953. if (tinfo)
  954. memset(tinfo, 0, sizeof(jack_transport_info_t));
  955. }
  956. // statistics.h
  957. EXPORT float jack_get_max_delayed_usecs(jack_client_t* client)
  958. {
  959. JackLog("jack_get_max_delayed_usecs: not yet implemented\n");
  960. return 0.f;
  961. }
  962. EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* client)
  963. {
  964. JackLog("jack_get_xrun_delayed_usecs: not yet implemented\n");
  965. return 0.f;
  966. }
  967. EXPORT void jack_reset_max_delayed_usecs(jack_client_t* client)
  968. {
  969. JackLog("jack_reset_max_delayed_usecs: not yet implemented\n");
  970. }
  971. // thread.h
  972. EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority)
  973. {
  974. JackLog("jack_acquire_real_time_scheduling: not yet implemented\n");
  975. return -1;
  976. }
  977. EXPORT int jack_client_create_thread(jack_client_t* client,
  978. pthread_t *thread,
  979. int priority,
  980. int realtime, /* boolean */
  981. void *(*start_routine)(void*),
  982. void *arg)
  983. {
  984. JackLog("jack_client_create_thread: not yet implemented\n");
  985. return -1;
  986. }
  987. EXPORT int jack_drop_real_time_scheduling(pthread_t thread)
  988. {
  989. JackLog("jack_drop_real_time_scheduling: not yet implemented\n");
  990. return -1;
  991. }
  992. // intclient.h
  993. EXPORT char* jack_get_internal_client_name(jack_client_t* client, jack_intclient_t intclient)
  994. {
  995. JackLog("jack_get_internal_client_name: not yet implemented\n");
  996. return "";
  997. }
  998. EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* client, const char* client_name, jack_status_t* status)
  999. {
  1000. JackLog("jack_internal_client_handle: not yet implemented\n");
  1001. return 0;
  1002. }
  1003. EXPORT jack_intclient_t jack_internal_client_load(jack_client_t* client, const char* client_name, jack_options_t options, jack_status_t* status, ...)
  1004. {
  1005. JackLog("jack_internal_client_load: not yet implemented\n");
  1006. return 0;
  1007. }
  1008. EXPORT jack_status_t jack_internal_client_unload(jack_client_t* client, jack_intclient_t intclient)
  1009. {
  1010. JackLog("jack_internal_client_unload: not yet implemented\n");
  1011. return JackFailure;
  1012. }