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.

1125 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 xrun_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(xrun_callback, arg);
  506. }
  507. }
  508. EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_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(init_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. GetEngineControl()->ReadFrameTime(&timer);
  781. return (jack_nframes_t) floor((((float)GetEngineControl()->fSampleRate) / 1000000.0f) * (GetMicroSeconds() - timer.fCurrentCallback));
  782. }
  783. EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client)
  784. {
  785. JackClient* client = (JackClient*)ext_client;
  786. if (client == NULL) {
  787. jack_error("jack_frame_time called with a NULL client");
  788. return 0;
  789. } else {
  790. JackTimer timer;
  791. //GetEngineControl()->fFrameTimer.ReadFrameTime(&timer);
  792. GetEngineControl()->ReadFrameTime(&timer);
  793. if (timer.fInitialized) {
  794. return timer.fFrames +
  795. (long) rint(((double) ((jack_time_t)(GetMicroSeconds() - timer.fCurrentWakeup)) /
  796. ((jack_time_t)(timer.fNextWakeUp - timer.fCurrentWakeup))) * GetEngineControl()->fBufferSize);
  797. } else {
  798. return 0;
  799. }
  800. }
  801. }
  802. EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client)
  803. {
  804. JackTimer timer;
  805. //GetEngineControl()->fFrameTimer.ReadFrameTime(&timer);
  806. GetEngineControl()->ReadFrameTime(&timer);
  807. return timer.fFrames;
  808. }
  809. EXPORT float jack_cpu_load(jack_client_t* ext_client)
  810. {
  811. JackClient* client = (JackClient*)ext_client;
  812. if (client == NULL) {
  813. jack_error("jack_cpu_load called with a NULL client");
  814. return 0.0f;
  815. } else {
  816. return GetEngineControl()->fCPULoad;
  817. }
  818. }
  819. EXPORT pthread_t jack_client_thread_id(jack_client_t* ext_client)
  820. {
  821. JackClient* client = (JackClient*)ext_client;
  822. if (client == NULL) {
  823. jack_error("jack_client_thread_id called with a NULL client");
  824. return (pthread_t)NULL;
  825. } else {
  826. return client->GetThreadID();
  827. }
  828. }
  829. EXPORT char* jack_get_client_name (jack_client_t* ext_client)
  830. {
  831. JackClient* client = (JackClient*)ext_client;
  832. if (client == NULL) {
  833. jack_error("jack_get_client_name called with a NULL client");
  834. return NULL;
  835. } else {
  836. return client->GetClientControl()->fName;
  837. }
  838. }
  839. EXPORT int jack_client_name_size(void)
  840. {
  841. return JACK_CLIENT_NAME_SIZE;
  842. }
  843. EXPORT int jack_port_name_size(void)
  844. {
  845. return JACK_PORT_NAME_SIZE;
  846. }
  847. // transport.h
  848. EXPORT int jack_release_timebase(jack_client_t* ext_client)
  849. {
  850. JackClient* client = (JackClient*)ext_client;
  851. if (client == NULL) {
  852. jack_error("jack_release_timebase called with a NULL client");
  853. return -1;
  854. } else {
  855. return client->ReleaseTimebase();
  856. }
  857. }
  858. EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg)
  859. {
  860. JackClient* client = (JackClient*)ext_client;
  861. if (client == NULL) {
  862. jack_error("jack_set_sync_callback called with a NULL client");
  863. return -1;
  864. } else {
  865. return client->SetSyncCallback(sync_callback, arg);
  866. }
  867. }
  868. EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout)
  869. {
  870. JackClient* client = (JackClient*)ext_client;
  871. if (client == NULL) {
  872. jack_error("jack_set_sync_timeout called with a NULL client");
  873. return -1;
  874. } else {
  875. return client->SetSyncTimeout(timeout);
  876. }
  877. }
  878. EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg)
  879. {
  880. JackClient* client = (JackClient*)ext_client;
  881. if (client == NULL) {
  882. jack_error("jack_set_timebase_callback called with a NULL client");
  883. return -1;
  884. } else {
  885. return client->SetTimebaseCallback(conditional, timebase_callback, arg);
  886. }
  887. }
  888. EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame)
  889. {
  890. JackClient* client = (JackClient*)ext_client;
  891. if (client == NULL) {
  892. jack_error("jack_transport_locate called with a NULL client");
  893. return -1;
  894. } else {
  895. return client->TransportLocate(frame);
  896. }
  897. }
  898. EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos)
  899. {
  900. JackClient* client = (JackClient*)ext_client;
  901. if (client == NULL) {
  902. jack_error("jack_transport_query called with a NULL client");
  903. return JackTransportStopped;
  904. } else {
  905. return client->TransportQuery(pos);
  906. }
  907. }
  908. EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client)
  909. {
  910. JackClient* client = (JackClient*)ext_client;
  911. if (client == NULL) {
  912. jack_error("jack_get_current_transport_frame called with a NULL client");
  913. return 0;
  914. } else {
  915. return client->GetCurrentTransportFrame();
  916. }
  917. }
  918. EXPORT int jack_transport_reposition(jack_client_t* ext_client, jack_position_t* pos)
  919. {
  920. JackClient* client = (JackClient*)ext_client;
  921. if (client == NULL) {
  922. jack_error("jack_transport_reposition called with a NULL client");
  923. return -1;
  924. } else {
  925. return client->TransportReposition(pos);
  926. }
  927. }
  928. EXPORT void jack_transport_start(jack_client_t* ext_client)
  929. {
  930. JackClient* client = (JackClient*)ext_client;
  931. if (client == NULL) {
  932. jack_error("jack_transport_start called with a NULL client");
  933. } else {
  934. client->TransportStart();
  935. }
  936. }
  937. EXPORT void jack_transport_stop(jack_client_t* ext_client)
  938. {
  939. JackClient* client = (JackClient*)ext_client;
  940. if (client == NULL) {
  941. jack_error("jack_transport_stop called with a NULL client");
  942. } else {
  943. client->TransportStop();
  944. }
  945. }
  946. // deprecated
  947. EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
  948. {
  949. JackLog("jack_get_transport_info : deprecated");
  950. if (tinfo)
  951. memset(tinfo, 0, sizeof(jack_transport_info_t));
  952. }
  953. EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
  954. {
  955. JackLog("jack_set_transport_info : deprecated");
  956. if (tinfo)
  957. memset(tinfo, 0, sizeof(jack_transport_info_t));
  958. }
  959. // statistics.h
  960. EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client)
  961. {
  962. JackLog("jack_get_max_delayed_usecs: not yet implemented\n");
  963. return 0.f;
  964. }
  965. EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client)
  966. {
  967. JackLog("jack_get_xrun_delayed_usecs: not yet implemented\n");
  968. return 0.f;
  969. }
  970. EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client)
  971. {
  972. JackLog("jack_reset_max_delayed_usecs: not yet implemented\n");
  973. }
  974. // thread.h
  975. EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority)
  976. {
  977. JackLog("jack_acquire_real_time_scheduling: not yet implemented\n");
  978. return -1;
  979. }
  980. EXPORT int jack_client_create_thread(jack_client_t* client,
  981. pthread_t *thread,
  982. int priority,
  983. int realtime, /* boolean */
  984. void *(*start_routine)(void*),
  985. void *arg)
  986. {
  987. JackLog("jack_client_create_thread: not yet implemented\n");
  988. return -1;
  989. }
  990. EXPORT int jack_drop_real_time_scheduling(pthread_t thread)
  991. {
  992. JackLog("jack_drop_real_time_scheduling: not yet implemented\n");
  993. return -1;
  994. }
  995. // intclient.h
  996. EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient)
  997. {
  998. JackLog("jack_get_internal_client_name: not yet implemented\n");
  999. return "";
  1000. }
  1001. EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, const char* client_name, jack_status_t* status)
  1002. {
  1003. JackLog("jack_internal_client_handle: not yet implemented\n");
  1004. return 0;
  1005. }
  1006. 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, ...)
  1007. {
  1008. JackLog("jack_internal_client_load: not yet implemented\n");
  1009. return 0;
  1010. }
  1011. EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack_intclient_t intclient)
  1012. {
  1013. JackLog("jack_internal_client_unload: not yet implemented\n");
  1014. return JackFailure;
  1015. }