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

Generated on Thu Feb 14 11:16:01 2008 for Jackdmp by  doxygen 1.5.1