Jack2  1.9.8
JackAPI.cpp
1 /*
2 Copyright (C) 2001-2003 Paul Davis
3 Copyright (C) 2004-2008 Grame
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14 
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 */
20 
21 #include "JackClient.h"
22 #include "JackError.h"
23 #include "JackGraphManager.h"
24 #include "JackEngineControl.h"
25 #include "JackClientControl.h"
26 #include "JackGlobals.h"
27 #include "JackTime.h"
28 #include "JackPortType.h"
29 #include <math.h>
30 
31 #ifdef __CLIENTDEBUG__
32 #include "JackLibGlobals.h"
33 #endif
34 
35 using namespace Jack;
36 
37 #ifdef __cplusplus
38 extern "C"
39 {
40 #endif
41 
42  typedef void (*print_function)(const char*);
43  typedef void *(*thread_routine)(void*);
44 
45  LIB_EXPORT
46  void
47  jack_get_version(
48  int *major_ptr,
49  int *minor_ptr,
50  int *micro_ptr,
51  int *proto_ptr);
52 
53  LIB_EXPORT
54  const char*
55  jack_get_version_string();
56 
57  jack_client_t * jack_client_new_aux(const char* client_name,
58  jack_options_t options,
59  jack_status_t *status);
60 
61  LIB_EXPORT jack_client_t * jack_client_open(const char* client_name,
62  jack_options_t options,
63  jack_status_t *status, ...);
64  LIB_EXPORT jack_client_t * jack_client_new(const char* client_name);
65  LIB_EXPORT int jack_client_name_size(void);
66  LIB_EXPORT char* jack_get_client_name(jack_client_t *client);
67  LIB_EXPORT int jack_internal_client_new(const char* client_name,
68  const char* load_name,
69  const char* load_init);
70  LIB_EXPORT void jack_internal_client_close(const char* client_name);
71  LIB_EXPORT int jack_is_realtime(jack_client_t *client);
72  LIB_EXPORT void jack_on_shutdown(jack_client_t *client,
73  JackShutdownCallback shutdown_callback, void *arg);
74  LIB_EXPORT void jack_on_info_shutdown(jack_client_t *client,
75  JackInfoShutdownCallback shutdown_callback, void *arg);
76  LIB_EXPORT int jack_set_process_callback(jack_client_t *client,
77  JackProcessCallback process_callback,
78  void *arg);
79  LIB_EXPORT jack_nframes_t jack_thread_wait(jack_client_t *client, int status);
80 
81  // new
82  LIB_EXPORT jack_nframes_t jack_cycle_wait(jack_client_t*);
83  LIB_EXPORT void jack_cycle_signal(jack_client_t*, int status);
84  LIB_EXPORT int jack_set_process_thread(jack_client_t* client, JackThreadCallback fun, void *arg);
85 
86  LIB_EXPORT int jack_set_thread_init_callback(jack_client_t *client,
87  JackThreadInitCallback thread_init_callback,
88  void *arg);
89  LIB_EXPORT int jack_set_freewheel_callback(jack_client_t *client,
90  JackFreewheelCallback freewheel_callback,
91  void *arg);
92  LIB_EXPORT int jack_set_freewheel(jack_client_t* client, int onoff);
93  LIB_EXPORT int jack_set_buffer_size(jack_client_t *client, jack_nframes_t nframes);
94  LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t *client,
95  JackBufferSizeCallback bufsize_callback,
96  void *arg);
97  LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t *client,
98  JackSampleRateCallback srate_callback,
99  void *arg);
100  LIB_EXPORT int jack_set_client_registration_callback(jack_client_t *,
101  JackClientRegistrationCallback
102  registration_callback, void *arg);
103  LIB_EXPORT int jack_set_port_registration_callback(jack_client_t *,
104  JackPortRegistrationCallback
105  registration_callback, void *arg);
106  LIB_EXPORT int jack_set_port_connect_callback(jack_client_t *,
107  JackPortConnectCallback
108  connect_callback, void *arg);
109  LIB_EXPORT int jack_set_port_rename_callback(jack_client_t *,
110  JackPortRenameCallback
111  rename_callback, void *arg);
112  LIB_EXPORT int jack_set_graph_order_callback(jack_client_t *,
113  JackGraphOrderCallback graph_callback,
114  void *);
115  LIB_EXPORT int jack_set_xrun_callback(jack_client_t *,
116  JackXRunCallback xrun_callback, void *arg);
117  LIB_EXPORT int jack_set_latency_callback(jack_client_t *client,
118  JackLatencyCallback latency_callback, void *arg);
119 
120  LIB_EXPORT int jack_activate(jack_client_t *client);
121  LIB_EXPORT int jack_deactivate(jack_client_t *client);
122  LIB_EXPORT jack_port_t * jack_port_register(jack_client_t *client,
123  const char* port_name,
124  const char* port_type,
125  unsigned long flags,
126  unsigned long buffer_size);
127  LIB_EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *);
128  LIB_EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t);
129  LIB_EXPORT const char* jack_port_name(const jack_port_t *port);
130  LIB_EXPORT const char* jack_port_short_name(const jack_port_t *port);
131  LIB_EXPORT int jack_port_flags(const jack_port_t *port);
132  LIB_EXPORT const char* jack_port_type(const jack_port_t *port);
133  LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port);
134  LIB_EXPORT int jack_port_is_mine(const jack_client_t *, const jack_port_t *port);
135  LIB_EXPORT int jack_port_connected(const jack_port_t *port);
136  LIB_EXPORT int jack_port_connected_to(const jack_port_t *port,
137  const char* port_name);
138  LIB_EXPORT const char* * jack_port_get_connections(const jack_port_t *port);
139  LIB_EXPORT const char* * jack_port_get_all_connections(const jack_client_t *client,
140  const jack_port_t *port);
141  LIB_EXPORT int jack_port_tie(jack_port_t *src, jack_port_t *dst);
142  LIB_EXPORT int jack_port_untie(jack_port_t *port);
143 
144  // Old latency API
145  LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t *port);
146  LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t *,
147  jack_port_t *port);
148  LIB_EXPORT void jack_port_set_latency(jack_port_t *, jack_nframes_t);
149  LIB_EXPORT int jack_recompute_total_latency(jack_client_t*, jack_port_t* port);
150 
151  // New latency API
152  LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range);
153  LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range);
154  LIB_EXPORT int jack_recompute_total_latencies(jack_client_t*);
155 
156  LIB_EXPORT int jack_port_set_name(jack_port_t *port, const char* port_name);
157  LIB_EXPORT int jack_port_set_alias(jack_port_t *port, const char* alias);
158  LIB_EXPORT int jack_port_unset_alias(jack_port_t *port, const char* alias);
159  LIB_EXPORT int jack_port_get_aliases(const jack_port_t *port, char* const aliases[2]);
160  LIB_EXPORT int jack_port_request_monitor(jack_port_t *port, int onoff);
161  LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t *client,
162  const char* port_name, int onoff);
163  LIB_EXPORT int jack_port_ensure_monitor(jack_port_t *port, int onoff);
164  LIB_EXPORT int jack_port_monitoring_input(jack_port_t *port);
165  LIB_EXPORT int jack_connect(jack_client_t *,
166  const char* source_port,
167  const char* destination_port);
168  LIB_EXPORT int jack_disconnect(jack_client_t *,
169  const char* source_port,
170  const char* destination_port);
171  LIB_EXPORT int jack_port_disconnect(jack_client_t *, jack_port_t *);
172  LIB_EXPORT int jack_port_name_size(void);
173  LIB_EXPORT int jack_port_type_size(void);
174  LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t *client, const char* port_type);
175  LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t *);
176  LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t *);
177  LIB_EXPORT const char* * jack_get_ports(jack_client_t *,
178  const char* port_name_pattern,
179  const char* type_name_pattern,
180  unsigned long flags);
181  LIB_EXPORT jack_port_t * jack_port_by_name(jack_client_t *, const char* port_name);
182  LIB_EXPORT jack_port_t * jack_port_by_id(jack_client_t *client,
183  jack_port_id_t port_id);
184  LIB_EXPORT int jack_engine_takeover_timebase(jack_client_t *);
185  LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t *);
186  LIB_EXPORT jack_time_t jack_get_time();
187  LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t time);
188  LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t frames);
189  LIB_EXPORT jack_nframes_t jack_frame_time(const jack_client_t *);
190  LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t *client);
191  LIB_EXPORT float jack_cpu_load(jack_client_t *client);
192  LIB_EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t *);
193  LIB_EXPORT void jack_set_error_function(print_function);
194  LIB_EXPORT void jack_set_info_function(print_function);
195 
196  LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t *client);
197  LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t *client);
198  LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t *client);
199 
200  LIB_EXPORT int jack_release_timebase(jack_client_t *client);
201  LIB_EXPORT int jack_set_sync_callback(jack_client_t *client,
202  JackSyncCallback sync_callback,
203  void *arg);
204  LIB_EXPORT int jack_set_sync_timeout(jack_client_t *client,
205  jack_time_t timeout);
206  LIB_EXPORT int jack_set_timebase_callback(jack_client_t *client,
207  int conditional,
208  JackTimebaseCallback timebase_callback,
209  void *arg);
210  LIB_EXPORT int jack_transport_locate(jack_client_t *client,
211  jack_nframes_t frame);
212  LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t *client,
213  jack_position_t *pos);
214  LIB_EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t *client);
215  LIB_EXPORT int jack_transport_reposition(jack_client_t *client,
216  const jack_position_t *pos);
217  LIB_EXPORT void jack_transport_start(jack_client_t *client);
218  LIB_EXPORT void jack_transport_stop(jack_client_t *client);
219  LIB_EXPORT void jack_get_transport_info(jack_client_t *client,
220  jack_transport_info_t *tinfo);
221  LIB_EXPORT void jack_set_transport_info(jack_client_t *client,
222  jack_transport_info_t *tinfo);
223 
224  LIB_EXPORT int jack_client_real_time_priority(jack_client_t*);
225  LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t*);
226  LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority);
227  LIB_EXPORT int jack_client_create_thread(jack_client_t* client,
228  jack_native_thread_t *thread,
229  int priority,
230  int realtime, // boolean
231  thread_routine routine,
232  void *arg);
233  LIB_EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread);
234 
235  LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread);
236  LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread);
237 #ifndef WIN32
238  LIB_EXPORT void jack_set_thread_creator(jack_thread_creator_t jtc);
239 #endif
240  LIB_EXPORT char * jack_get_internal_client_name(jack_client_t *client,
241  jack_intclient_t intclient);
242  LIB_EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t *client,
243  const char* client_name,
244  jack_status_t *status);
245  LIB_EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client,
246  const char* client_name,
247  jack_options_t options,
248  jack_status_t *status, ...);
249  LIB_EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t *client,
250  const char* client_name,
251  jack_options_t options,
252  jack_status_t *status, va_list ap);
253 
254  LIB_EXPORT jack_status_t jack_internal_client_unload(jack_client_t *client,
255  jack_intclient_t intclient);
256  LIB_EXPORT void jack_free(void* ptr);
257 
258  LIB_EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg);
259  LIB_EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path);
260  LIB_EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event);
261  LIB_EXPORT void jack_session_event_free(jack_session_event_t* ev);
262  LIB_EXPORT char* jack_client_get_uuid (jack_client_t *client);
263  LIB_EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name);
264  LIB_EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid);
265  LIB_EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* name, const char* uuid);
266  LIB_EXPORT void jack_session_commands_free(jack_session_command_t *cmds);
267  LIB_EXPORT int jack_client_has_session_callback(jack_client_t *client, const char* client_name);
268 
269 #ifdef __cplusplus
270 }
271 #endif
272 
273 static inline bool CheckPort(jack_port_id_t port_index)
274 {
275  return (port_index > 0 && port_index < PORT_NUM_MAX);
276 }
277 
278 static inline bool CheckBufferSize(jack_nframes_t buffer_size)
279 {
280  return (buffer_size >= 1 && buffer_size <= BUFFER_SIZE_MAX);
281 }
282 
283 static inline void WaitGraphChange()
284 {
285  /*
286  TLS key that is set only in RT thread, so never waits for pending
287  graph change in RT context (just read the current graph state).
288  */
289 
290  if (jack_tls_get(JackGlobals::fRealTime) == NULL) {
291  JackGraphManager* manager = GetGraphManager();
292  JackEngineControl* control = GetEngineControl();
293  assert(manager);
294  assert(control);
295  if (manager->IsPendingChange()) {
296  jack_log("WaitGraphChange...");
297  JackSleep(int(control->fPeriodUsecs * 1.1f));
298  }
299  }
300 }
301 
302 LIB_EXPORT void jack_set_error_function(print_function func)
303 {
304  jack_error_callback = (func == NULL) ? &default_jack_error_callback : func;
305 }
306 
307 LIB_EXPORT void jack_set_info_function(print_function func)
308 {
309  jack_info_callback = (func == NULL) ? &default_jack_info_callback : func;
310 }
311 
312 LIB_EXPORT jack_client_t* jack_client_new(const char* client_name)
313 {
314 #ifdef __CLIENTDEBUG__
315  JackGlobals::CheckContext("jack_client_new");
316 #endif
317  try {
318  assert(JackGlobals::fOpenMutex);
319  JackGlobals::fOpenMutex->Lock();
320  jack_error("jack_client_new: deprecated");
321  int options = JackUseExactName;
322  if (getenv("JACK_START_SERVER") == NULL)
323  options |= JackNoStartServer;
324  jack_client_t* res = jack_client_new_aux(client_name, (jack_options_t)options, NULL);
325  JackGlobals::fOpenMutex->Unlock();
326  return res;
327  } catch (std::bad_alloc& e) {
328  jack_error("Memory allocation error...");
329  return NULL;
330  } catch (...) {
331  jack_error("Unknown error...");
332  return NULL;
333  }
334 }
335 
336 LIB_EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
337 {
338 #ifdef __CLIENTDEBUG__
339  JackGlobals::CheckContext("jack_port_get_buffer");
340 #endif
341  uintptr_t port_aux = (uintptr_t)port;
342  jack_port_id_t myport = (jack_port_id_t)port_aux;
343  if (!CheckPort(myport)) {
344  jack_error("jack_port_get_buffer called with an incorrect port %ld", myport);
345  return NULL;
346  } else {
347  JackGraphManager* manager = GetGraphManager();
348  return (manager ? manager->GetBuffer(myport, frames) : NULL);
349  }
350 }
351 
352 LIB_EXPORT const char* jack_port_name(const jack_port_t* port)
353 {
354 #ifdef __CLIENTDEBUG__
355  JackGlobals::CheckContext("jack_port_name");
356 #endif
357  uintptr_t port_aux = (uintptr_t)port;
358  jack_port_id_t myport = (jack_port_id_t)port_aux;
359  if (!CheckPort(myport)) {
360  jack_error("jack_port_name called with an incorrect port %ld", myport);
361  return NULL;
362  } else {
363  JackGraphManager* manager = GetGraphManager();
364  return (manager ? manager->GetPort(myport)->GetName() : NULL);
365  }
366 }
367 
368 LIB_EXPORT const char* jack_port_short_name(const jack_port_t* port)
369 {
370 #ifdef __CLIENTDEBUG__
371  JackGlobals::CheckContext("jack_port_short_name");
372 #endif
373  uintptr_t port_aux = (uintptr_t)port;
374  jack_port_id_t myport = (jack_port_id_t)port_aux;
375  if (!CheckPort(myport)) {
376  jack_error("jack_port_short_name called with an incorrect port %ld", myport);
377  return NULL;
378  } else {
379  JackGraphManager* manager = GetGraphManager();
380  return (manager ? manager->GetPort(myport)->GetShortName() : NULL);
381  }
382 }
383 
384 LIB_EXPORT int jack_port_flags(const jack_port_t* port)
385 {
386 #ifdef __CLIENTDEBUG__
387  JackGlobals::CheckContext("jack_port_flags");
388 #endif
389  uintptr_t port_aux = (uintptr_t)port;
390  jack_port_id_t myport = (jack_port_id_t)port_aux;
391  if (!CheckPort(myport)) {
392  jack_error("jack_port_flags called with an incorrect port %ld", myport);
393  return -1;
394  } else {
395  JackGraphManager* manager = GetGraphManager();
396  return (manager ? manager->GetPort(myport)->GetFlags() : -1);
397  }
398 }
399 
400 LIB_EXPORT const char* jack_port_type(const jack_port_t* port)
401 {
402 #ifdef __CLIENTDEBUG__
403  JackGlobals::CheckContext("jack_port_type");
404 #endif
405  uintptr_t port_aux = (uintptr_t)port;
406  jack_port_id_t myport = (jack_port_id_t)port_aux;
407  if (!CheckPort(myport)) {
408  jack_error("jack_port_flags called an incorrect port %ld", myport);
409  return NULL;
410  } else {
411  JackGraphManager* manager = GetGraphManager();
412  return (manager ? manager->GetPort(myport)->GetType() : NULL);
413  }
414 }
415 
416 LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port)
417 {
418 #ifdef __CLIENTDEBUG__
419  JackGlobals::CheckContext("jack_port_type_id");
420 #endif
421  uintptr_t port_aux = (uintptr_t)port;
422  jack_port_id_t myport = (jack_port_id_t)port_aux;
423  if (!CheckPort(myport)) {
424  jack_error("jack_port_type_id called an incorrect port %ld", myport);
425  return 0;
426  } else {
427  JackGraphManager* manager = GetGraphManager();
428  return (manager ? GetPortTypeId(manager->GetPort(myport)->GetType()) : 0);
429  }
430 }
431 
432 LIB_EXPORT int jack_port_connected(const jack_port_t* port)
433 {
434 #ifdef __CLIENTDEBUG__
435  JackGlobals::CheckContext("jack_port_connected");
436 #endif
437  uintptr_t port_aux = (uintptr_t)port;
438  jack_port_id_t myport = (jack_port_id_t)port_aux;
439  if (!CheckPort(myport)) {
440  jack_error("jack_port_connected called with an incorrect port %ld", myport);
441  return -1;
442  } else {
443  WaitGraphChange();
444  JackGraphManager* manager = GetGraphManager();
445  return (manager ? manager->GetConnectionsNum(myport) : -1);
446  }
447 }
448 
449 LIB_EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name)
450 {
451 #ifdef __CLIENTDEBUG__
452  JackGlobals::CheckContext("jack_port_connected_to");
453 #endif
454  uintptr_t port_aux = (uintptr_t)port;
455  jack_port_id_t src = (jack_port_id_t)port_aux;
456  if (!CheckPort(src)) {
457  jack_error("jack_port_connected_to called with an incorrect port %ld", src);
458  return -1;
459  } else if (port_name == NULL) {
460  jack_error("jack_port_connected_to called with a NULL port name");
461  return -1;
462  } else {
463  WaitGraphChange();
464  JackGraphManager* manager = GetGraphManager();
465  jack_port_id_t dst = (manager ? manager->GetPort(port_name) : NO_PORT);
466  if (dst == NO_PORT) {
467  jack_error("Unknown destination port port_name = %s", port_name);
468  return 0;
469  } else {
470  return manager->IsConnected(src, dst);
471  }
472  }
473 }
474 
475 LIB_EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst)
476 {
477 #ifdef __CLIENTDEBUG__
478  JackGlobals::CheckContext("jack_port_tie");
479 #endif
480  uintptr_t src_aux = (uintptr_t)src;
481  jack_port_id_t mysrc = (jack_port_id_t)src_aux;
482  if (!CheckPort(mysrc)) {
483  jack_error("jack_port_tie called with a NULL src port");
484  return -1;
485  }
486  uintptr_t dst_aux = (uintptr_t)dst;
487  jack_port_id_t mydst = (jack_port_id_t)dst_aux;
488  if (!CheckPort(mydst)) {
489  jack_error("jack_port_tie called with a NULL dst port");
490  return -1;
491  }
492  JackGraphManager* manager = GetGraphManager();
493  if (manager && manager->GetPort(mysrc)->GetRefNum() != manager->GetPort(mydst)->GetRefNum()) {
494  jack_error("jack_port_tie called with ports not belonging to the same client");
495  return -1;
496  } else {
497  return manager->GetPort(mydst)->Tie(mysrc);
498  }
499 }
500 
501 LIB_EXPORT int jack_port_untie(jack_port_t* port)
502 {
503 #ifdef __CLIENTDEBUG__
504  JackGlobals::CheckContext("jack_port_untie");
505 #endif
506  uintptr_t port_aux = (uintptr_t)port;
507  jack_port_id_t myport = (jack_port_id_t)port_aux;
508  if (!CheckPort(myport)) {
509  jack_error("jack_port_untie called with an incorrect port %ld", myport);
510  return -1;
511  } else {
512  JackGraphManager* manager = GetGraphManager();
513  return (manager ? manager->GetPort(myport)->UnTie() : -1);
514  }
515 }
516 
517 LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port)
518 {
519 #ifdef __CLIENTDEBUG__
520  JackGlobals::CheckContext("jack_port_get_latency");
521 #endif
522  uintptr_t port_aux = (uintptr_t)port;
523  jack_port_id_t myport = (jack_port_id_t)port_aux;
524  if (!CheckPort(myport)) {
525  jack_error("jack_port_get_latency called with an incorrect port %ld", myport);
526  return 0;
527  } else {
528  WaitGraphChange();
529  JackGraphManager* manager = GetGraphManager();
530  return (manager ? manager->GetPort(myport)->GetLatency() : 0);
531  }
532 }
533 
534 LIB_EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames)
535 {
536 #ifdef __CLIENTDEBUG__
537  JackGlobals::CheckContext("jack_port_set_latency");
538 #endif
539  uintptr_t port_aux = (uintptr_t)port;
540  jack_port_id_t myport = (jack_port_id_t)port_aux;
541  if (!CheckPort(myport)) {
542  jack_error("jack_port_set_latency called with an incorrect port %ld", myport);
543  } else {
544  JackGraphManager* manager = GetGraphManager();
545  if (manager)
546  manager->GetPort(myport)->SetLatency(frames);
547  }
548 }
549 
550 LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
551 {
552 #ifdef __CLIENTDEBUG__
553  JackGlobals::CheckContext("jack_port_get_latency_range");
554 #endif
555  uintptr_t port_aux = (uintptr_t)port;
556  jack_port_id_t myport = (jack_port_id_t)port_aux;
557  if (!CheckPort(myport)) {
558  jack_error("jack_port_get_latency_range called with an incorrect port %ld", myport);
559  } else {
560  WaitGraphChange();
561  JackGraphManager* manager = GetGraphManager();
562  if (manager)
563  manager->GetPort(myport)->GetLatencyRange(mode, range);
564  }
565 }
566 
567 LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
568 {
569 #ifdef __CLIENTDEBUG__
570  JackGlobals::CheckContext("jack_port_set_latency_range");
571 #endif
572  uintptr_t port_aux = (uintptr_t)port;
573  jack_port_id_t myport = (jack_port_id_t)port_aux;
574  if (!CheckPort(myport)) {
575  jack_error("jack_port_set_latency_range called with an incorrect port %ld", myport);
576  } else {
577  WaitGraphChange();
578  JackGraphManager* manager = GetGraphManager();
579  if (manager)
580  manager->GetPort(myport)->SetLatencyRange(mode, range);
581  }
582 }
583 
584 LIB_EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port)
585 {
586 #ifdef __CLIENTDEBUG__
587  JackGlobals::CheckContext("jack_recompute_total_latency");
588 #endif
589 
590  JackClient* client = (JackClient*)ext_client;
591  uintptr_t port_aux = (uintptr_t)port;
592  jack_port_id_t myport = (jack_port_id_t)port_aux;
593  if (client == NULL) {
594  jack_error("jack_recompute_total_latency called with a NULL client");
595  return -1;
596  } else if (!CheckPort(myport)) {
597  jack_error("jack_recompute_total_latency called with a NULL port");
598  return -1;
599  } else {
600  WaitGraphChange();
601  JackGraphManager* manager = GetGraphManager();
602  return (manager ? manager->ComputeTotalLatency(myport) : -1);
603  }
604 }
605 
606 LIB_EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client)
607 {
608 #ifdef __CLIENTDEBUG__
609  JackGlobals::CheckContext("jack_recompute_total_latencies");
610 #endif
611 
612  JackClient* client = (JackClient*)ext_client;
613  if (client == NULL) {
614  jack_error("jack_recompute_total_latencies called with a NULL client");
615  return -1;
616  } else {
617  return client->ComputeTotalLatencies();
618  }
619 }
620 
621 LIB_EXPORT int jack_port_set_name(jack_port_t* port, const char* name)
622 {
623 #ifdef __CLIENTDEBUG__
624  JackGlobals::CheckContext("jack_port_set_name");
625 #endif
626  uintptr_t port_aux = (uintptr_t)port;
627  jack_port_id_t myport = (jack_port_id_t)port_aux;
628  if (!CheckPort(myport)) {
629  jack_error("jack_port_set_name called with an incorrect port %ld", myport);
630  return -1;
631  } else if (name == NULL) {
632  jack_error("jack_port_set_name called with a NULL port name");
633  return -1;
634  } else {
635  JackClient* client = NULL;
636  for (int i = 0; i < CLIENT_NUM; i++) {
637  // Find a valid client
638  if ((client = JackGlobals::fClientTable[i])) {
639  break;
640  }
641  }
642  return (client) ? client->PortRename(myport, name) : -1;
643  }
644 }
645 
646 LIB_EXPORT int jack_port_set_alias(jack_port_t* port, const char* name)
647 {
648 #ifdef __CLIENTDEBUG__
649  JackGlobals::CheckContext("jack_port_set_alias");
650 #endif
651  uintptr_t port_aux = (uintptr_t)port;
652  jack_port_id_t myport = (jack_port_id_t)port_aux;
653  if (!CheckPort(myport)) {
654  jack_error("jack_port_set_alias called with an incorrect port %ld", myport);
655  return -1;
656  } else if (name == NULL) {
657  jack_error("jack_port_set_alias called with a NULL port name");
658  return -1;
659  } else {
660  JackGraphManager* manager = GetGraphManager();
661  return (manager ? manager->GetPort(myport)->SetAlias(name) : -1);
662  }
663 }
664 
665 LIB_EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name)
666 {
667 #ifdef __CLIENTDEBUG__
668  JackGlobals::CheckContext("jack_port_unset_alias");
669 #endif
670  uintptr_t port_aux = (uintptr_t)port;
671  jack_port_id_t myport = (jack_port_id_t)port_aux;
672  if (!CheckPort(myport)) {
673  jack_error("jack_port_unset_alias called with an incorrect port %ld", myport);
674  return -1;
675  } else if (name == NULL) {
676  jack_error("jack_port_unset_alias called with a NULL port name");
677  return -1;
678  } else {
679  JackGraphManager* manager = GetGraphManager();
680  return (manager ? manager->GetPort(myport)->UnsetAlias(name) : -1);
681  }
682 }
683 
684 LIB_EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2])
685 {
686 #ifdef __CLIENTDEBUG__
687  JackGlobals::CheckContext("jack_port_get_aliases");
688 #endif
689  uintptr_t port_aux = (uintptr_t)port;
690  jack_port_id_t myport = (jack_port_id_t)port_aux;
691  if (!CheckPort(myport)) {
692  jack_error("jack_port_get_aliases called with an incorrect port %ld", myport);
693  return -1;
694  } else {
695  JackGraphManager* manager = GetGraphManager();
696  return (manager ? manager->GetPort(myport)->GetAliases(aliases) : -1);
697  }
698 }
699 
700 LIB_EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff)
701 {
702 #ifdef __CLIENTDEBUG__
703  JackGlobals::CheckContext("jack_port_request_monitor");
704 #endif
705  uintptr_t port_aux = (uintptr_t)port;
706  jack_port_id_t myport = (jack_port_id_t)port_aux;
707  if (!CheckPort(myport)) {
708  jack_error("jack_port_request_monitor called with an incorrect port %ld", myport);
709  return -1;
710  } else {
711  JackGraphManager* manager = GetGraphManager();
712  return (manager ? manager->RequestMonitor(myport, onoff) : -1);
713  }
714 }
715 
716 LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff)
717 {
718 #ifdef __CLIENTDEBUG__
719  JackGlobals::CheckContext("jack_port_request_monitor_by_name");
720 #endif
721  JackClient* client = (JackClient*)ext_client;
722  if (client == NULL) {
723  jack_error("jack_port_request_monitor_by_name called with a NULL client");
724  return -1;
725  } else {
726  JackGraphManager* manager = GetGraphManager();
727  if (!manager)
728  return -1;
729  jack_port_id_t myport = manager->GetPort(port_name);
730  if (!CheckPort(myport)) {
731  jack_error("jack_port_request_monitor_by_name called with an incorrect port %s", port_name);
732  return -1;
733  } else {
734  return manager->RequestMonitor(myport, onoff);
735  }
736  }
737 }
738 
739 LIB_EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff)
740 {
741 #ifdef __CLIENTDEBUG__
742  JackGlobals::CheckContext("jack_port_ensure_monitor");
743 #endif
744  uintptr_t port_aux = (uintptr_t)port;
745  jack_port_id_t myport = (jack_port_id_t)port_aux;
746  if (!CheckPort(myport)) {
747  jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport);
748  return -1;
749  } else {
750  JackGraphManager* manager = GetGraphManager();
751  return (manager ? manager->GetPort(myport)->EnsureMonitor(onoff) : -1);
752  }
753 }
754 
755 LIB_EXPORT int jack_port_monitoring_input(jack_port_t* port)
756 {
757 #ifdef __CLIENTDEBUG__
758  JackGlobals::CheckContext("jack_port_monitoring_input");
759 #endif
760  uintptr_t port_aux = (uintptr_t)port;
761  jack_port_id_t myport = (jack_port_id_t)port_aux;
762  if (!CheckPort(myport)) {
763  jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport);
764  return -1;
765  } else {
766  JackGraphManager* manager = GetGraphManager();
767  return (manager ? manager->GetPort(myport)->MonitoringInput() : -1);
768  }
769 }
770 
771 LIB_EXPORT int jack_is_realtime(jack_client_t* ext_client)
772 {
773 #ifdef __CLIENTDEBUG__
774  JackGlobals::CheckContext("jack_is_realtime");
775 #endif
776  JackClient* client = (JackClient*)ext_client;
777  if (client == NULL) {
778  jack_error("jack_is_realtime called with a NULL client");
779  return -1;
780  } else {
781  JackEngineControl* control = GetEngineControl();
782  return (control ? control->fRealTime : -1);
783  }
784 }
785 
786 LIB_EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback callback, void* arg)
787 {
788 #ifdef __CLIENTDEBUG__
789  JackGlobals::CheckContext("jack_on_shutdown");
790 #endif
791  JackClient* client = (JackClient*)ext_client;
792  if (client == NULL) {
793  jack_error("jack_on_shutdown called with a NULL client");
794  } else {
795  client->OnShutdown(callback, arg);
796  }
797 }
798 
799 LIB_EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg)
800 {
801 #ifdef __CLIENTDEBUG__
802  JackGlobals::CheckContext("jack_on_info_shutdown");
803 #endif
804  JackClient* client = (JackClient*)ext_client;
805  if (client == NULL) {
806  jack_error("jack_on_info_shutdown called with a NULL client");
807  } else {
808  client->OnInfoShutdown(callback, arg);
809  }
810 }
811 
812 LIB_EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg)
813 {
814 #ifdef __CLIENTDEBUG__
815  JackGlobals::CheckContext("jack_set_process_callback");
816 #endif
817  JackClient* client = (JackClient*)ext_client;
818  if (client == NULL) {
819  jack_error("jack_set_process_callback called with a NULL client");
820  return -1;
821  } else {
822  return client->SetProcessCallback(callback, arg);
823  }
824 }
825 
826 LIB_EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status)
827 {
828 #ifdef __CLIENTDEBUG__
829  JackGlobals::CheckContext("jack_thread_wait");
830 #endif
831  JackClient* client = (JackClient*)ext_client;
832  if (client == NULL) {
833  jack_error("jack_thread_wait called with a NULL client");
834  return 0;
835  } else {
836  jack_error("jack_thread_wait: deprecated, use jack_cycle_wait/jack_cycle_signal");
837  return 0;
838  }
839 }
840 
841 LIB_EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client)
842 {
843 #ifdef __CLIENTDEBUG__
844  JackGlobals::CheckContext("jack_cycle_wait");
845 #endif
846  JackClient* client = (JackClient*)ext_client;
847  if (client == NULL) {
848  jack_error("jack_cycle_wait called with a NULL client");
849  return 0;
850  } else {
851  return client->CycleWait();
852  }
853 }
854 
855 LIB_EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status)
856 {
857 #ifdef __CLIENTDEBUG__
858  JackGlobals::CheckContext("jack_cycle_signal");
859 #endif
860  JackClient* client = (JackClient*)ext_client;
861  if (client == NULL) {
862  jack_error("jack_cycle_signal called with a NULL client");
863  } else {
864  client->CycleSignal(status);
865  }
866 }
867 
868 LIB_EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback fun, void *arg)
869 {
870 #ifdef __CLIENTDEBUG__
871  JackGlobals::CheckContext("jack_set_process_thread");
872 #endif
873  JackClient* client = (JackClient*)ext_client;
874  if (client == NULL) {
875  jack_error("jack_set_process_thread called with a NULL client");
876  return -1;
877  } else {
878  return client->SetProcessThread(fun, arg);
879  }
880 }
881 
882 LIB_EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg)
883 {
884 #ifdef __CLIENTDEBUG__
885  JackGlobals::CheckContext("jack_set_freewheel_callback");
886 #endif
887  JackClient* client = (JackClient*)ext_client;
888  if (client == NULL) {
889  jack_error("jack_set_freewheel_callback called with a NULL client");
890  return -1;
891  } else {
892  return client->SetFreewheelCallback(freewheel_callback, arg);
893  }
894 }
895 
896 LIB_EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff)
897 {
898 #ifdef __CLIENTDEBUG__
899  JackGlobals::CheckContext("jack_set_freewheel");
900 #endif
901  JackClient* client = (JackClient*)ext_client;
902  if (client == NULL) {
903  jack_error("jack_set_freewheel called with a NULL client");
904  return -1;
905  } else {
906  return client->SetFreeWheel(onoff);
907  }
908 }
909 
910 LIB_EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size)
911 {
912 #ifdef __CLIENTDEBUG__
913  JackGlobals::CheckContext("jack_set_buffer_size");
914 #endif
915  JackClient* client = (JackClient*)ext_client;
916  if (client == NULL) {
917  jack_error("jack_set_buffer_size called with a NULL client");
918  return -1;
919  } else if (!CheckBufferSize(buffer_size)) {
920  return -1;
921  } else {
922  return client->SetBufferSize(buffer_size);
923  }
924 }
925 
926 LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg)
927 {
928 #ifdef __CLIENTDEBUG__
929  JackGlobals::CheckContext("jack_set_buffer_size_callback");
930 #endif
931  JackClient* client = (JackClient*)ext_client;
932  if (client == NULL) {
933  jack_error("jack_set_buffer_size_callback called with a NULL client");
934  return -1;
935  } else {
936  return client->SetBufferSizeCallback(bufsize_callback, arg);
937  }
938 }
939 
940 LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg)
941 {
942 #ifdef __CLIENTDEBUG__
943  JackGlobals::CheckContext("jack_set_sample_rate_callback");
944 #endif
945  JackClient* client = (JackClient*)ext_client;
946  if (client == NULL) {
947  jack_error("jack_set_sample_rate_callback called with a NULL client");
948  return -1;
949  } else {
950  return client->SetSampleRateCallback(srate_callback, arg);
951  }
952 }
953 
954 LIB_EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, JackClientRegistrationCallback registration_callback, void* arg)
955 {
956 #ifdef __CLIENTDEBUG__
957  JackGlobals::CheckContext("jack_set_client_registration_callback");
958 #endif
959  JackClient* client = (JackClient*)ext_client;
960  if (client == NULL) {
961  jack_error("jack_set_client_registration_callback called with a NULL client");
962  return -1;
963  } else {
964  return client->SetClientRegistrationCallback(registration_callback, arg);
965  }
966 }
967 
968 LIB_EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg)
969 {
970 #ifdef __CLIENTDEBUG__
971  JackGlobals::CheckContext("jack_set_port_registration_callback");
972 #endif
973  JackClient* client = (JackClient*)ext_client;
974  if (client == NULL) {
975  jack_error("jack_set_port_registration_callback called with a NULL client");
976  return -1;
977  } else {
978  return client->SetPortRegistrationCallback(registration_callback, arg);
979  }
980 }
981 
982 LIB_EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortConnectCallback portconnect_callback, void* arg)
983 {
984 #ifdef __CLIENTDEBUG__
985  JackGlobals::CheckContext("jack_set_port_connect_callback");
986 #endif
987  JackClient* client = (JackClient*)ext_client;
988  if (client == NULL) {
989  jack_error("jack_set_port_connect_callback called with a NULL client");
990  return -1;
991  } else {
992  return client->SetPortConnectCallback(portconnect_callback, arg);
993  }
994 }
995 
996 LIB_EXPORT int jack_set_port_rename_callback(jack_client_t* ext_client, JackPortRenameCallback rename_callback, void* arg)
997 {
998 #ifdef __CLIENTDEBUG__
999  JackGlobals::CheckContext("jack_set_port_rename_callback");
1000 #endif
1001  JackClient* client = (JackClient*)ext_client;
1002  if (client == NULL) {
1003  jack_error("jack_set_port_rename_callback called with a NULL client");
1004  return -1;
1005  } else {
1006  return client->SetPortRenameCallback(rename_callback, arg);
1007  }
1008 }
1009 
1010 LIB_EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrderCallback graph_callback, void* arg)
1011 {
1012 #ifdef __CLIENTDEBUG__
1013  JackGlobals::CheckContext("jack_set_graph_order_callback");
1014 #endif
1015  JackClient* client = (JackClient*)ext_client;
1016  jack_log("jack_set_graph_order_callback ext_client %x client %x ", ext_client, client);
1017  if (client == NULL) {
1018  jack_error("jack_set_graph_order_callback called with a NULL client");
1019  return -1;
1020  } else {
1021  return client->SetGraphOrderCallback(graph_callback, arg);
1022  }
1023 }
1024 
1025 LIB_EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xrun_callback, void* arg)
1026 {
1027 #ifdef __CLIENTDEBUG__
1028  JackGlobals::CheckContext("jack_set_xrun_callback");
1029 #endif
1030  JackClient* client = (JackClient*)ext_client;
1031  if (client == NULL) {
1032  jack_error("jack_set_xrun_callback called with a NULL client");
1033  return -1;
1034  } else {
1035  return client->SetXRunCallback(xrun_callback, arg);
1036  }
1037 }
1038 
1039 LIB_EXPORT int jack_set_latency_callback(jack_client_t* ext_client, JackLatencyCallback latency_callback, void *arg)
1040 {
1041 #ifdef __CLIENTDEBUG__
1042  JackGlobals::CheckContext("jack_set_latency_callback");
1043 #endif
1044  JackClient* client = (JackClient*)ext_client;
1045  if (client == NULL) {
1046  jack_error("jack_set_latency_callback called with a NULL client");
1047  return -1;
1048  } else {
1049  return client->SetLatencyCallback(latency_callback, arg);
1050  }
1051 }
1052 
1053 LIB_EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg)
1054 {
1055 #ifdef __CLIENTDEBUG__
1056  JackGlobals::CheckContext("jack_set_thread_init_callback");
1057 #endif
1058  JackClient* client = (JackClient*)ext_client;
1059  jack_log("jack_set_thread_init_callback ext_client %x client %x ", ext_client, client);
1060  if (client == NULL) {
1061  jack_error("jack_set_thread_init_callback called with a NULL client");
1062  return -1;
1063  } else {
1064  return client->SetInitCallback(init_callback, arg);
1065  }
1066 }
1067 
1068 LIB_EXPORT int jack_activate(jack_client_t* ext_client)
1069 {
1070 #ifdef __CLIENTDEBUG__
1071  JackGlobals::CheckContext("jack_activate");
1072 #endif
1073  JackClient* client = (JackClient*)ext_client;
1074  if (client == NULL) {
1075  jack_error("jack_activate called with a NULL client");
1076  return -1;
1077  } else {
1078  return client->Activate();
1079  }
1080 }
1081 
1082 LIB_EXPORT int jack_deactivate(jack_client_t* ext_client)
1083 {
1084 #ifdef __CLIENTDEBUG__
1085  JackGlobals::CheckContext("jack_deactivate");
1086 #endif
1087  JackClient* client = (JackClient*)ext_client;
1088  if (client == NULL) {
1089  jack_error("jack_deactivate called with a NULL client");
1090  return -1;
1091  } else {
1092  return client->Deactivate();
1093  }
1094 }
1095 
1096 LIB_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)
1097 {
1098 #ifdef __CLIENTDEBUG__
1099  JackGlobals::CheckContext("jack_port_register");
1100 #endif
1101  JackClient* client = (JackClient*)ext_client;
1102  if (client == NULL) {
1103  jack_error("jack_port_register called with a NULL client");
1104  return NULL;
1105  } else if ((port_name == NULL) || (port_type == NULL)) {
1106  jack_error("jack_port_register called with a NULL port name or a NULL port_type");
1107  return NULL;
1108  } else {
1109  return (jack_port_t *)((uintptr_t)client->PortRegister(port_name, port_type, flags, buffer_size));
1110  }
1111 }
1112 
1113 LIB_EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port)
1114 {
1115 #ifdef __CLIENTDEBUG__
1116  JackGlobals::CheckContext("jack_port_unregister");
1117 #endif
1118  JackClient* client = (JackClient*)ext_client;
1119  if (client == NULL) {
1120  jack_error("jack_port_unregister called with a NULL client");
1121  return -1;
1122  }
1123  uintptr_t port_aux = (uintptr_t)port;
1124  jack_port_id_t myport = (jack_port_id_t)port_aux;
1125  if (!CheckPort(myport)) {
1126  jack_error("jack_port_unregister called with an incorrect port %ld", myport);
1127  return -1;
1128  }
1129  return client->PortUnRegister(myport);
1130 }
1131 
1132 LIB_EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* port)
1133 {
1134 #ifdef __CLIENTDEBUG__
1135  JackGlobals::CheckContext("jack_port_is_mine");
1136 #endif
1137  JackClient* client = (JackClient*)ext_client;
1138  if (client == NULL) {
1139  jack_error("jack_port_is_mine called with a NULL client");
1140  return -1;
1141  }
1142  uintptr_t port_aux = (uintptr_t)port;
1143  jack_port_id_t myport = (jack_port_id_t)port_aux;
1144  if (!CheckPort(myport)) {
1145  jack_error("jack_port_is_mine called with an incorrect port %ld", myport);
1146  return -1;
1147  }
1148  return client->PortIsMine(myport);
1149 }
1150 
1151 LIB_EXPORT const char** jack_port_get_connections(const jack_port_t* port)
1152 {
1153 #ifdef __CLIENTDEBUG__
1154  JackGlobals::CheckContext("jack_port_get_connections");
1155 #endif
1156  uintptr_t port_aux = (uintptr_t)port;
1157  jack_port_id_t myport = (jack_port_id_t)port_aux;
1158  if (!CheckPort(myport)) {
1159  jack_error("jack_port_get_connections called with an incorrect port %ld", myport);
1160  return NULL;
1161  } else {
1162  WaitGraphChange();
1163  JackGraphManager* manager = GetGraphManager();
1164  return (manager ? manager->GetConnections(myport) : NULL);
1165  }
1166 }
1167 
1168 // Calling client does not need to "own" the port
1169 LIB_EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_client, const jack_port_t* port)
1170 {
1171 #ifdef __CLIENTDEBUG__
1172  JackGlobals::CheckContext("jack_port_get_all_connections");
1173 #endif
1174  JackClient* client = (JackClient*)ext_client;
1175  if (client == NULL) {
1176  jack_error("jack_port_get_all_connections called with a NULL client");
1177  return NULL;
1178  }
1179 
1180  uintptr_t port_aux = (uintptr_t)port;
1181  jack_port_id_t myport = (jack_port_id_t)port_aux;
1182  if (!CheckPort(myport)) {
1183  jack_error("jack_port_get_all_connections called with an incorrect port %ld", myport);
1184  return NULL;
1185  } else {
1186  WaitGraphChange();
1187  JackGraphManager* manager = GetGraphManager();
1188  return (manager ? manager->GetConnections(myport) : NULL);
1189  }
1190 }
1191 
1192 LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jack_port_t* port)
1193 {
1194 #ifdef __CLIENTDEBUG__
1195  JackGlobals::CheckContext("jack_port_get_total_latency");
1196 #endif
1197  JackClient* client = (JackClient*)ext_client;
1198  if (client == NULL) {
1199  jack_error("jack_port_get_total_latency called with a NULL client");
1200  return 0;
1201  }
1202 
1203  uintptr_t port_aux = (uintptr_t)port;
1204  jack_port_id_t myport = (jack_port_id_t)port_aux;
1205  if (!CheckPort(myport)) {
1206  jack_error("jack_port_get_total_latency called with an incorrect port %ld", myport);
1207  return 0;
1208  } else {
1209  WaitGraphChange();
1210  JackGraphManager* manager = GetGraphManager();
1211  if (manager) {
1212  manager->ComputeTotalLatency(myport);
1213  return manager->GetPort(myport)->GetTotalLatency();
1214  } else {
1215  return 0;
1216  }
1217  }
1218 }
1219 
1220 LIB_EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* dst)
1221 {
1222 #ifdef __CLIENTDEBUG__
1223  JackGlobals::CheckContext("jack_connect");
1224 #endif
1225  JackClient* client = (JackClient*)ext_client;
1226  if (client == NULL) {
1227  jack_error("jack_connect called with a NULL client");
1228  return -1;
1229  } else if ((src == NULL) || (dst == NULL)) {
1230  jack_error("jack_connect called with a NULL port name");
1231  return -1;
1232  } else {
1233  return client->PortConnect(src, dst);
1234  }
1235 }
1236 
1237 LIB_EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const char* dst)
1238 {
1239 #ifdef __CLIENTDEBUG__
1240  JackGlobals::CheckContext("jack_disconnect");
1241 #endif
1242  JackClient* client = (JackClient*)ext_client;
1243  if (client == NULL) {
1244  jack_error("jack_disconnect called with a NULL client");
1245  return -1;
1246  } else if ((src == NULL) || (dst == NULL)) {
1247  jack_error("jack_connect called with a NULL port name");
1248  return -1;
1249  } else {
1250  return client->PortDisconnect(src, dst);
1251  }
1252 }
1253 
1254 LIB_EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src)
1255 {
1256 #ifdef __CLIENTDEBUG__
1257  JackGlobals::CheckContext("jack_port_disconnect");
1258 #endif
1259  JackClient* client = (JackClient*)ext_client;
1260  if (client == NULL) {
1261  jack_error("jack_port_disconnect called with a NULL client");
1262  return -1;
1263  }
1264  uintptr_t port_aux = (uintptr_t)src;
1265  jack_port_id_t myport = (jack_port_id_t)port_aux;
1266  if (!CheckPort(myport)) {
1267  jack_error("jack_port_disconnect called with an incorrect port %ld", myport);
1268  return -1;
1269  }
1270  return client->PortDisconnect(myport);
1271 }
1272 
1273 LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client)
1274 {
1275 #ifdef __CLIENTDEBUG__
1276  JackGlobals::CheckContext("jack_get_sample_rate");
1277 #endif
1278  JackClient* client = (JackClient*)ext_client;
1279  if (client == NULL) {
1280  jack_error("jack_get_sample_rate called with a NULL client");
1281  return 0;
1282  } else {
1283  JackEngineControl* control = GetEngineControl();
1284  return (control ? control->fSampleRate : 0);
1285  }
1286 }
1287 
1288 LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client)
1289 {
1290 #ifdef __CLIENTDEBUG__
1291  JackGlobals::CheckContext("jack_get_buffer_size");
1292 #endif
1293  JackClient* client = (JackClient*)ext_client;
1294  if (client == NULL) {
1295  jack_error("jack_get_buffer_size called with a NULL client");
1296  return 0;
1297  } else {
1298  JackEngineControl* control = GetEngineControl();
1299  return (control ? control->fBufferSize : 0);
1300  }
1301 }
1302 
1303 LIB_EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
1304 {
1305 #ifdef __CLIENTDEBUG__
1306  JackGlobals::CheckContext("jack_get_ports");
1307 #endif
1308  JackClient* client = (JackClient*)ext_client;
1309  if (client == NULL) {
1310  jack_error("jack_get_ports called with a NULL client");
1311  return NULL;
1312  }
1313  JackGraphManager* manager = GetGraphManager();
1314  return (manager ? manager->GetPorts(port_name_pattern, type_name_pattern, flags) : NULL);
1315 }
1316 
1317 LIB_EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* portname)
1318 {
1319 #ifdef __CLIENTDEBUG__
1320  JackGlobals::CheckContext("jack_port_by_name");
1321 #endif
1322  JackClient* client = (JackClient*)ext_client;
1323  if (client == NULL) {
1324  jack_error("jack_get_ports called with a NULL client");
1325  return 0;
1326  }
1327 
1328  if (portname == NULL) {
1329  jack_error("jack_port_by_name called with a NULL port name");
1330  return NULL;
1331  } else {
1332  JackGraphManager* manager = GetGraphManager();
1333  if (!manager)
1334  return NULL;
1335  int res = manager->GetPort(portname); // returns a port index at least > 1
1336  return (res == NO_PORT) ? NULL : (jack_port_t*)((uintptr_t)res);
1337  }
1338 }
1339 
1340 LIB_EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id)
1341 {
1342 #ifdef __CLIENTDEBUG__
1343  JackGlobals::CheckContext("jack_port_by_id");
1344 #endif
1345  /* jack_port_t* type is actually the port index */
1346  return (jack_port_t*)((uintptr_t)id);
1347 }
1348 
1349 LIB_EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client)
1350 {
1351 #ifdef __CLIENTDEBUG__
1352  JackGlobals::CheckContext("jack_engine_takeover_timebase");
1353 #endif
1354  JackClient* client = (JackClient*)ext_client;
1355  if (client == NULL) {
1356  jack_error("jack_engine_takeover_timebase called with a NULL client");
1357  return -1;
1358  } else {
1359  jack_error("jack_engine_takeover_timebase: deprecated\n");
1360  return 0;
1361  }
1362 }
1363 
1364 LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_client)
1365 {
1366 #ifdef __CLIENTDEBUG__
1367  JackGlobals::CheckContext("jack_frames_since_cycle_start");
1368 #endif
1369  JackTimer timer;
1370  JackEngineControl* control = GetEngineControl();
1371  if (control) {
1372  control->ReadFrameTime(&timer);
1373  return timer.FramesSinceCycleStart(GetMicroSeconds(), control->fSampleRate);
1374  } else {
1375  return 0;
1376  }
1377 }
1378 
1379 LIB_EXPORT jack_time_t jack_get_time()
1380 {
1381 #ifdef __CLIENTDEBUG__
1382  JackGlobals::CheckContext("jack_get_time");
1383 #endif
1384  return GetMicroSeconds();
1385 }
1386 
1387 LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nframes_t frames)
1388 {
1389 #ifdef __CLIENTDEBUG__
1390  JackGlobals::CheckContext("jack_frames_to_time");
1391 #endif
1392  JackClient* client = (JackClient*)ext_client;
1393  if (client == NULL) {
1394  jack_error("jack_frames_to_time called with a NULL client");
1395  return 0;
1396  } else {
1397  JackTimer timer;
1398  JackEngineControl* control = GetEngineControl();
1399  if (control) {
1400  control->ReadFrameTime(&timer);
1401  return timer.Frames2Time(frames, control->fBufferSize);
1402  } else {
1403  return 0;
1404  }
1405  }
1406 }
1407 
1408 LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_time_t time)
1409 {
1410 #ifdef __CLIENTDEBUG__
1411  JackGlobals::CheckContext("jack_time_to_frames");
1412 #endif
1413  JackClient* client = (JackClient*)ext_client;
1414  if (client == NULL) {
1415  jack_error("jack_time_to_frames called with a NULL client");
1416  return 0;
1417  } else {
1418  JackTimer timer;
1419  JackEngineControl* control = GetEngineControl();
1420  if (control) {
1421  control->ReadFrameTime(&timer);
1422  return timer.Time2Frames(time, control->fBufferSize);
1423  } else {
1424  return 0;
1425  }
1426  }
1427 }
1428 
1429 LIB_EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client)
1430 {
1431 #ifdef __CLIENTDEBUG__
1432  JackGlobals::CheckContext("jack_frame_time");
1433 #endif
1434  return jack_time_to_frames(ext_client, GetMicroSeconds());
1435 }
1436 
1437 LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client)
1438 {
1439 #ifdef __CLIENTDEBUG__
1440  JackGlobals::CheckContext("jack_last_frame_time");
1441 #endif
1442  JackEngineControl* control = GetEngineControl();
1443  return (control) ? control->fFrameTimer.ReadCurrentState()->CurFrame() : 0;
1444 }
1445 
1446 LIB_EXPORT float jack_cpu_load(jack_client_t* ext_client)
1447 {
1448 #ifdef __CLIENTDEBUG__
1449  JackGlobals::CheckContext("jack_cpu_load");
1450 #endif
1451  JackClient* client = (JackClient*)ext_client;
1452  if (client == NULL) {
1453  jack_error("jack_cpu_load called with a NULL client");
1454  return 0.0f;
1455  } else {
1456  JackEngineControl* control = GetEngineControl();
1457  return (control ? control->fCPULoad : 0.0f);
1458  }
1459 }
1460 
1461 LIB_EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t* ext_client)
1462 {
1463 #ifdef __CLIENTDEBUG__
1464  JackGlobals::CheckContext("jack_client_thread_id");
1465 #endif
1466  JackClient* client = (JackClient*)ext_client;
1467  if (client == NULL) {
1468  jack_error("jack_client_thread_id called with a NULL client");
1469  return (jack_native_thread_t)NULL;
1470  } else {
1471  return client->GetThreadID();
1472  }
1473 }
1474 
1475 LIB_EXPORT char* jack_get_client_name(jack_client_t* ext_client)
1476 {
1477 #ifdef __CLIENTDEBUG__
1478  JackGlobals::CheckContext("jack_get_client_name");
1479 #endif
1480  JackClient* client = (JackClient*)ext_client;
1481  if (client == NULL) {
1482  jack_error("jack_get_client_name called with a NULL client");
1483  return NULL;
1484  } else {
1485  return client->GetClientControl()->fName;
1486  }
1487 }
1488 
1489 LIB_EXPORT int jack_client_name_size(void)
1490 {
1491  return JACK_CLIENT_NAME_SIZE;
1492 }
1493 
1494 LIB_EXPORT int jack_port_name_size(void)
1495 {
1496  return REAL_JACK_PORT_NAME_SIZE;
1497 }
1498 
1499 LIB_EXPORT int jack_port_type_size(void)
1500 {
1501  return JACK_PORT_TYPE_SIZE;
1502 }
1503 
1504 LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t* ext_client, const char* port_type)
1505 {
1506 #ifdef __CLIENTDEBUG__
1507  JackGlobals::CheckContext("jack_port_type_get_buffer_size");
1508 #endif
1509  JackClient* client = (JackClient*)ext_client;
1510  if (client == NULL) {
1511  jack_error("jack_port_type_get_buffer_size called with a NULL client");
1512  return 0;
1513  } else {
1514  jack_port_type_id_t port_id = GetPortTypeId(port_type);
1515  if (port_id == PORT_TYPES_MAX) {
1516  jack_error("jack_port_type_get_buffer_size called with an unknown port type = %s", port_type);
1517  return 0;
1518  } else {
1519  return GetPortType(port_id)->size();
1520  }
1521  }
1522 }
1523 
1524 // transport.h
1525 LIB_EXPORT int jack_release_timebase(jack_client_t* ext_client)
1526 {
1527 #ifdef __CLIENTDEBUG__
1528  JackGlobals::CheckContext("jack_release_timebase");
1529 #endif
1530  JackClient* client = (JackClient*)ext_client;
1531  if (client == NULL) {
1532  jack_error("jack_release_timebase called with a NULL client");
1533  return -1;
1534  } else {
1535  return client->ReleaseTimebase();
1536  }
1537 }
1538 
1539 LIB_EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg)
1540 {
1541 #ifdef __CLIENTDEBUG__
1542  JackGlobals::CheckContext("jack_set_sync_callback");
1543 #endif
1544  JackClient* client = (JackClient*)ext_client;
1545  if (client == NULL) {
1546  jack_error("jack_set_sync_callback called with a NULL client");
1547  return -1;
1548  } else {
1549  return client->SetSyncCallback(sync_callback, arg);
1550  }
1551 }
1552 
1553 LIB_EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout)
1554 {
1555 #ifdef __CLIENTDEBUG__
1556  JackGlobals::CheckContext("jack_set_sync_timeout");
1557 #endif
1558  JackClient* client = (JackClient*)ext_client;
1559  if (client == NULL) {
1560  jack_error("jack_set_sync_timeout called with a NULL client");
1561  return -1;
1562  } else {
1563  return client->SetSyncTimeout(timeout);
1564  }
1565 }
1566 
1567 LIB_EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg)
1568 {
1569 #ifdef __CLIENTDEBUG__
1570  JackGlobals::CheckContext("jack_set_timebase_callback");
1571 #endif
1572  JackClient* client = (JackClient*)ext_client;
1573  if (client == NULL) {
1574  jack_error("jack_set_timebase_callback called with a NULL client");
1575  return -1;
1576  } else {
1577  return client->SetTimebaseCallback(conditional, timebase_callback, arg);
1578  }
1579 }
1580 
1581 LIB_EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame)
1582 {
1583 #ifdef __CLIENTDEBUG__
1584  JackGlobals::CheckContext("jack_transport_locate");
1585 #endif
1586  JackClient* client = (JackClient*)ext_client;
1587  if (client == NULL) {
1588  jack_error("jack_transport_locate called with a NULL client");
1589  return -1;
1590  } else {
1591  client->TransportLocate(frame);
1592  return 0;
1593  }
1594 }
1595 
1596 LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos)
1597 {
1598 #ifdef __CLIENTDEBUG__
1599  JackGlobals::CheckContext("jack_transport_query");
1600 #endif
1601  JackClient* client = (JackClient*)ext_client;
1602  if (client == NULL) {
1603  jack_error("jack_transport_query called with a NULL client");
1604  return JackTransportStopped;
1605  } else {
1606  return client->TransportQuery(pos);
1607  }
1608 }
1609 
1610 LIB_EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client)
1611 {
1612 #ifdef __CLIENTDEBUG__
1613  JackGlobals::CheckContext("jack_get_current_transport_frame");
1614 #endif
1615  JackClient* client = (JackClient*)ext_client;
1616  if (client == NULL) {
1617  jack_error("jack_get_current_transport_frame called with a NULL client");
1618  return 0;
1619  } else {
1620  return client->GetCurrentTransportFrame();
1621  }
1622 }
1623 
1624 LIB_EXPORT int jack_transport_reposition(jack_client_t* ext_client, const jack_position_t* pos)
1625 {
1626 #ifdef __CLIENTDEBUG__
1627  JackGlobals::CheckContext("jack_transport_reposition");
1628 #endif
1629  JackClient* client = (JackClient*)ext_client;
1630  if (client == NULL) {
1631  jack_error("jack_transport_reposition called with a NULL client");
1632  return -1;
1633  } else {
1634  client->TransportReposition(pos);
1635  return 0;
1636  }
1637 }
1638 
1639 LIB_EXPORT void jack_transport_start(jack_client_t* ext_client)
1640 {
1641 #ifdef __CLIENTDEBUG__
1642  JackGlobals::CheckContext("jack_transport_start");
1643 #endif
1644  JackClient* client = (JackClient*)ext_client;
1645  if (client == NULL) {
1646  jack_error("jack_transport_start called with a NULL client");
1647  } else {
1648  client->TransportStart();
1649  }
1650 }
1651 
1652 LIB_EXPORT void jack_transport_stop(jack_client_t* ext_client)
1653 {
1654 #ifdef __CLIENTDEBUG__
1655  JackGlobals::CheckContext("jack_transport_stop");
1656 #endif
1657  JackClient* client = (JackClient*)ext_client;
1658  if (client == NULL) {
1659  jack_error("jack_transport_stop called with a NULL client");
1660  } else {
1661  client->TransportStop();
1662  }
1663 }
1664 
1665 // deprecated
1666 LIB_EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
1667 {
1668 #ifdef __CLIENTDEBUG__
1669  JackGlobals::CheckContext("jack_get_transport_info");
1670 #endif
1671  jack_error("jack_get_transport_info: deprecated");
1672  if (tinfo)
1673  memset(tinfo, 0, sizeof(jack_transport_info_t));
1674 }
1675 
1676 LIB_EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
1677 {
1678 #ifdef __CLIENTDEBUG__
1679  JackGlobals::CheckContext("jack_set_transport_info");
1680 #endif
1681  jack_error("jack_set_transport_info: deprecated");
1682  if (tinfo)
1683  memset(tinfo, 0, sizeof(jack_transport_info_t));
1684 }
1685 
1686 // statistics.h
1687 LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client)
1688 {
1689 #ifdef __CLIENTDEBUG__
1690  JackGlobals::CheckContext("jack_get_max_delayed_usecs");
1691 #endif
1692  JackClient* client = (JackClient*)ext_client;
1693  if (client == NULL) {
1694  jack_error("jack_get_max_delayed_usecs called with a NULL client");
1695  return 0.f;
1696  } else {
1697  JackEngineControl* control = GetEngineControl();
1698  return (control ? control->fMaxDelayedUsecs : 0.f);
1699  }
1700  }
1701 
1702 LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client)
1703 {
1704 #ifdef __CLIENTDEBUG__
1705  JackGlobals::CheckContext("jack_get_xrun_delayed_usecs");
1706 #endif
1707  JackClient* client = (JackClient*)ext_client;
1708  if (client == NULL) {
1709  jack_error("jack_get_xrun_delayed_usecs called with a NULL client");
1710  return 0.f;
1711  } else {
1712  JackEngineControl* control = GetEngineControl();
1713  return (control ? control->fXrunDelayedUsecs : 0.f);
1714  }
1715 }
1716 
1717 LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client)
1718 {
1719 #ifdef __CLIENTDEBUG__
1720  JackGlobals::CheckContext("jack_reset_max_delayed_usecs");
1721 #endif
1722  JackClient* client = (JackClient*)ext_client;
1723  if (client == NULL) {
1724  jack_error("jack_reset_max_delayed_usecs called with a NULL client");
1725  } else {
1726  JackEngineControl* control = GetEngineControl();
1727  control->ResetXRun();
1728  }
1729 }
1730 
1731 // thread.h
1732 LIB_EXPORT int jack_client_real_time_priority(jack_client_t* ext_client)
1733 {
1734 #ifdef __CLIENTDEBUG__
1735  JackGlobals::CheckContext("jack_client_real_time_priority");
1736 #endif
1737  JackClient* client = (JackClient*)ext_client;
1738  if (client == NULL) {
1739  jack_error("jack_client_real_time_priority called with a NULL client");
1740  return -1;
1741  } else {
1742  JackEngineControl* control = GetEngineControl();
1743  return (control->fRealTime) ? control->fClientPriority : -1;
1744  }
1745 }
1746 
1747 LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client)
1748 {
1749 #ifdef __CLIENTDEBUG__
1750  JackGlobals::CheckContext("jack_client_max_real_time_priority");
1751 #endif
1752  JackClient* client = (JackClient*)ext_client;
1753  if (client == NULL) {
1754  jack_error("jack_client_max_real_time_priority called with a NULL client");
1755  return -1;
1756  } else {
1757  JackEngineControl* control = GetEngineControl();
1758  return (control->fRealTime) ? control->fMaxClientPriority : -1;
1759  }
1760 }
1761 
1762 LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority)
1763 {
1764  JackEngineControl* control = GetEngineControl();
1765  return (control
1766  ? JackThread::AcquireRealTimeImp(thread, priority, control->fPeriod, control->fComputation, control->fConstraint)
1767  : -1);
1768 }
1769 
1770 LIB_EXPORT int jack_client_create_thread(jack_client_t* client,
1771  jack_native_thread_t *thread,
1772  int priority,
1773  int realtime, /* boolean */
1774  thread_routine routine,
1775  void *arg)
1776 {
1777 #ifdef __CLIENTDEBUG__
1778  JackGlobals::CheckContext("jack_client_create_thread");
1779 #endif
1780  JackEngineControl* control = GetEngineControl();
1781  int res = JackThread::StartImp(thread, priority, realtime, routine, arg);
1782  return (res == 0)
1783  ? ((realtime ? JackThread::AcquireRealTimeImp(*thread, priority, control->fPeriod, control->fComputation, control->fConstraint) : res))
1784  : res;
1785 }
1786 
1787 LIB_EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread)
1788 {
1789  return JackThread::DropRealTimeImp(thread);
1790 }
1791 
1792 LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread)
1793 {
1794 #ifdef __CLIENTDEBUG__
1795  JackGlobals::CheckContext("jack_client_stop_thread");
1796 #endif
1797  return JackThread::StopImp(thread);
1798 }
1799 
1800 LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread)
1801 {
1802 #ifdef __CLIENTDEBUG__
1803  JackGlobals::CheckContext("jack_client_kill_thread");
1804 #endif
1805  return JackThread::KillImp(thread);
1806 }
1807 
1808 #ifndef WIN32
1809 LIB_EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc)
1810 {
1811  JackGlobals::fJackThreadCreator = (jtc == NULL) ? pthread_create : jtc;
1812 }
1813 #endif
1814 
1815 // intclient.h
1816 LIB_EXPORT int jack_internal_client_new (const char* client_name,
1817  const char* load_name,
1818  const char* load_init)
1819 {
1820 #ifdef __CLIENTDEBUG__
1821  JackGlobals::CheckContext("jack_internal_client_new");
1822 #endif
1823  jack_error("jack_internal_client_new: deprecated");
1824  return -1;
1825 }
1826 
1827 LIB_EXPORT void jack_internal_client_close (const char* client_name)
1828 {
1829 #ifdef __CLIENTDEBUG__
1830  JackGlobals::CheckContext("jack_internal_client_close");
1831 #endif
1832  jack_error("jack_internal_client_close: deprecated");
1833 }
1834 
1835 LIB_EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient)
1836 {
1837 #ifdef __CLIENTDEBUG__
1838  JackGlobals::CheckContext("jack_get_internal_client_name");
1839 #endif
1840  JackClient* client = (JackClient*)ext_client;
1841  if (client == NULL) {
1842  jack_error("jack_get_internal_client_name called with a NULL client");
1843  return NULL;
1844  } else if (intclient >= CLIENT_NUM) {
1845  jack_error("jack_get_internal_client_name: incorrect client");
1846  return NULL;
1847  } else {
1848  return client->GetInternalClientName(intclient);
1849  }
1850 }
1851 
1852 LIB_EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, const char* client_name, jack_status_t* status)
1853 {
1854 #ifdef __CLIENTDEBUG__
1855  JackGlobals::CheckContext("jack_internal_client_handle");
1856 #endif
1857  JackClient* client = (JackClient*)ext_client;
1858  if (client == NULL) {
1859  jack_error("jack_internal_client_handle called with a NULL client");
1860  return 0;
1861  } else {
1862  jack_status_t my_status;
1863  if (status == NULL) /* no status from caller? */
1864  status = &my_status; /* use local status word */
1865  *status = (jack_status_t)0;
1866  return client->InternalClientHandle(client_name, status);
1867  }
1868 }
1869 
1870 LIB_EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t* ext_client, const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
1871 {
1872 #ifdef __CLIENTDEBUG__
1873  JackGlobals::CheckContext("jack_internal_client_load_aux");
1874 #endif
1875  JackClient* client = (JackClient*)ext_client;
1876  if (client == NULL) {
1877  jack_error("jack_internal_client_load called with a NULL client");
1878  return 0;
1879  } else {
1880  jack_varargs_t va;
1881  jack_status_t my_status;
1882 
1883  if (status == NULL) /* no status from caller? */
1884  status = &my_status; /* use local status word */
1885  *status = (jack_status_t)0;
1886 
1887  /* validate parameters */
1888  if ((options & ~JackLoadOptions)) {
1889  int my_status1 = *status | (JackFailure | JackInvalidOption);
1890  *status = (jack_status_t)my_status1;
1891  return 0;
1892  }
1893 
1894  /* parse variable arguments */
1895  jack_varargs_parse(options, ap, &va);
1896  return client->InternalClientLoad(client_name, options, status, &va);
1897  }
1898 }
1899 
1900 LIB_EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const char* client_name, jack_options_t options, jack_status_t *status, ...)
1901 {
1902 #ifdef __CLIENTDEBUG__
1903  JackGlobals::CheckContext("jack_internal_client_load");
1904 #endif
1905  va_list ap;
1906  va_start(ap, status);
1907  jack_intclient_t res = jack_internal_client_load_aux(client, client_name, options, status, ap);
1908  va_end(ap);
1909  return res;
1910 }
1911 
1912 LIB_EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack_intclient_t intclient)
1913 {
1914 #ifdef __CLIENTDEBUG__
1915  JackGlobals::CheckContext("jack_internal_client_load");
1916 #endif
1917  JackClient* client = (JackClient*)ext_client;
1918  if (client == NULL) {
1919  jack_error("jack_internal_client_unload called with a NULL client");
1920  return (jack_status_t)(JackNoSuchClient | JackFailure);
1921  } else if (intclient >= CLIENT_NUM) {
1922  jack_error("jack_internal_client_unload: incorrect client");
1923  return (jack_status_t)(JackNoSuchClient | JackFailure);
1924  } else {
1925  jack_status_t my_status;
1926  client->InternalClientUnload(intclient, &my_status);
1927  return my_status;
1928  }
1929 }
1930 
1931 LIB_EXPORT void jack_get_version(int *major_ptr,
1932  int *minor_ptr,
1933  int *micro_ptr,
1934  int *proto_ptr)
1935 {
1936 #ifdef __CLIENTDEBUG__
1937  JackGlobals::CheckContext("jack_get_version");
1938 #endif
1939  // FIXME: We need these comming from build system
1940  *major_ptr = 0;
1941  *minor_ptr = 0;
1942  *micro_ptr = 0;
1943  *proto_ptr = 0;
1944 }
1945 
1946 LIB_EXPORT const char* jack_get_version_string()
1947 {
1948 #ifdef __CLIENTDEBUG__
1949  JackGlobals::CheckContext("jack_get_version_string");
1950 #endif
1951  return VERSION;
1952 }
1953 
1954 LIB_EXPORT void jack_free(void* ptr)
1955 {
1956 #ifdef __CLIENTDEBUG__
1957  JackGlobals::CheckContext("jack_free");
1958 #endif
1959  if (ptr) {
1960  free(ptr);
1961  }
1962 }
1963 
1964 // session.h
1965 LIB_EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg)
1966 {
1967 #ifdef __CLIENTDEBUG__
1968  JackGlobals::CheckContext("jack_set_session_callback");
1969 #endif
1970  JackClient* client = (JackClient*)ext_client;
1971  jack_log("jack_set_session_callback ext_client %x client %x ", ext_client, client);
1972  if (client == NULL) {
1973  jack_error("jack_set_session_callback called with a NULL client");
1974  return -1;
1975  } else {
1976  return client->SetSessionCallback(session_callback, arg);
1977  }
1978 }
1979 
1980 LIB_EXPORT jack_session_command_t* jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path)
1981 {
1982 #ifdef __CLIENTDEBUG__
1983  JackGlobals::CheckContext("jack_session_notify");
1984 #endif
1985  JackClient* client = (JackClient*)ext_client;
1986  jack_log("jack_session_notify ext_client %x client %x ", ext_client, client);
1987  if (client == NULL) {
1988  jack_error("jack_session_notify called with a NULL client");
1989  return NULL;
1990  } else {
1991  return client->SessionNotify(target, ev_type, path);
1992  }
1993 }
1994 
1995 LIB_EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event)
1996 {
1997 #ifdef __CLIENTDEBUG__
1998  JackGlobals::CheckContext("jack_session_reply");
1999 #endif
2000  JackClient* client = (JackClient*)ext_client;
2001  jack_log("jack_session_reply ext_client %x client %x ", ext_client, client);
2002  if (client == NULL) {
2003  jack_error("jack_session_reply called with a NULL client");
2004  return -1;
2005  } else {
2006  return client->SessionReply(event);
2007  }
2008 }
2009 
2011 {
2012 #ifdef __CLIENTDEBUG__
2013  JackGlobals::CheckContext("jack_session_event_free");
2014 #endif
2015  if (ev) {
2016  if (ev->session_dir)
2017  free((void *)ev->session_dir);
2018  if (ev->client_uuid)
2019  free((void *)ev->client_uuid);
2020  if (ev->command_line)
2021  free(ev->command_line);
2022  free(ev);
2023  }
2024 }
2025 
2026 LIB_EXPORT char *jack_client_get_uuid(jack_client_t* ext_client)
2027 {
2028 #ifdef __CLIENTDEBUG__
2029  JackGlobals::CheckContext("jack_client_get_uuid");
2030 #endif
2031  JackClient* client = (JackClient*)ext_client;
2032  if (client == NULL) {
2033  jack_error("jack_client_get_uuid called with a NULL client");
2034  return NULL;
2035  } else {
2036  char retval[16];
2037  snprintf(retval, sizeof(retval), "%d", client->GetClientControl()->fSessionID);
2038  return strdup(retval);
2039  }
2040 }
2041 
2042 LIB_EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name)
2043 {
2044 #ifdef __CLIENTDEBUG__
2045  JackGlobals::CheckContext("jack_get_uuid_for_client_name");
2046 #endif
2047  JackClient* client = (JackClient*)ext_client;
2048  jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client);
2049  if (client == NULL) {
2050  jack_error("jack_get_uuid_for_client_name called with a NULL client");
2051  return NULL;
2052  } else {
2053  return client->GetUUIDForClientName(client_name);
2054  }
2055 }
2056 
2057 LIB_EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid)
2058 {
2059 #ifdef __CLIENTDEBUG__
2060  JackGlobals::CheckContext("jack_get_client_name_by_uuid");
2061 #endif
2062  JackClient* client = (JackClient*)ext_client;
2063  jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client);
2064  if (client == NULL) {
2065  jack_error("jack_get_client_name_by_uuid called with a NULL client");
2066  return NULL;
2067  } else {
2068  return client->GetClientNameByUUID(client_uuid);
2069  }
2070 }
2071 
2072 LIB_EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* client_name, const char* uuid)
2073 {
2074 #ifdef __CLIENTDEBUG__
2075  JackGlobals::CheckContext("jack_reserve_client_name");
2076 #endif
2077  JackClient* client = (JackClient*)ext_client;
2078  jack_log("jack_reserve_client_name ext_client %x client %x ", ext_client, client);
2079  if (client == NULL) {
2080  jack_error("jack_reserve_client_name called with a NULL client");
2081  return -1;
2082  } else {
2083  return client->ReserveClientName(client_name, uuid);
2084  }
2085 }
2086 
2088 {
2089 #ifdef __CLIENTDEBUG__
2090  JackGlobals::CheckContext("jack_session_commands_free");
2091 #endif
2092 
2093  if (!cmds) {
2094  return;
2095  }
2096 
2097  int i = 0;
2098  while (1) {
2099  if (cmds[i].client_name) {
2100  free ((char *)cmds[i].client_name);
2101  }
2102  if (cmds[i].command) {
2103  free ((char *)cmds[i].command);
2104  }
2105  if (cmds[i].uuid) {
2106  free ((char *)cmds[i].uuid);
2107  } else {
2108  break;
2109  }
2110 
2111  i += 1;
2112  }
2113 
2114  free(cmds);
2115 }
2116 
2117 LIB_EXPORT int jack_client_has_session_callback(jack_client_t* ext_client, const char* client_name)
2118 {
2119 #ifdef __CLIENTDEBUG__
2120  JackGlobals::CheckContext("jack_client_has_session_callback");
2121 #endif
2122  JackClient* client = (JackClient*)ext_client;
2123  jack_log("jack_client_has_session_callback ext_client %x client %x ", ext_client, client);
2124  if (client == NULL) {
2125  jack_error("jack_client_has_session_callback called with a NULL client");
2126  return -1;
2127  } else {
2128  return client->ClientHasSessionCallback(client_name);
2129  }
2130 }