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