jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
19KB

  1. //=============================================================================
  2. // MuseScore
  3. // Linux Music Score Editor
  4. // $Id:
  5. //
  6. // jackWeakAPI based on code from Stéphane Letz (Grame)
  7. // partly based on Julien Pommier (PianoTeq : http://www.pianoteq.com/) code.
  8. //
  9. // Copyright (C) 2002-2007 Werner Schweer and others
  10. // Copyright (C) 2009 Grame
  11. // This program is free software; you can redistribute it and/or modify
  12. // it under the terms of the GNU Lesser General Public License as published by
  13. // the Free Software Foundation; either version 2.1 of the License, or
  14. // (at your option) any later version.
  15. // This program is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. // GNU Lesser General Public License for more details.
  19. // You should have received a copy of the GNU Lesser General Public License
  20. // along with this program; if not, write to the Free Software
  21. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22. #include <jack/jack.h>
  23. #include <jack/thread.h>
  24. #include <jack/midiport.h>
  25. #include <math.h>
  26. #ifndef WIN32
  27. #include <dlfcn.h>
  28. #endif
  29. #include <stdlib.h>
  30. #include <iostream>
  31. /* dynamically load libjack and forward all registered calls to libjack
  32. (similar to what relaytool is trying to do, but more portably..)
  33. */
  34. typedef void (*print_function)(const char *);
  35. typedef void *(*thread_routine)(void*);
  36. using std::cerr;
  37. int libjack_is_present = 0; // public symbol, similar to what relaytool does.
  38. #ifdef WIN32
  39. HMODULE libjack_handle = 0;
  40. #else
  41. static void *libjack_handle = 0;
  42. #endif
  43. static void __attribute__((constructor)) tryload_libjack()
  44. {
  45. if (getenv("SKIP_LIBJACK") == 0) { // just in case libjack is causing troubles..
  46. #ifdef __APPLE__
  47. libjack_handle = dlopen("libjack.0.dylib", RTLD_LAZY);
  48. #elif defined(WIN32)
  49. libjack_handle = LoadLibrary("libjack.dll");
  50. #else
  51. libjack_handle = dlopen("libjack.so.0", RTLD_LAZY);
  52. #endif
  53. }
  54. libjack_is_present = (libjack_handle != 0);
  55. }
  56. void *load_jack_function(const char *fn_name)
  57. {
  58. void *fn = 0;
  59. if (!libjack_handle) {
  60. fprintf (stderr, "libjack not found, so do not try to load %s ffs !\n", fn_name);
  61. return 0;
  62. }
  63. #ifdef WIN32
  64. fn = (void*)GetProcAddress(libjack_handle, fn_name);
  65. #else
  66. fn = dlsym(libjack_handle, fn_name);
  67. #endif
  68. if (!fn) {
  69. #ifdef WIN32
  70. char* lpMsgBuf;
  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, "could not GetProcAddress( %s ), %s \n", fn_name, lpMsgBuf) ;
  73. #else
  74. fprintf (stderr, "could not dlsym( %s ), %s \n", fn_name, dlerror()) ;
  75. #endif
  76. }
  77. return fn;
  78. }
  79. #define DECL_FUNCTION(return_type, fn_name, arguments_types, arguments) \
  80. typedef return_type (*fn_name##_ptr_t)arguments_types; \
  81. return_type fn_name arguments_types { \
  82. static fn_name##_ptr_t fn = 0; \
  83. if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \
  84. if (fn) return (*fn)arguments; \
  85. else return (return_type)-1; \
  86. }
  87. #define DECL_FUNCTION_NULL(return_type, fn_name, arguments_types, arguments) \
  88. typedef return_type (*fn_name##_ptr_t)arguments_types; \
  89. return_type fn_name arguments_types { \
  90. static fn_name##_ptr_t fn = 0; \
  91. if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \
  92. if (fn) return (*fn)arguments; \
  93. else return (return_type)0; \
  94. }
  95. #define DECL_VOID_FUNCTION(fn_name, arguments_types, arguments) \
  96. typedef void (*fn_name##_ptr_t)arguments_types; \
  97. void fn_name arguments_types { \
  98. static fn_name##_ptr_t fn = 0; \
  99. if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \
  100. if (fn) (*fn)arguments; \
  101. }
  102. 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));
  103. DECL_FUNCTION_NULL(const char *, jack_get_version_string, (), ());
  104. DECL_FUNCTION_NULL(jack_client_t *, jack_client_open, (const char *client_name, jack_options_t options, jack_status_t *status, ...),
  105. (client_name, options, status));
  106. DECL_FUNCTION(int, jack_client_close, (jack_client_t *client), (client));
  107. DECL_FUNCTION_NULL(jack_client_t *, jack_client_new, (const char *client_name), (client_name));
  108. DECL_FUNCTION(int, jack_client_name_size, (), ());
  109. DECL_FUNCTION_NULL(char*, jack_get_client_name, (jack_client_t *client), (client));
  110. DECL_FUNCTION(int, jack_internal_client_new, (const char *client_name,
  111. const char *load_name,
  112. const char *load_init), (client_name, load_name, load_init));
  113. DECL_VOID_FUNCTION(jack_internal_client_close, (const char *client_name), (client_name));
  114. DECL_FUNCTION(int, jack_is_realtime, (jack_client_t *client), (client));
  115. DECL_VOID_FUNCTION(jack_on_shutdown, (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg), (client, shutdown_callback, arg));
  116. DECL_VOID_FUNCTION(jack_on_info_shutdown, (jack_client_t* client, JackInfoShutdownCallback shutdown_callback, void* arg), (client, shutdown_callback, arg));
  117. DECL_FUNCTION(int, jack_set_process_callback, (jack_client_t *client,
  118. JackProcessCallback process_callback,
  119. void *arg), (client, process_callback, arg));
  120. DECL_FUNCTION(jack_nframes_t, jack_thread_wait, (jack_client_t *client, int status), (client, status));
  121. //
  122. DECL_FUNCTION(jack_nframes_t, jack_cycle_wait, (jack_client_t *client), (client));
  123. DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, int status), (client, status));
  124. DECL_FUNCTION(int, jack_set_process_thread, (jack_client_t *client,
  125. JackThreadCallback fun,
  126. void *arg), (client, fun, arg));
  127. DECL_FUNCTION(int, jack_set_thread_init_callback, (jack_client_t *client,
  128. JackThreadInitCallback thread_init_callback,
  129. void *arg), (client, thread_init_callback, arg));
  130. DECL_FUNCTION(int, jack_set_freewheel_callback, (jack_client_t *client,
  131. JackFreewheelCallback freewheel_callback,
  132. void *arg), (client, freewheel_callback, arg));
  133. DECL_FUNCTION(int, jack_set_freewheel, (jack_client_t *client, int onoff), (client, onoff));
  134. DECL_FUNCTION(int, jack_set_buffer_size, (jack_client_t *client, jack_nframes_t nframes), (client, nframes));
  135. DECL_FUNCTION(int, jack_set_buffer_size_callback, (jack_client_t *client,
  136. JackBufferSizeCallback bufsize_callback,
  137. void *arg), (client, bufsize_callback, arg));
  138. DECL_FUNCTION(int, jack_set_sample_rate_callback, (jack_client_t *client,
  139. JackSampleRateCallback srate_callback,
  140. void *arg), (client, srate_callback, arg));
  141. DECL_FUNCTION(int, jack_set_client_registration_callback, (jack_client_t *client,
  142. JackClientRegistrationCallback registration_callback,
  143. void *arg), (client, registration_callback, arg));
  144. DECL_FUNCTION(int, jack_set_port_registration_callback, (jack_client_t *client,
  145. JackPortRegistrationCallback registration_callback,
  146. void *arg), (client, registration_callback, arg));
  147. DECL_FUNCTION(int, jack_set_port_connect_callback, (jack_client_t *client,
  148. JackPortConnectCallback connect_callback,
  149. void *arg), (client, connect_callback, arg));
  150. DECL_FUNCTION(int, jack_set_port_rename_callback, (jack_client_t *client,
  151. JackPortRenameCallback rename_callback,
  152. void *arg), (client, rename_callback, arg));
  153. DECL_FUNCTION(int, jack_set_graph_order_callback, (jack_client_t *client,
  154. JackGraphOrderCallback graph_callback,
  155. void *arg), (client, graph_callback, arg));
  156. DECL_FUNCTION(int, jack_set_xrun_callback, (jack_client_t *client,
  157. JackXRunCallback xrun_callback,
  158. void *arg), (client, xrun_callback, arg));
  159. DECL_FUNCTION(int, jack_activate, (jack_client_t *client), (client));
  160. DECL_FUNCTION(int, jack_deactivate, (jack_client_t *client), (client));
  161. DECL_FUNCTION_NULL(jack_port_t *, jack_port_register, (jack_client_t *client, const char *port_name, const char *port_type,
  162. unsigned long flags, unsigned long buffer_size),
  163. (client, port_name, port_type, flags, buffer_size));
  164. DECL_FUNCTION(int, jack_port_unregister, (jack_client_t *client, jack_port_t* port), (client, port));
  165. DECL_FUNCTION_NULL(void *, jack_port_get_buffer, (jack_port_t *port, jack_nframes_t nframes), (port, nframes));
  166. DECL_FUNCTION_NULL(const char*, jack_port_name, (const jack_port_t *port), (port));
  167. DECL_FUNCTION_NULL(const char*, jack_port_short_name, (const jack_port_t *port), (port));
  168. DECL_FUNCTION(int, jack_port_flags, (const jack_port_t *port), (port));
  169. DECL_FUNCTION_NULL(const char*, jack_port_type, (const jack_port_t *port), (port));
  170. DECL_FUNCTION(jack_port_type_id_t, jack_port_type_id, (const jack_port_t *port), (port));
  171. DECL_FUNCTION(int, jack_port_is_mine, (const jack_client_t *client, const jack_port_t* port), (client, port));
  172. DECL_FUNCTION(int, jack_port_connected, (const jack_port_t *port), (port));
  173. DECL_FUNCTION(int, jack_port_connected_to, (const jack_port_t *port, const char *port_name), (port, port_name));
  174. DECL_FUNCTION_NULL(const char**, jack_port_get_connections, (const jack_port_t *port), (port));
  175. DECL_FUNCTION_NULL(const char**, jack_port_get_all_connections, (const jack_client_t *client,const jack_port_t *port), (client, port));
  176. DECL_FUNCTION(int, jack_port_tie, (jack_port_t *src, jack_port_t *dst), (src, dst));
  177. DECL_FUNCTION(int, jack_port_untie, (jack_port_t *port), (port));
  178. DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_port_t *port), (port));
  179. DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency ,(jack_client_t * client, jack_port_t *port), (client, port));
  180. DECL_VOID_FUNCTION(jack_port_set_latency, (jack_port_t * port, jack_nframes_t frames), (port, frames));
  181. DECL_FUNCTION(int, jack_recompute_total_latency, (jack_client_t* client, jack_port_t* port), (client, port));
  182. DECL_FUNCTION(int, jack_recompute_total_latencies, (jack_client_t* client),(client));
  183. DECL_FUNCTION(int, jack_port_set_name, (jack_port_t *port, const char *port_name), (port, port_name));
  184. DECL_FUNCTION(int, jack_port_set_alias, (jack_port_t *port, const char *alias), (port, alias));
  185. DECL_FUNCTION(int, jack_port_unset_alias, (jack_port_t *port, const char *alias), (port, alias));
  186. DECL_FUNCTION(int, jack_port_get_aliases, (const jack_port_t *port, char* const aliases[2]), (port,aliases));
  187. DECL_FUNCTION(int, jack_port_request_monitor, (jack_port_t *port, int onoff), (port, onoff));
  188. DECL_FUNCTION(int, jack_port_request_monitor_by_name, (jack_client_t *client, const char *port_name, int onoff), (client, port_name, onoff));
  189. DECL_FUNCTION(int, jack_port_ensure_monitor, (jack_port_t *port, int onoff), (port, onoff));
  190. DECL_FUNCTION(int, jack_port_monitoring_input, (jack_port_t *port) ,(port));
  191. DECL_FUNCTION(int, jack_connect, (jack_client_t * client, const char *source_port, const char *destination_port), (client, source_port, destination_port));
  192. DECL_FUNCTION(int, jack_disconnect, (jack_client_t * client, const char *source_port, const char *destination_port), (client, source_port, destination_port));
  193. DECL_FUNCTION(int, jack_port_disconnect, (jack_client_t * client, jack_port_t * port), (client, port));
  194. DECL_FUNCTION(int, jack_port_name_size,(),());
  195. DECL_FUNCTION(int, jack_port_type_size,(),());
  196. DECL_FUNCTION(jack_nframes_t, jack_get_sample_rate, (jack_client_t *client), (client));
  197. DECL_FUNCTION(jack_nframes_t, jack_get_buffer_size, (jack_client_t *client), (client));
  198. DECL_FUNCTION_NULL(const char**, jack_get_ports, (jack_client_t *client, const char *port_name_pattern, const char * type_name_pattern,
  199. unsigned long flags), (client, port_name_pattern, type_name_pattern, flags));
  200. DECL_FUNCTION_NULL(jack_port_t *, jack_port_by_name, (jack_client_t * client, const char *port_name), (client, port_name));
  201. DECL_FUNCTION_NULL(jack_port_t *, jack_port_by_id, (jack_client_t *client, jack_port_id_t port_id), (client, port_id));
  202. DECL_FUNCTION(int, jack_engine_takeover_timebase, (jack_client_t * client), (client));
  203. DECL_FUNCTION(jack_nframes_t, jack_frames_since_cycle_start, (const jack_client_t * client), (client));
  204. DECL_FUNCTION(jack_time_t, jack_get_time, (), ());
  205. DECL_FUNCTION(jack_nframes_t, jack_time_to_frames, (const jack_client_t *client, jack_time_t time), (client, time));
  206. DECL_FUNCTION(jack_time_t, jack_frames_to_time, (const jack_client_t *client, jack_nframes_t frames), (client, frames));
  207. DECL_FUNCTION(jack_nframes_t, jack_frame_time, (const jack_client_t *client), (client));
  208. DECL_FUNCTION(jack_nframes_t, jack_last_frame_time, (const jack_client_t *client), (client));
  209. DECL_FUNCTION(float, jack_cpu_load, (jack_client_t *client), (client));
  210. DECL_FUNCTION_NULL(pthread_t, jack_client_thread_id, (jack_client_t *client), (client));
  211. DECL_VOID_FUNCTION(jack_set_error_function, (print_function fun), (fun));
  212. DECL_VOID_FUNCTION(jack_set_info_function, (print_function fun), (fun));
  213. DECL_FUNCTION(float, jack_get_max_delayed_usecs, (jack_client_t *client), (client));
  214. DECL_FUNCTION(float, jack_get_xrun_delayed_usecs, (jack_client_t *client), (client));
  215. DECL_VOID_FUNCTION(jack_reset_max_delayed_usecs, (jack_client_t *client), (client));
  216. DECL_FUNCTION(int, jack_release_timebase, (jack_client_t *client), (client));
  217. DECL_FUNCTION(int, jack_set_sync_callback, (jack_client_t *client, JackSyncCallback sync_callback, void *arg), (client, sync_callback, arg));
  218. DECL_FUNCTION(int, jack_set_sync_timeout, (jack_client_t *client, jack_time_t timeout), (client, timeout));
  219. DECL_FUNCTION(int, jack_set_timebase_callback, (jack_client_t *client,
  220. int conditional,
  221. JackTimebaseCallback timebase_callback,
  222. void *arg), (client, conditional, timebase_callback, arg));
  223. DECL_FUNCTION(int, jack_transport_locate, (jack_client_t *client, jack_nframes_t frame), (client, frame));
  224. DECL_FUNCTION(jack_transport_state_t, jack_transport_query, (const jack_client_t *client, jack_position_t *pos), (client, pos));
  225. DECL_FUNCTION(jack_nframes_t, jack_get_current_transport_frame, (const jack_client_t *client), (client));
  226. DECL_FUNCTION(int, jack_transport_reposition, (jack_client_t *client, jack_position_t *pos), (client, pos));
  227. DECL_VOID_FUNCTION(jack_transport_start, (jack_client_t *client), (client));
  228. DECL_VOID_FUNCTION(jack_transport_stop, (jack_client_t *client), (client));
  229. DECL_VOID_FUNCTION(jack_get_transport_info, (jack_client_t *client, jack_transport_info_t *tinfo), (client,tinfo));
  230. DECL_VOID_FUNCTION(jack_set_transport_info, (jack_client_t *client, jack_transport_info_t *tinfo), (client,tinfo));
  231. DECL_FUNCTION(int, jack_client_real_time_priority, (jack_client_t* client), (client));
  232. DECL_FUNCTION(int, jack_client_max_real_time_priority, (jack_client_t* client), (client));
  233. DECL_FUNCTION(int, jack_acquire_real_time_scheduling, (pthread_t thread, int priority), (thread, priority));
  234. DECL_FUNCTION(int, jack_client_create_thread, (jack_client_t* client,
  235. pthread_t *thread,
  236. int priority,
  237. int realtime, // boolean
  238. thread_routine routine,
  239. void *arg), (client, thread, priority, realtime, routine, arg));
  240. DECL_FUNCTION(int, jack_drop_real_time_scheduling, (pthread_t thread), (thread));
  241. DECL_FUNCTION(int, jack_client_stop_thread, (jack_client_t* client, pthread_t thread), (client, thread));
  242. DECL_FUNCTION(int, jack_client_kill_thread, (jack_client_t* client, pthread_t thread), (client, thread));
  243. #ifndef WIN32
  244. DECL_VOID_FUNCTION(jack_set_thread_creator, (jack_thread_creator_t jtc), (jtc));
  245. #endif
  246. DECL_FUNCTION(char *, jack_get_internal_client_name, (jack_client_t *client, jack_intclient_t intclient), (client, intclient));
  247. 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));
  248. /*
  249. DECL_FUNCTION(jack_intclient_t, jack_internal_client_load, (jack_client_t *client,
  250. const char *client_name,
  251. jack_options_t options,
  252. jack_status_t *status
  253. , ...), (client, client_name, options, status, ...));
  254. */
  255. DECL_FUNCTION(jack_status_t, jack_internal_client_unload, (jack_client_t *client, jack_intclient_t intclient), (client, intclient));
  256. DECL_VOID_FUNCTION(jack_free, (void* ptr), (ptr));
  257. // MIDI
  258. DECL_FUNCTION(jack_nframes_t, jack_midi_get_event_count, (void* port_buffer), (port_buffer));
  259. 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)) ;
  260. DECL_VOID_FUNCTION(jack_midi_clear_buffer, (void* port_buffer), (port_buffer));
  261. DECL_FUNCTION(size_t, jack_midi_max_event_size, (void* port_buffer), (port_buffer));
  262. 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));
  263. 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));
  264. DECL_FUNCTION(jack_nframes_t, jack_midi_get_lost_event_count, (void* port_buffer), (port_buffer));