diff --git a/.gitmodules b/.gitmodules index 4d715329ec4..4a8c9adc1ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "plugins/LadspaEffect/tap/tap-plugins"] path = plugins/LadspaEffect/tap/tap-plugins url = https://github.com/tomszilagyi/tap-plugins +[submodule "src/3rdparty/weakjack/weakjack"] + path = src/3rdparty/weakjack/weakjack + url = https://github.com/x42/weakjack.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 99619b9e77b..6ec7bdae665 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -394,6 +394,7 @@ IF(WANT_JACK) IF(JACK_FOUND) IF(WANT_WEAKJACK) SET(LMMS_HAVE_WEAKJACK TRUE) + SET(WEAKJACK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/3rdparty/weakjack/weakjack) SET(STATUS_JACK "OK (weak linking enabled)") SET(JACK_INCLUDE_DIRS "") # use dlsym instead diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 0e14943311d..ddb46008903 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -108,6 +108,12 @@ if lsmod |grep vboxguest > /dev/null 2>&1; then echo "VirtualBox detected. Forcing libgl software rendering." export LIBGL_ALWAYS_SOFTWARE=1; fi +if ldconfig -p | grep libjack.so.0 > /dev/null 2>&1; then + echo "Jack appears to be installed on this system, so we'll use it." +else + echo "Jack does not appear to be installed. That's OK, we'll use a dummy version instead." + export LD_LIBRARY_PATH=\$DIR/usr/lib/lmms/optional:\$LD_LIBRARY_PATH +fi QT_X11_NO_NATIVE_MENUBAR=1 QT_AUTO_SCREEN_SCALE_FACTOR=1 \$DIR/usr/bin/lmms.real "\$@" EOL @@ -163,6 +169,12 @@ ln -sr "$VSTBIN" "$VSTLIB" # Remove wine library conflict rm -f "${APPDIR}/usr/lib/libwine.so.1" +# Remove problematic jack library, replace with weakjack +if [ -e "${APPDIR}/usr/lib/libjack.so.0" ]; then + rm -f "${APPDIR}/usr/lib/libjack.so.0" + ln -sr "${APPDIR}usr/lib/lmms/optional/libweakjack.so" "${APPDIR}usr/lib/lmms/optional/libjack.so.0" +fi + # Create AppImage echo -e "\nFinishing the AppImage..." echo -e "\n\n>>>>> appimagetool" >> "$LOGFILE" diff --git a/cmake/modules/CheckSubmodules.cmake b/cmake/modules/CheckSubmodules.cmake index d90cd622b87..6512617afd7 100644 --- a/cmake/modules/CheckSubmodules.cmake +++ b/cmake/modules/CheckSubmodules.cmake @@ -83,7 +83,7 @@ MACRO(GIT_SUBMODULE SUBMODULE_PATH FORCE_DEINIT) ) SET(GIT_MESSAGE "${GIT_STDOUT}${GIT_STDERR}") - MESSAGE(${GIT_MESSAGE}) + MESSAGE("${GIT_MESSAGE}") ENDIF() ENDMACRO() diff --git a/include/AudioJack.h b/include/AudioJack.h index 9bbb3bd4880..c3207c82984 100644 --- a/include/AudioJack.h +++ b/include/AudioJack.h @@ -31,7 +31,7 @@ #ifndef LMMS_HAVE_WEAKJACK #include #else -#include "AudioWeakJack.h" +#include "weak_libjack.h" #endif #include diff --git a/include/AudioWeakJack.def b/include/AudioWeakJack.def deleted file mode 100644 index 1684a56b0e1..00000000000 --- a/include/AudioWeakJack.def +++ /dev/null @@ -1,159 +0,0 @@ -/* macro-absraction of the JACK API - * - * see weak_libjack.c for details, in general arguments are: - * - * [required], [return type], [name], [arguments], [code or return value] - * - * This file is included multiple times with different macro definitions - * do not add header guards. - * see https://en.wikibooks.org/wiki/C_Programming/Preprocessor#X-Macros - */ - -#ifdef USE_WEAK_JACK - -/* */ -JCFUN(1, int, client_close, 0) -JCFUN(1, char*, get_client_name, NULL) -JVFUN(0, on_shutdown, (jack_client_t *c, JackShutdownCallback s, void *a), (c,s,a),) -JVFUN(0, on_info_shutdown, (jack_client_t *c, JackInfoShutdownCallback s, void *a), (c,s,a),) - -JPFUN(1, int, set_process_callback, (jack_client_t *c, JackProcessCallback p, void *a), (c,p,a), -1) -JPFUN(1, int, set_freewheel_callback, (jack_client_t *c, JackFreewheelCallback p, void *a), (c,p,a), -1) -JPFUN(1, int, set_buffer_size_callback, (jack_client_t *c, JackBufferSizeCallback p, void *a), (c,p,a), -1) -JPFUN(1, int, set_sample_rate_callback, (jack_client_t *c, JackSampleRateCallback p, void *a), (c,p,a), -1) -JPFUN(1, int, set_port_registration_callback, (jack_client_t *c, JackPortRegistrationCallback p, void *a), (c,p,a), -1) -JPFUN(1, int, set_port_connect_callback, (jack_client_t *c, JackPortConnectCallback p, void *a), (c,p,a), -1) -JPFUN(1, int, set_graph_order_callback, (jack_client_t *c, JackGraphOrderCallback g, void *a), (c,g,a), -1) -JPFUN(1, int, set_xrun_callback, (jack_client_t *c, JackXRunCallback g, void *a), (c,g,a), -1) -JPFUN(1, int, set_latency_callback, (jack_client_t *c, JackLatencyCallback g, void *a), (c,g,a), -1) -JVFUN(1, set_error_function, (void (*f)(const char *)), (f),) -JVFUN(1, set_info_function, (void (*f)(const char *)), (f),) - -JCFUN(1, int, activate, -1) -JCFUN(1, int, deactivate, -1) - -JPFUN(1, int, client_name_size, (), (), 32) - -JCFUN(1, jack_nframes_t, get_sample_rate, 0) -JCFUN(1, jack_nframes_t, get_buffer_size, 0) -JPFUN(1, jack_nframes_t, frames_since_cycle_start, (const jack_client_t *c), (c), 0) -JPFUN(1, jack_nframes_t, frame_time, (const jack_client_t *c), (c), 0) -JPFUN(1, jack_nframes_t, last_frame_time, (const jack_client_t *c), (c), 0) -JPFUN(1, jack_time_t, get_time, (void), (), 0) -JCFUN(1, float, cpu_load, 0) -JCFUN(1, int, is_realtime, 0) - -JPFUN(1, int, set_freewheel, (jack_client_t *c, int o), (c,o), 0) -JPFUN(1, int, set_buffer_size, (jack_client_t *c, jack_nframes_t b), (c,b), 0) - -JCFUN(0, int, recompute_total_latencies, 0) -JPFUN(0, jack_nframes_t, port_get_total_latency, (jack_client_t *c, jack_port_t *p), (c,p), 0) -JVFUN(0, port_get_latency_range, (jack_port_t *p, jack_latency_callback_mode_t m, jack_latency_range_t *r), (p,m,r), if (r) {r->min = r->max = 0;}) -JVFUN(0, port_set_latency_range, (jack_port_t *p, jack_latency_callback_mode_t m, jack_latency_range_t *r), (p,m,r),) - -JPFUN(1, void*, port_get_buffer, (jack_port_t *p, jack_nframes_t n), (p,n), NULL) -JPFUN(1, int, port_request_monitor, (jack_port_t *p, int o), (p,o), 0) -JPFUN(1, int, port_ensure_monitor, (jack_port_t *p, int o), (p,o), 0) -JPFUN(1, int, port_monitoring_input, (jack_port_t *p), (p), 0) - -JPFUN(1, const char*, port_name, (const jack_port_t *p), (p), NULL) -JPFUN(1, const char*, port_short_name, (const jack_port_t *p), (p), NULL) -JPFUN(1, int, port_flags, (const jack_port_t *p), (p), 0) -JPFUN(1, const char**, get_ports,(jack_client_t *c, const char *p, const char *t, unsigned long f), (c,p,t,f), NULL) -JPFUN(1, int, port_name_size, (void), (), 0) -JPFUN(1, int, port_type_size, (void), (), 0) -JPFUN(1, size_t, port_type_get_buffer_size, (jack_client_t *c, const char *t), (c,t), 0) -JPFUN(1, jack_port_t*, port_by_name, (jack_client_t *c, const char *n), (c,n), NULL) -JPFUN(1, jack_port_t*, port_by_id, (jack_client_t *c, jack_port_id_t i), (c,i), NULL) -JPFUN(1, jack_port_t*, port_register, (jack_client_t *c, const char *n, const char *t, unsigned long f, unsigned long b), (c,n,t,f,b), NULL) -JPFUN(1, int, port_unregister, (jack_client_t *c, jack_port_t *p), (c,p), 0) -JPFUN(1, const char *, port_type, (const jack_port_t *p), (p), 0) -JPFUN(1, const char **, port_get_connections, (const jack_port_t *p), (p), 0) -JPFUN(1, const char **, port_get_all_connections, (const jack_client_t *c, const jack_port_t *p), (c,p), 0) -JPFUN(1, int, port_set_name, (jack_port_t *p, const char *n), (p,n), -1) -JXFUN(0, int, port_rename, (jack_client_t *c, jack_port_t *p, const char *n), (c,p,n), return jack_port_set_name (p,n);) -JPFUN(1, int, port_get_aliases, (const jack_port_t *port, char* const aliases[2]), (port,aliases), 0) -JPFUN(1, int, port_disconnect, (jack_client_t *c, jack_port_t *p), (c,p), 0) -JPFUN(1, int, connect, (jack_client_t *c, const char *s, const char *d), (c,s,d), -1) -JPFUN(1, int, disconnect, (jack_client_t *c, const char *s, const char *d), (c,s,d), -1) -JVFUN(0, free, (void *p), (p), free(p);) - -JCFUN(1, jack_nframes_t, cycle_wait, 0) -JVFUN(1, cycle_signal, (jack_client_t *c, int s), (c,s),) -JPFUN(1, int, set_process_thread, (jack_client_t *c, JackThreadCallback p, void *a), (c,p,a), -1) -JPFUN(1, int, set_thread_init_callback, (jack_client_t *c, JackThreadInitCallback p, void *a), (c,p,a), -1) - -JPFUN(1, int, transport_locate, (jack_client_t *c, jack_nframes_t f), (c,f), 0) -JVFUN(1, transport_start, (jack_client_t *c), (c),) -JVFUN(1, transport_stop, (jack_client_t *c), (c),) -JPFUN(1, jack_nframes_t, get_current_transport_frame, (const jack_client_t *c), (c), 0) -JXFUN(1, jack_transport_state_t, transport_query, (const jack_client_t *c, jack_position_t *p), (c,p), memset(p, 0, sizeof(jack_position_t)); return JackTransportStopped;) -JPFUN(1, int, set_sync_callback, (jack_client_t *c, JackSyncCallback p, void *a), (c,p,a), -1) -JPFUN(1, int, set_timebase_callback, (jack_client_t *c, int l, JackTimebaseCallback p, void *a), (c,l,p,a), -1) -JCFUN(1, int, release_timebase, 0) - -/* */ -JPFUN(1, uint32_t, midi_get_event_count, (void* p), (p), 0) -JPFUN(1, int, midi_event_get, (jack_midi_event_t *e, void *p, uint32_t i), (e,p,i), -1) -JPFUN(1, int, midi_event_write, (void *b, jack_nframes_t t, const jack_midi_data_t *d, size_t s), (b,t,d,s), -1) -JVFUN(1, midi_clear_buffer, (void *b), (b),) - -/* */ -JPFUN(0, int, set_session_callback, (jack_client_t *c, JackSessionCallback s, void *a), (c,s,a), -1) -JPFUN(0, int, session_reply, (jack_client_t *c, jack_session_event_t *e), (c,e), -1) -JVFUN(0, session_event_free, (jack_session_event_t *e), (e), ) - -/* */ -JPFUN(1, jack_ringbuffer_t *, ringbuffer_create, (size_t s), (s), NULL) -JVFUN(1, ringbuffer_free, (jack_ringbuffer_t *rb), (rb), ) -JVFUN(1, ringbuffer_reset, (jack_ringbuffer_t *rb), (rb), ) -JVFUN(1, ringbuffer_read_advance, (jack_ringbuffer_t *rb, size_t c), (rb,c), ) -JVFUN(1, ringbuffer_write_advance, (jack_ringbuffer_t *rb, size_t c), (rb,c), ) -JPFUN(1, size_t, ringbuffer_read_space, (const jack_ringbuffer_t *rb), (rb), 0) -JPFUN(1, size_t, ringbuffer_write_space, (const jack_ringbuffer_t *rb), (rb), 0) -JPFUN(1, size_t, ringbuffer_read, (jack_ringbuffer_t *rb, char *d, size_t c), (rb,d,c), 0) -JPFUN(1, size_t, ringbuffer_write, (jack_ringbuffer_t *rb, const char *s, size_t c), (rb,s,c), 0) -JPFUN(0, int, ringbuffer_mlock, (jack_ringbuffer_t *rb), (rb), 0) -JVFUN(0, ringbuffer_get_read_vector, (const jack_ringbuffer_t *rb, jack_ringbuffer_data_t *v), (rb,v), if (v) {v->buf=NULL; v->len=0;} ) -JVFUN(0, ringbuffer_get_write_vector, (const jack_ringbuffer_t *rb, jack_ringbuffer_data_t *v), (rb,v), if (v) {v->buf=NULL; v->len=0;} ) -JPFUN(0, size_t, ringbuffer_peek, (jack_ringbuffer_t *rb, char *d, size_t c), (rb,d,c), 0) - -/* */ -JCFUN(0, int, client_real_time_priority, 0) -JCFUN(0, int, client_max_real_time_priority, 0) -JPFUN(0, int, acquire_real_time_scheduling, (jack_native_thread_t t, int p), (t,p), 0) -JPFUN(0, int, drop_real_time_scheduling, (jack_native_thread_t t), (t), 0) -JPFUN(0, int, client_stop_thread, (jack_client_t* c, jack_native_thread_t t), (c,t), 0) -JPFUN(0, int, client_kill_thread, (jack_client_t* c, jack_native_thread_t t), (c,t), 0) -#ifndef _WIN32 -JVFUN(0, set_thread_creator, (jack_thread_creator_t c), (c),) -#endif -JPFUN(1, int, client_create_thread, \ - (jack_client_t* c, jack_native_thread_t *t, int p, int r, void *(*f)(void*), void *a), (c,t,p,r,f,a), 0) - -#ifndef NO_JACK_METADATA -/* - TODO*/ - -/* */ -JPFUN(0, char *, get_uuid_for_client_name, (jack_client_t* c, const char* n), (c,n), NULL) -JPFUN(0, char *, get_client_name_by_uuid, (jack_client_t* c, const char* u), (c,u), NULL) -JPFUN(0, jack_uuid_t, port_uuid, (const jack_port_t *p), (p), 0) - -/* */ -JPFUN(0, int, set_property, (jack_client_t* c, jack_uuid_t s, const char* k, const char* v, const char* t), (c,s,k,v,t), -1) -JXFUN(0, int, get_property, (jack_uuid_t s, const char* k, char** v, char** t), (s,k,v,t), if (v) *v=NULL; if (t) *t=NULL; return -1;) -JVFUN(0, free_description, (jack_description_t* d, int f), (d,f),) -JXFUN(0, int, get_properties, (jack_uuid_t s, jack_description_t* d), (s,d), if (d) {d->properties = NULL; d->property_cnt = 0;} return -1;) -JXFUN(0, int, get_all_properties, (jack_description_t** d), (d), if (d) *d=NULL; return -1;) -JPFUN(0, int, remove_property, (jack_client_t* c, jack_uuid_t s, const char* k), (c,s,k), -1) -JPFUN(0, int, remove_properties, (jack_client_t* c, jack_uuid_t s), (c,s), -1) -JPFUN(0, int, remove_all_properties, (jack_client_t* c), (c), -1) -JPFUN(0, int, set_property_change_callback, (jack_client_t *c, JackPropertyChangeCallback s, void *a), (c,s,a), -1) -#endif - -/* */ -JCFUN(1, float, get_max_delayed_usecs, 0.0) -JCFUN(1, float, get_xrun_delayed_usecs, 0.0) -JVFUN(0, reset_max_delayed_usecs, (jack_client_t *c), (c),) - -#endif // end USE_WEAK_JACK diff --git a/include/AudioWeakJack.h b/include/AudioWeakJack.h deleted file mode 100644 index e53fced8eaa..00000000000 --- a/include/AudioWeakJack.h +++ /dev/null @@ -1,237 +0,0 @@ -/* runtime/weak dynamic JACK linking - * - * (C) 2014 Robin Gareus - * - * The wrapped jack API itself is - * (C) 2001 Paul Davis - * (C) 2004 Jack O'Quin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#ifndef _WEAK_JACK_H -#define _WEAK_JACK_H - -// LMMS uses LMMS_HAVE_WEAKJACK instead -#ifndef USE_WEAK_JACK -#define USE_WEAK_JACK -#endif - -// LMMS doesn't use metadata.h -#ifndef NO_JACK_METADATA -#define NO_JACK_METADATA -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** check if libjack is available - * - * return 0 if libjack is dynamically linked of was - * successfully dl-opened. Otherwise: - * - * -1: library was not initialized - * -2: libjack was not found - * > 0 bitwise flags: - * 1: a required function was not found in libjack - * 2: jack_client_open was not found in libjack - */ -int have_libjack(void); - -#ifdef __cplusplus -} -#endif - -#ifdef USE_WEAK_JACK - -/* */ -#define jack_client_close WJACK_client_close -#define jack_get_client_name WJACK_get_client_name -#define jack_get_sample_rate WJACK_get_sample_rate -#define jack_get_buffer_size WJACK_get_buffer_size -#define jack_frames_since_cycle_start WJACK_frames_since_cycle_start -#define jack_frame_time WJACK_frame_time -#define jack_last_frame_time WJACK_last_frame_time -#define jack_get_time WJACK_get_time -#define jack_cpu_load WJACK_cpu_load -#define jack_is_realtime WJACK_is_realtime - -#define jack_client_name_size WJACK_client_name_size - -#define jack_set_freewheel WJACK_set_freewheel -#define jack_set_buffer_size WJACK_set_buffer_size - -#define jack_on_shutdown WJACK_on_shutdown -#define jack_on_info_shutdown WJACK_on_info_shutdown -#define jack_set_process_callback WJACK_set_process_callback -#define jack_set_freewheel_callback WJACK_set_freewheel_callback -#define jack_set_buffer_size_callback WJACK_set_buffer_size_callback -#define jack_set_sample_rate_callback WJACK_set_sample_rate_callback -#define jack_set_port_registration_callback WJACK_set_port_registration_callback -#define jack_set_port_connect_callback WJACK_set_port_connect_callback -#define jack_set_graph_order_callback WJACK_set_graph_order_callback -#define jack_set_xrun_callback WJACK_set_xrun_callback -#define jack_set_latency_callback WJACK_set_latency_callback -#define jack_set_error_function WJACK_set_error_function -#define jack_set_info_function WJACK_set_info_function - -#define jack_activate WJACK_activate -#define jack_deactivate WJACK_deactivate - -#define jack_recompute_total_latencies WJACK_recompute_total_latencies -#define jack_port_get_total_latency WJACK_port_get_total_latency -#define jack_port_get_latency_range WJACK_port_get_latency_range -#define jack_port_set_latency_range WJACK_port_set_latency_range -#define jack_port_get_buffer WJACK_port_get_buffer -#define jack_port_request_monitor WJACK_port_request_monitor -#define jack_port_ensure_monitor WJACK_port_ensure_monitor -#define jack_port_monitoring_input WJACK_port_monitoring_input - -#define jack_port_name WJACK_port_name -#define jack_port_short_name WJACK_port_short_name -#define jack_port_flags WJACK_port_flags -#define jack_get_ports WJACK_get_ports -#define jack_port_name_size WJACK_port_name_size -#define jack_port_type_size WJACK_port_type_size -#define jack_port_type_get_buffer_size WJACK_port_type_get_buffer_size -#define jack_port_by_name WJACK_port_by_name -#define jack_port_by_id WJACK_port_by_id -#define jack_port_set_name WJACK_port_set_name -#define jack_port_get_aliases WJACK_port_get_aliases -#define jack_port_rename WJACK_port_rename -#define jack_port_disconnect WJACK_port_disconnect -#define jack_port_register WJACK_port_register -#define jack_port_unregister WJACK_port_unregister -#define jack_port_type WJACK_port_type -#define jack_port_get_connections WJACK_port_get_connections -#define jack_port_get_all_connections WJACK_port_get_all_connections -#define jack_connect WJACK_connect -#define jack_disconnect WJACK_disconnect -#define jack_free WJACK_free - -#define jack_cycle_wait WJACK_cycle_wait -#define jack_cycle_signal WJACK_cycle_signal -#define jack_set_process_thread WJACK_set_process_thread -#define jack_set_thread_init_callback WJACK_set_thread_init_callback - -/* */ -#define jack_get_current_transport_frame WJACK_get_current_transport_frame -#define jack_transport_locate WJACK_transport_locate -#define jack_transport_start WJACK_transport_start -#define jack_transport_stop WJACK_transport_stop -#define jack_transport_query WJACK_transport_query -#define jack_set_sync_callback WJACK_set_sync_callback -#define jack_set_timebase_callback WJACK_set_timebase_callback -#define jack_release_timebase WJACK_release_timebase - -/* */ -#define jack_midi_get_event_count WJACK_midi_get_event_count -#define jack_midi_event_get WJACK_midi_event_get -#define jack_midi_event_write WJACK_midi_event_write -#define jack_midi_clear_buffer WJACK_midi_clear_buffer - -/* */ -#define jack_set_session_callback WJACK_set_session_callback -#define jack_session_reply WJACK_session_reply -#define jack_session_event_free WJACK_session_event_free - -/* */ -#define jack_ringbuffer_create WJACK_ringbuffer_create -#define jack_ringbuffer_free WJACK_ringbuffer_free -#define jack_ringbuffer_reset WJACK_ringbuffer_reset -#define jack_ringbuffer_read_advance WJACK_ringbuffer_read_advance -#define jack_ringbuffer_write_advance WJACK_ringbuffer_write_advance -#define jack_ringbuffer_read_space WJACK_ringbuffer_read_space -#define jack_ringbuffer_write_space WJACK_ringbuffer_write_space -#define jack_ringbuffer_read WJACK_ringbuffer_read -#define jack_ringbuffer_write WJACK_ringbuffer_write -#define jack_ringbuffer_mlock WJACK_ringbuffer_mlock -#define jack_ringbuffer_get_read_vector WJACK_ringbuffer_get_read_vector -#define jack_ringbuffer_get_write_vector WJACK_ringbuffer_get_write_vector -#define jack_ringbuffer_peek WJACK_ringbuffer_peek - -/* */ -#define jack_client_real_time_priority WJACK_client_real_time_priority -#define jack_client_max_real_time_priority WJACK_client_max_real_time_priority -#define jack_acquire_real_time_scheduling WJACK_acquire_real_time_scheduling -#define jack_client_create_thread WJACK_client_create_thread -#define jack_drop_real_time_scheduling WJACK_drop_real_time_scheduling -#define jack_client_stop_thread WJACK_client_stop_thread -#define jack_client_kill_thread WJACK_client_kill_thread -#define jack_set_thread_creator WJACK_set_thread_creator - -#define jack_client_open WJACK_client_client_openXXX - -#ifndef NO_JACK_METADATA -/* */ -#define jack_get_uuid_for_client_name WJACK_get_uuid_for_client_name -#define jack_get_client_name_by_uuid WJACK_get_client_name_by_uuid -#define jack_port_uuid WJACK_port_uuid - -#define jack_set_property WJACK_set_property -#define jack_get_property WJACK_get_property -#define jack_free_description WJACK_free_description -#define jack_get_properties WJACK_get_properties -#define jack_get_all_properties WJACK_get_all_properties -#define jack_remove_property WJACK_remove_property -#define jack_remove_properties WJACK_remove_properties -#define jack_remove_all_properties WJACK_remove_all_properties -#define jack_set_property_change_callback WJACK_set_property_change_callback -#endif - -/* */ -#define jack_get_max_delayed_usecs WJACK_get_max_delayed_usecs -#define jack_get_xrun_delayed_usecs WJACK_get_xrun_delayed_usecs -#define jack_reset_max_delayed_usecs WJACK_reset_max_delayed_usecs - -#endif // end USE_WEAK_JACK - -#include -#include -#include -#include -#include -#include - -#ifndef NO_JACK_METADATA -#include -#endif - -#ifdef USE_WEAK_JACK - -#undef jack_client_open - -/* var-args hack */ - -#ifdef __cplusplus -extern "C" { -#endif -void (* WJACK_get_client_open (void)) (void); -jack_client_t * WJACK_no_client_open (const char *client_name, jack_options_t options, jack_status_t *status, ...); -#ifdef __cplusplus -} -#endif - -#define jack_client_open(...) \ -( \ - (WJACK_get_client_open() != NULL) \ - ? ((jack_client_t* (*)(const char *, jack_options_t, jack_status_t *, ...))(WJACK_get_client_open()))(__VA_ARGS__) \ - : WJACK_no_client_open(__VA_ARGS__) \ -) - -#endif // end USE_WEAK_JACK - -#endif // _WEAK_JACK_H diff --git a/include/MidiJack.h b/include/MidiJack.h index b3634bc34a8..8ebb6925f51 100644 --- a/include/MidiJack.h +++ b/include/MidiJack.h @@ -32,7 +32,7 @@ #include #include #else -#include "AudioWeakJack.h" +#include "weak_libjack.h" #endif #include diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index 4067413e3d5..3b7c62f514c 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -2,3 +2,4 @@ set(CMAKE_C_FLAGS "") set(CMAKE_CXX_FLAGS "") ADD_SUBDIRECTORY(rpmalloc) +ADD_SUBDIRECTORY(weakjack) diff --git a/src/3rdparty/weakjack/CMakeLists.txt b/src/3rdparty/weakjack/CMakeLists.txt new file mode 100644 index 00000000000..b9f24e33132 --- /dev/null +++ b/src/3rdparty/weakjack/CMakeLists.txt @@ -0,0 +1,12 @@ +# Use weak jack library linking +IF(LMMS_HAVE_WEAKJACK) + SET(CMAKE_C_FLAGS "-std=c11") + + # Enable weakjack, disable metadata support + ADD_DEFINITIONS(-DUSE_WEAK_JACK=1 -DNO_JACK_METADATA=1) + + # Library stub for AppImages running on systems without jack + ADD_LIBRARY(weakjack MODULE weakjack/weak_libjack.c weakjack/weak_libjack.h) + TARGET_INCLUDE_DIRECTORIES(weakjack PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/weakjack) + INSTALL(TARGETS weakjack LIBRARY DESTINATION "${PLUGIN_DIR}/optional") +ENDIF() diff --git a/src/3rdparty/weakjack/weakjack b/src/3rdparty/weakjack/weakjack new file mode 160000 index 00000000000..bffe90c8b18 --- /dev/null +++ b/src/3rdparty/weakjack/weakjack @@ -0,0 +1 @@ +Subproject commit bffe90c8b18c0b0f9c5840528fbb995e2cc8b84a diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 28d2455b030..cd5d704b73a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,6 +67,13 @@ ELSEIF(NOT ("${SDL_INCLUDE_DIR}" STREQUAL "")) INCLUDE_DIRECTORIES("${SDL_INCLUDE_DIR}") ENDIF() +IF(LMMS_HAVE_WEAKJACK) + LIST(APPEND LMMS_SRCS "${WEAKJACK_INCLUDE_DIRS}/weak_libjack.c") + LIST(APPEND LMMS_INCLUDES "${WEAKJACK_INCLUDE_DIRS}/weak_libjack.h") + INCLUDE_DIRECTORIES("${WEAKJACK_INCLUDE_DIRS}") + ADD_DEFINITIONS(-DUSE_WEAK_JACK=1 -DNO_JACK_METADATA=1) +ENDIF() + IF(NOT ("${PORTAUDIO_INCLUDE_DIR}" STREQUAL "")) INCLUDE_DIRECTORIES("${PORTAUDIO_INCLUDE_DIR}") ENDIF() diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d9ef34bcdc5..604a63c040e 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,7 +1,3 @@ -IF(LMMS_HAVE_WEAKJACK) - set(WEAKJACK core/audio/AudioWeakJack.c) -ENDIF() - set(LMMS_SRCS ${LMMS_SRCS} core/AutomatableModel.cpp @@ -77,7 +73,6 @@ set(LMMS_SRCS core/audio/AudioFileOgg.cpp core/audio/AudioFileFlac.cpp core/audio/AudioFileWave.cpp - ${WEAKJACK} core/audio/AudioJack.cpp core/audio/AudioOss.cpp core/audio/AudioSndio.cpp diff --git a/src/core/audio/AudioWeakJack.c b/src/core/audio/AudioWeakJack.c deleted file mode 100644 index 5cf93cdd839..00000000000 --- a/src/core/audio/AudioWeakJack.c +++ /dev/null @@ -1,273 +0,0 @@ -/* runtime/weak dynamic JACK linking - * - * (C) 2014 Robin Gareus - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "AudioWeakJack.h" - -#ifndef USE_WEAK_JACK - -int have_libjack (void) { - return 0; -} - -#else - -#include -#include -#include - -#ifdef _WIN32 -#include -#else -#include -#endif - -static void* lib_open(const char* const so) { -#ifdef _WIN32 - return (void*) LoadLibraryA(so); -#else - return dlopen(so, RTLD_NOW|RTLD_LOCAL); -#endif -} - -static void* lib_symbol(void* const lib, const char* const sym) { -#ifdef _WIN32 - return (void*) GetProcAddress((HMODULE)lib, sym); -#else - return dlsym(lib, sym); -#endif -} - -#if _MSC_VER && !__INTEL_COMPILER -typedef void * pvoid_t; -#define MAPSYM(SYM, FAIL) _j._ ## SYM = (func_t)lib_symbol(lib, "jack_" # SYM); \ - if (!_j._ ## SYM) err |= FAIL; -#elif defined NDEBUG -typedef void * __attribute__ ((__may_alias__)) pvoid_t; -#define MAPSYM(SYM, FAIL) *(pvoid_t *)(&_j._ ## SYM) = lib_symbol(lib, "jack_" # SYM); \ - if (!_j._ ## SYM) err |= FAIL; -#else -typedef void * __attribute__ ((__may_alias__)) pvoid_t; -#define MAPSYM(SYM, FAIL) *(pvoid_t *)(&_j._ ## SYM) = lib_symbol(lib, "jack_" # SYM); \ - if (!_j._ ## SYM) { \ - if (FAIL) { \ - fprintf(stderr, "*** WEAK-JACK: required symbol 'jack_%s' was not found\n", "" # SYM); \ - } \ - err |= FAIL; \ - } -#endif - -typedef void (* func_t) (void); - -/* function pointers to the real jack API */ -static struct WeakJack { - func_t _client_open; // special case due to varargs - -#define JCFUN(ERR, RTYPE, NAME, RVAL) func_t _ ## NAME ; -#define JPFUN(ERR, RTYPE, NAME, DEF, ARGS, RVAL) func_t _ ## NAME ; -#define JXFUN(ERR, RTYPE, NAME, DEF, ARGS, CODE) func_t _ ## NAME ; -#define JVFUN(ERR, NAME, DEF, ARGS, CODE) func_t _ ## NAME ; - -#include "AudioWeakJack.def" - -#undef JCFUN -#undef JPFUN -#undef JXFUN -#undef JVFUN -} _j; - -static int _status = -1; - -__attribute__((constructor)) -static void init_weak_jack(void) -{ - void* lib; - int err = 0; -#ifndef NDEBUG - fprintf(stderr, "*** WEAK-JACK: initializing\n"); -#endif - - memset(&_j, 0, sizeof(_j)); - -#ifdef __APPLE__ - lib = lib_open("libjack.dylib"); - if (!lib) { - lib = lib_open("/usr/local/lib/libjack.dylib"); - } -#elif (defined _WIN32) -# ifdef __x86_64__ - lib = lib_open("libjack64.dll"); -# else - lib = lib_open("libjack.dll"); -# endif -#else - lib = lib_open("libjack.so.0"); -#endif - if (!lib) { -#ifndef NDEBUG - fprintf(stderr, "*** WEAK-JACK: libjack was not found\n"); -#endif - _status = -2; - return; - } - - /* found library, now lookup functions */ - MAPSYM(client_open, 2) - -#define JCFUN(ERR, RTYPE, NAME, RVAL) MAPSYM(NAME, ERR) -#define JPFUN(ERR, RTYPE, NAME, DEF, ARGS, RVAL) MAPSYM(NAME, ERR) -#define JXFUN(ERR, RTYPE, NAME, DEF, ARGS, CODE) MAPSYM(NAME, ERR) -#define JVFUN(ERR, NAME, DEF, ARGS, CODE) MAPSYM(NAME, ERR) - -#include "AudioWeakJack.def" - -#undef JCFUN -#undef JPFUN -#undef JXFUN -#undef JVFUN - - /* if a required symbol is not found, disable JACK completly */ - if (err) { - _j._client_open = NULL; - } - _status = err; -#ifndef NDEBUG - fprintf(stderr, "*** WEAK-JACK: %s. (%d)\n", err ? "jack is not available" : "OK", _status); -#endif -} - -int have_libjack (void) { - if (_status == -1) { - init_weak_jack(); - } - return _status; -} - -/******************************************************************************* - * helper macros - */ - -#if defined(__GNUC__) && (__GNUC__ > 2) && !defined(NDEBUG) -#define likely(expr) (__builtin_expect (!!(expr), 1)) -#else -#define likely(expr) (expr) -#endif - -#ifndef NDEBUG -# define WJACK_WARNING(NAME) \ - fprintf(stderr, "*** WEAK-JACK: function 'jack_%s' ignored\n", "" # NAME); -#else -# define WJACK_WARNING(NAME) ; -#endif - -/****************************************************************************** - * JACK API wrapper functions. - * - * if a function pointer is set in the static struct WeakJack _j, - * the function is called directly. - * Otherwise a dummy NOOP implementation is provided. - * The latter is mainly for compile-time warnings. - * - * If libjack is not found, jack_client_open() will fail. - * In that case the application should not call any other libjack - * functions. Hence a real implementation is not needed. - * (jack ringbuffer may be an exception for some apps) - */ - -/* dedicated support for jack_client_open(,..) variable arg function macro */ -func_t WJACK_get_client_open(void) { - if (_status == -1) { - init_weak_jack(); - } - return _j._client_open; -} - -/* callback to set status */ -jack_client_t * WJACK_no_client_open (const char *client_name, jack_options_t options, jack_status_t *status, ...) { - WJACK_WARNING(client_open); - if (status) { *status = JackFailure; } - return NULL; -} - -/******************************************************************************* - * Macros to wrap jack API - */ - -/* abstraction for jack_client functions - * rtype jack_function_name (jack_client_t *client) { return rval; } - */ -#define JCFUN(ERR, RTYPE, NAME, RVAL) \ - RTYPE WJACK_ ## NAME (jack_client_t *client) { \ - if likely(_j._ ## NAME) { \ - return ((RTYPE (*)(jack_client_t *client)) _j._ ## NAME)(client); \ - } else { \ - WJACK_WARNING(NAME) \ - return RVAL; \ - } \ - } - -/* abstraction for NOOP functions with return value - * rtype jack_function_name (ARGS) { return rval; } - */ -#define JPFUN(ERR, RTYPE, NAME, DEF, ARGS, RVAL) \ - RTYPE WJACK_ ## NAME DEF { \ - if likely(_j._ ## NAME) { \ - return ((RTYPE (*)DEF) _j._ ## NAME) ARGS; \ - } else { \ - WJACK_WARNING(NAME) \ - return RVAL; \ - } \ - } - -/* abstraction for functions that need custom code. - * e.g. functions with return-value-pointer args, - * use CODE to initialize value - * - * rtype jack_function_name (ARGS) { CODE } - */ -#define JXFUN(ERR, RTYPE, NAME, DEF, ARGS, CODE) \ - RTYPE WJACK_ ## NAME DEF { \ - if likely(_j._ ## NAME) { \ - return ((RTYPE (*)DEF) _j._ ## NAME) ARGS; \ - } else { \ - WJACK_WARNING(NAME) \ - CODE \ - } \ - } - -/* abstraction for void functions with return-value-pointer args - * void jack_function_name (ARGS) { CODE } - */ -#define JVFUN(ERR, NAME, DEF, ARGS, CODE) \ - void WJACK_ ## NAME DEF { \ - if likely(_j._ ## NAME) { \ - ((void (*)DEF) _j._ ## NAME) ARGS; \ - } else { \ - WJACK_WARNING(NAME) \ - CODE \ - } \ - } - -#include "AudioWeakJack.def" - -#undef JCFUN -#undef JPFUN -#undef JXFUN -#undef JVFUN - -#endif // end USE_WEAK_JACK