DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

JackBridge.cpp (84696B)


      1 /*
      2  * JackBridge for DPF
      3  * Copyright (C) 2013-2022 Filipe Coelho <falktx@falktx.com>
      4  *
      5  * Permission to use, copy, modify, and/or distribute this software for any purpose with
      6  * or without fee is hereby granted, provided that the above copyright notice and this
      7  * permission notice appear in all copies.
      8  *
      9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
     10  * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
     11  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
     12  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
     13  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 #include "JackBridge.hpp"
     18 #include "../../DistrhoStandaloneUtils.hpp"
     19 
     20 #if ! (defined(JACKBRIDGE_DIRECT) || defined(JACKBRIDGE_DUMMY))
     21 
     22 #ifdef __WINE__
     23 # ifndef NOMINMAX
     24 #  define NOMINMAX
     25 # endif
     26 # include <windows.h>
     27 # include <pthread.h>
     28 #endif
     29 
     30 #if defined(DISTRHO_OS_WINDOWS) && ! defined(__WINE__)
     31 # define JACKSYM_API __cdecl
     32 #else
     33 # define JACKSYM_API
     34 #endif
     35 
     36 #include <cerrno>
     37 
     38 #ifdef HAVE_JACK
     39 # include "../../extra/LibraryUtils.hpp"
     40 #else
     41 typedef void* lib_t;
     42 #endif
     43 
     44 // in case JACK fails, we fallback to native bridges simulating JACK API
     45 #include "NativeBridge.hpp"
     46 
     47 #if defined(DISTRHO_OS_WASM)
     48 # include "WebBridge.hpp"
     49 #endif
     50 
     51 #ifndef DISTRHO_PROPER_CPP11_SUPPORT
     52 # undef HAVE_RTAUDIO
     53 #endif
     54 
     55 #ifdef DPF_JACK_STANDALONE_SKIP_RTAUDIO_FALLBACK
     56 # undef HAVE_RTAUDIO
     57 #endif
     58 
     59 #ifdef DPF_JACK_STANDALONE_SKIP_SDL2_FALLBACK
     60 # undef HAVE_SDL2
     61 #endif
     62 
     63 #if defined(HAVE_RTAUDIO) && DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
     64 // fix conflict between DGL and macOS names
     65 # define Point CorePoint
     66 # define Size CoreSize
     67 # include "RtAudioBridge.hpp"
     68 # ifdef RTAUDIO_API_TYPE
     69 #  include "rtaudio/RtAudio.cpp"
     70 # endif
     71 # ifdef RTMIDI_API_TYPE
     72 #  include "rtmidi/RtMidi.cpp"
     73 # endif
     74 # undef Point
     75 # undef Size
     76 #endif
     77 
     78 #if defined(HAVE_SDL2) && DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
     79 # include "SDL2Bridge.hpp"
     80 #endif
     81 
     82 // -----------------------------------------------------------------------------
     83 
     84 extern "C" {
     85 
     86 typedef void (JACKSYM_API *JackSymLatencyCallback)(jack_latency_callback_mode_t, void*);
     87 typedef int  (JACKSYM_API *JackSymProcessCallback)(jack_nframes_t, void*);
     88 typedef void (JACKSYM_API *JackSymThreadInitCallback)(void*);
     89 typedef int  (JACKSYM_API *JackSymGraphOrderCallback)(void*);
     90 typedef int  (JACKSYM_API *JackSymXRunCallback)(void*);
     91 typedef int  (JACKSYM_API *JackSymBufferSizeCallback)(jack_nframes_t, void*);
     92 typedef int  (JACKSYM_API *JackSymSampleRateCallback)(jack_nframes_t, void*);
     93 typedef void (JACKSYM_API *JackSymPortRegistrationCallback)(jack_port_id_t, int, void*);
     94 typedef void (JACKSYM_API *JackSymClientRegistrationCallback)(const char*, int, void*);
     95 typedef void (JACKSYM_API *JackSymPortConnectCallback)(jack_port_id_t, jack_port_id_t, int, void*);
     96 typedef void (JACKSYM_API *JackSymPortRenameCallback)(jack_port_id_t, const char*, const char*, void*);
     97 typedef void (JACKSYM_API *JackSymFreewheelCallback)(int, void*);
     98 typedef void (JACKSYM_API *JackSymShutdownCallback)(void*);
     99 typedef void (JACKSYM_API *JackSymInfoShutdownCallback)(jack_status_t, const char*, void*);
    100 typedef int  (JACKSYM_API *JackSymSyncCallback)(jack_transport_state_t, jack_position_t*, void*);
    101 typedef void (JACKSYM_API *JackSymTimebaseCallback)(jack_transport_state_t, jack_nframes_t, jack_position_t*, int, void*);
    102 typedef void (JACKSYM_API *JackSymSessionCallback)(jack_session_event_t*, void*);
    103 typedef void (JACKSYM_API *JackSymPropertyChangeCallback)(jack_uuid_t, const char*, jack_property_change_t, void*);
    104 typedef void* (JACKSYM_API *JackSymThreadCallback)(void*);
    105 
    106 typedef void        (JACKSYM_API *jacksym_get_version)(int*, int*, int*, int*);
    107 typedef const char* (JACKSYM_API *jacksym_get_version_string)(void);
    108 
    109 typedef jack_client_t* (JACKSYM_API *jacksym_client_open)(const char*, jack_options_t, jack_status_t*, ...);
    110 typedef int            (JACKSYM_API *jacksym_client_close)(jack_client_t*);
    111 
    112 typedef int   (JACKSYM_API *jacksym_client_name_size)(void);
    113 typedef char* (JACKSYM_API *jacksym_get_client_name)(jack_client_t*);
    114 
    115 typedef char* (JACKSYM_API *jacksym_client_get_uuid)(jack_client_t*);
    116 typedef char* (JACKSYM_API *jacksym_get_uuid_for_client_name)(jack_client_t*, const char*);
    117 typedef char* (JACKSYM_API *jacksym_get_client_name_by_uuid)(jack_client_t*, const char*);
    118 
    119 typedef int  (JACKBRIDGE_API *jacksym_uuid_parse)(const char*, jack_uuid_t*);
    120 typedef void (JACKBRIDGE_API *jacksym_uuid_unparse)(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]);
    121 
    122 typedef int (JACKSYM_API *jacksym_activate)(jack_client_t*);
    123 typedef int (JACKSYM_API *jacksym_deactivate)(jack_client_t*);
    124 typedef int (JACKSYM_API *jacksym_is_realtime)(jack_client_t*);
    125 
    126 typedef int  (JACKSYM_API *jacksym_set_thread_init_callback)(jack_client_t*, JackSymThreadInitCallback, void*);
    127 typedef void (JACKSYM_API *jacksym_on_shutdown)(jack_client_t*, JackSymShutdownCallback, void*);
    128 typedef void (JACKSYM_API *jacksym_on_info_shutdown)(jack_client_t*, JackSymInfoShutdownCallback, void*);
    129 typedef int  (JACKSYM_API *jacksym_set_process_callback)(jack_client_t*, JackSymProcessCallback, void*);
    130 typedef int  (JACKSYM_API *jacksym_set_freewheel_callback)(jack_client_t*, JackSymFreewheelCallback, void*);
    131 typedef int  (JACKSYM_API *jacksym_set_buffer_size_callback)(jack_client_t*, JackSymBufferSizeCallback, void*);
    132 typedef int  (JACKSYM_API *jacksym_set_sample_rate_callback)(jack_client_t*, JackSymSampleRateCallback, void*);
    133 typedef int  (JACKSYM_API *jacksym_set_client_registration_callback)(jack_client_t*, JackSymClientRegistrationCallback, void*);
    134 typedef int  (JACKSYM_API *jacksym_set_port_registration_callback)(jack_client_t*, JackSymPortRegistrationCallback, void*);
    135 typedef int  (JACKSYM_API *jacksym_set_port_rename_callback)(jack_client_t*, JackSymPortRenameCallback, void*);
    136 typedef int  (JACKSYM_API *jacksym_set_port_connect_callback)(jack_client_t*, JackSymPortConnectCallback, void*);
    137 typedef int  (JACKSYM_API *jacksym_set_graph_order_callback)(jack_client_t*, JackSymGraphOrderCallback, void*);
    138 typedef int  (JACKSYM_API *jacksym_set_xrun_callback)(jack_client_t*, JackSymXRunCallback, void*);
    139 typedef int  (JACKSYM_API *jacksym_set_latency_callback)(jack_client_t*, JackSymLatencyCallback, void*);
    140 
    141 typedef int (JACKSYM_API *jacksym_set_freewheel)(jack_client_t*, int);
    142 typedef int (JACKSYM_API *jacksym_set_buffer_size)(jack_client_t*, jack_nframes_t);
    143 
    144 typedef jack_nframes_t (JACKSYM_API *jacksym_get_sample_rate)(jack_client_t*);
    145 typedef jack_nframes_t (JACKSYM_API *jacksym_get_buffer_size)(jack_client_t*);
    146 typedef float          (JACKSYM_API *jacksym_cpu_load)(jack_client_t*);
    147 
    148 typedef jack_port_t* (JACKSYM_API *jacksym_port_register)(jack_client_t*, const char*, const char*, ulong, ulong);
    149 typedef int          (JACKSYM_API *jacksym_port_unregister)(jack_client_t*, jack_port_t*);
    150 typedef void*        (JACKSYM_API *jacksym_port_get_buffer)(jack_port_t*, jack_nframes_t);
    151 
    152 typedef const char*  (JACKSYM_API *jacksym_port_name)(const jack_port_t*);
    153 typedef jack_uuid_t  (JACKSYM_API *jacksym_port_uuid)(const jack_port_t*);
    154 typedef const char*  (JACKSYM_API *jacksym_port_short_name)(const jack_port_t*);
    155 typedef int          (JACKSYM_API *jacksym_port_flags)(const jack_port_t*);
    156 typedef const char*  (JACKSYM_API *jacksym_port_type)(const jack_port_t*);
    157 typedef int          (JACKSYM_API *jacksym_port_is_mine)(const jack_client_t*, const jack_port_t*);
    158 typedef int          (JACKSYM_API *jacksym_port_connected)(const jack_port_t*);
    159 typedef int          (JACKSYM_API *jacksym_port_connected_to)(const jack_port_t*, const char*);
    160 typedef const char** (JACKSYM_API *jacksym_port_get_connections)(const jack_port_t*);
    161 typedef const char** (JACKSYM_API *jacksym_port_get_all_connections)(const jack_client_t*, const jack_port_t*);
    162 
    163 typedef int (JACKSYM_API *jacksym_port_rename)(jack_client_t*, jack_port_t*, const char*);
    164 typedef int (JACKSYM_API *jacksym_port_set_name)(jack_port_t*, const char*);
    165 typedef int (JACKSYM_API *jacksym_port_set_alias)(jack_port_t*, const char*);
    166 typedef int (JACKSYM_API *jacksym_port_unset_alias)(jack_port_t*, const char*);
    167 typedef int (JACKSYM_API *jacksym_port_get_aliases)(const jack_port_t*, char* const aliases[2]);
    168 
    169 typedef int (JACKSYM_API *jacksym_port_request_monitor)(jack_port_t*, int);
    170 typedef int (JACKSYM_API *jacksym_port_request_monitor_by_name)(jack_client_t*, const char*, int);
    171 typedef int (JACKSYM_API *jacksym_port_ensure_monitor)(jack_port_t*, int);
    172 typedef int (JACKSYM_API *jacksym_port_monitoring_input)(jack_port_t*);
    173 
    174 typedef int (JACKSYM_API *jacksym_connect)(jack_client_t*, const char*, const char*);
    175 typedef int (JACKSYM_API *jacksym_disconnect)(jack_client_t*, const char*, const char*);
    176 typedef int (JACKSYM_API *jacksym_port_disconnect)(jack_client_t*, jack_port_t*);
    177 
    178 typedef int    (JACKSYM_API *jacksym_port_name_size)(void);
    179 typedef int    (JACKSYM_API *jacksym_port_type_size)(void);
    180 typedef size_t (JACKSYM_API *jacksym_port_type_get_buffer_size)(jack_client_t*, const char*);
    181 
    182 typedef void (JACKSYM_API *jacksym_port_get_latency_range)(jack_port_t*, jack_latency_callback_mode_t, jack_latency_range_t*);
    183 typedef void (JACKSYM_API *jacksym_port_set_latency_range)(jack_port_t*, jack_latency_callback_mode_t, jack_latency_range_t*);
    184 typedef int  (JACKSYM_API *jacksym_recompute_total_latencies)(jack_client_t*);
    185 
    186 typedef const char** (JACKSYM_API *jacksym_get_ports)(jack_client_t*, const char*, const char*, ulong);
    187 typedef jack_port_t* (JACKSYM_API *jacksym_port_by_name)(jack_client_t*, const char*);
    188 typedef jack_port_t* (JACKSYM_API *jacksym_port_by_id)(jack_client_t*, jack_port_id_t);
    189 
    190 typedef void (JACKSYM_API *jacksym_free)(void*);
    191 
    192 typedef uint32_t (JACKSYM_API *jacksym_midi_get_event_count)(void*);
    193 typedef int      (JACKSYM_API *jacksym_midi_event_get)(jack_midi_event_t*, void*, uint32_t);
    194 typedef void     (JACKSYM_API *jacksym_midi_clear_buffer)(void*);
    195 typedef int      (JACKSYM_API *jacksym_midi_event_write)(void*, jack_nframes_t, const jack_midi_data_t*, size_t);
    196 typedef jack_midi_data_t* (JACKSYM_API *jacksym_midi_event_reserve)(void*, jack_nframes_t, size_t);
    197 
    198 typedef int (JACKSYM_API *jacksym_release_timebase)(jack_client_t*);
    199 typedef int (JACKSYM_API *jacksym_set_sync_callback)(jack_client_t*, JackSymSyncCallback, void*);
    200 typedef int (JACKSYM_API *jacksym_set_sync_timeout)(jack_client_t*, jack_time_t);
    201 typedef int (JACKSYM_API *jacksym_set_timebase_callback)(jack_client_t*, int, JackSymTimebaseCallback, void*);
    202 typedef int (JACKSYM_API *jacksym_transport_locate)(jack_client_t*, jack_nframes_t);
    203 
    204 typedef jack_transport_state_t (JACKSYM_API *jacksym_transport_query)(const jack_client_t*, jack_position_t*);
    205 typedef jack_nframes_t         (JACKSYM_API *jacksym_get_current_transport_frame)(const jack_client_t*);
    206 
    207 typedef int  (JACKSYM_API *jacksym_transport_reposition)(jack_client_t*, const jack_position_t*);
    208 typedef void (JACKSYM_API *jacksym_transport_start)(jack_client_t*);
    209 typedef void (JACKSYM_API *jacksym_transport_stop)(jack_client_t*);
    210 
    211 typedef int  (JACKSYM_API *jacksym_set_property)(jack_client_t*, jack_uuid_t, const char*, const char*, const char*);
    212 typedef int  (JACKSYM_API *jacksym_get_property)(jack_uuid_t, const char*, char**, char**);
    213 typedef void (JACKSYM_API *jacksym_free_description)(jack_description_t*, int);
    214 typedef int  (JACKSYM_API *jacksym_get_properties)(jack_uuid_t, jack_description_t*);
    215 typedef int  (JACKSYM_API *jacksym_get_all_properties)(jack_description_t**);
    216 typedef int  (JACKSYM_API *jacksym_remove_property)(jack_client_t*, jack_uuid_t, const char*);
    217 typedef int  (JACKSYM_API *jacksym_remove_properties)(jack_client_t*, jack_uuid_t);
    218 typedef int  (JACKSYM_API *jacksym_remove_all_properties)(jack_client_t*);
    219 typedef int  (JACKSYM_API *jacksym_set_property_change_callback)(jack_client_t*, JackSymPropertyChangeCallback, void*);
    220 
    221 typedef bool           (JACKSYM_API *jacksym_set_process_thread)(jack_client_t*, JackSymThreadCallback callback, void*);
    222 typedef jack_nframes_t (JACKSYM_API *jacksym_cycle_wait)(jack_client_t*);
    223 typedef void           (JACKSYM_API *jacksym_cycle_signal)(jack_client_t*, int);
    224 
    225 #ifdef __WINE__
    226 typedef int  (JACKSYM_API *jacksym_thread_creator_t)(pthread_t*, const pthread_attr_t*, void *(*)(void*), void*);
    227 typedef void (JACKSYM_API *jacksym_set_thread_creator)(jacksym_thread_creator_t);
    228 #endif
    229 
    230 } // extern "C"
    231 
    232 // -----------------------------------------------------------------------------
    233 
    234 struct JackBridge {
    235     lib_t lib;
    236 
    237     jacksym_get_version get_version_ptr;
    238     jacksym_get_version_string get_version_string_ptr;
    239 
    240     jacksym_client_open client_open_ptr;
    241     jacksym_client_close client_close_ptr;
    242 
    243     jacksym_client_name_size client_name_size_ptr;
    244     jacksym_get_client_name get_client_name_ptr;
    245 
    246     jacksym_client_get_uuid client_get_uuid_ptr;
    247     jacksym_get_uuid_for_client_name get_uuid_for_client_name_ptr;
    248     jacksym_get_client_name_by_uuid get_client_name_by_uuid_ptr;
    249 
    250     jacksym_uuid_parse uuid_parse_ptr;
    251     jacksym_uuid_unparse uuid_unparse_ptr;
    252 
    253     jacksym_activate activate_ptr;
    254     jacksym_deactivate deactivate_ptr;
    255     jacksym_is_realtime is_realtime_ptr;
    256 
    257     jacksym_set_thread_init_callback set_thread_init_callback_ptr;
    258     jacksym_on_shutdown on_shutdown_ptr;
    259     jacksym_on_info_shutdown on_info_shutdown_ptr;
    260     jacksym_set_process_callback set_process_callback_ptr;
    261     jacksym_set_freewheel_callback set_freewheel_callback_ptr;
    262     jacksym_set_buffer_size_callback set_buffer_size_callback_ptr;
    263     jacksym_set_sample_rate_callback set_sample_rate_callback_ptr;
    264     jacksym_set_client_registration_callback set_client_registration_callback_ptr;
    265     jacksym_set_port_registration_callback set_port_registration_callback_ptr;
    266     jacksym_set_port_rename_callback set_port_rename_callback_ptr;
    267     jacksym_set_port_connect_callback set_port_connect_callback_ptr;
    268     jacksym_set_graph_order_callback set_graph_order_callback_ptr;
    269     jacksym_set_xrun_callback set_xrun_callback_ptr;
    270     jacksym_set_latency_callback set_latency_callback_ptr;
    271 
    272     jacksym_set_freewheel set_freewheel_ptr;
    273     jacksym_set_buffer_size set_buffer_size_ptr;
    274 
    275     jacksym_get_sample_rate get_sample_rate_ptr;
    276     jacksym_get_buffer_size get_buffer_size_ptr;
    277     jacksym_cpu_load cpu_load_ptr;
    278 
    279     jacksym_port_register port_register_ptr;
    280     jacksym_port_unregister port_unregister_ptr;
    281     jacksym_port_get_buffer port_get_buffer_ptr;
    282 
    283     jacksym_port_name port_name_ptr;
    284     jacksym_port_uuid port_uuid_ptr;
    285     jacksym_port_short_name port_short_name_ptr;
    286     jacksym_port_flags port_flags_ptr;
    287     jacksym_port_type port_type_ptr;
    288     jacksym_port_is_mine port_is_mine_ptr;
    289     jacksym_port_connected port_connected_ptr;
    290     jacksym_port_connected_to port_connected_to_ptr;
    291     jacksym_port_get_connections port_get_connections_ptr;
    292     jacksym_port_get_all_connections port_get_all_connections_ptr;
    293 
    294     jacksym_port_rename port_rename_ptr;
    295     jacksym_port_set_name port_set_name_ptr;
    296     jacksym_port_set_alias port_set_alias_ptr;
    297     jacksym_port_unset_alias port_unset_alias_ptr;
    298     jacksym_port_get_aliases port_get_aliases_ptr;
    299 
    300     jacksym_port_request_monitor port_request_monitor_ptr;
    301     jacksym_port_request_monitor_by_name port_request_monitor_by_name_ptr;
    302     jacksym_port_ensure_monitor port_ensure_monitor_ptr;
    303     jacksym_port_monitoring_input port_monitoring_input_ptr;
    304 
    305     jacksym_connect connect_ptr;
    306     jacksym_disconnect disconnect_ptr;
    307     jacksym_port_disconnect port_disconnect_ptr;
    308 
    309     jacksym_port_name_size port_name_size_ptr;
    310     jacksym_port_type_size port_type_size_ptr;
    311     jacksym_port_type_get_buffer_size port_type_get_buffer_size_ptr;
    312 
    313     jacksym_port_get_latency_range port_get_latency_range_ptr;
    314     jacksym_port_set_latency_range port_set_latency_range_ptr;
    315     jacksym_recompute_total_latencies recompute_total_latencies_ptr;
    316 
    317     jacksym_get_ports get_ports_ptr;
    318     jacksym_port_by_name port_by_name_ptr;
    319     jacksym_port_by_id port_by_id_ptr;
    320 
    321     jacksym_free free_ptr;
    322 
    323     jacksym_midi_get_event_count midi_get_event_count_ptr;
    324     jacksym_midi_event_get midi_event_get_ptr;
    325     jacksym_midi_clear_buffer midi_clear_buffer_ptr;
    326     jacksym_midi_event_write midi_event_write_ptr;
    327     jacksym_midi_event_reserve midi_event_reserve_ptr;
    328 
    329     jacksym_release_timebase release_timebase_ptr;
    330     jacksym_set_sync_callback set_sync_callback_ptr;
    331     jacksym_set_sync_timeout set_sync_timeout_ptr;
    332     jacksym_set_timebase_callback set_timebase_callback_ptr;
    333     jacksym_transport_locate transport_locate_ptr;
    334 
    335     jacksym_transport_query transport_query_ptr;
    336     jacksym_get_current_transport_frame get_current_transport_frame_ptr;
    337 
    338     jacksym_transport_reposition transport_reposition_ptr;
    339     jacksym_transport_start transport_start_ptr;
    340     jacksym_transport_stop transport_stop_ptr;
    341 
    342     jacksym_set_property set_property_ptr;
    343     jacksym_get_property get_property_ptr;
    344     jacksym_free_description free_description_ptr;
    345     jacksym_get_properties get_properties_ptr;
    346     jacksym_get_all_properties get_all_properties_ptr;
    347     jacksym_remove_property remove_property_ptr;
    348     jacksym_remove_properties remove_properties_ptr;
    349     jacksym_remove_all_properties remove_all_properties_ptr;
    350     jacksym_set_property_change_callback set_property_change_callback_ptr;
    351 
    352     jacksym_set_process_thread set_process_thread_ptr;
    353     jacksym_cycle_wait cycle_wait_ptr;
    354     jacksym_cycle_signal cycle_signal_ptr;
    355 
    356    #ifdef __WINE__
    357     jacksym_set_thread_creator set_thread_creator_ptr;
    358    #endif
    359 
    360     JackBridge()
    361         : lib(nullptr),
    362           get_version_ptr(nullptr),
    363           get_version_string_ptr(nullptr),
    364           client_open_ptr(nullptr),
    365           client_close_ptr(nullptr),
    366           client_name_size_ptr(nullptr),
    367           get_client_name_ptr(nullptr),
    368           client_get_uuid_ptr(nullptr),
    369           get_uuid_for_client_name_ptr(nullptr),
    370           get_client_name_by_uuid_ptr(nullptr),
    371           uuid_parse_ptr(nullptr),
    372           uuid_unparse_ptr(nullptr),
    373           activate_ptr(nullptr),
    374           deactivate_ptr(nullptr),
    375           is_realtime_ptr(nullptr),
    376           set_thread_init_callback_ptr(nullptr),
    377           on_shutdown_ptr(nullptr),
    378           on_info_shutdown_ptr(nullptr),
    379           set_process_callback_ptr(nullptr),
    380           set_freewheel_callback_ptr(nullptr),
    381           set_buffer_size_callback_ptr(nullptr),
    382           set_sample_rate_callback_ptr(nullptr),
    383           set_client_registration_callback_ptr(nullptr),
    384           set_port_registration_callback_ptr(nullptr),
    385           set_port_rename_callback_ptr(nullptr),
    386           set_port_connect_callback_ptr(nullptr),
    387           set_graph_order_callback_ptr(nullptr),
    388           set_xrun_callback_ptr(nullptr),
    389           set_latency_callback_ptr(nullptr),
    390           set_freewheel_ptr(nullptr),
    391           set_buffer_size_ptr(nullptr),
    392           get_sample_rate_ptr(nullptr),
    393           get_buffer_size_ptr(nullptr),
    394           cpu_load_ptr(nullptr),
    395           port_register_ptr(nullptr),
    396           port_unregister_ptr(nullptr),
    397           port_get_buffer_ptr(nullptr),
    398           port_name_ptr(nullptr),
    399           port_uuid_ptr(nullptr),
    400           port_short_name_ptr(nullptr),
    401           port_flags_ptr(nullptr),
    402           port_type_ptr(nullptr),
    403           port_is_mine_ptr(nullptr),
    404           port_connected_ptr(nullptr),
    405           port_connected_to_ptr(nullptr),
    406           port_get_connections_ptr(nullptr),
    407           port_get_all_connections_ptr(nullptr),
    408           port_rename_ptr(nullptr),
    409           port_set_name_ptr(nullptr),
    410           port_set_alias_ptr(nullptr),
    411           port_unset_alias_ptr(nullptr),
    412           port_get_aliases_ptr(nullptr),
    413           port_request_monitor_ptr(nullptr),
    414           port_request_monitor_by_name_ptr(nullptr),
    415           port_ensure_monitor_ptr(nullptr),
    416           port_monitoring_input_ptr(nullptr),
    417           connect_ptr(nullptr),
    418           disconnect_ptr(nullptr),
    419           port_disconnect_ptr(nullptr),
    420           port_name_size_ptr(nullptr),
    421           port_type_size_ptr(nullptr),
    422           port_type_get_buffer_size_ptr(nullptr),
    423           port_get_latency_range_ptr(nullptr),
    424           port_set_latency_range_ptr(nullptr),
    425           recompute_total_latencies_ptr(nullptr),
    426           get_ports_ptr(nullptr),
    427           port_by_name_ptr(nullptr),
    428           port_by_id_ptr(nullptr),
    429           free_ptr(nullptr),
    430           midi_get_event_count_ptr(nullptr),
    431           midi_event_get_ptr(nullptr),
    432           midi_clear_buffer_ptr(nullptr),
    433           midi_event_write_ptr(nullptr),
    434           midi_event_reserve_ptr(nullptr),
    435           release_timebase_ptr(nullptr),
    436           set_sync_callback_ptr(nullptr),
    437           set_sync_timeout_ptr(nullptr),
    438           set_timebase_callback_ptr(nullptr),
    439           transport_locate_ptr(nullptr),
    440           transport_query_ptr(nullptr),
    441           get_current_transport_frame_ptr(nullptr),
    442           transport_reposition_ptr(nullptr),
    443           transport_start_ptr(nullptr),
    444           transport_stop_ptr(nullptr),
    445           set_property_ptr(nullptr),
    446           get_property_ptr(nullptr),
    447           free_description_ptr(nullptr),
    448           get_properties_ptr(nullptr),
    449           get_all_properties_ptr(nullptr),
    450           remove_property_ptr(nullptr),
    451           remove_properties_ptr(nullptr),
    452           remove_all_properties_ptr(nullptr),
    453           set_property_change_callback_ptr(nullptr),
    454           set_process_thread_ptr(nullptr),
    455           cycle_wait_ptr(nullptr),
    456           cycle_signal_ptr(nullptr)
    457          #ifdef __WINE__
    458         , set_thread_creator_ptr(nullptr)
    459          #endif
    460     {
    461       #ifdef HAVE_JACK
    462        #if defined(DISTRHO_OS_MAC)
    463         const char* const filename = "libjack.dylib";
    464        #elif defined(DISTRHO_OS_WINDOWS) && defined(_WIN64)
    465         const char* const filename = "libjack64.dll";
    466        #elif defined(DISTRHO_OS_WINDOWS)
    467         const char* const filename = "libjack.dll";
    468        #else
    469         const char* const filename = "libjack.so.0";
    470        #endif
    471 
    472         USE_NAMESPACE_DISTRHO
    473 
    474         lib = lib_open(filename);
    475 
    476         if (lib == nullptr)
    477         {
    478             d_stderr("Failed to load JACK DLL, reason:\n%s", lib_error(filename));
    479             return;
    480         }
    481         else
    482         {
    483             d_stdout("%s loaded successfully!", filename);
    484         }
    485 
    486         #define JOIN(a, b) a ## b
    487         #define LIB_SYMBOL(NAME) JOIN(NAME, _ptr) = lib_symbol<jacksym_##NAME>(lib, "jack_" #NAME);
    488 
    489         LIB_SYMBOL(get_version)
    490         LIB_SYMBOL(get_version_string)
    491 
    492         LIB_SYMBOL(client_open)
    493         LIB_SYMBOL(client_close)
    494 
    495         LIB_SYMBOL(client_name_size)
    496         LIB_SYMBOL(get_client_name)
    497 
    498         LIB_SYMBOL(client_get_uuid)
    499         LIB_SYMBOL(get_uuid_for_client_name)
    500         LIB_SYMBOL(get_client_name_by_uuid)
    501 
    502         LIB_SYMBOL(uuid_parse)
    503         LIB_SYMBOL(uuid_unparse)
    504 
    505         LIB_SYMBOL(activate)
    506         LIB_SYMBOL(deactivate)
    507         LIB_SYMBOL(is_realtime)
    508 
    509         LIB_SYMBOL(set_thread_init_callback)
    510         LIB_SYMBOL(on_shutdown)
    511         LIB_SYMBOL(on_info_shutdown)
    512         LIB_SYMBOL(set_process_callback)
    513         LIB_SYMBOL(set_freewheel_callback)
    514         LIB_SYMBOL(set_buffer_size_callback)
    515         LIB_SYMBOL(set_sample_rate_callback)
    516         LIB_SYMBOL(set_client_registration_callback)
    517         LIB_SYMBOL(set_port_registration_callback)
    518         LIB_SYMBOL(set_port_rename_callback)
    519         LIB_SYMBOL(set_port_connect_callback)
    520         LIB_SYMBOL(set_graph_order_callback)
    521         LIB_SYMBOL(set_xrun_callback)
    522         LIB_SYMBOL(set_latency_callback)
    523 
    524         LIB_SYMBOL(set_freewheel)
    525         LIB_SYMBOL(set_buffer_size)
    526 
    527         LIB_SYMBOL(get_sample_rate)
    528         LIB_SYMBOL(get_buffer_size)
    529         LIB_SYMBOL(cpu_load)
    530 
    531         LIB_SYMBOL(port_register)
    532         LIB_SYMBOL(port_unregister)
    533         LIB_SYMBOL(port_get_buffer)
    534 
    535         LIB_SYMBOL(port_name)
    536         LIB_SYMBOL(port_uuid)
    537         LIB_SYMBOL(port_short_name)
    538         LIB_SYMBOL(port_flags)
    539         LIB_SYMBOL(port_type)
    540         LIB_SYMBOL(port_is_mine)
    541         LIB_SYMBOL(port_connected)
    542         LIB_SYMBOL(port_connected_to)
    543         LIB_SYMBOL(port_get_connections)
    544         LIB_SYMBOL(port_get_all_connections)
    545 
    546         LIB_SYMBOL(port_rename)
    547         LIB_SYMBOL(port_set_name)
    548         LIB_SYMBOL(port_set_alias)
    549         LIB_SYMBOL(port_unset_alias)
    550         LIB_SYMBOL(port_get_aliases)
    551 
    552         LIB_SYMBOL(port_request_monitor)
    553         LIB_SYMBOL(port_request_monitor_by_name)
    554         LIB_SYMBOL(port_ensure_monitor)
    555         LIB_SYMBOL(port_monitoring_input)
    556 
    557         LIB_SYMBOL(connect)
    558         LIB_SYMBOL(disconnect)
    559         LIB_SYMBOL(port_disconnect)
    560 
    561         LIB_SYMBOL(port_name_size)
    562         LIB_SYMBOL(port_type_size)
    563         LIB_SYMBOL(port_type_get_buffer_size)
    564 
    565         LIB_SYMBOL(port_get_latency_range)
    566         LIB_SYMBOL(port_set_latency_range)
    567         LIB_SYMBOL(recompute_total_latencies)
    568 
    569         LIB_SYMBOL(get_ports)
    570         LIB_SYMBOL(port_by_name)
    571         LIB_SYMBOL(port_by_id)
    572 
    573         LIB_SYMBOL(free)
    574 
    575         LIB_SYMBOL(midi_get_event_count)
    576         LIB_SYMBOL(midi_event_get)
    577         LIB_SYMBOL(midi_clear_buffer)
    578         LIB_SYMBOL(midi_event_write)
    579         LIB_SYMBOL(midi_event_reserve)
    580 
    581         LIB_SYMBOL(release_timebase)
    582         LIB_SYMBOL(set_sync_callback)
    583         LIB_SYMBOL(set_sync_timeout)
    584         LIB_SYMBOL(set_timebase_callback)
    585         LIB_SYMBOL(transport_locate)
    586         LIB_SYMBOL(transport_query)
    587         LIB_SYMBOL(get_current_transport_frame)
    588         LIB_SYMBOL(transport_reposition)
    589         LIB_SYMBOL(transport_start)
    590         LIB_SYMBOL(transport_stop)
    591 
    592         LIB_SYMBOL(set_property)
    593         LIB_SYMBOL(get_property)
    594         LIB_SYMBOL(free_description)
    595         LIB_SYMBOL(get_properties)
    596         LIB_SYMBOL(get_all_properties)
    597         LIB_SYMBOL(remove_property)
    598         LIB_SYMBOL(remove_properties)
    599         LIB_SYMBOL(remove_all_properties)
    600         LIB_SYMBOL(set_property_change_callback)
    601 
    602         LIB_SYMBOL(set_process_thread)
    603         LIB_SYMBOL(cycle_wait)
    604         LIB_SYMBOL(cycle_signal)
    605 
    606        #ifdef __WINE__
    607         LIB_SYMBOL(set_thread_creator)
    608        #endif
    609       #endif
    610 
    611         #undef JOIN
    612         #undef LIB_SYMBOL
    613     }
    614 
    615    #ifdef HAVE_JACK
    616     ~JackBridge() noexcept
    617     {
    618         USE_NAMESPACE_DISTRHO
    619 
    620         if (lib != nullptr)
    621         {
    622             lib_close(lib);
    623             lib = nullptr;
    624         }
    625     }
    626    #endif
    627 
    628     DISTRHO_DECLARE_NON_COPYABLE(JackBridge);
    629 };
    630 
    631 static bool usingNativeBridge = false;
    632 static bool usingRealJACK = true;
    633 static NativeBridge* nativeBridge = nullptr;
    634 
    635 // -----------------------------------------------------------------------------
    636 
    637 static JackBridge& getBridgeInstance() noexcept
    638 {
    639     static JackBridge bridge;
    640     return bridge;
    641 }
    642 
    643 #endif // ! (defined(JACKBRIDGE_DIRECT) || defined(JACKBRIDGE_DUMMY))
    644 
    645 // -----------------------------------------------------------------------------
    646 
    647 #if defined(__WINE__) && ! defined(JACKBRIDGE_DIRECT)
    648 
    649 struct WineBridge {
    650     void* ptr;
    651     JackLatencyCallback latency_cb;
    652     JackProcessCallback process_cb;
    653     JackThreadInitCallback thread_init_cb;
    654     JackGraphOrderCallback graph_order_cb;
    655     JackXRunCallback xrun_cb;
    656     JackBufferSizeCallback bufsize_cb;
    657     JackSampleRateCallback srate_cb;
    658     JackPortRegistrationCallback port_reg_cb;
    659     JackClientRegistrationCallback client_reg_cb;
    660     JackPortConnectCallback port_conn_cb;
    661     JackPortRenameCallback port_rename_cb;
    662     JackFreewheelCallback freewheel_cb;
    663     JackShutdownCallback shutdown_cb;
    664     JackInfoShutdownCallback info_shutdown_cb;
    665     JackSyncCallback sync_cb;
    666     JackTimebaseCallback timebase_cb;
    667     JackSessionCallback session_cb;
    668     JackPropertyChangeCallback prop_change_cb;
    669     JackThreadCallback proc_thread_cb;
    670 
    671     void* (*creator_func)(void*);
    672     void* creator_arg;
    673     HANDLE creator_handle;
    674     pthread_t creator_pthread;
    675 
    676     WineBridge() noexcept
    677         : ptr(nullptr),
    678           latency_cb(nullptr),
    679           process_cb(nullptr),
    680           thread_init_cb(nullptr),
    681           graph_order_cb(nullptr),
    682           xrun_cb(nullptr),
    683           bufsize_cb(nullptr),
    684           srate_cb(nullptr),
    685           port_reg_cb(nullptr),
    686           client_reg_cb(nullptr),
    687           port_conn_cb(nullptr),
    688           port_rename_cb(nullptr),
    689           freewheel_cb(nullptr),
    690           shutdown_cb(nullptr),
    691           info_shutdown_cb(nullptr),
    692           sync_cb(nullptr),
    693           timebase_cb(nullptr),
    694           session_cb(nullptr),
    695           prop_change_cb(nullptr),
    696           proc_thread_cb(nullptr),
    697           creator_func(nullptr),
    698           creator_arg(nullptr),
    699           creator_handle(nullptr),
    700           creator_pthread(0) {}
    701 
    702     static WineBridge& getInstance() noexcept
    703     {
    704         static WineBridge bridge;
    705         return bridge;
    706     }
    707 
    708     void set_latency       (JackLatencyCallback            cb) noexcept { latency_cb       = cb; }
    709     void set_process       (JackProcessCallback            cb) noexcept { process_cb       = cb; }
    710     void set_thread_init   (JackThreadInitCallback         cb) noexcept { thread_init_cb   = cb; }
    711     void set_graph_order   (JackGraphOrderCallback         cb) noexcept { graph_order_cb   = cb; }
    712     void set_xrun          (JackXRunCallback               cb) noexcept { xrun_cb          = cb; }
    713     void set_bufsize       (JackBufferSizeCallback         cb) noexcept { bufsize_cb       = cb; }
    714     void set_srate         (JackSampleRateCallback         cb) noexcept { srate_cb         = cb; }
    715     void set_port_reg      (JackPortRegistrationCallback   cb) noexcept { port_reg_cb      = cb; }
    716     void set_client_reg    (JackClientRegistrationCallback cb) noexcept { client_reg_cb    = cb; }
    717     void set_port_conn     (JackPortConnectCallback        cb) noexcept { port_conn_cb     = cb; }
    718     void set_port_rename   (JackPortRenameCallback         cb) noexcept { port_rename_cb   = cb; }
    719     void set_freewheel     (JackFreewheelCallback          cb) noexcept { freewheel_cb     = cb; }
    720     void set_shutdown      (JackShutdownCallback           cb) noexcept { shutdown_cb      = cb; }
    721     void set_info_shutdown (JackInfoShutdownCallback       cb) noexcept { info_shutdown_cb = cb; }
    722     void set_sync          (JackSyncCallback               cb) noexcept { sync_cb          = cb; }
    723     void set_timebase      (JackTimebaseCallback           cb) noexcept { timebase_cb      = cb; }
    724     void set_session       (JackSessionCallback            cb) noexcept { session_cb       = cb; }
    725     void set_prop_change   (JackPropertyChangeCallback     cb) noexcept { prop_change_cb   = cb; }
    726     void set_process_thread(JackThreadCallback             cb) noexcept { proc_thread_cb   = cb; }
    727 
    728     static DWORD WINAPI thread_creator_helper(LPVOID)
    729     {
    730         WineBridge& inst(getInstance());
    731 
    732         inst.creator_pthread = pthread_self();
    733         SetEvent(inst.creator_handle);
    734         inst.creator_func(inst.creator_arg);
    735         return 0;
    736     }
    737 
    738     static int thread_creator(pthread_t* thread_id, const pthread_attr_t*, void *(*function)(void*), void* arg)
    739     {
    740         WineBridge& inst(getInstance());
    741 
    742         inst.creator_func   = function;
    743         inst.creator_arg    = arg;
    744         inst.creator_handle = ::CreateEventW(nullptr, false, false, nullptr);
    745 
    746 #if 0
    747         ::CreateThread(nullptr, 0, thread_creator_helper, arg, 0, nullptr);
    748 #else
    749         HANDLE handle = ::CreateThread(nullptr, 0, thread_creator_helper, arg, CREATE_SUSPENDED, nullptr);
    750 
    751         if (handle == INVALID_HANDLE_VALUE)
    752             return 1;
    753 
    754         // TODO read attrs and decide this
    755         ::SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL);
    756         ::ResumeThread(handle);
    757 #endif
    758 
    759         ::WaitForSingleObject(inst.creator_handle, INFINITE);
    760         *thread_id = inst.creator_pthread;
    761         return 0;
    762     }
    763 
    764     static void latency(jack_latency_callback_mode_t mode, void* arg)
    765     {
    766         return getInstance().latency_cb(mode, arg);
    767     }
    768 
    769     static int process(jack_nframes_t nframes, void* arg)
    770     {
    771         return getInstance().process_cb(nframes, arg);
    772     }
    773 
    774     static void thread_init(void* arg)
    775     {
    776         return getInstance().thread_init_cb(arg);
    777     }
    778 
    779     static int graph_order(void* arg)
    780     {
    781         return getInstance().graph_order_cb(arg);
    782     }
    783 
    784     static int xrun(void* arg)
    785     {
    786         return getInstance().xrun_cb(arg);
    787     }
    788 
    789     static int bufsize(jack_nframes_t nframes, void* arg)
    790     {
    791         return getInstance().bufsize_cb(nframes, arg);
    792     }
    793 
    794     static int srate(jack_nframes_t nframes, void* arg)
    795     {
    796         return getInstance().srate_cb(nframes, arg);
    797     }
    798 
    799     static void port_reg(jack_port_id_t port, int register_, void* arg)
    800     {
    801         return getInstance().port_reg_cb(port, register_, arg);
    802     }
    803 
    804     static void client_reg(const char* name, int register_, void* arg)
    805     {
    806         return getInstance().client_reg_cb(name, register_, arg);
    807     }
    808 
    809     static void port_conn(jack_port_id_t a, jack_port_id_t b, int connect, void* arg)
    810     {
    811         return getInstance().port_conn_cb(a, b, connect, arg);
    812     }
    813 
    814     static void port_rename(jack_port_id_t port, const char* old_name, const char* new_name, void* arg)
    815     {
    816         getInstance().port_rename_cb(port, old_name, new_name, arg);
    817     }
    818 
    819     static void freewheel(int starting, void* arg)
    820     {
    821         return getInstance().freewheel_cb(starting, arg);
    822     }
    823 
    824     static void shutdown(void* arg)
    825     {
    826         return getInstance().shutdown_cb(arg);
    827     }
    828 
    829     static void info_shutdown(jack_status_t code, const char* reason, void* arg)
    830     {
    831         return getInstance().info_shutdown_cb(code, reason, arg);
    832     }
    833 
    834     static int sync(jack_transport_state_t state, jack_position_t* pos, void* arg)
    835     {
    836         return getInstance().sync_cb(state, pos, arg);
    837     }
    838 
    839     static void timebase(jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg)
    840     {
    841         return getInstance().timebase_cb(state, nframes, pos, new_pos, arg);
    842     }
    843 
    844     static void session(jack_session_event_t* event, void* arg)
    845     {
    846         return getInstance().session_cb(event, arg);
    847     }
    848 
    849     static void prop_change(jack_uuid_t subject, const char* key, jack_property_change_t change, void* arg)
    850     {
    851         return getInstance().prop_change_cb(subject, key, change, arg);
    852     }
    853 
    854     static void* process_thread(void* arg)
    855     {
    856         return getInstance().proc_thread_cb(arg);
    857     }
    858 
    859     DISTRHO_DECLARE_NON_COPYABLE(WineBridge);
    860 };
    861 
    862 #endif // __WINE__ && ! JACKBRIDGE_DIRECT
    863 
    864 // -----------------------------------------------------------------------------
    865 
    866 bool jackbridge_is_ok() noexcept
    867 {
    868 #if defined(JACKBRIDGE_DUMMY)
    869     return false;
    870 #elif defined(JACKBRIDGE_DIRECT) || defined(DISTRHO_OS_WASM) || defined(RTAUDIO_API_TYPE)
    871     return true;
    872 #else
    873     return (getBridgeInstance().lib != nullptr);
    874 #endif
    875 }
    876 
    877 void jackbridge_init()
    878 {
    879 #if defined(__WINE__) && !defined(JACKBRIDGE_DIRECT)
    880     if (getBridgeInstance().set_thread_creator_ptr != nullptr)
    881         getBridgeInstance().set_thread_creator_ptr(WineBridge::thread_creator);
    882 #endif
    883 }
    884 
    885 // -----------------------------------------------------------------------------
    886 
    887 void jackbridge_get_version(int* major_ptr, int* minor_ptr, int* micro_ptr, int* proto_ptr)
    888 {
    889 #if defined(JACKBRIDGE_DUMMY)
    890 #elif defined(JACKBRIDGE_DIRECT)
    891     return jack_get_version(major_ptr, minor_ptr, micro_ptr, proto_ptr);
    892 #else
    893     if (usingRealJACK && getBridgeInstance().get_version_ptr != nullptr)
    894         return getBridgeInstance().get_version_ptr(major_ptr, minor_ptr, micro_ptr, proto_ptr);
    895 #endif
    896     if (major_ptr != nullptr)
    897         *major_ptr = 0;
    898     if (minor_ptr != nullptr)
    899         *minor_ptr = 0;
    900     if (micro_ptr != nullptr)
    901         *micro_ptr = 0;
    902     if (proto_ptr != nullptr)
    903         *proto_ptr = 0;
    904 }
    905 
    906 const char* jackbridge_get_version_string()
    907 {
    908 #if defined(JACKBRIDGE_DUMMY)
    909 #elif defined(JACKBRIDGE_DIRECT)
    910     return jack_get_version_string();
    911 #else
    912     if (usingRealJACK && getBridgeInstance().get_version_string_ptr != nullptr)
    913         return getBridgeInstance().get_version_string_ptr();
    914 #endif
    915     return nullptr;
    916 }
    917 
    918 // -----------------------------------------------------------------------------
    919 
    920 jack_client_t* jackbridge_client_open(const char* client_name, uint32_t options, jack_status_t* status)
    921 {
    922 #if defined(JACKBRIDGE_DUMMY)
    923 #elif defined(JACKBRIDGE_DIRECT)
    924     return jack_client_open(client_name, static_cast<jack_options_t>(options), status);
    925 #else
    926    #ifndef DISTRHO_OS_WASM
    927     if (getBridgeInstance().client_open_ptr != nullptr)
    928         if (jack_client_t* const client = getBridgeInstance().client_open_ptr(client_name, static_cast<jack_options_t>(options), status))
    929             return client;
    930    #endif
    931 
    932     static jack_client_t* const kValidClient = (jack_client_t*)0x1;
    933 
    934     // maybe unused
    935     (void)kValidClient;
    936 
    937     usingNativeBridge = true;
    938     usingRealJACK = false;
    939 
    940    #ifdef DISTRHO_OS_WASM
    941     nativeBridge = new WebBridge;
    942     if (nativeBridge->open(client_name))
    943         return kValidClient;
    944     delete nativeBridge;
    945    #endif
    946     
    947    #if defined(HAVE_RTAUDIO) && defined(RTAUDIO_API_TYPE)
    948     nativeBridge = new RtAudioBridge;
    949     if (nativeBridge->open(client_name))
    950         return kValidClient;
    951     delete nativeBridge;
    952    #endif
    953 
    954    #if defined(HAVE_SDL2) && DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
    955     nativeBridge = new SDL2Bridge;
    956     if (nativeBridge->open(client_name))
    957         return kValidClient;
    958     delete nativeBridge;
    959    #endif
    960 #endif
    961 
    962     if (status != nullptr)
    963     {
    964         int err = JackServerError;
    965 
    966        #if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
    967         if (nativeBridge != nullptr)
    968         {
    969             err
    970             #ifdef HAVE_JACK
    971              |=
    972             #else
    973              =
    974             #endif
    975             JackBridgeNativeFailed;
    976         }
    977        #endif
    978 
    979         *status = static_cast<jack_status_t>(err);
    980     }
    981 
    982     return nullptr;
    983 }
    984 
    985 bool jackbridge_client_close(jack_client_t* client)
    986 {
    987 #if defined(JACKBRIDGE_DUMMY)
    988 #elif defined(JACKBRIDGE_DIRECT)
    989     return (jack_client_close(client) == 0);
    990 #else
    991     if (usingNativeBridge)
    992     {
    993         if (nativeBridge != nullptr)
    994         {
    995             nativeBridge->close();
    996             delete nativeBridge;
    997             nativeBridge = nullptr;
    998         }
    999         usingNativeBridge = false;
   1000         usingRealJACK = true;
   1001         return true;
   1002     }
   1003     if (getBridgeInstance().client_close_ptr != nullptr)
   1004         return (getBridgeInstance().client_close_ptr(client) == 0);
   1005 #endif
   1006     return false;
   1007 }
   1008 
   1009 // -----------------------------------------------------------------------------
   1010 
   1011 int jackbridge_client_name_size()
   1012 {
   1013 #if defined(JACKBRIDGE_DUMMY)
   1014 #elif defined(JACKBRIDGE_DIRECT)
   1015     return jack_client_name_size();
   1016 #else
   1017     if (usingRealJACK && getBridgeInstance().client_name_size_ptr != nullptr)
   1018         return getBridgeInstance().client_name_size_ptr();
   1019 #endif
   1020     return 33;
   1021 }
   1022 
   1023 const char* jackbridge_get_client_name(jack_client_t* client)
   1024 {
   1025 #if defined(JACKBRIDGE_DUMMY)
   1026 #elif defined(JACKBRIDGE_DIRECT)
   1027     return jack_get_client_name(client);
   1028 #else
   1029     if (usingNativeBridge)
   1030         return DISTRHO_PLUGIN_NAME;
   1031     if (getBridgeInstance().get_client_name_ptr != nullptr)
   1032         return getBridgeInstance().get_client_name_ptr(client);
   1033 #endif
   1034     return nullptr;
   1035 }
   1036 
   1037 // -----------------------------------------------------------------------------
   1038 
   1039 char* jackbridge_client_get_uuid(jack_client_t* client)
   1040 {
   1041 #if defined(JACKBRIDGE_DUMMY)
   1042 #elif defined(JACKBRIDGE_DIRECT)
   1043     return jack_client_get_uuid(client);
   1044 #else
   1045     if (usingRealJACK)
   1046         if (const jacksym_client_get_uuid func = getBridgeInstance().client_get_uuid_ptr)
   1047             return func(client);
   1048 #endif
   1049     return nullptr;
   1050 }
   1051 
   1052 char* jackbridge_get_uuid_for_client_name(jack_client_t* client, const char* name)
   1053 {
   1054 #if defined(JACKBRIDGE_DUMMY)
   1055 #elif defined(JACKBRIDGE_DIRECT)
   1056     return jack_get_uuid_for_client_name(client, name);
   1057 #else
   1058     if (usingRealJACK)
   1059         if (getBridgeInstance().get_uuid_for_client_name_ptr != nullptr)
   1060             return getBridgeInstance().get_uuid_for_client_name_ptr(client, name);
   1061 #endif
   1062     return nullptr;
   1063 }
   1064 
   1065 char* jackbridge_get_client_name_by_uuid(jack_client_t* client, const char* uuid)
   1066 {
   1067 #if defined(JACKBRIDGE_DUMMY)
   1068 #elif defined(JACKBRIDGE_DIRECT)
   1069     return jack_get_client_name_by_uuid(client, uuid);
   1070 #else
   1071     if (usingRealJACK)
   1072         if (getBridgeInstance().get_client_name_by_uuid_ptr != nullptr)
   1073             return getBridgeInstance().get_client_name_by_uuid_ptr(client, uuid);
   1074 #endif
   1075     return nullptr;
   1076 }
   1077 
   1078 // -----------------------------------------------------------------------------
   1079 
   1080 bool jackbridge_uuid_parse(const char* buf, jack_uuid_t* uuid)
   1081 {
   1082 #if defined(JACKBRIDGE_DUMMY)
   1083 #elif defined(JACKBRIDGE_DIRECT)
   1084     return (jack_uuid_parse(buf, uuid) == 0);
   1085 #else
   1086     if (usingRealJACK)
   1087         if (const jacksym_uuid_parse func = getBridgeInstance().uuid_parse_ptr)
   1088             return (func(buf, uuid) == 0);
   1089 #endif
   1090     return false;
   1091 }
   1092 
   1093 void jackbridge_uuid_unparse(jack_uuid_t uuid, char buf[JACK_UUID_STRING_SIZE])
   1094 {
   1095 #if defined(JACKBRIDGE_DUMMY)
   1096 #elif defined(JACKBRIDGE_DIRECT)
   1097     jack_uuid_unparse(uuid, buf);
   1098 #else
   1099     if (usingRealJACK)
   1100         if (const jacksym_uuid_unparse func = getBridgeInstance().uuid_unparse_ptr)
   1101             return func(uuid, buf);
   1102 #endif
   1103 }
   1104 
   1105 // -----------------------------------------------------------------------------
   1106 
   1107 bool jackbridge_activate(jack_client_t* client)
   1108 {
   1109 #if defined(JACKBRIDGE_DUMMY)
   1110 #elif defined(JACKBRIDGE_DIRECT)
   1111     return (jack_activate(client) == 0);
   1112 #else
   1113     if (usingNativeBridge)
   1114         return nativeBridge->activate();
   1115     if (getBridgeInstance().activate_ptr != nullptr)
   1116         return (getBridgeInstance().activate_ptr(client) == 0);
   1117 #endif
   1118     return false;
   1119 }
   1120 
   1121 bool jackbridge_deactivate(jack_client_t* client)
   1122 {
   1123 #if defined(JACKBRIDGE_DUMMY)
   1124 #elif defined(JACKBRIDGE_DIRECT)
   1125     return (jack_deactivate(client) == 0);
   1126 #else
   1127     if (usingNativeBridge)
   1128         return nativeBridge->deactivate();
   1129     if (getBridgeInstance().deactivate_ptr != nullptr)
   1130         return (getBridgeInstance().deactivate_ptr(client) == 0);
   1131 #endif
   1132     return false;
   1133 }
   1134 
   1135 bool jackbridge_is_realtime(jack_client_t* client)
   1136 {
   1137 #if defined(JACKBRIDGE_DUMMY)
   1138 #elif defined(JACKBRIDGE_DIRECT)
   1139     return jack_is_realtime(client);
   1140 #else
   1141     if (usingRealJACK)
   1142         if (getBridgeInstance().is_realtime_ptr != nullptr)
   1143             return getBridgeInstance().is_realtime_ptr(client);
   1144 #endif
   1145     return false;
   1146 }
   1147 
   1148 // -----------------------------------------------------------------------------
   1149 
   1150 bool jackbridge_set_thread_init_callback(jack_client_t* client, JackThreadInitCallback thread_init_callback, void* arg)
   1151 {
   1152 #if defined(JACKBRIDGE_DUMMY)
   1153 #elif defined(JACKBRIDGE_DIRECT)
   1154     return (jack_set_thread_init_callback(client, thread_init_callback, arg) == 0);
   1155 #else
   1156     if (usingRealJACK && getBridgeInstance().set_thread_init_callback_ptr != nullptr)
   1157     {
   1158 # ifdef __WINE__
   1159         WineBridge::getInstance().set_thread_init(thread_init_callback);
   1160         return (getBridgeInstance().set_thread_init_callback_ptr(client, WineBridge::thread_init, arg) == 0);
   1161 # else
   1162         return (getBridgeInstance().set_thread_init_callback_ptr(client, thread_init_callback, arg) == 0);
   1163 # endif
   1164     }
   1165 #endif
   1166     return false;
   1167 }
   1168 
   1169 void jackbridge_on_shutdown(jack_client_t* client, JackShutdownCallback shutdown_callback, void* arg)
   1170 {
   1171 #if defined(JACKBRIDGE_DUMMY)
   1172 #elif defined(JACKBRIDGE_DIRECT)
   1173     jack_on_shutdown(client, shutdown_callback, arg);
   1174 #else
   1175     if (usingRealJACK && getBridgeInstance().on_shutdown_ptr != nullptr)
   1176     {
   1177 # ifdef __WINE__
   1178         WineBridge::getInstance().set_shutdown(shutdown_callback);
   1179         getBridgeInstance().on_shutdown_ptr(client, WineBridge::shutdown, arg);
   1180 # else
   1181         getBridgeInstance().on_shutdown_ptr(client, shutdown_callback, arg);
   1182 # endif
   1183     }
   1184 #endif
   1185 }
   1186 
   1187 void jackbridge_on_info_shutdown(jack_client_t* client, JackInfoShutdownCallback shutdown_callback, void* arg)
   1188 {
   1189 #if defined(JACKBRIDGE_DUMMY)
   1190 #elif defined(JACKBRIDGE_DIRECT)
   1191     jack_on_info_shutdown(client, shutdown_callback, arg);
   1192 #else
   1193     if (usingRealJACK && getBridgeInstance().on_info_shutdown_ptr != nullptr)
   1194     {
   1195 # ifdef __WINE__
   1196         WineBridge::getInstance().set_info_shutdown(shutdown_callback);
   1197         getBridgeInstance().on_info_shutdown_ptr(client, WineBridge::info_shutdown, arg);
   1198 # else
   1199         getBridgeInstance().on_info_shutdown_ptr(client, shutdown_callback, arg);
   1200 # endif
   1201     }
   1202 #endif
   1203 }
   1204 
   1205 bool jackbridge_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg)
   1206 {
   1207 #if defined(JACKBRIDGE_DUMMY)
   1208 #elif defined(JACKBRIDGE_DIRECT)
   1209     return (jack_set_process_callback(client, process_callback, arg) == 0);
   1210 #else
   1211     if (usingNativeBridge)
   1212     {
   1213         nativeBridge->jackProcessCallback = process_callback;
   1214         nativeBridge->jackProcessArg = arg;
   1215         return true;
   1216     }
   1217     if (getBridgeInstance().set_process_callback_ptr != nullptr)
   1218     {
   1219 # ifdef __WINE__
   1220         WineBridge::getInstance().set_process(process_callback);
   1221         return (getBridgeInstance().set_process_callback_ptr(client, WineBridge::process, arg) == 0);
   1222 # else
   1223         return (getBridgeInstance().set_process_callback_ptr(client, process_callback, arg) == 0);
   1224 # endif
   1225     }
   1226 #endif
   1227     return false;
   1228 }
   1229 
   1230 bool jackbridge_set_freewheel_callback(jack_client_t* client, JackFreewheelCallback freewheel_callback, void* arg)
   1231 {
   1232 #if defined(JACKBRIDGE_DUMMY)
   1233 #elif defined(JACKBRIDGE_DIRECT)
   1234     return (jack_set_freewheel_callback(client, freewheel_callback, arg) == 0);
   1235 #else
   1236     if (usingRealJACK && getBridgeInstance().set_freewheel_callback_ptr != nullptr)
   1237     {
   1238 # ifdef __WINE__
   1239         WineBridge::getInstance().set_freewheel(freewheel_callback);
   1240         return (getBridgeInstance().set_freewheel_callback_ptr(client, WineBridge::freewheel, arg) == 0);
   1241 # else
   1242         return (getBridgeInstance().set_freewheel_callback_ptr(client, freewheel_callback, arg) == 0);
   1243 # endif
   1244     }
   1245 #endif
   1246     return false;
   1247 }
   1248 
   1249 bool jackbridge_set_buffer_size_callback(jack_client_t* client, JackBufferSizeCallback bufsize_callback, void* arg)
   1250 {
   1251 #if defined(JACKBRIDGE_DUMMY)
   1252 #elif defined(JACKBRIDGE_DIRECT)
   1253     return (jack_set_buffer_size_callback(client, bufsize_callback, arg) == 0);
   1254 #else
   1255     if (usingNativeBridge)
   1256     {
   1257         nativeBridge->bufferSizeCallback = bufsize_callback;
   1258         nativeBridge->jackBufferSizeArg = arg;
   1259         return true;
   1260     }
   1261     if (getBridgeInstance().set_buffer_size_callback_ptr != nullptr)
   1262     {
   1263 # ifdef __WINE__
   1264         WineBridge::getInstance().set_bufsize(bufsize_callback);
   1265         return (getBridgeInstance().set_buffer_size_callback_ptr(client, WineBridge::bufsize, arg) == 0);
   1266 # else
   1267         return (getBridgeInstance().set_buffer_size_callback_ptr(client, bufsize_callback, arg) == 0);
   1268 # endif
   1269     }
   1270 #endif
   1271     return false;
   1272 }
   1273 
   1274 bool jackbridge_set_sample_rate_callback(jack_client_t* client, JackSampleRateCallback srate_callback, void* arg)
   1275 {
   1276 #if defined(JACKBRIDGE_DUMMY)
   1277 #elif defined(JACKBRIDGE_DIRECT)
   1278     return (jack_set_sample_rate_callback(client, srate_callback, arg) == 0);
   1279 #else
   1280     if (usingRealJACK && getBridgeInstance().set_sample_rate_callback_ptr != nullptr)
   1281     {
   1282 # ifdef __WINE__
   1283         WineBridge::getInstance().set_srate(srate_callback);
   1284         return (getBridgeInstance().set_sample_rate_callback_ptr(client, WineBridge::srate, arg) == 0);
   1285 # else
   1286         return (getBridgeInstance().set_sample_rate_callback_ptr(client, srate_callback, arg) == 0);
   1287 # endif
   1288     }
   1289 #endif
   1290     return false;
   1291 }
   1292 
   1293 bool jackbridge_set_client_registration_callback(jack_client_t* client, JackClientRegistrationCallback registration_callback, void* arg)
   1294 {
   1295 #if defined(JACKBRIDGE_DUMMY)
   1296 #elif defined(JACKBRIDGE_DIRECT)
   1297     return (jack_set_client_registration_callback(client, registration_callback, arg) == 0);
   1298 #else
   1299     if (usingRealJACK && getBridgeInstance().set_client_registration_callback_ptr != nullptr)
   1300     {
   1301 # ifdef __WINE__
   1302         WineBridge::getInstance().set_client_reg(registration_callback);
   1303         return (getBridgeInstance().set_client_registration_callback_ptr(client, WineBridge::client_reg, arg) == 0);
   1304 # else
   1305         return (getBridgeInstance().set_client_registration_callback_ptr(client, registration_callback, arg) == 0);
   1306 # endif
   1307     }
   1308 #endif
   1309     return false;
   1310 }
   1311 
   1312 bool jackbridge_set_port_registration_callback(jack_client_t* client, JackPortRegistrationCallback registration_callback, void *arg)
   1313 {
   1314 #if defined(JACKBRIDGE_DUMMY)
   1315 #elif defined(JACKBRIDGE_DIRECT)
   1316     return (jack_set_port_registration_callback(client, registration_callback, arg) == 0);
   1317 #else
   1318     if (usingRealJACK && getBridgeInstance().set_port_registration_callback_ptr != nullptr)
   1319     {
   1320 # ifdef __WINE__
   1321         WineBridge::getInstance().set_port_reg(registration_callback);
   1322         return (getBridgeInstance().set_port_registration_callback_ptr(client, WineBridge::port_reg, arg) == 0);
   1323 # else
   1324         return (getBridgeInstance().set_port_registration_callback_ptr(client, registration_callback, arg) == 0);
   1325 # endif
   1326     }
   1327 #endif
   1328     return false;
   1329 }
   1330 
   1331 bool jackbridge_set_port_rename_callback(jack_client_t* client, JackPortRenameCallback rename_callback, void* arg)
   1332 {
   1333 #if defined(JACKBRIDGE_DUMMY)
   1334 #elif defined(JACKBRIDGE_DIRECT)
   1335     return (jack_set_port_rename_callback(client, rename_callback, arg) == 0);
   1336 #else
   1337     if (usingRealJACK && getBridgeInstance().set_port_rename_callback_ptr != nullptr)
   1338     {
   1339 # ifdef __WINE__
   1340         WineBridge::getInstance().set_port_rename(rename_callback);
   1341         return (getBridgeInstance().set_port_rename_callback_ptr(client, WineBridge::port_rename, arg) == 0);
   1342 # else
   1343         return (getBridgeInstance().set_port_rename_callback_ptr(client, rename_callback, arg) == 0);
   1344 # endif
   1345     }
   1346 #endif
   1347     return false;
   1348 }
   1349 
   1350 bool jackbridge_set_port_connect_callback(jack_client_t* client, JackPortConnectCallback connect_callback, void* arg)
   1351 {
   1352 #if defined(JACKBRIDGE_DUMMY)
   1353 #elif defined(JACKBRIDGE_DIRECT)
   1354     return (jack_set_port_connect_callback(client, connect_callback, arg) == 0);
   1355 #else
   1356     if (usingRealJACK && getBridgeInstance().set_port_connect_callback_ptr != nullptr)
   1357     {
   1358 # ifdef __WINE__
   1359         WineBridge::getInstance().set_port_conn(connect_callback);
   1360         return (getBridgeInstance().set_port_connect_callback_ptr(client, WineBridge::port_conn, arg) == 0);
   1361 # else
   1362         return (getBridgeInstance().set_port_connect_callback_ptr(client, connect_callback, arg) == 0);
   1363 # endif
   1364     }
   1365 #endif
   1366     return false;
   1367 }
   1368 
   1369 bool jackbridge_set_graph_order_callback(jack_client_t* client, JackGraphOrderCallback graph_callback, void* arg)
   1370 {
   1371 #if defined(JACKBRIDGE_DUMMY)
   1372 #elif defined(JACKBRIDGE_DIRECT)
   1373     return (jack_set_graph_order_callback(client, graph_callback, arg) == 0);
   1374 #else
   1375     if (usingRealJACK && getBridgeInstance().set_graph_order_callback_ptr != nullptr)
   1376     {
   1377 # ifdef __WINE__
   1378         WineBridge::getInstance().set_graph_order(graph_callback);
   1379         return (getBridgeInstance().set_graph_order_callback_ptr(client, WineBridge::graph_order, arg) == 0);
   1380 # else
   1381         return (getBridgeInstance().set_graph_order_callback_ptr(client, graph_callback, arg) == 0);
   1382 # endif
   1383     }
   1384 #endif
   1385     return false;
   1386 }
   1387 
   1388 bool jackbridge_set_xrun_callback(jack_client_t* client, JackXRunCallback xrun_callback, void* arg)
   1389 {
   1390 #if defined(JACKBRIDGE_DUMMY)
   1391 #elif defined(JACKBRIDGE_DIRECT)
   1392     return (jack_set_xrun_callback(client, xrun_callback, arg) == 0);
   1393 #else
   1394     if (usingRealJACK && getBridgeInstance().set_xrun_callback_ptr != nullptr)
   1395     {
   1396 # ifdef __WINE__
   1397         WineBridge::getInstance().set_xrun(xrun_callback);
   1398         return (getBridgeInstance().set_xrun_callback_ptr(client, WineBridge::xrun, arg) == 0);
   1399 # else
   1400         return (getBridgeInstance().set_xrun_callback_ptr(client, xrun_callback, arg) == 0);
   1401 # endif
   1402     }
   1403 #endif
   1404     return false;
   1405 }
   1406 
   1407 bool jackbridge_set_latency_callback(jack_client_t* client, JackLatencyCallback latency_callback, void* arg)
   1408 {
   1409 #if defined(JACKBRIDGE_DUMMY)
   1410 #elif defined(JACKBRIDGE_DIRECT)
   1411     return (jack_set_latency_callback(client, latency_callback, arg) == 0);
   1412 #else
   1413     if (usingRealJACK && getBridgeInstance().set_latency_callback_ptr != nullptr)
   1414     {
   1415 # ifdef __WINE__
   1416         WineBridge::getInstance().set_latency(latency_callback);
   1417         return (getBridgeInstance().set_latency_callback_ptr(client, WineBridge::latency, arg) == 0);
   1418 # else
   1419         return (getBridgeInstance().set_latency_callback_ptr(client, latency_callback, arg) == 0);
   1420 # endif
   1421     }
   1422 #endif
   1423     return false;
   1424 }
   1425 
   1426 // -----------------------------------------------------------------------------
   1427 
   1428 bool jackbridge_set_freewheel(jack_client_t* client, bool onoff)
   1429 {
   1430 #if defined(JACKBRIDGE_DUMMY)
   1431 #elif defined(JACKBRIDGE_DIRECT)
   1432     return jack_set_freewheel(client, onoff);
   1433 #else
   1434     if (usingRealJACK)
   1435         if (getBridgeInstance().set_freewheel_ptr != nullptr)
   1436             return getBridgeInstance().set_freewheel_ptr(client, onoff);
   1437 #endif
   1438     return false;
   1439 }
   1440 
   1441 bool jackbridge_set_buffer_size(jack_client_t* client, jack_nframes_t nframes)
   1442 {
   1443 #if defined(JACKBRIDGE_DUMMY)
   1444 #elif defined(JACKBRIDGE_DIRECT)
   1445     return jack_set_buffer_size(client, nframes);
   1446 #else
   1447     if (usingNativeBridge)
   1448         return nativeBridge->requestBufferSizeChange(nframes);
   1449     if (getBridgeInstance().set_buffer_size_ptr != nullptr)
   1450         return getBridgeInstance().set_buffer_size_ptr(client, nframes);
   1451 #endif
   1452     return false;
   1453 }
   1454 
   1455 // -----------------------------------------------------------------------------
   1456 
   1457 jack_nframes_t jackbridge_get_sample_rate(jack_client_t* client)
   1458 {
   1459 #if defined(JACKBRIDGE_DUMMY)
   1460 #elif defined(JACKBRIDGE_DIRECT)
   1461     return jack_get_sample_rate(client);
   1462 #else
   1463     if (usingNativeBridge)
   1464         return nativeBridge->sampleRate;
   1465     if (getBridgeInstance().get_sample_rate_ptr != nullptr)
   1466         return getBridgeInstance().get_sample_rate_ptr(client);
   1467 #endif
   1468     return 0;
   1469 }
   1470 
   1471 jack_nframes_t jackbridge_get_buffer_size(jack_client_t* client)
   1472 {
   1473 #if defined(JACKBRIDGE_DUMMY)
   1474 #elif defined(JACKBRIDGE_DIRECT)
   1475     return jack_get_buffer_size(client);
   1476 #else
   1477     if (usingNativeBridge)
   1478         return nativeBridge->bufferSize;
   1479     if (getBridgeInstance().get_buffer_size_ptr != nullptr)
   1480         return getBridgeInstance().get_buffer_size_ptr(client);
   1481 #endif
   1482     return 0;
   1483 }
   1484 
   1485 float jackbridge_cpu_load(jack_client_t* client)
   1486 {
   1487 #if defined(JACKBRIDGE_DUMMY)
   1488 #elif defined(JACKBRIDGE_DIRECT)
   1489     return jack_cpu_load(client);
   1490 #else
   1491     if (usingRealJACK)
   1492         if (getBridgeInstance().cpu_load_ptr != nullptr)
   1493             return getBridgeInstance().cpu_load_ptr(client);
   1494 #endif
   1495     return 0.0f;
   1496 }
   1497 
   1498 // -----------------------------------------------------------------------------
   1499 
   1500 jack_port_t* jackbridge_port_register(jack_client_t* client, const char* port_name, const char* type, uint64_t flags, uint64_t buffer_size)
   1501 {
   1502 #if defined(JACKBRIDGE_DUMMY)
   1503 #elif defined(JACKBRIDGE_DIRECT)
   1504     return jack_port_register(client, port_name, type, flags, buffer_size);
   1505 #else
   1506     if (usingNativeBridge)
   1507         return nativeBridge->registerPort(type, flags);
   1508     if (getBridgeInstance().port_register_ptr != nullptr)
   1509         return getBridgeInstance().port_register_ptr(client, port_name, type,
   1510                                                      static_cast<ulong>(flags),
   1511                                                      static_cast<ulong>(buffer_size));
   1512 #endif
   1513     return nullptr;
   1514 }
   1515 
   1516 bool jackbridge_port_unregister(jack_client_t* client, jack_port_t* port)
   1517 {
   1518 #if defined(JACKBRIDGE_DUMMY)
   1519 #elif defined(JACKBRIDGE_DIRECT)
   1520     return (jack_port_unregister(client, port) == 0);
   1521 #else
   1522     if (usingRealJACK)
   1523         if (getBridgeInstance().port_unregister_ptr != nullptr)
   1524             return (getBridgeInstance().port_unregister_ptr(client, port) == 0);
   1525 #endif
   1526     return false;
   1527 }
   1528 
   1529 void* jackbridge_port_get_buffer(jack_port_t* port, jack_nframes_t nframes)
   1530 {
   1531 #if defined(JACKBRIDGE_DUMMY)
   1532 #elif defined(JACKBRIDGE_DIRECT)
   1533     return jack_port_get_buffer(port, nframes);
   1534 #else
   1535     if (usingNativeBridge)
   1536         return nativeBridge->getPortBuffer(port);
   1537     if (getBridgeInstance().port_get_buffer_ptr != nullptr)
   1538         return getBridgeInstance().port_get_buffer_ptr(port, nframes);
   1539 #endif
   1540     return nullptr;
   1541 }
   1542 
   1543 // -----------------------------------------------------------------------------
   1544 
   1545 const char* jackbridge_port_name(const jack_port_t* port)
   1546 {
   1547 #if defined(JACKBRIDGE_DUMMY)
   1548 #elif defined(JACKBRIDGE_DIRECT)
   1549     return jack_port_name(port);
   1550 #else
   1551     if (usingRealJACK)
   1552         if (getBridgeInstance().port_name_ptr != nullptr)
   1553             return getBridgeInstance().port_name_ptr(port);
   1554 #endif
   1555     return nullptr;
   1556 }
   1557 
   1558 jack_uuid_t jackbridge_port_uuid(const jack_port_t* port)
   1559 {
   1560 #if defined(JACKBRIDGE_DUMMY)
   1561 #elif defined(JACKBRIDGE_DIRECT)
   1562     return jack_port_uuid(port);
   1563 #else
   1564     if (usingRealJACK)
   1565         if (getBridgeInstance().port_uuid_ptr != nullptr)
   1566             return getBridgeInstance().port_uuid_ptr(port);
   1567 #endif
   1568     return 0;
   1569 }
   1570 
   1571 const char* jackbridge_port_short_name(const jack_port_t* port)
   1572 {
   1573 #if defined(JACKBRIDGE_DUMMY)
   1574 #elif defined(JACKBRIDGE_DIRECT)
   1575     return jack_port_short_name(port);
   1576 #else
   1577     if (usingRealJACK)
   1578         if (getBridgeInstance().port_short_name_ptr != nullptr)
   1579             return getBridgeInstance().port_short_name_ptr(port);
   1580 #endif
   1581     return nullptr;
   1582 }
   1583 
   1584 int jackbridge_port_flags(const jack_port_t* port)
   1585 {
   1586 #if defined(JACKBRIDGE_DUMMY)
   1587 #elif defined(JACKBRIDGE_DIRECT)
   1588     return jack_port_flags(port);
   1589 #else
   1590     if (usingRealJACK)
   1591         if (getBridgeInstance().port_flags_ptr != nullptr)
   1592             return getBridgeInstance().port_flags_ptr(port);
   1593 #endif
   1594     return 0x0;
   1595 }
   1596 
   1597 const char* jackbridge_port_type(const jack_port_t* port)
   1598 {
   1599 #if defined(JACKBRIDGE_DUMMY)
   1600 #elif defined(JACKBRIDGE_DIRECT)
   1601     return jack_port_type(port);
   1602 #else
   1603     if (usingRealJACK)
   1604         if (getBridgeInstance().port_type_ptr != nullptr)
   1605             return getBridgeInstance().port_type_ptr(port);
   1606 #endif
   1607     return nullptr;
   1608 }
   1609 
   1610 bool jackbridge_port_is_mine(const jack_client_t* client, const jack_port_t* port)
   1611 {
   1612 #if defined(JACKBRIDGE_DUMMY)
   1613 #elif defined(JACKBRIDGE_DIRECT)
   1614     return jack_port_is_mine(client, port);
   1615 #else
   1616     if (usingRealJACK)
   1617         if (getBridgeInstance().port_is_mine_ptr != nullptr)
   1618             return getBridgeInstance().port_is_mine_ptr(client, port);
   1619 #endif
   1620     return false;
   1621 }
   1622 
   1623 int jackbridge_port_connected(const jack_port_t* port)
   1624 {
   1625 #if defined(JACKBRIDGE_DUMMY)
   1626 #elif defined(JACKBRIDGE_DIRECT)
   1627     return jack_port_connected(port);
   1628 #else
   1629     if (usingRealJACK)
   1630         if (getBridgeInstance().port_connected_ptr != nullptr)
   1631             return getBridgeInstance().port_connected_ptr(port);
   1632 #endif
   1633     return 0;
   1634 }
   1635 
   1636 bool jackbridge_port_connected_to(const jack_port_t* port, const char* port_name)
   1637 {
   1638 #if defined(JACKBRIDGE_DUMMY)
   1639 #elif defined(JACKBRIDGE_DIRECT)
   1640     return jack_port_connected_to(port, port_name);
   1641 #else
   1642     if (usingRealJACK)
   1643         if (getBridgeInstance().port_connected_to_ptr != nullptr)
   1644             return getBridgeInstance().port_connected_to_ptr(port, port_name);
   1645 #endif
   1646     return false;
   1647 }
   1648 
   1649 const char** jackbridge_port_get_connections(const jack_port_t* port)
   1650 {
   1651 #if defined(JACKBRIDGE_DUMMY)
   1652 #elif defined(JACKBRIDGE_DIRECT)
   1653     return jack_port_get_connections(port);
   1654 #else
   1655     if (usingRealJACK)
   1656         if (getBridgeInstance().port_get_connections_ptr != nullptr)
   1657             return getBridgeInstance().port_get_connections_ptr(port);
   1658 #endif
   1659     return nullptr;
   1660 }
   1661 
   1662 const char** jackbridge_port_get_all_connections(const jack_client_t* client, const jack_port_t* port)
   1663 {
   1664 #if defined(JACKBRIDGE_DUMMY)
   1665 #elif defined(JACKBRIDGE_DIRECT)
   1666     return jack_port_get_all_connections(client, port);
   1667 #else
   1668     if (usingRealJACK)
   1669         if (getBridgeInstance().port_get_all_connections_ptr != nullptr)
   1670             return getBridgeInstance().port_get_all_connections_ptr(client, port);
   1671 #endif
   1672     return nullptr;
   1673 }
   1674 
   1675 // -----------------------------------------------------------------------------
   1676 
   1677 bool jackbridge_port_rename(jack_client_t* client, jack_port_t* port, const char* port_name)
   1678 {
   1679 #if defined(JACKBRIDGE_DUMMY)
   1680 #elif defined(JACKBRIDGE_DIRECT)
   1681     return (jack_port_rename(client, port, port_name) == 0);
   1682 #else
   1683     if (usingNativeBridge)
   1684         return false;
   1685     // Try new API first
   1686     if (getBridgeInstance().port_rename_ptr != nullptr)
   1687         return (getBridgeInstance().port_rename_ptr(client, port, port_name) == 0);
   1688     // Try old API if using JACK2
   1689     if (getBridgeInstance().get_version_string_ptr != nullptr && getBridgeInstance().port_set_name_ptr != nullptr)
   1690         return (getBridgeInstance().port_set_name_ptr(port, port_name) == 0);
   1691 #endif
   1692     return false;
   1693 }
   1694 
   1695 bool jackbridge_port_set_alias(jack_port_t* port, const char* alias)
   1696 {
   1697 #if defined(JACKBRIDGE_DUMMY)
   1698 #elif defined(JACKBRIDGE_DIRECT)
   1699     return (jack_port_set_alias(port, alias) == 0);
   1700 #else
   1701     if (usingRealJACK)
   1702         if (getBridgeInstance().port_set_alias_ptr != nullptr)
   1703             return (getBridgeInstance().port_set_alias_ptr(port, alias) == 0);
   1704 #endif
   1705     return false;
   1706 }
   1707 
   1708 bool jackbridge_port_unset_alias(jack_port_t* port, const char* alias)
   1709 {
   1710 #if defined(JACKBRIDGE_DUMMY)
   1711 #elif defined(JACKBRIDGE_DIRECT)
   1712     return (jack_port_unset_alias(port, alias) == 0);
   1713 #else
   1714     if (usingRealJACK)
   1715         if (getBridgeInstance().port_unset_alias_ptr != nullptr)
   1716             return (getBridgeInstance().port_unset_alias_ptr(port, alias) == 0);
   1717 #endif
   1718     return false;
   1719 }
   1720 
   1721 int jackbridge_port_get_aliases(const jack_port_t* port, char* const aliases[2])
   1722 {
   1723 #if defined(JACKBRIDGE_DUMMY)
   1724 #elif defined(JACKBRIDGE_DIRECT)
   1725     return (jack_port_get_aliases(port, aliases) == 0);
   1726 #else
   1727     if (usingRealJACK)
   1728         if (getBridgeInstance().port_get_aliases_ptr != nullptr)
   1729             return getBridgeInstance().port_get_aliases_ptr(port, aliases);
   1730 #endif
   1731     return 0;
   1732 }
   1733 
   1734 // -----------------------------------------------------------------------------
   1735 
   1736 bool jackbridge_port_request_monitor(jack_port_t* port, bool onoff)
   1737 {
   1738 #if defined(JACKBRIDGE_DUMMY)
   1739 #elif defined(JACKBRIDGE_DIRECT)
   1740     return (jack_port_request_monitor(port, onoff) == 0);
   1741 #else
   1742     if (usingRealJACK)
   1743         if (getBridgeInstance().port_request_monitor_ptr != nullptr)
   1744             return (getBridgeInstance().port_request_monitor_ptr(port, onoff) == 0);
   1745 #endif
   1746     return false;
   1747 }
   1748 
   1749 bool jackbridge_port_request_monitor_by_name(jack_client_t* client, const char* port_name, bool onoff)
   1750 {
   1751 #if defined(JACKBRIDGE_DUMMY)
   1752 #elif defined(JACKBRIDGE_DIRECT)
   1753     return (jack_port_request_monitor_by_name(client, port_name, onoff) == 0);
   1754 #else
   1755     if (usingRealJACK)
   1756         if (getBridgeInstance().port_request_monitor_by_name_ptr != nullptr)
   1757             return (getBridgeInstance().port_request_monitor_by_name_ptr(client, port_name, onoff) == 0);
   1758 #endif
   1759     return false;
   1760 }
   1761 
   1762 bool jackbridge_port_ensure_monitor(jack_port_t* port, bool onoff)
   1763 {
   1764 #if defined(JACKBRIDGE_DUMMY)
   1765 #elif defined(JACKBRIDGE_DIRECT)
   1766     return (jack_port_ensure_monitor(port, onoff) == 0);
   1767 #else
   1768     if (usingRealJACK)
   1769         if (getBridgeInstance().port_ensure_monitor_ptr != nullptr)
   1770             return (getBridgeInstance().port_ensure_monitor_ptr(port, onoff) == 0);
   1771 #endif
   1772     return false;
   1773 }
   1774 
   1775 bool jackbridge_port_monitoring_input(jack_port_t* port)
   1776 {
   1777 #if defined(JACKBRIDGE_DUMMY)
   1778 #elif defined(JACKBRIDGE_DIRECT)
   1779     return jack_port_monitoring_input(port);
   1780 #else
   1781     if (usingRealJACK)
   1782         if (getBridgeInstance().port_monitoring_input_ptr != nullptr)
   1783             return getBridgeInstance().port_monitoring_input_ptr(port);
   1784 #endif
   1785     return false;
   1786 }
   1787 
   1788 // -----------------------------------------------------------------------------
   1789 
   1790 bool jackbridge_connect(jack_client_t* client, const char* source_port, const char* destination_port)
   1791 {
   1792 #if defined(JACKBRIDGE_DUMMY)
   1793 #elif defined(JACKBRIDGE_DIRECT)
   1794     return (jack_connect(client, source_port, destination_port) == 0);
   1795 #else
   1796     if (usingRealJACK && getBridgeInstance().connect_ptr != nullptr)
   1797     {
   1798         const int ret = getBridgeInstance().connect_ptr(client, source_port, destination_port);
   1799         return ret == 0 || ret == EEXIST;
   1800     }
   1801 #endif
   1802     return false;
   1803 }
   1804 
   1805 bool jackbridge_disconnect(jack_client_t* client, const char* source_port, const char* destination_port)
   1806 {
   1807 #if defined(JACKBRIDGE_DUMMY)
   1808 #elif defined(JACKBRIDGE_DIRECT)
   1809     return (jack_disconnect(client, source_port, destination_port) == 0);
   1810 #else
   1811     if (usingRealJACK)
   1812         if (getBridgeInstance().disconnect_ptr != nullptr)
   1813             return (getBridgeInstance().disconnect_ptr(client, source_port, destination_port) == 0);
   1814 #endif
   1815     return false;
   1816 }
   1817 
   1818 bool jackbridge_port_disconnect(jack_client_t* client, jack_port_t* port)
   1819 {
   1820 #if defined(JACKBRIDGE_DUMMY)
   1821 #elif defined(JACKBRIDGE_DIRECT)
   1822     return (jack_port_disconnect(client, port) == 0);
   1823 #else
   1824     if (usingRealJACK)
   1825         if (getBridgeInstance().port_disconnect_ptr != nullptr)
   1826             return (getBridgeInstance().port_disconnect_ptr(client, port) == 0);
   1827 #endif
   1828     return false;
   1829 }
   1830 
   1831 // -----------------------------------------------------------------------------
   1832 
   1833 int jackbridge_port_name_size()
   1834 {
   1835 #if defined(JACKBRIDGE_DUMMY)
   1836 #elif defined(JACKBRIDGE_DIRECT)
   1837     return jack_port_name_size();
   1838 #else
   1839     if (usingRealJACK)
   1840         if (getBridgeInstance().port_name_size_ptr != nullptr)
   1841             return getBridgeInstance().port_name_size_ptr();
   1842 #endif
   1843     return 256;
   1844 }
   1845 
   1846 int jackbridge_port_type_size()
   1847 {
   1848 #if defined(JACKBRIDGE_DUMMY)
   1849 #elif defined(JACKBRIDGE_DIRECT)
   1850     return jack_port_type_size();
   1851 #else
   1852     if (usingRealJACK)
   1853         if (getBridgeInstance().port_type_size_ptr != nullptr)
   1854             return getBridgeInstance().port_type_size_ptr();
   1855 #endif
   1856     return 32;
   1857 }
   1858 
   1859 uint32_t jackbridge_port_type_get_buffer_size(jack_client_t* client, const char* port_type)
   1860 {
   1861 #if defined(JACKBRIDGE_DUMMY)
   1862 #elif defined(JACKBRIDGE_DIRECT)
   1863     return static_cast<uint32_t>(jack_port_type_get_buffer_size(client, port_type));
   1864 #else
   1865     if (usingRealJACK)
   1866         if (getBridgeInstance().port_type_get_buffer_size_ptr != nullptr)
   1867             return static_cast<uint32_t>(getBridgeInstance().port_type_get_buffer_size_ptr(client, port_type));
   1868 #endif
   1869     return 0;
   1870 }
   1871 
   1872 // -----------------------------------------------------------------------------
   1873 
   1874 void jackbridge_port_get_latency_range(jack_port_t* port, uint32_t mode, jack_latency_range_t* range)
   1875 {
   1876 #if defined(JACKBRIDGE_DUMMY)
   1877 #elif defined(JACKBRIDGE_DIRECT)
   1878     return jack_port_get_latency_range(port, static_cast<jack_latency_callback_mode_t>(mode), range);
   1879 #else
   1880     if (usingRealJACK)
   1881         if (getBridgeInstance().port_get_latency_range_ptr != nullptr)
   1882             return getBridgeInstance().port_get_latency_range_ptr(port,
   1883                                                                   static_cast<jack_latency_callback_mode_t>(mode),
   1884                                                                   range);
   1885 #endif
   1886     range->min = 0;
   1887     range->max = 0;
   1888 }
   1889 
   1890 void jackbridge_port_set_latency_range(jack_port_t* port, uint32_t mode, jack_latency_range_t* range)
   1891 {
   1892 #if defined(JACKBRIDGE_DUMMY)
   1893 #elif defined(JACKBRIDGE_DIRECT)
   1894     jack_port_set_latency_range(port, static_cast<jack_latency_callback_mode_t>(mode), range);
   1895 #else
   1896     if (usingRealJACK)
   1897         if (getBridgeInstance().port_set_latency_range_ptr != nullptr)
   1898             getBridgeInstance().port_set_latency_range_ptr(port,
   1899                                                            static_cast<jack_latency_callback_mode_t>(mode),
   1900                                                            range);
   1901 #endif
   1902 }
   1903 
   1904 bool jackbridge_recompute_total_latencies(jack_client_t* client)
   1905 {
   1906 #if defined(JACKBRIDGE_DUMMY)
   1907 #elif defined(JACKBRIDGE_DIRECT)
   1908     return (jack_recompute_total_latencies(client) == 0);
   1909 #else
   1910     if (usingRealJACK)
   1911         if (getBridgeInstance().recompute_total_latencies_ptr != nullptr)
   1912             return (getBridgeInstance().recompute_total_latencies_ptr(client) == 0);
   1913 #endif
   1914     return false;
   1915 }
   1916 
   1917 // -----------------------------------------------------------------------------
   1918 
   1919 const char** jackbridge_get_ports(jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, uint64_t flags)
   1920 {
   1921 #if defined(JACKBRIDGE_DUMMY)
   1922 #elif defined(JACKBRIDGE_DIRECT)
   1923     return jack_get_ports(client, port_name_pattern, type_name_pattern, flags);
   1924 #else
   1925     if (usingRealJACK)
   1926         if (getBridgeInstance().get_ports_ptr != nullptr)
   1927             return getBridgeInstance().get_ports_ptr(client, port_name_pattern, type_name_pattern,
   1928                                                      static_cast<ulong>(flags));
   1929 #endif
   1930     return nullptr;
   1931 }
   1932 
   1933 jack_port_t* jackbridge_port_by_name(jack_client_t* client, const char* port_name)
   1934 {
   1935 #if defined(JACKBRIDGE_DUMMY)
   1936 #elif defined(JACKBRIDGE_DIRECT)
   1937     return jack_port_by_name(client, port_name);
   1938 #else
   1939     if (usingRealJACK)
   1940         if (getBridgeInstance().port_by_name_ptr != nullptr)
   1941             return getBridgeInstance().port_by_name_ptr(client, port_name);
   1942 #endif
   1943     return nullptr;
   1944 }
   1945 
   1946 jack_port_t* jackbridge_port_by_id(jack_client_t* client, jack_port_id_t port_id)
   1947 {
   1948 #if defined(JACKBRIDGE_DUMMY)
   1949 #elif defined(JACKBRIDGE_DIRECT)
   1950     return jack_port_by_id(client, port_id);
   1951 #else
   1952     if (usingRealJACK)
   1953         if (getBridgeInstance().port_by_id_ptr != nullptr)
   1954             return getBridgeInstance().port_by_id_ptr(client, port_id);
   1955 #endif
   1956     return nullptr;
   1957 }
   1958 
   1959 // -----------------------------------------------------------------------------
   1960 
   1961 void jackbridge_free(void* ptr)
   1962 {
   1963 #if defined(JACKBRIDGE_DUMMY)
   1964 #elif defined(JACKBRIDGE_DIRECT)
   1965     return jack_free(ptr);
   1966 #else
   1967     if (usingRealJACK)
   1968         if (getBridgeInstance().free_ptr != nullptr)
   1969             return getBridgeInstance().free_ptr(ptr);
   1970 
   1971     // just in case
   1972     std::free(ptr);
   1973 #endif
   1974 }
   1975 
   1976 // -----------------------------------------------------------------------------
   1977 
   1978 uint32_t jackbridge_midi_get_event_count(void* port_buffer)
   1979 {
   1980 #if defined(JACKBRIDGE_DUMMY)
   1981 #elif defined(JACKBRIDGE_DIRECT)
   1982     return jack_midi_get_event_count(port_buffer);
   1983 #else
   1984     if (usingNativeBridge)
   1985         return nativeBridge->getEventCount();
   1986     if (getBridgeInstance().midi_get_event_count_ptr != nullptr)
   1987         return getBridgeInstance().midi_get_event_count_ptr(port_buffer);
   1988 #endif
   1989     return 0;
   1990 }
   1991 
   1992 bool jackbridge_midi_event_get(jack_midi_event_t* event, void* port_buffer, uint32_t event_index)
   1993 {
   1994 #if defined(JACKBRIDGE_DUMMY)
   1995 #elif defined(JACKBRIDGE_DIRECT)
   1996     return (jack_midi_event_get(event, port_buffer, event_index) == 0);
   1997 #else
   1998     if (usingNativeBridge)
   1999         return nativeBridge->getEvent(event);
   2000     if (getBridgeInstance().midi_event_get_ptr != nullptr)
   2001         return (getBridgeInstance().midi_event_get_ptr(event, port_buffer, event_index) == 0);
   2002 #endif
   2003     return false;
   2004 }
   2005 
   2006 void jackbridge_midi_clear_buffer(void* port_buffer)
   2007 {
   2008 #if defined(JACKBRIDGE_DUMMY)
   2009 #elif defined(JACKBRIDGE_DIRECT)
   2010     jack_midi_clear_buffer(port_buffer);
   2011 #else
   2012     if (usingNativeBridge)
   2013         return nativeBridge->clearEventBuffer();
   2014     if (getBridgeInstance().midi_clear_buffer_ptr != nullptr)
   2015         getBridgeInstance().midi_clear_buffer_ptr(port_buffer);
   2016 #endif
   2017 }
   2018 
   2019 bool jackbridge_midi_event_write(void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, uint32_t data_size)
   2020 {
   2021 #if defined(JACKBRIDGE_DUMMY)
   2022 #elif defined(JACKBRIDGE_DIRECT)
   2023     return (jack_midi_event_write(port_buffer, time, data, data_size) == 0);
   2024 #else
   2025     if (usingNativeBridge)
   2026         return nativeBridge->writeEvent(time, data, data_size);
   2027     if (getBridgeInstance().midi_event_write_ptr != nullptr)
   2028         return (getBridgeInstance().midi_event_write_ptr(port_buffer, time, data, data_size) == 0);
   2029 #endif
   2030     return false;
   2031 }
   2032 
   2033 jack_midi_data_t* jackbridge_midi_event_reserve(void* port_buffer, jack_nframes_t time, uint32_t data_size)
   2034 {
   2035 #if defined(JACKBRIDGE_DUMMY)
   2036 #elif defined(JACKBRIDGE_DIRECT)
   2037     return jack_midi_event_reserve(port_buffer, time, data_size);
   2038 #else
   2039     if (usingRealJACK)
   2040         if (getBridgeInstance().midi_event_reserve_ptr != nullptr)
   2041             return getBridgeInstance().midi_event_reserve_ptr(port_buffer, time, data_size);
   2042 #endif
   2043     return nullptr;
   2044 }
   2045 
   2046 // -----------------------------------------------------------------------------
   2047 
   2048 bool jackbridge_release_timebase(jack_client_t* client)
   2049 {
   2050 #if defined(JACKBRIDGE_DUMMY)
   2051 #elif defined(JACKBRIDGE_DIRECT)
   2052     return (jack_release_timebase(client) == 0);
   2053 #else
   2054     if (usingRealJACK)
   2055         if (getBridgeInstance().release_timebase_ptr != nullptr)
   2056             return (getBridgeInstance().release_timebase_ptr(client) == 0);
   2057 #endif
   2058     return false;
   2059 }
   2060 
   2061 bool jackbridge_set_sync_callback(jack_client_t* client, JackSyncCallback sync_callback, void* arg)
   2062 {
   2063 #if defined(JACKBRIDGE_DUMMY)
   2064 #elif defined(JACKBRIDGE_DIRECT)
   2065     return (jack_set_sync_callback(client, sync_callback, arg) == 0);
   2066 #else
   2067     if (usingRealJACK && getBridgeInstance().set_sync_callback_ptr != nullptr)
   2068     {
   2069 # ifdef __WINE__
   2070         WineBridge::getInstance().set_sync(sync_callback);
   2071         return (getBridgeInstance().set_sync_callback_ptr(client, WineBridge::sync, arg) == 0);
   2072 # else
   2073         return (getBridgeInstance().set_sync_callback_ptr(client, sync_callback, arg) == 0);
   2074 # endif
   2075     }
   2076 #endif
   2077     return false;
   2078 }
   2079 
   2080 bool jackbridge_set_sync_timeout(jack_client_t* client, jack_time_t timeout)
   2081 {
   2082 #if defined(JACKBRIDGE_DUMMY)
   2083 #elif defined(JACKBRIDGE_DIRECT)
   2084     return (jack_set_sync_timeout(client, timeout) == 0);
   2085 #else
   2086     if (usingRealJACK)
   2087         if (getBridgeInstance().set_sync_timeout_ptr != nullptr)
   2088             return (getBridgeInstance().set_sync_timeout_ptr(client, timeout) == 0);
   2089 #endif
   2090     return false;
   2091 }
   2092 
   2093 bool jackbridge_set_timebase_callback(jack_client_t* client, bool conditional, JackTimebaseCallback timebase_callback, void* arg)
   2094 {
   2095 #if defined(JACKBRIDGE_DUMMY)
   2096 #elif defined(JACKBRIDGE_DIRECT)
   2097     return (jack_set_timebase_callback(client, conditional, timebase_callback, arg) == 0);
   2098 #else
   2099     if (usingRealJACK && getBridgeInstance().set_timebase_callback_ptr != nullptr)
   2100     {
   2101 # ifdef __WINE__
   2102         WineBridge::getInstance().set_timebase(timebase_callback);
   2103         return (getBridgeInstance().set_timebase_callback_ptr(client, conditional, WineBridge::timebase, arg) == 0);
   2104 # else
   2105         return (getBridgeInstance().set_timebase_callback_ptr(client, conditional, timebase_callback, arg) == 0);
   2106 # endif
   2107     }
   2108 #endif
   2109     return false;
   2110 }
   2111 
   2112 bool jackbridge_transport_locate(jack_client_t* client, jack_nframes_t frame)
   2113 {
   2114 #if defined(JACKBRIDGE_DUMMY)
   2115 #elif defined(JACKBRIDGE_DIRECT)
   2116     return (jack_transport_locate(client, frame) == 0);
   2117 #else
   2118     if (usingRealJACK)
   2119         if (getBridgeInstance().transport_locate_ptr != nullptr)
   2120             return (getBridgeInstance().transport_locate_ptr(client, frame) == 0);
   2121 #endif
   2122     return false;
   2123 }
   2124 
   2125 uint32_t jackbridge_transport_query(const jack_client_t* client, jack_position_t* pos)
   2126 {
   2127 #if defined(JACKBRIDGE_DUMMY)
   2128 #elif defined(JACKBRIDGE_DIRECT)
   2129     return jack_transport_query(client, pos);
   2130 #else
   2131     if (usingRealJACK)
   2132         if (getBridgeInstance().transport_query_ptr != nullptr)
   2133             return getBridgeInstance().transport_query_ptr(client, pos);
   2134 #endif
   2135     if (pos != nullptr)
   2136     {
   2137         // invalidate
   2138         std::memset(pos, 0, sizeof(*pos));
   2139         pos->unique_1 = 0;
   2140         pos->unique_2 = 1;
   2141     }
   2142     return JackTransportStopped;
   2143 }
   2144 
   2145 jack_nframes_t jackbridge_get_current_transport_frame(const jack_client_t* client)
   2146 {
   2147 #if defined(JACKBRIDGE_DUMMY)
   2148 #elif defined(JACKBRIDGE_DIRECT)
   2149     return jack_get_current_transport_frame(client);
   2150 #else
   2151     if (usingRealJACK)
   2152         if (getBridgeInstance().get_current_transport_frame_ptr != nullptr)
   2153             return getBridgeInstance().get_current_transport_frame_ptr(client);
   2154 #endif
   2155     return 0;
   2156 }
   2157 
   2158 bool jackbridge_transport_reposition(jack_client_t* client, const jack_position_t* pos)
   2159 {
   2160 #if defined(JACKBRIDGE_DUMMY)
   2161 #elif defined(JACKBRIDGE_DIRECT)
   2162     return (jack_transport_reposition(client, pos) == 0);
   2163 #else
   2164     if (usingRealJACK)
   2165         if (getBridgeInstance().transport_reposition_ptr != nullptr)
   2166             return (getBridgeInstance().transport_reposition_ptr(client, pos) == 0);
   2167 #endif
   2168     return false;
   2169 }
   2170 
   2171 void jackbridge_transport_start(jack_client_t* client)
   2172 {
   2173 #if defined(JACKBRIDGE_DUMMY)
   2174 #elif defined(JACKBRIDGE_DIRECT)
   2175     jack_transport_start(client);
   2176 #else
   2177     if (usingRealJACK)
   2178         if (getBridgeInstance().transport_start_ptr != nullptr)
   2179             getBridgeInstance().transport_start_ptr(client);
   2180 #endif
   2181 }
   2182 
   2183 void jackbridge_transport_stop(jack_client_t* client)
   2184 {
   2185 #if defined(JACKBRIDGE_DUMMY)
   2186 #elif defined(JACKBRIDGE_DIRECT)
   2187     jack_transport_stop(client);
   2188 #else
   2189     if (usingRealJACK)
   2190         if (getBridgeInstance().transport_stop_ptr != nullptr)
   2191             getBridgeInstance().transport_stop_ptr(client);
   2192 #endif
   2193 }
   2194 
   2195 // -----------------------------------------------------------------------------
   2196 
   2197 bool jackbridge_set_property(jack_client_t* client, jack_uuid_t subject, const char* key, const char* value, const char* type)
   2198 {
   2199 #if defined(JACKBRIDGE_DUMMY)
   2200 #elif defined(JACKBRIDGE_DIRECT)
   2201     return (jack_set_property(client, subject, key, value, type) == 0);
   2202 #else
   2203     if (usingRealJACK)
   2204         if (getBridgeInstance().set_property_ptr != nullptr)
   2205             return (getBridgeInstance().set_property_ptr(client, subject, key, value, type) == 0);
   2206 #endif
   2207     return false;
   2208 }
   2209 
   2210 bool jackbridge_get_property(jack_uuid_t subject, const char* key, char** value, char** type)
   2211 {
   2212 #if defined(JACKBRIDGE_DUMMY)
   2213 #elif defined(JACKBRIDGE_DIRECT)
   2214     return (jack_get_property(subject, key, value, type) == 0);
   2215 #else
   2216     if (usingRealJACK)
   2217         if (getBridgeInstance().get_property_ptr != nullptr)
   2218             return (getBridgeInstance().get_property_ptr(subject, key, value, type) == 0);
   2219 #endif
   2220     return false;
   2221 }
   2222 
   2223 void jackbridge_free_description(jack_description_t* desc, bool free_description_itself)
   2224 {
   2225 #if defined(JACKBRIDGE_DUMMY)
   2226 #elif defined(JACKBRIDGE_DIRECT)
   2227     jack_free_description(desc, free_description_itself);
   2228 #else
   2229     if (usingRealJACK)
   2230         if (getBridgeInstance().free_description_ptr != nullptr)
   2231             getBridgeInstance().free_description_ptr(desc, free_description_itself);
   2232 #endif
   2233 }
   2234 
   2235 bool jackbridge_get_properties(jack_uuid_t subject, jack_description_t* desc)
   2236 {
   2237 #if defined(JACKBRIDGE_DUMMY)
   2238 #elif defined(JACKBRIDGE_DIRECT)
   2239     return (jack_get_properties(subject, desc) == 0);
   2240 #else
   2241     if (usingRealJACK)
   2242         if (getBridgeInstance().get_properties_ptr != nullptr)
   2243             return (getBridgeInstance().get_properties_ptr(subject, desc) == 0);
   2244 #endif
   2245     return false;
   2246 }
   2247 
   2248 bool jackbridge_get_all_properties(jack_description_t** descs)
   2249 {
   2250 #if defined(JACKBRIDGE_DUMMY)
   2251 #elif defined(JACKBRIDGE_DIRECT)
   2252     return (jack_get_all_properties(descs) == 0);
   2253 #else
   2254     if (usingRealJACK)
   2255         if (getBridgeInstance().get_all_properties_ptr != nullptr)
   2256             return (getBridgeInstance().get_all_properties_ptr(descs) == 0);
   2257 #endif
   2258     return false;
   2259 }
   2260 
   2261 bool jackbridge_remove_property(jack_client_t* client, jack_uuid_t subject, const char* key)
   2262 {
   2263 #if defined(JACKBRIDGE_DUMMY)
   2264 #elif defined(JACKBRIDGE_DIRECT)
   2265     return (jack_remove_property(client, subject, key) == 0);
   2266 #else
   2267     if (usingRealJACK)
   2268         if (getBridgeInstance().remove_property_ptr != nullptr)
   2269             return (getBridgeInstance().remove_property_ptr(client, subject, key) == 0);
   2270 #endif
   2271     return false;
   2272 }
   2273 
   2274 int jackbridge_remove_properties(jack_client_t* client, jack_uuid_t subject)
   2275 {
   2276 #if defined(JACKBRIDGE_DUMMY)
   2277 #elif defined(JACKBRIDGE_DIRECT)
   2278     return jack_remove_properties(client, subject);
   2279 #else
   2280     if (usingRealJACK)
   2281         if (getBridgeInstance().remove_properties_ptr != nullptr)
   2282             return getBridgeInstance().remove_properties_ptr(client, subject);
   2283 #endif
   2284     return 0;
   2285 }
   2286 
   2287 bool jackbridge_remove_all_properties(jack_client_t* client)
   2288 {
   2289 #if defined(JACKBRIDGE_DUMMY)
   2290 #elif defined(JACKBRIDGE_DIRECT)
   2291     return (jack_remove_all_properties(client) == 0);
   2292 #else
   2293     if (usingRealJACK)
   2294         if (getBridgeInstance().remove_all_properties_ptr != nullptr)
   2295             return (getBridgeInstance().remove_all_properties_ptr(client) == 0);
   2296 #endif
   2297     return false;
   2298 }
   2299 
   2300 bool jackbridge_set_property_change_callback(jack_client_t* client, JackPropertyChangeCallback callback, void* arg)
   2301 {
   2302 #if defined(JACKBRIDGE_DUMMY)
   2303 #elif defined(JACKBRIDGE_DIRECT)
   2304     return (jack_set_property_change_callback(client, callback, arg) == 0);
   2305 #else
   2306     if (usingRealJACK && getBridgeInstance().set_property_change_callback_ptr != nullptr)
   2307     {
   2308 # ifdef __WINE__
   2309         WineBridge::getInstance().set_prop_change(callback);
   2310         return (getBridgeInstance().set_property_change_callback_ptr(client, WineBridge::prop_change, arg) == 0);
   2311 # else
   2312         return (getBridgeInstance().set_property_change_callback_ptr(client, callback, arg) == 0);
   2313 # endif
   2314     }
   2315 #endif
   2316     return false;
   2317 }
   2318 
   2319 bool jackbridge_set_process_thread(jack_client_t* client, JackThreadCallback callback, void* arg)
   2320 {
   2321 #if defined(JACKBRIDGE_DUMMY)
   2322 #elif defined(JACKBRIDGE_DIRECT)
   2323     return (jack_set_process_thread(client, callback, arg) == 0);
   2324 #else
   2325     if (usingRealJACK && getBridgeInstance().set_process_thread_ptr != nullptr)
   2326     {
   2327 # ifdef __WINE__
   2328         WineBridge::getInstance().set_process_thread(callback);
   2329         return (getBridgeInstance().set_process_thread_ptr(client, WineBridge::process_thread, arg) == 0);
   2330 # else
   2331         return (getBridgeInstance().set_process_thread_ptr(client, callback, arg) == 0);
   2332 # endif
   2333     }
   2334 #endif
   2335     return false;
   2336 }
   2337 
   2338 jack_nframes_t jackbridge_cycle_wait(jack_client_t* client)
   2339 {
   2340 #if defined(JACKBRIDGE_DUMMY)
   2341 #elif defined(JACKBRIDGE_DIRECT)
   2342     return jack_cycle_wait(client);
   2343 #else
   2344     if (usingRealJACK)
   2345         if (getBridgeInstance().cycle_wait_ptr != nullptr)
   2346             return getBridgeInstance().cycle_wait_ptr(client);
   2347 #endif
   2348     return 0;
   2349 }
   2350 
   2351 void jackbridge_cycle_signal(jack_client_t* client, int status)
   2352 {
   2353 #if defined(JACKBRIDGE_DUMMY)
   2354 #elif defined(JACKBRIDGE_DIRECT)
   2355     jack_cycle_signal(client, status);
   2356 #else
   2357     if (usingRealJACK)
   2358         if (getBridgeInstance().cycle_signal_ptr != nullptr)
   2359             getBridgeInstance().cycle_signal_ptr(client, status);
   2360 #endif
   2361 }
   2362 
   2363 // -----------------------------------------------------------------------------
   2364 
   2365 #ifndef JACKBRIDGE_SKIP_NATIVE_UTILS
   2366 
   2367 START_NAMESPACE_DISTRHO
   2368 
   2369 bool isUsingNativeAudio() noexcept
   2370 {
   2371 #if defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT)
   2372     return false;
   2373 #else
   2374     return usingNativeBridge;
   2375 #endif
   2376 }
   2377 
   2378 bool supportsAudioInput()
   2379 {
   2380 #if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
   2381     if (usingNativeBridge)
   2382         return nativeBridge->supportsAudioInput();
   2383 #endif
   2384     return false;
   2385 }
   2386 
   2387 bool supportsBufferSizeChanges()
   2388 {
   2389 #if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
   2390     if (usingNativeBridge)
   2391         return nativeBridge->supportsBufferSizeChanges();
   2392 #endif
   2393     return false;
   2394 }
   2395 
   2396 bool supportsMIDI()
   2397 {
   2398 #if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
   2399     if (usingNativeBridge)
   2400         return nativeBridge->supportsMIDI();
   2401 #endif
   2402     return false;
   2403 }
   2404 
   2405 bool isAudioInputEnabled()
   2406 {
   2407 #if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
   2408     if (usingNativeBridge)
   2409         return nativeBridge->isAudioInputEnabled();
   2410 #endif
   2411     return false;
   2412 }
   2413 
   2414 bool isMIDIEnabled()
   2415 {
   2416 #if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
   2417     if (usingNativeBridge)
   2418         return nativeBridge->isMIDIEnabled();
   2419 #endif
   2420     return false;
   2421 }
   2422 
   2423 uint getBufferSize()
   2424 {
   2425 #if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
   2426     if (usingNativeBridge)
   2427         return nativeBridge->getBufferSize();
   2428 #endif
   2429     return 0;
   2430 }
   2431 
   2432 bool requestAudioInput()
   2433 {
   2434 #if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
   2435     if (usingNativeBridge)
   2436         return nativeBridge->requestAudioInput();
   2437 #endif
   2438     return false;
   2439 }
   2440 
   2441 bool requestBufferSizeChange(const uint newBufferSize)
   2442 {
   2443 #if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
   2444     if (usingNativeBridge)
   2445         return nativeBridge->requestBufferSizeChange(newBufferSize);
   2446 #endif
   2447     return false;
   2448 }
   2449 
   2450 bool requestMIDI()
   2451 {
   2452 #if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
   2453     if (usingNativeBridge)
   2454         return nativeBridge->requestMIDI();
   2455 #endif
   2456     return false;
   2457 }
   2458 
   2459 END_NAMESPACE_DISTRHO
   2460 
   2461 #endif // JACKBRIDGE_SKIP_NATIVE_UTILS
   2462 
   2463 // -----------------------------------------------------------------------------