1 //=============================================================================
3 // jackWeakAPI partly based on Julien Pommier (PianoTeq : http://www.pianoteq.com/) code.
5 // Copyright (C) 2002-2007 Werner Schweer and others
6 // Copyright (C) 2009 Grame
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU Lesser General Public License as published by
10 // the Free Software Foundation; either version 2.1 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Lesser General Public License for more details.
18 // You should have received a copy of the GNU Lesser General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <jack/jack.h>
23 #include <jack/session.h>
24 #include <jack/thread.h>
25 #include <jack/midiport.h>
33 /* dynamically load libjack and forward all registered calls to libjack
34 (similar to what relaytool is trying to do, but more portably..)
37 typedef void (*print_function
)(const char *);
38 typedef void *(*thread_routine
)(void*);
40 static int libjack_is_present
= 0; // public symbol, similar to what relaytool does.
43 static HMODULE libjack_handle
= 0;
45 static void *libjack_handle
= 0;
48 static void __attribute__((constructor
)) tryload_libjack()
50 void tryload_libjack()
53 if (getenv("SKIP_LIBJACK") == 0) { // just in case libjack is causing troubles..
55 libjack_handle
= dlopen("libjack.0.dylib", RTLD_LAZY
);
56 if (!libjack_handle
) {
57 fprintf(stderr
, "dlopen error : %s \n", dlerror());
59 libjack_handle
= dlopen("/usr/local/lib/libjack.0.dylib", RTLD_LAZY
);
60 if (!libjack_handle
) {
61 fprintf(stderr
, "dlopen error : %s \n", dlerror());
65 libjack_handle
= LoadLibraryA("libjack64.dll");
67 libjack_handle
= LoadLibraryA("libjack.dll");
69 if (!libjack_handle
) {
71 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
,NULL
,GetLastError(),MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),(LPTSTR
) &lpMsgBuf
,0,NULL
);
72 fprintf(stderr
, "Failed to load libjack DLL: %d", lpMsgBuf
);
75 libjack_handle
= dlopen("libjack.so.0", RTLD_LAZY
);
78 libjack_is_present
= (libjack_handle
!= 0);
81 void *load_jack_function(const char *fn_name
)
84 if (!libjack_handle
) {
86 if (!libjack_handle
) {
87 fprintf (stderr
, "libjack not found, so do not try to load %s ffs !\n", fn_name
);
92 fn
= (void*)GetProcAddress(libjack_handle
, fn_name
);
94 fn
= dlsym(libjack_handle
, fn_name
);
99 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
,NULL
,GetLastError(),MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),(LPTSTR
) &lpMsgBuf
,0,NULL
);
100 fprintf(stderr
, "could not GetProcAddress( %s ), %s \n", fn_name
, lpMsgBuf
);
102 fprintf(stderr
, "could not dlsym( %s ), %s \n", fn_name
, dlerror());
108 #define DECL_FUNCTION(return_type, fn_name, arguments_types, arguments) \
109 typedef return_type (*fn_name##_ptr_t)arguments_types; \
110 return_type fn_name arguments_types { \
111 static fn_name##_ptr_t fn = 0; \
112 if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \
113 if (fn) return (*fn)arguments; \
114 else return (return_type)-1; \
117 #define DECL_FUNCTION_NULL(return_type, fn_name, arguments_types, arguments) \
118 typedef return_type (*fn_name##_ptr_t)arguments_types; \
119 return_type fn_name arguments_types { \
120 static fn_name##_ptr_t fn = 0; \
121 if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \
122 if (fn) return (*fn)arguments; \
123 else return (return_type)0; \
126 #define DECL_VOID_FUNCTION(fn_name, arguments_types, arguments) \
127 typedef void (*fn_name##_ptr_t)arguments_types; \
128 void fn_name arguments_types { \
129 static fn_name##_ptr_t fn = 0; \
130 if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \
131 if (fn) (*fn)arguments; \
135 DECL_VOID_FUNCTION(jack_get_version
, (int *major_ptr
, int *minor_ptr
, int *micro_ptr
, int *proto_ptr
), (major_ptr
, minor_ptr
, micro_ptr
, proto_ptr
));
136 DECL_FUNCTION_NULL(const char *, jack_get_version_string
, (), ());
137 DECL_FUNCTION_NULL(jack_client_t
*, jack_client_open
, (const char *client_name
, jack_options_t options
, jack_status_t
*status
, ...),
138 (client_name
, options
, status
));
139 DECL_FUNCTION(int, jack_client_close
, (jack_client_t
*client
), (client
));
140 DECL_FUNCTION_NULL(jack_client_t
*, jack_client_new
, (const char *client_name
), (client_name
));
141 DECL_FUNCTION(int, jack_client_name_size
, (), ());
142 DECL_FUNCTION_NULL(char*, jack_get_client_name
, (jack_client_t
*client
), (client
));
143 DECL_FUNCTION(int, jack_internal_client_new
, (const char *client_name
,
144 const char *load_name
,
145 const char *load_init
), (client_name
, load_name
, load_init
));
146 DECL_VOID_FUNCTION(jack_internal_client_close
, (const char *client_name
), (client_name
));
147 DECL_FUNCTION(int, jack_is_realtime
, (jack_client_t
*client
), (client
));
148 DECL_VOID_FUNCTION(jack_on_shutdown
, (jack_client_t
*client
, JackShutdownCallback shutdown_callback
, void *arg
), (client
, shutdown_callback
, arg
));
149 DECL_VOID_FUNCTION(jack_on_info_shutdown
, (jack_client_t
* client
, JackInfoShutdownCallback shutdown_callback
, void* arg
), (client
, shutdown_callback
, arg
));
150 DECL_FUNCTION(int, jack_set_process_callback
, (jack_client_t
*client
,
151 JackProcessCallback process_callback
,
152 void *arg
), (client
, process_callback
, arg
));
153 DECL_FUNCTION(jack_nframes_t
, jack_thread_wait
, (jack_client_t
*client
, int status
), (client
, status
));
156 DECL_FUNCTION(jack_nframes_t
, jack_cycle_wait
, (jack_client_t
*client
), (client
));
157 DECL_VOID_FUNCTION(jack_cycle_signal
, (jack_client_t
*client
, int status
), (client
, status
));
158 DECL_FUNCTION(int, jack_set_process_thread
, (jack_client_t
*client
,
159 JackThreadCallback fun
,
160 void *arg
), (client
, fun
, arg
));
161 DECL_FUNCTION(int, jack_set_thread_init_callback
, (jack_client_t
*client
,
162 JackThreadInitCallback thread_init_callback
,
163 void *arg
), (client
, thread_init_callback
, arg
));
164 DECL_FUNCTION(int, jack_set_freewheel_callback
, (jack_client_t
*client
,
165 JackFreewheelCallback freewheel_callback
,
166 void *arg
), (client
, freewheel_callback
, arg
));
167 DECL_FUNCTION(int, jack_set_freewheel
, (jack_client_t
*client
, int onoff
), (client
, onoff
));
168 DECL_FUNCTION(int, jack_set_buffer_size
, (jack_client_t
*client
, jack_nframes_t nframes
), (client
, nframes
));
169 DECL_FUNCTION(int, jack_set_buffer_size_callback
, (jack_client_t
*client
,
170 JackBufferSizeCallback bufsize_callback
,
171 void *arg
), (client
, bufsize_callback
, arg
));
172 DECL_FUNCTION(int, jack_set_sample_rate_callback
, (jack_client_t
*client
,
173 JackSampleRateCallback srate_callback
,
174 void *arg
), (client
, srate_callback
, arg
));
175 DECL_FUNCTION(int, jack_set_client_registration_callback
, (jack_client_t
*client
,
176 JackClientRegistrationCallback registration_callback
,
177 void *arg
), (client
, registration_callback
, arg
));
178 DECL_FUNCTION(int, jack_set_port_registration_callback
, (jack_client_t
*client
,
179 JackPortRegistrationCallback registration_callback
,
180 void *arg
), (client
, registration_callback
, arg
));
181 DECL_FUNCTION(int, jack_set_port_connect_callback
, (jack_client_t
*client
,
182 JackPortConnectCallback connect_callback
,
183 void *arg
), (client
, connect_callback
, arg
));
184 DECL_FUNCTION(int, jack_set_port_rename_callback
, (jack_client_t
*client
,
185 JackPortRenameCallback rename_callback
,
186 void *arg
), (client
, rename_callback
, arg
));
187 DECL_FUNCTION(int, jack_set_graph_order_callback
, (jack_client_t
*client
,
188 JackGraphOrderCallback graph_callback
,
189 void *arg
), (client
, graph_callback
, arg
));
190 DECL_FUNCTION(int, jack_set_xrun_callback
, (jack_client_t
*client
,
191 JackXRunCallback xrun_callback
,
192 void *arg
), (client
, xrun_callback
, arg
));
193 DECL_FUNCTION(int, jack_set_latency_callback
, (jack_client_t
*client
,
194 JackLatencyCallback latency_callback
,
195 void *arg
), (client
, latency_callback
, arg
));
196 DECL_FUNCTION(int, jack_activate
, (jack_client_t
*client
), (client
));
197 DECL_FUNCTION(int, jack_deactivate
, (jack_client_t
*client
), (client
));
198 DECL_FUNCTION_NULL(jack_port_t
*, jack_port_register
, (jack_client_t
*client
, const char *port_name
, const char *port_type
,
199 unsigned long flags
, unsigned long buffer_size
),
200 (client
, port_name
, port_type
, flags
, buffer_size
));
201 DECL_FUNCTION(int, jack_port_unregister
, (jack_client_t
*client
, jack_port_t
* port
), (client
, port
));
202 DECL_FUNCTION_NULL(void *, jack_port_get_buffer
, (jack_port_t
*port
, jack_nframes_t nframes
), (port
, nframes
));
203 DECL_FUNCTION_NULL(const char*, jack_port_name
, (const jack_port_t
*port
), (port
));
204 DECL_FUNCTION_NULL(const char*, jack_port_short_name
, (const jack_port_t
*port
), (port
));
205 DECL_FUNCTION(int, jack_port_flags
, (const jack_port_t
*port
), (port
));
206 DECL_FUNCTION_NULL(const char*, jack_port_type
, (const jack_port_t
*port
), (port
));
207 DECL_FUNCTION(jack_port_type_id_t
, jack_port_type_id
, (const jack_port_t
*port
), (port
));
208 DECL_FUNCTION(int, jack_port_is_mine
, (const jack_client_t
*client
, const jack_port_t
* port
), (client
, port
));
209 DECL_FUNCTION(int, jack_port_connected
, (const jack_port_t
*port
), (port
));
210 DECL_FUNCTION(int, jack_port_connected_to
, (const jack_port_t
*port
, const char *port_name
), (port
, port_name
));
211 DECL_FUNCTION_NULL(const char**, jack_port_get_connections
, (const jack_port_t
*port
), (port
));
212 DECL_FUNCTION_NULL(const char**, jack_port_get_all_connections
, (const jack_client_t
*client
,const jack_port_t
*port
), (client
, port
));
213 DECL_FUNCTION(int, jack_port_tie
, (jack_port_t
*src
, jack_port_t
*dst
), (src
, dst
));
214 DECL_FUNCTION(int, jack_port_untie
, (jack_port_t
*port
), (port
));
215 DECL_FUNCTION(jack_nframes_t
, jack_port_get_latency
, (jack_port_t
*port
), (port
));
216 DECL_FUNCTION(jack_nframes_t
, jack_port_get_total_latency
,(jack_client_t
* client
, jack_port_t
*port
), (client
, port
));
217 DECL_VOID_FUNCTION(jack_port_set_latency
, (jack_port_t
* port
, jack_nframes_t frames
), (port
, frames
));
218 DECL_FUNCTION(int, jack_recompute_total_latency
, (jack_client_t
* client
, jack_port_t
* port
), (client
, port
));
219 DECL_VOID_FUNCTION(jack_port_get_latency_range
, (jack_port_t
*port
, jack_latency_callback_mode_t mode
, jack_latency_range_t
*range
), (port
, mode
, range
));
220 DECL_VOID_FUNCTION(jack_port_set_latency_range
, (jack_port_t
*port
, jack_latency_callback_mode_t mode
, jack_latency_range_t
*range
), (port
, mode
, range
));
221 DECL_FUNCTION(int, jack_recompute_total_latencies
, (jack_client_t
* client
),(client
));
223 DECL_FUNCTION(int, jack_port_set_name
, (jack_port_t
*port
, const char *port_name
), (port
, port_name
));
224 DECL_FUNCTION(int, jack_port_rename
, (jack_client_t
*client
, jack_port_t
*port
, const char *port_name
), (client
, port
, port_name
));
225 DECL_FUNCTION(int, jack_port_set_alias
, (jack_port_t
*port
, const char *alias
), (port
, alias
));
226 DECL_FUNCTION(int, jack_port_unset_alias
, (jack_port_t
*port
, const char *alias
), (port
, alias
));
227 DECL_FUNCTION(int, jack_port_get_aliases
, (const jack_port_t
*port
, char* const aliases
[2]), (port
,aliases
));
228 DECL_FUNCTION(int, jack_port_request_monitor
, (jack_port_t
*port
, int onoff
), (port
, onoff
));
229 DECL_FUNCTION(int, jack_port_request_monitor_by_name
, (jack_client_t
*client
, const char *port_name
, int onoff
), (client
, port_name
, onoff
));
230 DECL_FUNCTION(int, jack_port_ensure_monitor
, (jack_port_t
*port
, int onoff
), (port
, onoff
));
231 DECL_FUNCTION(int, jack_port_monitoring_input
, (jack_port_t
*port
) ,(port
));
232 DECL_FUNCTION(int, jack_connect
, (jack_client_t
* client
, const char *source_port
, const char *destination_port
), (client
, source_port
, destination_port
));
233 DECL_FUNCTION(int, jack_disconnect
, (jack_client_t
* client
, const char *source_port
, const char *destination_port
), (client
, source_port
, destination_port
));
234 DECL_FUNCTION(int, jack_port_disconnect
, (jack_client_t
* client
, jack_port_t
* port
), (client
, port
));
235 DECL_FUNCTION(int, jack_port_name_size
,(),());
236 DECL_FUNCTION(int, jack_port_type_size
,(),());
237 DECL_FUNCTION(size_t, jack_port_type_get_buffer_size
, (jack_client_t
*client
, const char* port_type
), (client
, port_type
));
239 DECL_FUNCTION(jack_nframes_t
, jack_get_sample_rate
, (jack_client_t
*client
), (client
));
240 DECL_FUNCTION(jack_nframes_t
, jack_get_buffer_size
, (jack_client_t
*client
), (client
));
241 DECL_FUNCTION_NULL(const char**, jack_get_ports
, (jack_client_t
*client
, const char *port_name_pattern
, const char * type_name_pattern
,
242 unsigned long flags
), (client
, port_name_pattern
, type_name_pattern
, flags
));
243 DECL_FUNCTION_NULL(jack_port_t
*, jack_port_by_name
, (jack_client_t
* client
, const char *port_name
), (client
, port_name
));
244 DECL_FUNCTION_NULL(jack_port_t
*, jack_port_by_id
, (jack_client_t
*client
, jack_port_id_t port_id
), (client
, port_id
));
246 DECL_FUNCTION(int, jack_engine_takeover_timebase
, (jack_client_t
* client
), (client
));
247 DECL_FUNCTION(jack_nframes_t
, jack_frames_since_cycle_start
, (const jack_client_t
* client
), (client
));
248 DECL_FUNCTION(jack_time_t
, jack_get_time
, (), ());
249 DECL_FUNCTION(jack_nframes_t
, jack_time_to_frames
, (const jack_client_t
*client
, jack_time_t time
), (client
, time
));
250 DECL_FUNCTION(jack_time_t
, jack_frames_to_time
, (const jack_client_t
*client
, jack_nframes_t frames
), (client
, frames
));
251 DECL_FUNCTION(jack_nframes_t
, jack_frame_time
, (const jack_client_t
*client
), (client
));
252 DECL_FUNCTION(jack_nframes_t
, jack_last_frame_time
, (const jack_client_t
*client
), (client
));
253 DECL_FUNCTION(float, jack_cpu_load
, (jack_client_t
*client
), (client
));
254 DECL_FUNCTION_NULL(jack_native_thread_t
, jack_client_thread_id
, (jack_client_t
*client
), (client
));
255 DECL_VOID_FUNCTION(jack_set_error_function
, (print_function fun
), (fun
));
256 DECL_VOID_FUNCTION(jack_set_info_function
, (print_function fun
), (fun
));
258 DECL_FUNCTION(float, jack_get_max_delayed_usecs
, (jack_client_t
*client
), (client
));
259 DECL_FUNCTION(float, jack_get_xrun_delayed_usecs
, (jack_client_t
*client
), (client
));
260 DECL_VOID_FUNCTION(jack_reset_max_delayed_usecs
, (jack_client_t
*client
), (client
));
262 DECL_FUNCTION(int, jack_release_timebase
, (jack_client_t
*client
), (client
));
263 DECL_FUNCTION(int, jack_set_sync_callback
, (jack_client_t
*client
, JackSyncCallback sync_callback
, void *arg
), (client
, sync_callback
, arg
));
264 DECL_FUNCTION(int, jack_set_sync_timeout
, (jack_client_t
*client
, jack_time_t timeout
), (client
, timeout
));
265 DECL_FUNCTION(int, jack_set_timebase_callback
, (jack_client_t
*client
,
267 JackTimebaseCallback timebase_callback
,
268 void *arg
), (client
, conditional
, timebase_callback
, arg
));
269 DECL_FUNCTION(int, jack_transport_locate
, (jack_client_t
*client
, jack_nframes_t frame
), (client
, frame
));
270 DECL_FUNCTION(jack_transport_state_t
, jack_transport_query
, (const jack_client_t
*client
, jack_position_t
*pos
), (client
, pos
));
271 DECL_FUNCTION(jack_nframes_t
, jack_get_current_transport_frame
, (const jack_client_t
*client
), (client
));
272 DECL_FUNCTION(int, jack_transport_reposition
, (jack_client_t
*client
, const jack_position_t
*pos
), (client
, pos
));
273 DECL_VOID_FUNCTION(jack_transport_start
, (jack_client_t
*client
), (client
));
274 DECL_VOID_FUNCTION(jack_transport_stop
, (jack_client_t
*client
), (client
));
275 DECL_VOID_FUNCTION(jack_get_transport_info
, (jack_client_t
*client
, jack_transport_info_t
*tinfo
), (client
,tinfo
));
276 DECL_VOID_FUNCTION(jack_set_transport_info
, (jack_client_t
*client
, jack_transport_info_t
*tinfo
), (client
,tinfo
));
278 DECL_FUNCTION(int, jack_client_real_time_priority
, (jack_client_t
* client
), (client
));
279 DECL_FUNCTION(int, jack_client_max_real_time_priority
, (jack_client_t
* client
), (client
));
280 DECL_FUNCTION(int, jack_acquire_real_time_scheduling
, (jack_native_thread_t thread
, int priority
), (thread
, priority
));
281 DECL_FUNCTION(int, jack_client_create_thread
, (jack_client_t
* client
,
282 jack_native_thread_t
*thread
,
284 int realtime
, // boolean
285 thread_routine routine
,
286 void *arg
), (client
, thread
, priority
, realtime
, routine
, arg
));
287 DECL_FUNCTION(int, jack_drop_real_time_scheduling
, (jack_native_thread_t thread
), (thread
));
289 DECL_FUNCTION(int, jack_client_stop_thread
, (jack_client_t
* client
, jack_native_thread_t thread
), (client
, thread
));
290 DECL_FUNCTION(int, jack_client_kill_thread
, (jack_client_t
* client
, jack_native_thread_t thread
), (client
, thread
));
292 DECL_VOID_FUNCTION(jack_set_thread_creator
, (jack_thread_creator_t jtc
), (jtc
));
294 DECL_FUNCTION(char *, jack_get_internal_client_name
, (jack_client_t
*client
, jack_intclient_t intclient
), (client
, intclient
));
295 DECL_FUNCTION(jack_intclient_t
, jack_internal_client_handle
, (jack_client_t
*client
, const char *client_name
, jack_status_t
*status
), (client
, client_name
, status
));
297 DECL_FUNCTION(jack_intclient_t, jack_internal_client_load, (jack_client_t *client,
298 const char *client_name,
299 jack_options_t options,
300 jack_status_t *status
301 , ...), (client, client_name, options, status, ...));
303 DECL_FUNCTION(jack_status_t
, jack_internal_client_unload
, (jack_client_t
*client
, jack_intclient_t intclient
), (client
, intclient
));
304 DECL_VOID_FUNCTION(jack_free
, (void* ptr
), (ptr
));
307 DECL_FUNCTION(int, jack_set_session_callback
, (jack_client_t
* ext_client
, JackSessionCallback session_callback
, void* arg
), (ext_client
, session_callback
, arg
));
308 DECL_FUNCTION(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
), (ext_client
, target
, ev_type
, path
));
309 DECL_FUNCTION(int, jack_session_reply
, (jack_client_t
* ext_client
, jack_session_event_t
*event
), (ext_client
, event
));
310 DECL_VOID_FUNCTION(jack_session_event_free
, (jack_session_event_t
* ev
), (ev
));
311 DECL_FUNCTION(char*, jack_client_get_uuid
, (jack_client_t
* ext_client
),(ext_client
));
312 DECL_FUNCTION(char*, jack_get_uuid_for_client_name
, (jack_client_t
* ext_client
, const char* client_name
),(ext_client
, client_name
));
313 DECL_FUNCTION(char*, jack_get_client_name_by_uuid
, (jack_client_t
* ext_client
, const char* client_uuid
),(ext_client
, client_uuid
));
314 DECL_FUNCTION(int, jack_reserve_client_name
, (jack_client_t
* ext_client
, const char* name
, const char* uuid
),(ext_client
, name
, uuid
));
315 DECL_VOID_FUNCTION(jack_session_commands_free
, (jack_session_command_t
*cmds
),(cmds
));
316 DECL_FUNCTION(int, jack_client_has_session_callback
, (jack_client_t
*client
, const char* client_name
),(client
, client_name
));
319 DECL_FUNCTION(jack_nframes_t
, jack_midi_get_event_count
, (void* port_buffer
), (port_buffer
));
320 DECL_FUNCTION(int, jack_midi_event_get
, (jack_midi_event_t
* event
, void* port_buffer
, jack_nframes_t event_index
), (event
, port_buffer
, event_index
)) ;
321 DECL_VOID_FUNCTION(jack_midi_clear_buffer
, (void* port_buffer
), (port_buffer
));
322 DECL_FUNCTION(size_t, jack_midi_max_event_size
, (void* port_buffer
), (port_buffer
));
323 DECL_FUNCTION_NULL(jack_midi_data_t
*, jack_midi_event_reserve
, (void* port_buffer
, jack_nframes_t time
, size_t data_size
), (port_buffer
, time
, data_size
));
324 DECL_FUNCTION(int, jack_midi_event_write
, (void* port_buffer
, jack_nframes_t time
, const jack_midi_data_t
* data
, size_t data_size
), (port_buffer
, time
, data
, data_size
));
325 DECL_FUNCTION(jack_nframes_t
, jack_midi_get_lost_event_count
, (void* port_buffer
), (port_buffer
));