Jack2 1.9.8

JackAPI.cpp

00001 /*
00002 Copyright (C) 2001-2003 Paul Davis
00003 Copyright (C) 2004-2008 Grame
00004 
00005 This program is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU Lesser General Public License as published by
00007 the Free Software Foundation; either version 2.1 of the License, or
00008 (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU Lesser General Public License for more details.
00014 
00015 You should have received a copy of the GNU Lesser General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 
00019 */
00020 
00021 #include "JackClient.h"
00022 #include "JackError.h"
00023 #include "JackGraphManager.h"
00024 #include "JackEngineControl.h"
00025 #include "JackClientControl.h"
00026 #include "JackGlobals.h"
00027 #include "JackTime.h"
00028 #include "JackPortType.h"
00029 #include <math.h>
00030 
00031 #ifdef __CLIENTDEBUG__
00032 #include "JackLibGlobals.h"
00033 #endif
00034 
00035 using namespace Jack;
00036 
00037 #ifdef __cplusplus
00038 extern "C"
00039 {
00040 #endif
00041 
00042     typedef void (*print_function)(const char*);
00043     typedef void *(*thread_routine)(void*);
00044 
00045     LIB_EXPORT
00046     void
00047     jack_get_version(
00048         int *major_ptr,
00049         int *minor_ptr,
00050         int *micro_ptr,
00051         int *proto_ptr);
00052 
00053     LIB_EXPORT
00054     const char*
00055     jack_get_version_string();
00056 
00057     jack_client_t * jack_client_new_aux(const char* client_name,
00058             jack_options_t options,
00059             jack_status_t *status);
00060 
00061     LIB_EXPORT jack_client_t * jack_client_open(const char* client_name,
00062             jack_options_t options,
00063             jack_status_t *status, ...);
00064     LIB_EXPORT jack_client_t * jack_client_new(const char* client_name);
00065     LIB_EXPORT int jack_client_name_size(void);
00066     LIB_EXPORT char* jack_get_client_name(jack_client_t *client);
00067     LIB_EXPORT int jack_internal_client_new(const char* client_name,
00068                                          const char* load_name,
00069                                          const char* load_init);
00070     LIB_EXPORT void jack_internal_client_close(const char* client_name);
00071     LIB_EXPORT int jack_is_realtime(jack_client_t *client);
00072     LIB_EXPORT void jack_on_shutdown(jack_client_t *client,
00073                                   JackShutdownCallback shutdown_callback, void *arg);
00074     LIB_EXPORT void jack_on_info_shutdown(jack_client_t *client,
00075                                   JackInfoShutdownCallback shutdown_callback, void *arg);
00076     LIB_EXPORT int jack_set_process_callback(jack_client_t *client,
00077                                           JackProcessCallback process_callback,
00078                                           void *arg);
00079     LIB_EXPORT jack_nframes_t jack_thread_wait(jack_client_t *client, int status);
00080 
00081     // new
00082     LIB_EXPORT jack_nframes_t jack_cycle_wait(jack_client_t*);
00083     LIB_EXPORT void jack_cycle_signal(jack_client_t*, int status);
00084     LIB_EXPORT int jack_set_process_thread(jack_client_t* client, JackThreadCallback fun, void *arg);
00085 
00086     LIB_EXPORT int jack_set_thread_init_callback(jack_client_t *client,
00087             JackThreadInitCallback thread_init_callback,
00088             void *arg);
00089     LIB_EXPORT int jack_set_freewheel_callback(jack_client_t *client,
00090                                             JackFreewheelCallback freewheel_callback,
00091                                             void *arg);
00092     LIB_EXPORT int jack_set_freewheel(jack_client_t* client, int onoff);
00093     LIB_EXPORT int jack_set_buffer_size(jack_client_t *client, jack_nframes_t nframes);
00094     LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t *client,
00095             JackBufferSizeCallback bufsize_callback,
00096             void *arg);
00097     LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t *client,
00098             JackSampleRateCallback srate_callback,
00099             void *arg);
00100     LIB_EXPORT int jack_set_client_registration_callback(jack_client_t *,
00101             JackClientRegistrationCallback
00102             registration_callback, void *arg);
00103     LIB_EXPORT int jack_set_port_registration_callback(jack_client_t *,
00104             JackPortRegistrationCallback
00105             registration_callback, void *arg);
00106     LIB_EXPORT int jack_set_port_connect_callback(jack_client_t *,
00107             JackPortConnectCallback
00108             connect_callback, void *arg);
00109     LIB_EXPORT int jack_set_port_rename_callback(jack_client_t *,
00110                                     JackPortRenameCallback
00111                                     rename_callback, void *arg);
00112     LIB_EXPORT int jack_set_graph_order_callback(jack_client_t *,
00113             JackGraphOrderCallback graph_callback,
00114             void *);
00115     LIB_EXPORT int jack_set_xrun_callback(jack_client_t *,
00116                                        JackXRunCallback xrun_callback, void *arg);
00117     LIB_EXPORT int jack_set_latency_callback(jack_client_t *client,
00118                                JackLatencyCallback latency_callback, void *arg);
00119 
00120     LIB_EXPORT int jack_activate(jack_client_t *client);
00121     LIB_EXPORT int jack_deactivate(jack_client_t *client);
00122     LIB_EXPORT jack_port_t * jack_port_register(jack_client_t *client,
00123             const char* port_name,
00124             const char* port_type,
00125             unsigned long flags,
00126             unsigned long buffer_size);
00127     LIB_EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *);
00128     LIB_EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t);
00129     LIB_EXPORT const char*  jack_port_name(const jack_port_t *port);
00130     LIB_EXPORT const char*  jack_port_short_name(const jack_port_t *port);
00131     LIB_EXPORT int jack_port_flags(const jack_port_t *port);
00132     LIB_EXPORT const char*  jack_port_type(const jack_port_t *port);
00133     LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port);
00134     LIB_EXPORT int jack_port_is_mine(const jack_client_t *, const jack_port_t *port);
00135     LIB_EXPORT int jack_port_connected(const jack_port_t *port);
00136     LIB_EXPORT int jack_port_connected_to(const jack_port_t *port,
00137                                        const char* port_name);
00138     LIB_EXPORT const char* * jack_port_get_connections(const jack_port_t *port);
00139     LIB_EXPORT const char* * jack_port_get_all_connections(const jack_client_t *client,
00140             const jack_port_t *port);
00141     LIB_EXPORT int jack_port_tie(jack_port_t *src, jack_port_t *dst);
00142     LIB_EXPORT int jack_port_untie(jack_port_t *port);
00143 
00144     // Old latency API
00145     LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t *port);
00146     LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t *,
00147             jack_port_t *port);
00148     LIB_EXPORT void jack_port_set_latency(jack_port_t *, jack_nframes_t);
00149     LIB_EXPORT int jack_recompute_total_latency(jack_client_t*, jack_port_t* port);
00150 
00151     // New latency API
00152     LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range);
00153     LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range);
00154     LIB_EXPORT int jack_recompute_total_latencies(jack_client_t*);
00155 
00156     LIB_EXPORT int jack_port_set_name(jack_port_t *port, const char* port_name);
00157     LIB_EXPORT int jack_port_set_alias(jack_port_t *port, const char* alias);
00158     LIB_EXPORT int jack_port_unset_alias(jack_port_t *port, const char* alias);
00159     LIB_EXPORT int jack_port_get_aliases(const jack_port_t *port, char* const aliases[2]);
00160     LIB_EXPORT int jack_port_request_monitor(jack_port_t *port, int onoff);
00161     LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t *client,
00162             const char* port_name, int onoff);
00163     LIB_EXPORT int jack_port_ensure_monitor(jack_port_t *port, int onoff);
00164     LIB_EXPORT int jack_port_monitoring_input(jack_port_t *port);
00165     LIB_EXPORT int jack_connect(jack_client_t *,
00166                              const char* source_port,
00167                              const char* destination_port);
00168     LIB_EXPORT int jack_disconnect(jack_client_t *,
00169                                 const char* source_port,
00170                                 const char* destination_port);
00171     LIB_EXPORT int jack_port_disconnect(jack_client_t *, jack_port_t *);
00172     LIB_EXPORT int jack_port_name_size(void);
00173     LIB_EXPORT int jack_port_type_size(void);
00174     LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t *client, const char* port_type);
00175     LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t *);
00176     LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t *);
00177     LIB_EXPORT const char* * jack_get_ports(jack_client_t *,
00178                                          const char* port_name_pattern,
00179                                          const char* type_name_pattern,
00180                                          unsigned long flags);
00181     LIB_EXPORT jack_port_t * jack_port_by_name(jack_client_t *, const char* port_name);
00182     LIB_EXPORT jack_port_t * jack_port_by_id(jack_client_t *client,
00183                                           jack_port_id_t port_id);
00184     LIB_EXPORT int jack_engine_takeover_timebase(jack_client_t *);
00185     LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t *);
00186     LIB_EXPORT jack_time_t jack_get_time();
00187     LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t time);
00188     LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t frames);
00189     LIB_EXPORT jack_nframes_t jack_frame_time(const jack_client_t *);
00190     LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t *client);
00191     LIB_EXPORT float jack_cpu_load(jack_client_t *client);
00192     LIB_EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t *);
00193     LIB_EXPORT void jack_set_error_function(print_function);
00194     LIB_EXPORT void jack_set_info_function(print_function);
00195 
00196     LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t *client);
00197     LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t *client);
00198     LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t *client);
00199 
00200     LIB_EXPORT int jack_release_timebase(jack_client_t *client);
00201     LIB_EXPORT int jack_set_sync_callback(jack_client_t *client,
00202                                        JackSyncCallback sync_callback,
00203                                        void *arg);
00204     LIB_EXPORT int jack_set_sync_timeout(jack_client_t *client,
00205                                       jack_time_t timeout);
00206     LIB_EXPORT int jack_set_timebase_callback(jack_client_t *client,
00207                                            int conditional,
00208                                            JackTimebaseCallback timebase_callback,
00209                                            void *arg);
00210     LIB_EXPORT int jack_transport_locate(jack_client_t *client,
00211                                       jack_nframes_t frame);
00212     LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t *client,
00213             jack_position_t *pos);
00214     LIB_EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t *client);
00215     LIB_EXPORT int jack_transport_reposition(jack_client_t *client,
00216                                           const jack_position_t *pos);
00217     LIB_EXPORT void jack_transport_start(jack_client_t *client);
00218     LIB_EXPORT void jack_transport_stop(jack_client_t *client);
00219     LIB_EXPORT void jack_get_transport_info(jack_client_t *client,
00220                                          jack_transport_info_t *tinfo);
00221     LIB_EXPORT void jack_set_transport_info(jack_client_t *client,
00222                                          jack_transport_info_t *tinfo);
00223 
00224     LIB_EXPORT int jack_client_real_time_priority(jack_client_t*);
00225     LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t*);
00226     LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority);
00227     LIB_EXPORT int jack_client_create_thread(jack_client_t* client,
00228                                           jack_native_thread_t *thread,
00229                                           int priority,
00230                                           int realtime,         // boolean
00231                                           thread_routine routine,
00232                                           void *arg);
00233     LIB_EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread);
00234 
00235     LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread);
00236     LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread);
00237 #ifndef WIN32
00238     LIB_EXPORT void jack_set_thread_creator(jack_thread_creator_t jtc);
00239 #endif
00240     LIB_EXPORT char * jack_get_internal_client_name(jack_client_t *client,
00241             jack_intclient_t intclient);
00242     LIB_EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t *client,
00243             const char* client_name,
00244             jack_status_t *status);
00245     LIB_EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client,
00246             const char* client_name,
00247             jack_options_t options,
00248             jack_status_t *status, ...);
00249     LIB_EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t *client,
00250             const char* client_name,
00251             jack_options_t options,
00252             jack_status_t *status, va_list ap);
00253 
00254     LIB_EXPORT jack_status_t jack_internal_client_unload(jack_client_t *client,
00255             jack_intclient_t intclient);
00256     LIB_EXPORT void jack_free(void* ptr);
00257 
00258     LIB_EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg);
00259     LIB_EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path);
00260     LIB_EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event);
00261     LIB_EXPORT void jack_session_event_free(jack_session_event_t* ev);
00262     LIB_EXPORT char* jack_client_get_uuid (jack_client_t *client);
00263     LIB_EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name);
00264     LIB_EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid);
00265     LIB_EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* name, const char* uuid);
00266     LIB_EXPORT void jack_session_commands_free(jack_session_command_t *cmds);
00267     LIB_EXPORT int jack_client_has_session_callback(jack_client_t *client, const char* client_name);
00268 
00269 #ifdef __cplusplus
00270 }
00271 #endif
00272 
00273 static inline bool CheckPort(jack_port_id_t port_index)
00274 {
00275     return (port_index > 0 && port_index < PORT_NUM_MAX);
00276 }
00277 
00278 static inline bool CheckBufferSize(jack_nframes_t buffer_size)
00279 {
00280     return (buffer_size >= 1 && buffer_size <= BUFFER_SIZE_MAX);
00281 }
00282 
00283 static inline void WaitGraphChange()
00284 {
00285     /*
00286     TLS key that is set only in RT thread, so never waits for pending
00287     graph change in RT context (just read the current graph state).
00288     */
00289 
00290     if (jack_tls_get(JackGlobals::fRealTime) == NULL) {
00291         JackGraphManager* manager = GetGraphManager();
00292         JackEngineControl* control = GetEngineControl();
00293         assert(manager);
00294         assert(control);
00295         if (manager->IsPendingChange()) {
00296             jack_log("WaitGraphChange...");
00297             JackSleep(int(control->fPeriodUsecs * 1.1f));
00298         }
00299     }
00300 }
00301 
00302 LIB_EXPORT void jack_set_error_function(print_function func)
00303 {
00304     jack_error_callback = (func == NULL) ? &default_jack_error_callback : func;
00305 }
00306 
00307 LIB_EXPORT void jack_set_info_function(print_function func)
00308 {
00309     jack_info_callback = (func == NULL) ? &default_jack_info_callback : func;
00310 }
00311 
00312 LIB_EXPORT jack_client_t* jack_client_new(const char* client_name)
00313 {
00314 #ifdef __CLIENTDEBUG__
00315     JackGlobals::CheckContext("jack_client_new");
00316 #endif
00317     try {
00318         assert(JackGlobals::fOpenMutex);
00319         JackGlobals::fOpenMutex->Lock();
00320         jack_error("jack_client_new: deprecated");
00321         int options = JackUseExactName;
00322         if (getenv("JACK_START_SERVER") == NULL)
00323             options |= JackNoStartServer;
00324         jack_client_t* res = jack_client_new_aux(client_name, (jack_options_t)options, NULL);
00325         JackGlobals::fOpenMutex->Unlock();
00326         return res;
00327     } catch (std::bad_alloc& e) {
00328         jack_error("Memory allocation error...");
00329         return NULL;
00330     } catch (...) {
00331         jack_error("Unknown error...");
00332         return NULL;
00333     }
00334 }
00335 
00336 LIB_EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
00337 {
00338 #ifdef __CLIENTDEBUG__
00339     JackGlobals::CheckContext("jack_port_get_buffer");
00340 #endif
00341     uintptr_t port_aux = (uintptr_t)port;
00342     jack_port_id_t myport = (jack_port_id_t)port_aux;
00343     if (!CheckPort(myport)) {
00344         jack_error("jack_port_get_buffer called with an incorrect port %ld", myport);
00345         return NULL;
00346     } else {
00347         JackGraphManager* manager = GetGraphManager();
00348         return (manager ? manager->GetBuffer(myport, frames) : NULL);
00349     }
00350 }
00351 
00352 LIB_EXPORT const char* jack_port_name(const jack_port_t* port)
00353 {
00354 #ifdef __CLIENTDEBUG__
00355     JackGlobals::CheckContext("jack_port_name");
00356 #endif
00357     uintptr_t port_aux = (uintptr_t)port;
00358     jack_port_id_t myport = (jack_port_id_t)port_aux;
00359     if (!CheckPort(myport)) {
00360         jack_error("jack_port_name called with an incorrect port %ld", myport);
00361         return NULL;
00362     } else {
00363         JackGraphManager* manager = GetGraphManager();
00364         return (manager ? manager->GetPort(myport)->GetName() : NULL);
00365     }
00366 }
00367 
00368 LIB_EXPORT const char* jack_port_short_name(const jack_port_t* port)
00369 {
00370 #ifdef __CLIENTDEBUG__
00371     JackGlobals::CheckContext("jack_port_short_name");
00372 #endif
00373     uintptr_t port_aux = (uintptr_t)port;
00374     jack_port_id_t myport = (jack_port_id_t)port_aux;
00375     if (!CheckPort(myport)) {
00376         jack_error("jack_port_short_name called with an incorrect port %ld", myport);
00377         return NULL;
00378     } else {
00379         JackGraphManager* manager = GetGraphManager();
00380         return (manager ? manager->GetPort(myport)->GetShortName() : NULL);
00381     }
00382 }
00383 
00384 LIB_EXPORT int jack_port_flags(const jack_port_t* port)
00385 {
00386 #ifdef __CLIENTDEBUG__
00387     JackGlobals::CheckContext("jack_port_flags");
00388 #endif
00389     uintptr_t port_aux = (uintptr_t)port;
00390     jack_port_id_t myport = (jack_port_id_t)port_aux;
00391     if (!CheckPort(myport)) {
00392         jack_error("jack_port_flags called with an incorrect port %ld", myport);
00393         return -1;
00394     } else {
00395         JackGraphManager* manager = GetGraphManager();
00396         return (manager ? manager->GetPort(myport)->GetFlags() : -1);
00397     }
00398 }
00399 
00400 LIB_EXPORT const char* jack_port_type(const jack_port_t* port)
00401 {
00402 #ifdef __CLIENTDEBUG__
00403     JackGlobals::CheckContext("jack_port_type");
00404 #endif
00405     uintptr_t port_aux = (uintptr_t)port;
00406     jack_port_id_t myport = (jack_port_id_t)port_aux;
00407    if (!CheckPort(myport)) {
00408         jack_error("jack_port_flags called an incorrect port %ld", myport);
00409         return NULL;
00410     } else {
00411         JackGraphManager* manager = GetGraphManager();
00412         return (manager ? manager->GetPort(myport)->GetType() : NULL);
00413     }
00414 }
00415 
00416 LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port)
00417 {
00418 #ifdef __CLIENTDEBUG__
00419     JackGlobals::CheckContext("jack_port_type_id");
00420 #endif
00421     uintptr_t port_aux = (uintptr_t)port;
00422     jack_port_id_t myport = (jack_port_id_t)port_aux;
00423     if (!CheckPort(myport)) {
00424         jack_error("jack_port_type_id called an incorrect port %ld", myport);
00425         return 0;
00426     } else {
00427         JackGraphManager* manager = GetGraphManager();
00428         return (manager ? GetPortTypeId(manager->GetPort(myport)->GetType()) : 0);
00429     }
00430 }
00431 
00432 LIB_EXPORT int jack_port_connected(const jack_port_t* port)
00433 {
00434 #ifdef __CLIENTDEBUG__
00435     JackGlobals::CheckContext("jack_port_connected");
00436 #endif
00437     uintptr_t port_aux = (uintptr_t)port;
00438     jack_port_id_t myport = (jack_port_id_t)port_aux;
00439     if (!CheckPort(myport)) {
00440         jack_error("jack_port_connected called with an incorrect port %ld", myport);
00441         return -1;
00442     } else {
00443         WaitGraphChange();
00444         JackGraphManager* manager = GetGraphManager();
00445         return (manager ? manager->GetConnectionsNum(myport) : -1);
00446     }
00447 }
00448 
00449 LIB_EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name)
00450 {
00451 #ifdef __CLIENTDEBUG__
00452     JackGlobals::CheckContext("jack_port_connected_to");
00453 #endif
00454     uintptr_t port_aux = (uintptr_t)port;
00455     jack_port_id_t src = (jack_port_id_t)port_aux;
00456     if (!CheckPort(src)) {
00457         jack_error("jack_port_connected_to called with an incorrect port %ld", src);
00458         return -1;
00459     } else if (port_name == NULL) {
00460         jack_error("jack_port_connected_to called with a NULL port name");
00461         return -1;
00462     } else {
00463         WaitGraphChange();
00464         JackGraphManager* manager = GetGraphManager();
00465         jack_port_id_t dst = (manager ? manager->GetPort(port_name) : NO_PORT);
00466         if (dst == NO_PORT) {
00467             jack_error("Unknown destination port port_name = %s", port_name);
00468             return 0;
00469         } else {
00470             return manager->IsConnected(src, dst);
00471         }
00472     }
00473 }
00474 
00475 LIB_EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst)
00476 {
00477 #ifdef __CLIENTDEBUG__
00478     JackGlobals::CheckContext("jack_port_tie");
00479 #endif
00480     uintptr_t src_aux = (uintptr_t)src;
00481     jack_port_id_t mysrc = (jack_port_id_t)src_aux;
00482     if (!CheckPort(mysrc)) {
00483         jack_error("jack_port_tie called with a NULL src port");
00484         return -1;
00485     }
00486     uintptr_t dst_aux = (uintptr_t)dst;
00487     jack_port_id_t mydst = (jack_port_id_t)dst_aux;
00488     if (!CheckPort(mydst)) {
00489         jack_error("jack_port_tie called with a NULL dst port");
00490         return -1;
00491     }
00492     JackGraphManager* manager = GetGraphManager();
00493     if (manager && manager->GetPort(mysrc)->GetRefNum() != manager->GetPort(mydst)->GetRefNum()) {
00494         jack_error("jack_port_tie called with ports not belonging to the same client");
00495         return -1;
00496     } else {
00497         return manager->GetPort(mydst)->Tie(mysrc);
00498     }
00499 }
00500 
00501 LIB_EXPORT int jack_port_untie(jack_port_t* port)
00502 {
00503 #ifdef __CLIENTDEBUG__
00504     JackGlobals::CheckContext("jack_port_untie");
00505 #endif
00506     uintptr_t port_aux = (uintptr_t)port;
00507     jack_port_id_t myport = (jack_port_id_t)port_aux;
00508     if (!CheckPort(myport)) {
00509         jack_error("jack_port_untie called with an incorrect port %ld", myport);
00510         return -1;
00511     } else {
00512         JackGraphManager* manager = GetGraphManager();
00513         return (manager ? manager->GetPort(myport)->UnTie() : -1);
00514     }
00515 }
00516 
00517 LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port)
00518 {
00519 #ifdef __CLIENTDEBUG__
00520     JackGlobals::CheckContext("jack_port_get_latency");
00521 #endif
00522     uintptr_t port_aux = (uintptr_t)port;
00523     jack_port_id_t myport = (jack_port_id_t)port_aux;
00524     if (!CheckPort(myport)) {
00525         jack_error("jack_port_get_latency called with an incorrect port %ld", myport);
00526         return 0;
00527     } else {
00528         WaitGraphChange();
00529         JackGraphManager* manager = GetGraphManager();
00530         return (manager ? manager->GetPort(myport)->GetLatency() : 0);
00531     }
00532 }
00533 
00534 LIB_EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames)
00535 {
00536 #ifdef __CLIENTDEBUG__
00537     JackGlobals::CheckContext("jack_port_set_latency");
00538 #endif
00539     uintptr_t port_aux = (uintptr_t)port;
00540     jack_port_id_t myport = (jack_port_id_t)port_aux;
00541     if (!CheckPort(myport)) {
00542         jack_error("jack_port_set_latency called with an incorrect port %ld", myport);
00543     } else {
00544         JackGraphManager* manager = GetGraphManager();
00545         if (manager)
00546             manager->GetPort(myport)->SetLatency(frames);
00547     }
00548 }
00549 
00550 LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
00551 {
00552 #ifdef __CLIENTDEBUG__
00553     JackGlobals::CheckContext("jack_port_get_latency_range");
00554 #endif
00555     uintptr_t port_aux = (uintptr_t)port;
00556     jack_port_id_t myport = (jack_port_id_t)port_aux;
00557     if (!CheckPort(myport)) {
00558         jack_error("jack_port_get_latency_range called with an incorrect port %ld", myport);
00559     } else {
00560         WaitGraphChange();
00561         JackGraphManager* manager = GetGraphManager();
00562         if (manager)
00563             manager->GetPort(myport)->GetLatencyRange(mode, range);
00564     }
00565 }
00566 
00567 LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
00568 {
00569 #ifdef __CLIENTDEBUG__
00570     JackGlobals::CheckContext("jack_port_set_latency_range");
00571 #endif
00572     uintptr_t port_aux = (uintptr_t)port;
00573     jack_port_id_t myport = (jack_port_id_t)port_aux;
00574     if (!CheckPort(myport)) {
00575         jack_error("jack_port_set_latency_range called with an incorrect port %ld", myport);
00576     } else {
00577         WaitGraphChange();
00578         JackGraphManager* manager = GetGraphManager();
00579         if (manager)
00580             manager->GetPort(myport)->SetLatencyRange(mode, range);
00581     }
00582 }
00583 
00584 LIB_EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port)
00585 {
00586 #ifdef __CLIENTDEBUG__
00587     JackGlobals::CheckContext("jack_recompute_total_latency");
00588 #endif
00589 
00590     JackClient* client = (JackClient*)ext_client;
00591     uintptr_t port_aux = (uintptr_t)port;
00592     jack_port_id_t myport = (jack_port_id_t)port_aux;
00593     if (client == NULL) {
00594         jack_error("jack_recompute_total_latency called with a NULL client");
00595         return -1;
00596     } else if (!CheckPort(myport)) {
00597         jack_error("jack_recompute_total_latency called with a NULL port");
00598         return -1;
00599     } else {
00600         WaitGraphChange();
00601         JackGraphManager* manager = GetGraphManager();
00602         return (manager ? manager->ComputeTotalLatency(myport) : -1);
00603     }
00604 }
00605 
00606 LIB_EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client)
00607 {
00608 #ifdef __CLIENTDEBUG__
00609     JackGlobals::CheckContext("jack_recompute_total_latencies");
00610 #endif
00611 
00612     JackClient* client = (JackClient*)ext_client;
00613     if (client == NULL) {
00614         jack_error("jack_recompute_total_latencies called with a NULL client");
00615         return -1;
00616     } else {
00617         return client->ComputeTotalLatencies();
00618     }
00619 }
00620 
00621 LIB_EXPORT int jack_port_set_name(jack_port_t* port, const char* name)
00622 {
00623 #ifdef __CLIENTDEBUG__
00624     JackGlobals::CheckContext("jack_port_set_name");
00625 #endif
00626     uintptr_t port_aux = (uintptr_t)port;
00627     jack_port_id_t myport = (jack_port_id_t)port_aux;
00628     if (!CheckPort(myport)) {
00629         jack_error("jack_port_set_name called with an incorrect port %ld", myport);
00630         return -1;
00631     } else if (name == NULL) {
00632         jack_error("jack_port_set_name called with a NULL port name");
00633         return -1;
00634     } else {
00635         JackClient* client = NULL;
00636         for (int i = 0; i < CLIENT_NUM; i++) {
00637             // Find a valid client
00638             if ((client = JackGlobals::fClientTable[i])) {
00639                 break;
00640             }
00641         }
00642         return (client) ? client->PortRename(myport, name) : -1;
00643     }
00644 }
00645 
00646 LIB_EXPORT int jack_port_set_alias(jack_port_t* port, const char* name)
00647 {
00648 #ifdef __CLIENTDEBUG__
00649     JackGlobals::CheckContext("jack_port_set_alias");
00650 #endif
00651     uintptr_t port_aux = (uintptr_t)port;
00652     jack_port_id_t myport = (jack_port_id_t)port_aux;
00653     if (!CheckPort(myport)) {
00654         jack_error("jack_port_set_alias called with an incorrect port %ld", myport);
00655         return -1;
00656     } else if (name == NULL) {
00657         jack_error("jack_port_set_alias called with a NULL port name");
00658         return -1;
00659     } else {
00660         JackGraphManager* manager = GetGraphManager();
00661         return (manager ? manager->GetPort(myport)->SetAlias(name) : -1);
00662     }
00663 }
00664 
00665 LIB_EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name)
00666 {
00667 #ifdef __CLIENTDEBUG__
00668     JackGlobals::CheckContext("jack_port_unset_alias");
00669 #endif
00670     uintptr_t port_aux = (uintptr_t)port;
00671     jack_port_id_t myport = (jack_port_id_t)port_aux;
00672     if (!CheckPort(myport)) {
00673         jack_error("jack_port_unset_alias called with an incorrect port %ld", myport);
00674         return -1;
00675     } else if (name == NULL) {
00676         jack_error("jack_port_unset_alias called with a NULL port name");
00677         return -1;
00678     } else {
00679         JackGraphManager* manager = GetGraphManager();
00680         return (manager ? manager->GetPort(myport)->UnsetAlias(name) : -1);
00681     }
00682 }
00683 
00684 LIB_EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2])
00685 {
00686 #ifdef __CLIENTDEBUG__
00687     JackGlobals::CheckContext("jack_port_get_aliases");
00688 #endif
00689     uintptr_t port_aux = (uintptr_t)port;
00690     jack_port_id_t myport = (jack_port_id_t)port_aux;
00691     if (!CheckPort(myport)) {
00692         jack_error("jack_port_get_aliases called with an incorrect port %ld", myport);
00693         return -1;
00694     } else {
00695         JackGraphManager* manager = GetGraphManager();
00696         return (manager ? manager->GetPort(myport)->GetAliases(aliases) : -1);
00697     }
00698 }
00699 
00700 LIB_EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff)
00701 {
00702 #ifdef __CLIENTDEBUG__
00703     JackGlobals::CheckContext("jack_port_request_monitor");
00704 #endif
00705     uintptr_t port_aux = (uintptr_t)port;
00706     jack_port_id_t myport = (jack_port_id_t)port_aux;
00707     if (!CheckPort(myport)) {
00708         jack_error("jack_port_request_monitor called with an incorrect port %ld", myport);
00709         return -1;
00710     } else {
00711         JackGraphManager* manager = GetGraphManager();
00712         return (manager ? manager->RequestMonitor(myport, onoff) : -1);
00713     }
00714 }
00715 
00716 LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff)
00717 {
00718 #ifdef __CLIENTDEBUG__
00719     JackGlobals::CheckContext("jack_port_request_monitor_by_name");
00720 #endif
00721     JackClient* client = (JackClient*)ext_client;
00722     if (client == NULL) {
00723         jack_error("jack_port_request_monitor_by_name called with a NULL client");
00724         return -1;
00725     } else {
00726         JackGraphManager* manager = GetGraphManager();
00727         if (!manager)
00728             return -1;
00729         jack_port_id_t myport = manager->GetPort(port_name);
00730         if (!CheckPort(myport)) {
00731             jack_error("jack_port_request_monitor_by_name called with an incorrect port %s", port_name);
00732             return -1;
00733         } else {
00734             return manager->RequestMonitor(myport, onoff);
00735         }
00736     }
00737 }
00738 
00739 LIB_EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff)
00740 {
00741 #ifdef __CLIENTDEBUG__
00742     JackGlobals::CheckContext("jack_port_ensure_monitor");
00743 #endif
00744     uintptr_t port_aux = (uintptr_t)port;
00745     jack_port_id_t myport = (jack_port_id_t)port_aux;
00746     if (!CheckPort(myport)) {
00747         jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport);
00748         return -1;
00749     } else {
00750         JackGraphManager* manager = GetGraphManager();
00751         return (manager ? manager->GetPort(myport)->EnsureMonitor(onoff) : -1);
00752     }
00753 }
00754 
00755 LIB_EXPORT int jack_port_monitoring_input(jack_port_t* port)
00756 {
00757 #ifdef __CLIENTDEBUG__
00758     JackGlobals::CheckContext("jack_port_monitoring_input");
00759 #endif
00760     uintptr_t port_aux = (uintptr_t)port;
00761     jack_port_id_t myport = (jack_port_id_t)port_aux;
00762     if (!CheckPort(myport)) {
00763         jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport);
00764         return -1;
00765     } else {
00766         JackGraphManager* manager = GetGraphManager();
00767         return (manager ? manager->GetPort(myport)->MonitoringInput() : -1);
00768     }
00769 }
00770 
00771 LIB_EXPORT int jack_is_realtime(jack_client_t* ext_client)
00772 {
00773 #ifdef __CLIENTDEBUG__
00774     JackGlobals::CheckContext("jack_is_realtime");
00775 #endif
00776     JackClient* client = (JackClient*)ext_client;
00777     if (client == NULL) {
00778         jack_error("jack_is_realtime called with a NULL client");
00779         return -1;
00780     } else {
00781         JackEngineControl* control = GetEngineControl();
00782         return (control ? control->fRealTime : -1);
00783     }
00784 }
00785 
00786 LIB_EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback callback, void* arg)
00787 {
00788 #ifdef __CLIENTDEBUG__
00789     JackGlobals::CheckContext("jack_on_shutdown");
00790 #endif
00791     JackClient* client = (JackClient*)ext_client;
00792     if (client == NULL) {
00793         jack_error("jack_on_shutdown called with a NULL client");
00794     } else {
00795         client->OnShutdown(callback, arg);
00796     }
00797 }
00798 
00799 LIB_EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg)
00800 {
00801 #ifdef __CLIENTDEBUG__
00802     JackGlobals::CheckContext("jack_on_info_shutdown");
00803 #endif
00804     JackClient* client = (JackClient*)ext_client;
00805     if (client == NULL) {
00806         jack_error("jack_on_info_shutdown called with a NULL client");
00807     } else {
00808         client->OnInfoShutdown(callback, arg);
00809     }
00810 }
00811 
00812 LIB_EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg)
00813 {
00814 #ifdef __CLIENTDEBUG__
00815     JackGlobals::CheckContext("jack_set_process_callback");
00816 #endif
00817     JackClient* client = (JackClient*)ext_client;
00818     if (client == NULL) {
00819         jack_error("jack_set_process_callback called with a NULL client");
00820         return -1;
00821     } else {
00822         return client->SetProcessCallback(callback, arg);
00823     }
00824 }
00825 
00826 LIB_EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status)
00827 {
00828 #ifdef __CLIENTDEBUG__
00829     JackGlobals::CheckContext("jack_thread_wait");
00830 #endif
00831     JackClient* client = (JackClient*)ext_client;
00832     if (client == NULL) {
00833         jack_error("jack_thread_wait called with a NULL client");
00834         return 0;
00835     } else {
00836         jack_error("jack_thread_wait: deprecated, use jack_cycle_wait/jack_cycle_signal");
00837         return 0;
00838     }
00839 }
00840 
00841 LIB_EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client)
00842 {
00843 #ifdef __CLIENTDEBUG__
00844     JackGlobals::CheckContext("jack_cycle_wait");
00845 #endif
00846     JackClient* client = (JackClient*)ext_client;
00847     if (client == NULL) {
00848         jack_error("jack_cycle_wait called with a NULL client");
00849         return 0;
00850     } else {
00851         return client->CycleWait();
00852     }
00853 }
00854 
00855 LIB_EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status)
00856 {
00857 #ifdef __CLIENTDEBUG__
00858     JackGlobals::CheckContext("jack_cycle_signal");
00859 #endif
00860     JackClient* client = (JackClient*)ext_client;
00861     if (client == NULL) {
00862         jack_error("jack_cycle_signal called with a NULL client");
00863     } else {
00864         client->CycleSignal(status);
00865     }
00866 }
00867 
00868 LIB_EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback fun, void *arg)
00869 {
00870 #ifdef __CLIENTDEBUG__
00871     JackGlobals::CheckContext("jack_set_process_thread");
00872 #endif
00873     JackClient* client = (JackClient*)ext_client;
00874     if (client == NULL) {
00875         jack_error("jack_set_process_thread called with a NULL client");
00876         return -1;
00877     } else {
00878         return client->SetProcessThread(fun, arg);
00879     }
00880 }
00881 
00882 LIB_EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg)
00883 {
00884 #ifdef __CLIENTDEBUG__
00885     JackGlobals::CheckContext("jack_set_freewheel_callback");
00886 #endif
00887     JackClient* client = (JackClient*)ext_client;
00888     if (client == NULL) {
00889         jack_error("jack_set_freewheel_callback called with a NULL client");
00890         return -1;
00891     } else {
00892         return client->SetFreewheelCallback(freewheel_callback, arg);
00893     }
00894 }
00895 
00896 LIB_EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff)
00897 {
00898 #ifdef __CLIENTDEBUG__
00899     JackGlobals::CheckContext("jack_set_freewheel");
00900 #endif
00901     JackClient* client = (JackClient*)ext_client;
00902     if (client == NULL) {
00903         jack_error("jack_set_freewheel called with a NULL client");
00904         return -1;
00905     } else {
00906         return client->SetFreeWheel(onoff);
00907     }
00908 }
00909 
00910 LIB_EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size)
00911 {
00912 #ifdef __CLIENTDEBUG__
00913     JackGlobals::CheckContext("jack_set_buffer_size");
00914 #endif
00915     JackClient* client = (JackClient*)ext_client;
00916     if (client == NULL) {
00917         jack_error("jack_set_buffer_size called with a NULL client");
00918         return -1;
00919     } else if (!CheckBufferSize(buffer_size)) {
00920         return -1;
00921     } else {
00922         return client->SetBufferSize(buffer_size);
00923     }
00924 }
00925 
00926 LIB_EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg)
00927 {
00928 #ifdef __CLIENTDEBUG__
00929     JackGlobals::CheckContext("jack_set_buffer_size_callback");
00930 #endif
00931     JackClient* client = (JackClient*)ext_client;
00932     if (client == NULL) {
00933         jack_error("jack_set_buffer_size_callback called with a NULL client");
00934         return -1;
00935     } else {
00936         return client->SetBufferSizeCallback(bufsize_callback, arg);
00937     }
00938 }
00939 
00940 LIB_EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg)
00941 {
00942 #ifdef __CLIENTDEBUG__
00943     JackGlobals::CheckContext("jack_set_sample_rate_callback");
00944 #endif
00945     JackClient* client = (JackClient*)ext_client;
00946     if (client == NULL) {
00947         jack_error("jack_set_sample_rate_callback called with a NULL client");
00948         return -1;
00949     } else {
00950         return client->SetSampleRateCallback(srate_callback, arg);
00951     }
00952 }
00953 
00954 LIB_EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, JackClientRegistrationCallback registration_callback, void* arg)
00955 {
00956 #ifdef __CLIENTDEBUG__
00957     JackGlobals::CheckContext("jack_set_client_registration_callback");
00958 #endif
00959     JackClient* client = (JackClient*)ext_client;
00960     if (client == NULL) {
00961         jack_error("jack_set_client_registration_callback called with a NULL client");
00962         return -1;
00963     } else {
00964         return client->SetClientRegistrationCallback(registration_callback, arg);
00965     }
00966 }
00967 
00968 LIB_EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg)
00969 {
00970 #ifdef __CLIENTDEBUG__
00971     JackGlobals::CheckContext("jack_set_port_registration_callback");
00972 #endif
00973     JackClient* client = (JackClient*)ext_client;
00974     if (client == NULL) {
00975         jack_error("jack_set_port_registration_callback called with a NULL client");
00976         return -1;
00977     } else {
00978         return client->SetPortRegistrationCallback(registration_callback, arg);
00979     }
00980 }
00981 
00982 LIB_EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortConnectCallback portconnect_callback, void* arg)
00983 {
00984 #ifdef __CLIENTDEBUG__
00985     JackGlobals::CheckContext("jack_set_port_connect_callback");
00986 #endif
00987     JackClient* client = (JackClient*)ext_client;
00988     if (client == NULL) {
00989         jack_error("jack_set_port_connect_callback called with a NULL client");
00990         return -1;
00991     } else {
00992         return client->SetPortConnectCallback(portconnect_callback, arg);
00993     }
00994 }
00995 
00996 LIB_EXPORT int jack_set_port_rename_callback(jack_client_t* ext_client, JackPortRenameCallback rename_callback, void* arg)
00997 {
00998 #ifdef __CLIENTDEBUG__
00999     JackGlobals::CheckContext("jack_set_port_rename_callback");
01000 #endif
01001     JackClient* client = (JackClient*)ext_client;
01002     if (client == NULL) {
01003         jack_error("jack_set_port_rename_callback called with a NULL client");
01004         return -1;
01005     } else {
01006         return client->SetPortRenameCallback(rename_callback, arg);
01007     }
01008 }
01009 
01010 LIB_EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrderCallback graph_callback, void* arg)
01011 {
01012 #ifdef __CLIENTDEBUG__
01013     JackGlobals::CheckContext("jack_set_graph_order_callback");
01014 #endif
01015     JackClient* client = (JackClient*)ext_client;
01016     jack_log("jack_set_graph_order_callback ext_client %x client %x ", ext_client, client);
01017     if (client == NULL) {
01018         jack_error("jack_set_graph_order_callback called with a NULL client");
01019         return -1;
01020     } else {
01021         return client->SetGraphOrderCallback(graph_callback, arg);
01022     }
01023 }
01024 
01025 LIB_EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xrun_callback, void* arg)
01026 {
01027 #ifdef __CLIENTDEBUG__
01028     JackGlobals::CheckContext("jack_set_xrun_callback");
01029 #endif
01030     JackClient* client = (JackClient*)ext_client;
01031     if (client == NULL) {
01032         jack_error("jack_set_xrun_callback called with a NULL client");
01033         return -1;
01034     } else {
01035         return client->SetXRunCallback(xrun_callback, arg);
01036     }
01037 }
01038 
01039 LIB_EXPORT int jack_set_latency_callback(jack_client_t* ext_client, JackLatencyCallback latency_callback, void *arg)
01040 {
01041 #ifdef __CLIENTDEBUG__
01042     JackGlobals::CheckContext("jack_set_latency_callback");
01043 #endif
01044     JackClient* client = (JackClient*)ext_client;
01045     if (client == NULL) {
01046         jack_error("jack_set_latency_callback called with a NULL client");
01047         return -1;
01048     } else {
01049         return client->SetLatencyCallback(latency_callback, arg);
01050     }
01051 }
01052 
01053 LIB_EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg)
01054 {
01055 #ifdef __CLIENTDEBUG__
01056     JackGlobals::CheckContext("jack_set_thread_init_callback");
01057 #endif
01058     JackClient* client = (JackClient*)ext_client;
01059     jack_log("jack_set_thread_init_callback ext_client %x client %x ", ext_client, client);
01060     if (client == NULL) {
01061         jack_error("jack_set_thread_init_callback called with a NULL client");
01062         return -1;
01063     } else {
01064         return client->SetInitCallback(init_callback, arg);
01065     }
01066 }
01067 
01068 LIB_EXPORT int jack_activate(jack_client_t* ext_client)
01069 {
01070 #ifdef __CLIENTDEBUG__
01071     JackGlobals::CheckContext("jack_activate");
01072 #endif
01073     JackClient* client = (JackClient*)ext_client;
01074     if (client == NULL) {
01075         jack_error("jack_activate called with a NULL client");
01076         return -1;
01077     } else {
01078         return client->Activate();
01079     }
01080 }
01081 
01082 LIB_EXPORT int jack_deactivate(jack_client_t* ext_client)
01083 {
01084 #ifdef __CLIENTDEBUG__
01085     JackGlobals::CheckContext("jack_deactivate");
01086 #endif
01087     JackClient* client = (JackClient*)ext_client;
01088     if (client == NULL) {
01089         jack_error("jack_deactivate called with a NULL client");
01090         return -1;
01091     } else {
01092         return client->Deactivate();
01093     }
01094 }
01095 
01096 LIB_EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size)
01097 {
01098 #ifdef __CLIENTDEBUG__
01099     JackGlobals::CheckContext("jack_port_register");
01100 #endif
01101     JackClient* client = (JackClient*)ext_client;
01102     if (client == NULL) {
01103         jack_error("jack_port_register called with a NULL client");
01104         return NULL;
01105     } else if ((port_name == NULL) || (port_type == NULL)) {
01106         jack_error("jack_port_register called with a NULL port name or a NULL port_type");
01107         return NULL;
01108     } else {
01109         return (jack_port_t *)((uintptr_t)client->PortRegister(port_name, port_type, flags, buffer_size));
01110     }
01111 }
01112 
01113 LIB_EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port)
01114 {
01115 #ifdef __CLIENTDEBUG__
01116     JackGlobals::CheckContext("jack_port_unregister");
01117 #endif
01118     JackClient* client = (JackClient*)ext_client;
01119     if (client == NULL) {
01120         jack_error("jack_port_unregister called with a NULL client");
01121         return -1;
01122     }
01123     uintptr_t port_aux = (uintptr_t)port;
01124     jack_port_id_t myport = (jack_port_id_t)port_aux;
01125     if (!CheckPort(myport)) {
01126         jack_error("jack_port_unregister called with an incorrect port %ld", myport);
01127         return -1;
01128     }
01129     return client->PortUnRegister(myport);
01130 }
01131 
01132 LIB_EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* port)
01133 {
01134 #ifdef __CLIENTDEBUG__
01135     JackGlobals::CheckContext("jack_port_is_mine");
01136 #endif
01137     JackClient* client = (JackClient*)ext_client;
01138     if (client == NULL) {
01139         jack_error("jack_port_is_mine called with a NULL client");
01140         return -1;
01141     }
01142     uintptr_t port_aux = (uintptr_t)port;
01143     jack_port_id_t myport = (jack_port_id_t)port_aux;
01144     if (!CheckPort(myport)) {
01145         jack_error("jack_port_is_mine called with an incorrect port %ld", myport);
01146         return -1;
01147     }
01148     return client->PortIsMine(myport);
01149 }
01150 
01151 LIB_EXPORT const char** jack_port_get_connections(const jack_port_t* port)
01152 {
01153 #ifdef __CLIENTDEBUG__
01154     JackGlobals::CheckContext("jack_port_get_connections");
01155 #endif
01156     uintptr_t port_aux = (uintptr_t)port;
01157     jack_port_id_t myport = (jack_port_id_t)port_aux;
01158     if (!CheckPort(myport)) {
01159         jack_error("jack_port_get_connections called with an incorrect port %ld", myport);
01160         return NULL;
01161     } else {
01162         WaitGraphChange();
01163         JackGraphManager* manager = GetGraphManager();
01164         return (manager ? manager->GetConnections(myport) : NULL);
01165     }
01166 }
01167 
01168 // Calling client does not need to "own" the port
01169 LIB_EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_client, const jack_port_t* port)
01170 {
01171 #ifdef __CLIENTDEBUG__
01172     JackGlobals::CheckContext("jack_port_get_all_connections");
01173 #endif
01174     JackClient* client = (JackClient*)ext_client;
01175     if (client == NULL) {
01176         jack_error("jack_port_get_all_connections called with a NULL client");
01177         return NULL;
01178     }
01179 
01180     uintptr_t port_aux = (uintptr_t)port;
01181     jack_port_id_t myport = (jack_port_id_t)port_aux;
01182     if (!CheckPort(myport)) {
01183         jack_error("jack_port_get_all_connections called with an incorrect port %ld", myport);
01184         return NULL;
01185     } else {
01186         WaitGraphChange();
01187         JackGraphManager* manager = GetGraphManager();
01188         return (manager ? manager->GetConnections(myport) : NULL);
01189     }
01190 }
01191 
01192 LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jack_port_t* port)
01193 {
01194 #ifdef __CLIENTDEBUG__
01195     JackGlobals::CheckContext("jack_port_get_total_latency");
01196 #endif
01197     JackClient* client = (JackClient*)ext_client;
01198     if (client == NULL) {
01199         jack_error("jack_port_get_total_latency called with a NULL client");
01200         return 0;
01201     }
01202 
01203     uintptr_t port_aux = (uintptr_t)port;
01204     jack_port_id_t myport = (jack_port_id_t)port_aux;
01205     if (!CheckPort(myport)) {
01206         jack_error("jack_port_get_total_latency called with an incorrect port %ld", myport);
01207         return 0;
01208     } else {
01209         WaitGraphChange();
01210         JackGraphManager* manager = GetGraphManager();
01211         if (manager) {
01212             manager->ComputeTotalLatency(myport);
01213             return manager->GetPort(myport)->GetTotalLatency();
01214         } else {
01215             return 0;
01216         }
01217     }
01218 }
01219 
01220 LIB_EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* dst)
01221 {
01222 #ifdef __CLIENTDEBUG__
01223     JackGlobals::CheckContext("jack_connect");
01224 #endif
01225     JackClient* client = (JackClient*)ext_client;
01226     if (client == NULL) {
01227         jack_error("jack_connect called with a NULL client");
01228         return -1;
01229     } else if ((src == NULL) || (dst == NULL)) {
01230         jack_error("jack_connect called with a NULL port name");
01231         return -1;
01232     } else {
01233         return client->PortConnect(src, dst);
01234     }
01235 }
01236 
01237 LIB_EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const char* dst)
01238 {
01239 #ifdef __CLIENTDEBUG__
01240     JackGlobals::CheckContext("jack_disconnect");
01241 #endif
01242     JackClient* client = (JackClient*)ext_client;
01243     if (client == NULL) {
01244         jack_error("jack_disconnect called with a NULL client");
01245         return -1;
01246     } else if ((src == NULL) || (dst == NULL)) {
01247         jack_error("jack_connect called with a NULL port name");
01248         return -1;
01249     } else {
01250         return client->PortDisconnect(src, dst);
01251     }
01252 }
01253 
01254 LIB_EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src)
01255 {
01256 #ifdef __CLIENTDEBUG__
01257     JackGlobals::CheckContext("jack_port_disconnect");
01258 #endif
01259     JackClient* client = (JackClient*)ext_client;
01260     if (client == NULL) {
01261         jack_error("jack_port_disconnect called with a NULL client");
01262         return -1;
01263     }
01264     uintptr_t port_aux = (uintptr_t)src;
01265     jack_port_id_t myport = (jack_port_id_t)port_aux;
01266     if (!CheckPort(myport)) {
01267         jack_error("jack_port_disconnect called with an incorrect port %ld", myport);
01268         return -1;
01269     }
01270     return client->PortDisconnect(myport);
01271 }
01272 
01273 LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client)
01274 {
01275 #ifdef __CLIENTDEBUG__
01276     JackGlobals::CheckContext("jack_get_sample_rate");
01277 #endif
01278     JackClient* client = (JackClient*)ext_client;
01279     if (client == NULL) {
01280         jack_error("jack_get_sample_rate called with a NULL client");
01281         return 0;
01282     } else {
01283         JackEngineControl* control = GetEngineControl();
01284         return (control ? control->fSampleRate : 0);
01285     }
01286 }
01287 
01288 LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client)
01289 {
01290 #ifdef __CLIENTDEBUG__
01291     JackGlobals::CheckContext("jack_get_buffer_size");
01292 #endif
01293     JackClient* client = (JackClient*)ext_client;
01294     if (client == NULL) {
01295         jack_error("jack_get_buffer_size called with a NULL client");
01296         return 0;
01297     } else {
01298         JackEngineControl* control = GetEngineControl();
01299         return (control ? control->fBufferSize : 0);
01300     }
01301 }
01302 
01303 LIB_EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
01304 {
01305 #ifdef __CLIENTDEBUG__
01306     JackGlobals::CheckContext("jack_get_ports");
01307 #endif
01308     JackClient* client = (JackClient*)ext_client;
01309     if (client == NULL) {
01310         jack_error("jack_get_ports called with a NULL client");
01311         return NULL;
01312     }
01313     JackGraphManager* manager = GetGraphManager();
01314     return (manager ? manager->GetPorts(port_name_pattern, type_name_pattern, flags) : NULL);
01315 }
01316 
01317 LIB_EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* portname)
01318 {
01319 #ifdef __CLIENTDEBUG__
01320     JackGlobals::CheckContext("jack_port_by_name");
01321 #endif
01322     JackClient* client = (JackClient*)ext_client;
01323     if (client == NULL) {
01324         jack_error("jack_get_ports called with a NULL client");
01325         return 0;
01326     }
01327 
01328     if (portname == NULL) {
01329         jack_error("jack_port_by_name called with a NULL port name");
01330         return NULL;
01331     } else {
01332         JackGraphManager* manager = GetGraphManager();
01333         if (!manager)
01334             return NULL;
01335         int res = manager->GetPort(portname); // returns a port index at least > 1
01336         return (res == NO_PORT) ? NULL : (jack_port_t*)((uintptr_t)res);
01337     }
01338 }
01339 
01340 LIB_EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id)
01341 {
01342 #ifdef __CLIENTDEBUG__
01343     JackGlobals::CheckContext("jack_port_by_id");
01344 #endif
01345     /* jack_port_t* type is actually the port index */
01346     return (jack_port_t*)((uintptr_t)id);
01347 }
01348 
01349 LIB_EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client)
01350 {
01351 #ifdef __CLIENTDEBUG__
01352     JackGlobals::CheckContext("jack_engine_takeover_timebase");
01353 #endif
01354     JackClient* client = (JackClient*)ext_client;
01355     if (client == NULL) {
01356         jack_error("jack_engine_takeover_timebase called with a NULL client");
01357         return -1;
01358     } else {
01359         jack_error("jack_engine_takeover_timebase: deprecated\n");
01360         return 0;
01361     }
01362 }
01363 
01364 LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_client)
01365 {
01366 #ifdef __CLIENTDEBUG__
01367     JackGlobals::CheckContext("jack_frames_since_cycle_start");
01368 #endif
01369     JackTimer timer;
01370     JackEngineControl* control = GetEngineControl();
01371     if (control) {
01372         control->ReadFrameTime(&timer);
01373         return timer.FramesSinceCycleStart(GetMicroSeconds(), control->fSampleRate);
01374     } else {
01375         return 0;
01376     }
01377 }
01378 
01379 LIB_EXPORT jack_time_t jack_get_time()
01380 {
01381 #ifdef __CLIENTDEBUG__
01382     JackGlobals::CheckContext("jack_get_time");
01383 #endif
01384     return GetMicroSeconds();
01385 }
01386 
01387 LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nframes_t frames)
01388 {
01389 #ifdef __CLIENTDEBUG__
01390     JackGlobals::CheckContext("jack_frames_to_time");
01391 #endif
01392     JackClient* client = (JackClient*)ext_client;
01393     if (client == NULL) {
01394         jack_error("jack_frames_to_time called with a NULL client");
01395         return 0;
01396     } else {
01397         JackTimer timer;
01398         JackEngineControl* control = GetEngineControl();
01399         if (control) {
01400             control->ReadFrameTime(&timer);
01401             return timer.Frames2Time(frames, control->fBufferSize);
01402         } else {
01403             return 0;
01404         }
01405     }
01406 }
01407 
01408 LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_time_t time)
01409 {
01410 #ifdef __CLIENTDEBUG__
01411     JackGlobals::CheckContext("jack_time_to_frames");
01412 #endif
01413     JackClient* client = (JackClient*)ext_client;
01414     if (client == NULL) {
01415         jack_error("jack_time_to_frames called with a NULL client");
01416         return 0;
01417     } else {
01418         JackTimer timer;
01419         JackEngineControl* control = GetEngineControl();
01420         if (control) {
01421             control->ReadFrameTime(&timer);
01422             return timer.Time2Frames(time, control->fBufferSize);
01423         } else {
01424             return 0;
01425         }
01426     }
01427 }
01428 
01429 LIB_EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client)
01430 {
01431 #ifdef __CLIENTDEBUG__
01432     JackGlobals::CheckContext("jack_frame_time");
01433 #endif
01434     return jack_time_to_frames(ext_client, GetMicroSeconds());
01435 }
01436 
01437 LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client)
01438 {
01439 #ifdef __CLIENTDEBUG__
01440     JackGlobals::CheckContext("jack_last_frame_time");
01441 #endif
01442     JackEngineControl* control = GetEngineControl();
01443     return (control) ? control->fFrameTimer.ReadCurrentState()->CurFrame() : 0;
01444 }
01445 
01446 LIB_EXPORT float jack_cpu_load(jack_client_t* ext_client)
01447 {
01448 #ifdef __CLIENTDEBUG__
01449     JackGlobals::CheckContext("jack_cpu_load");
01450 #endif
01451     JackClient* client = (JackClient*)ext_client;
01452     if (client == NULL) {
01453         jack_error("jack_cpu_load called with a NULL client");
01454         return 0.0f;
01455     } else {
01456         JackEngineControl* control = GetEngineControl();
01457         return (control ? control->fCPULoad :  0.0f);
01458     }
01459 }
01460 
01461 LIB_EXPORT jack_native_thread_t jack_client_thread_id(jack_client_t* ext_client)
01462 {
01463 #ifdef __CLIENTDEBUG__
01464     JackGlobals::CheckContext("jack_client_thread_id");
01465 #endif
01466     JackClient* client = (JackClient*)ext_client;
01467     if (client == NULL) {
01468         jack_error("jack_client_thread_id called with a NULL client");
01469         return (jack_native_thread_t)NULL;
01470     } else {
01471         return client->GetThreadID();
01472     }
01473 }
01474 
01475 LIB_EXPORT char* jack_get_client_name(jack_client_t* ext_client)
01476 {
01477 #ifdef __CLIENTDEBUG__
01478     JackGlobals::CheckContext("jack_get_client_name");
01479 #endif
01480     JackClient* client = (JackClient*)ext_client;
01481     if (client == NULL) {
01482         jack_error("jack_get_client_name called with a NULL client");
01483         return NULL;
01484     } else {
01485         return client->GetClientControl()->fName;
01486     }
01487 }
01488 
01489 LIB_EXPORT int jack_client_name_size(void)
01490 {
01491     return JACK_CLIENT_NAME_SIZE;
01492 }
01493 
01494 LIB_EXPORT int jack_port_name_size(void)
01495 {
01496     return REAL_JACK_PORT_NAME_SIZE;
01497 }
01498 
01499 LIB_EXPORT int jack_port_type_size(void)
01500 {
01501     return JACK_PORT_TYPE_SIZE;
01502 }
01503 
01504 LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t* ext_client, const char* port_type)
01505 {
01506 #ifdef __CLIENTDEBUG__
01507     JackGlobals::CheckContext("jack_port_type_get_buffer_size");
01508 #endif
01509     JackClient* client = (JackClient*)ext_client;
01510     if (client == NULL) {
01511         jack_error("jack_port_type_get_buffer_size called with a NULL client");
01512         return 0;
01513     } else {
01514         jack_port_type_id_t port_id = GetPortTypeId(port_type);
01515         if (port_id == PORT_TYPES_MAX) {
01516             jack_error("jack_port_type_get_buffer_size called with an unknown port type = %s", port_type);
01517             return 0;
01518         } else {
01519             return GetPortType(port_id)->size();
01520         }
01521     }
01522 }
01523 
01524 // transport.h
01525 LIB_EXPORT int jack_release_timebase(jack_client_t* ext_client)
01526 {
01527 #ifdef __CLIENTDEBUG__
01528     JackGlobals::CheckContext("jack_release_timebase");
01529 #endif
01530     JackClient* client = (JackClient*)ext_client;
01531     if (client == NULL) {
01532         jack_error("jack_release_timebase called with a NULL client");
01533         return -1;
01534     } else {
01535         return client->ReleaseTimebase();
01536     }
01537 }
01538 
01539 LIB_EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg)
01540 {
01541 #ifdef __CLIENTDEBUG__
01542     JackGlobals::CheckContext("jack_set_sync_callback");
01543 #endif
01544     JackClient* client = (JackClient*)ext_client;
01545     if (client == NULL) {
01546         jack_error("jack_set_sync_callback called with a NULL client");
01547         return -1;
01548     } else {
01549         return client->SetSyncCallback(sync_callback, arg);
01550     }
01551 }
01552 
01553 LIB_EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout)
01554 {
01555 #ifdef __CLIENTDEBUG__
01556     JackGlobals::CheckContext("jack_set_sync_timeout");
01557 #endif
01558     JackClient* client = (JackClient*)ext_client;
01559     if (client == NULL) {
01560         jack_error("jack_set_sync_timeout called with a NULL client");
01561         return -1;
01562     } else {
01563         return client->SetSyncTimeout(timeout);
01564     }
01565 }
01566 
01567 LIB_EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg)
01568 {
01569 #ifdef __CLIENTDEBUG__
01570     JackGlobals::CheckContext("jack_set_timebase_callback");
01571 #endif
01572     JackClient* client = (JackClient*)ext_client;
01573     if (client == NULL) {
01574         jack_error("jack_set_timebase_callback called with a NULL client");
01575         return -1;
01576     } else {
01577         return client->SetTimebaseCallback(conditional, timebase_callback, arg);
01578     }
01579 }
01580 
01581 LIB_EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame)
01582 {
01583 #ifdef __CLIENTDEBUG__
01584     JackGlobals::CheckContext("jack_transport_locate");
01585 #endif
01586     JackClient* client = (JackClient*)ext_client;
01587     if (client == NULL) {
01588         jack_error("jack_transport_locate called with a NULL client");
01589         return -1;
01590     } else {
01591         client->TransportLocate(frame);
01592         return 0;
01593     }
01594 }
01595 
01596 LIB_EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos)
01597 {
01598 #ifdef __CLIENTDEBUG__
01599     JackGlobals::CheckContext("jack_transport_query");
01600 #endif
01601     JackClient* client = (JackClient*)ext_client;
01602     if (client == NULL) {
01603         jack_error("jack_transport_query called with a NULL client");
01604         return JackTransportStopped;
01605     } else {
01606         return client->TransportQuery(pos);
01607     }
01608 }
01609 
01610 LIB_EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client)
01611 {
01612 #ifdef __CLIENTDEBUG__
01613     JackGlobals::CheckContext("jack_get_current_transport_frame");
01614 #endif
01615     JackClient* client = (JackClient*)ext_client;
01616     if (client == NULL) {
01617         jack_error("jack_get_current_transport_frame called with a NULL client");
01618         return 0;
01619     } else {
01620         return client->GetCurrentTransportFrame();
01621     }
01622 }
01623 
01624 LIB_EXPORT int jack_transport_reposition(jack_client_t* ext_client, const jack_position_t* pos)
01625 {
01626 #ifdef __CLIENTDEBUG__
01627     JackGlobals::CheckContext("jack_transport_reposition");
01628 #endif
01629     JackClient* client = (JackClient*)ext_client;
01630     if (client == NULL) {
01631         jack_error("jack_transport_reposition called with a NULL client");
01632         return -1;
01633     } else {
01634         client->TransportReposition(pos);
01635         return 0;
01636     }
01637 }
01638 
01639 LIB_EXPORT void jack_transport_start(jack_client_t* ext_client)
01640 {
01641 #ifdef __CLIENTDEBUG__
01642     JackGlobals::CheckContext("jack_transport_start");
01643 #endif
01644     JackClient* client = (JackClient*)ext_client;
01645     if (client == NULL) {
01646         jack_error("jack_transport_start called with a NULL client");
01647     } else {
01648         client->TransportStart();
01649     }
01650 }
01651 
01652 LIB_EXPORT void jack_transport_stop(jack_client_t* ext_client)
01653 {
01654 #ifdef __CLIENTDEBUG__
01655     JackGlobals::CheckContext("jack_transport_stop");
01656 #endif
01657     JackClient* client = (JackClient*)ext_client;
01658     if (client == NULL) {
01659         jack_error("jack_transport_stop called with a NULL client");
01660     } else {
01661         client->TransportStop();
01662     }
01663 }
01664 
01665 // deprecated
01666 LIB_EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
01667 {
01668 #ifdef __CLIENTDEBUG__
01669     JackGlobals::CheckContext("jack_get_transport_info");
01670 #endif
01671     jack_error("jack_get_transport_info: deprecated");
01672     if (tinfo)
01673         memset(tinfo, 0, sizeof(jack_transport_info_t));
01674 }
01675 
01676 LIB_EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
01677 {
01678 #ifdef __CLIENTDEBUG__
01679     JackGlobals::CheckContext("jack_set_transport_info");
01680 #endif
01681     jack_error("jack_set_transport_info: deprecated");
01682     if (tinfo)
01683         memset(tinfo, 0, sizeof(jack_transport_info_t));
01684 }
01685 
01686 // statistics.h
01687 LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client)
01688 {
01689 #ifdef __CLIENTDEBUG__
01690     JackGlobals::CheckContext("jack_get_max_delayed_usecs");
01691 #endif
01692     JackClient* client = (JackClient*)ext_client;
01693     if (client == NULL) {
01694         jack_error("jack_get_max_delayed_usecs called with a NULL client");
01695         return 0.f;
01696     } else {
01697         JackEngineControl* control = GetEngineControl();
01698         return (control ? control->fMaxDelayedUsecs : 0.f);
01699     }
01700  }
01701 
01702 LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client)
01703 {
01704 #ifdef __CLIENTDEBUG__
01705     JackGlobals::CheckContext("jack_get_xrun_delayed_usecs");
01706 #endif
01707     JackClient* client = (JackClient*)ext_client;
01708     if (client == NULL) {
01709         jack_error("jack_get_xrun_delayed_usecs called with a NULL client");
01710         return 0.f;
01711     } else {
01712         JackEngineControl* control = GetEngineControl();
01713         return (control ? control->fXrunDelayedUsecs : 0.f);
01714     }
01715 }
01716 
01717 LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client)
01718 {
01719 #ifdef __CLIENTDEBUG__
01720     JackGlobals::CheckContext("jack_reset_max_delayed_usecs");
01721 #endif
01722     JackClient* client = (JackClient*)ext_client;
01723     if (client == NULL) {
01724         jack_error("jack_reset_max_delayed_usecs called with a NULL client");
01725     } else {
01726         JackEngineControl* control = GetEngineControl();
01727         control->ResetXRun();
01728     }
01729 }
01730 
01731 // thread.h
01732 LIB_EXPORT int jack_client_real_time_priority(jack_client_t* ext_client)
01733 {
01734 #ifdef __CLIENTDEBUG__
01735     JackGlobals::CheckContext("jack_client_real_time_priority");
01736 #endif
01737     JackClient* client = (JackClient*)ext_client;
01738     if (client == NULL) {
01739         jack_error("jack_client_real_time_priority called with a NULL client");
01740         return -1;
01741     } else {
01742         JackEngineControl* control = GetEngineControl();
01743         return (control->fRealTime) ? control->fClientPriority : -1;
01744     }
01745 }
01746 
01747 LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client)
01748 {
01749 #ifdef __CLIENTDEBUG__
01750     JackGlobals::CheckContext("jack_client_max_real_time_priority");
01751 #endif
01752     JackClient* client = (JackClient*)ext_client;
01753     if (client == NULL) {
01754         jack_error("jack_client_max_real_time_priority called with a NULL client");
01755         return -1;
01756     } else {
01757         JackEngineControl* control = GetEngineControl();
01758         return (control->fRealTime) ? control->fMaxClientPriority : -1;
01759     }
01760 }
01761 
01762 LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority)
01763 {
01764     JackEngineControl* control = GetEngineControl();
01765     return (control
01766         ? JackThread::AcquireRealTimeImp(thread, priority, control->fPeriod, control->fComputation, control->fConstraint)
01767         : -1);
01768 }
01769 
01770 LIB_EXPORT int jack_client_create_thread(jack_client_t* client,
01771                                      jack_native_thread_t *thread,
01772                                      int priority,
01773                                      int realtime,      /* boolean */
01774                                      thread_routine routine,
01775                                      void *arg)
01776 {
01777 #ifdef __CLIENTDEBUG__
01778     JackGlobals::CheckContext("jack_client_create_thread");
01779 #endif
01780     JackEngineControl* control = GetEngineControl();
01781     int res = JackThread::StartImp(thread, priority, realtime, routine, arg);
01782     return (res == 0)
01783         ? ((realtime ? JackThread::AcquireRealTimeImp(*thread, priority, control->fPeriod, control->fComputation, control->fConstraint) : res))
01784         : res;
01785 }
01786 
01787 LIB_EXPORT int jack_drop_real_time_scheduling(jack_native_thread_t thread)
01788 {
01789     return JackThread::DropRealTimeImp(thread);
01790 }
01791 
01792 LIB_EXPORT int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread)
01793 {
01794 #ifdef __CLIENTDEBUG__
01795     JackGlobals::CheckContext("jack_client_stop_thread");
01796 #endif
01797     return JackThread::StopImp(thread);
01798 }
01799 
01800 LIB_EXPORT int jack_client_kill_thread(jack_client_t* client, jack_native_thread_t thread)
01801 {
01802 #ifdef __CLIENTDEBUG__
01803     JackGlobals::CheckContext("jack_client_kill_thread");
01804 #endif
01805     return JackThread::KillImp(thread);
01806 }
01807 
01808 #ifndef WIN32
01809 LIB_EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc)
01810 {
01811     JackGlobals::fJackThreadCreator = (jtc == NULL) ? pthread_create : jtc;
01812 }
01813 #endif
01814 
01815 // intclient.h
01816 LIB_EXPORT int jack_internal_client_new (const char* client_name,
01817                                      const char* load_name,
01818                                      const char* load_init)
01819 {
01820 #ifdef __CLIENTDEBUG__
01821     JackGlobals::CheckContext("jack_internal_client_new");
01822 #endif
01823     jack_error("jack_internal_client_new: deprecated");
01824     return -1;
01825 }
01826 
01827 LIB_EXPORT void jack_internal_client_close (const char* client_name)
01828 {
01829 #ifdef __CLIENTDEBUG__
01830     JackGlobals::CheckContext("jack_internal_client_close");
01831 #endif
01832     jack_error("jack_internal_client_close: deprecated");
01833 }
01834 
01835 LIB_EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient)
01836 {
01837 #ifdef __CLIENTDEBUG__
01838     JackGlobals::CheckContext("jack_get_internal_client_name");
01839 #endif
01840     JackClient* client = (JackClient*)ext_client;
01841     if (client == NULL) {
01842         jack_error("jack_get_internal_client_name called with a NULL client");
01843         return NULL;
01844     } else if (intclient >= CLIENT_NUM) {
01845         jack_error("jack_get_internal_client_name: incorrect client");
01846         return NULL;
01847     } else {
01848         return client->GetInternalClientName(intclient);
01849     }
01850 }
01851 
01852 LIB_EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, const char* client_name, jack_status_t* status)
01853 {
01854 #ifdef __CLIENTDEBUG__
01855     JackGlobals::CheckContext("jack_internal_client_handle");
01856 #endif
01857     JackClient* client = (JackClient*)ext_client;
01858     if (client == NULL) {
01859         jack_error("jack_internal_client_handle called with a NULL client");
01860         return 0;
01861     } else {
01862         jack_status_t my_status;
01863         if (status == NULL)             /* no status from caller? */
01864             status = &my_status;        /* use local status word */
01865         *status = (jack_status_t)0;
01866         return client->InternalClientHandle(client_name, status);
01867     }
01868 }
01869 
01870 LIB_EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t* ext_client, const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
01871 {
01872 #ifdef __CLIENTDEBUG__
01873     JackGlobals::CheckContext("jack_internal_client_load_aux");
01874 #endif
01875     JackClient* client = (JackClient*)ext_client;
01876     if (client == NULL) {
01877         jack_error("jack_internal_client_load called with a NULL client");
01878         return 0;
01879     } else {
01880         jack_varargs_t va;
01881         jack_status_t my_status;
01882 
01883         if (status == NULL)             /* no status from caller? */
01884             status = &my_status;        /* use local status word */
01885         *status = (jack_status_t)0;
01886 
01887         /* validate parameters */
01888         if ((options & ~JackLoadOptions)) {
01889             int my_status1 = *status | (JackFailure | JackInvalidOption);
01890             *status = (jack_status_t)my_status1;
01891             return 0;
01892         }
01893 
01894         /* parse variable arguments */
01895         jack_varargs_parse(options, ap, &va);
01896         return client->InternalClientLoad(client_name, options, status, &va);
01897     }
01898 }
01899 
01900 LIB_EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const char* client_name, jack_options_t options, jack_status_t *status, ...)
01901 {
01902 #ifdef __CLIENTDEBUG__
01903     JackGlobals::CheckContext("jack_internal_client_load");
01904 #endif
01905     va_list ap;
01906     va_start(ap, status);
01907     jack_intclient_t res = jack_internal_client_load_aux(client, client_name, options, status, ap);
01908     va_end(ap);
01909     return res;
01910 }
01911 
01912 LIB_EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack_intclient_t intclient)
01913 {
01914 #ifdef __CLIENTDEBUG__
01915     JackGlobals::CheckContext("jack_internal_client_load");
01916 #endif
01917     JackClient* client = (JackClient*)ext_client;
01918     if (client == NULL) {
01919         jack_error("jack_internal_client_unload called with a NULL client");
01920         return (jack_status_t)(JackNoSuchClient | JackFailure);
01921     } else if (intclient >= CLIENT_NUM) {
01922         jack_error("jack_internal_client_unload: incorrect client");
01923         return (jack_status_t)(JackNoSuchClient | JackFailure);
01924     } else {
01925         jack_status_t my_status;
01926         client->InternalClientUnload(intclient, &my_status);
01927         return my_status;
01928     }
01929 }
01930 
01931 LIB_EXPORT void jack_get_version(int *major_ptr,
01932                             int *minor_ptr,
01933                             int *micro_ptr,
01934                             int *proto_ptr)
01935 {
01936 #ifdef __CLIENTDEBUG__
01937     JackGlobals::CheckContext("jack_get_version");
01938 #endif
01939     // FIXME: We need these comming from build system
01940     *major_ptr = 0;
01941     *minor_ptr = 0;
01942     *micro_ptr = 0;
01943     *proto_ptr = 0;
01944 }
01945 
01946 LIB_EXPORT const char* jack_get_version_string()
01947 {
01948 #ifdef __CLIENTDEBUG__
01949     JackGlobals::CheckContext("jack_get_version_string");
01950 #endif
01951     return VERSION;
01952 }
01953 
01954 LIB_EXPORT void jack_free(void* ptr)
01955 {
01956 #ifdef __CLIENTDEBUG__
01957     JackGlobals::CheckContext("jack_free");
01958 #endif
01959     if (ptr) {
01960         free(ptr);
01961     }
01962 }
01963 
01964 // session.h
01965 LIB_EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg)
01966 {
01967 #ifdef __CLIENTDEBUG__
01968     JackGlobals::CheckContext("jack_set_session_callback");
01969 #endif
01970     JackClient* client = (JackClient*)ext_client;
01971     jack_log("jack_set_session_callback ext_client %x client %x ", ext_client, client);
01972     if (client == NULL) {
01973         jack_error("jack_set_session_callback called with a NULL client");
01974         return -1;
01975     } else {
01976         return client->SetSessionCallback(session_callback, arg);
01977     }
01978 }
01979 
01980 LIB_EXPORT jack_session_command_t* jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char* path)
01981 {
01982 #ifdef __CLIENTDEBUG__
01983     JackGlobals::CheckContext("jack_session_notify");
01984 #endif
01985     JackClient* client = (JackClient*)ext_client;
01986     jack_log("jack_session_notify ext_client %x client %x ", ext_client, client);
01987     if (client == NULL) {
01988         jack_error("jack_session_notify called with a NULL client");
01989         return NULL;
01990     } else {
01991         return client->SessionNotify(target, ev_type, path);
01992     }
01993 }
01994 
01995 LIB_EXPORT int jack_session_reply(jack_client_t* ext_client, jack_session_event_t *event)
01996 {
01997 #ifdef __CLIENTDEBUG__
01998     JackGlobals::CheckContext("jack_session_reply");
01999 #endif
02000     JackClient* client = (JackClient*)ext_client;
02001     jack_log("jack_session_reply ext_client %x client %x ", ext_client, client);
02002     if (client == NULL) {
02003         jack_error("jack_session_reply called with a NULL client");
02004         return -1;
02005     } else {
02006         return client->SessionReply(event);
02007     }
02008 }
02009 
02010 LIB_EXPORT void jack_session_event_free(jack_session_event_t* ev)
02011 {
02012 #ifdef __CLIENTDEBUG__
02013     JackGlobals::CheckContext("jack_session_event_free");
02014 #endif
02015     if (ev) {
02016         if (ev->session_dir)
02017             free((void *)ev->session_dir);
02018         if (ev->client_uuid)
02019             free((void *)ev->client_uuid);
02020         if (ev->command_line)
02021             free(ev->command_line);
02022         free(ev);
02023     }
02024 }
02025 
02026 LIB_EXPORT char *jack_client_get_uuid(jack_client_t* ext_client)
02027 {
02028 #ifdef __CLIENTDEBUG__
02029     JackGlobals::CheckContext("jack_client_get_uuid");
02030 #endif
02031     JackClient* client = (JackClient*)ext_client;
02032     if (client == NULL) {
02033         jack_error("jack_client_get_uuid called with a NULL client");
02034         return NULL;
02035     } else {
02036         char retval[16];
02037         snprintf(retval, sizeof(retval), "%d", client->GetClientControl()->fSessionID);
02038         return strdup(retval);
02039     }
02040 }
02041 
02042 LIB_EXPORT char* jack_get_uuid_for_client_name(jack_client_t* ext_client, const char* client_name)
02043 {
02044 #ifdef __CLIENTDEBUG__
02045     JackGlobals::CheckContext("jack_get_uuid_for_client_name");
02046 #endif
02047     JackClient* client = (JackClient*)ext_client;
02048     jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client);
02049     if (client == NULL) {
02050         jack_error("jack_get_uuid_for_client_name called with a NULL client");
02051         return NULL;
02052     } else {
02053         return client->GetUUIDForClientName(client_name);
02054     }
02055 }
02056 
02057 LIB_EXPORT char* jack_get_client_name_by_uuid(jack_client_t* ext_client, const char* client_uuid)
02058 {
02059 #ifdef __CLIENTDEBUG__
02060     JackGlobals::CheckContext("jack_get_client_name_by_uuid");
02061 #endif
02062     JackClient* client = (JackClient*)ext_client;
02063     jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client);
02064     if (client == NULL) {
02065         jack_error("jack_get_client_name_by_uuid called with a NULL client");
02066         return NULL;
02067     } else {
02068         return client->GetClientNameByUUID(client_uuid);
02069     }
02070 }
02071 
02072 LIB_EXPORT int jack_reserve_client_name(jack_client_t* ext_client, const char* client_name, const char* uuid)
02073 {
02074 #ifdef __CLIENTDEBUG__
02075     JackGlobals::CheckContext("jack_reserve_client_name");
02076 #endif
02077     JackClient* client = (JackClient*)ext_client;
02078     jack_log("jack_reserve_client_name ext_client %x client %x ", ext_client, client);
02079     if (client == NULL) {
02080         jack_error("jack_reserve_client_name called with a NULL client");
02081         return -1;
02082     } else {
02083         return client->ReserveClientName(client_name, uuid);
02084     }
02085 }
02086 
02087 LIB_EXPORT void jack_session_commands_free(jack_session_command_t *cmds)
02088 {
02089 #ifdef __CLIENTDEBUG__
02090     JackGlobals::CheckContext("jack_session_commands_free");
02091 #endif
02092 
02093     if (!cmds) {
02094         return;
02095     }
02096 
02097     int i = 0;
02098     while (1) {
02099         if (cmds[i].client_name) {
02100             free ((char *)cmds[i].client_name);
02101         }
02102         if (cmds[i].command) {
02103             free ((char *)cmds[i].command);
02104         }
02105         if (cmds[i].uuid) {
02106             free ((char *)cmds[i].uuid);
02107         } else {
02108             break;
02109         }
02110 
02111         i += 1;
02112     }
02113 
02114     free(cmds);
02115 }
02116 
02117 LIB_EXPORT int jack_client_has_session_callback(jack_client_t* ext_client, const char* client_name)
02118 {
02119 #ifdef __CLIENTDEBUG__
02120     JackGlobals::CheckContext("jack_client_has_session_callback");
02121 #endif
02122     JackClient* client = (JackClient*)ext_client;
02123     jack_log("jack_client_has_session_callback ext_client %x client %x ", ext_client, client);
02124     if (client == NULL) {
02125         jack_error("jack_client_has_session_callback called with a NULL client");
02126         return -1;
02127     } else {
02128         return client->ClientHasSessionCallback(client_name);
02129     }
02130 }