Jack2 1.9.6

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