root/jack2/branches/control/common/JackAPI.cpp

Revision 2051, 54.4 kB (checked in by sletz, 2 years ago)

Add jack_port_type_id in jack API

Line 
1 /*
2 Copyright (C) 2001-2003 Paul Davis
3 Copyright (C) 2004-2008 Grame
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #include "JackClient.h"
22 #include "JackError.h"
23 #include "JackGraphManager.h"
24 #include "JackEngineControl.h"
25 #include "JackClientControl.h"
26 #include "JackGlobals.h"
27 #include "JackTime.h"
28 #include "JackExports.h"
29 #include "JackAPI.h"
30 #include "JackPortType.h"
31
32 #ifdef __APPLE__
33 #include "JackMachThread.h"
34 #elif WIN32
35 #include "JackWinThread.h"
36 #else
37 #include "JackPosixThread.h"
38 #endif
39 #include <math.h>
40
41 #ifdef __CLIENTDEBUG__
42 #include "JackLibGlobals.h"
43 #endif
44
45 using namespace Jack;
46
47 #ifdef __cplusplus
48 extern "C"
49 {
50 #endif
51
52     EXPORT jack_client_t * jack_client_open_aux (const char *client_name,
53             jack_options_t options,
54             jack_status_t *status, va_list ap);
55     EXPORT jack_client_t * jack_client_open (const char *client_name,
56             jack_options_t options,
57             jack_status_t *status, ...);
58     EXPORT jack_client_t * jack_client_new (const char *client_name);
59     EXPORT int jack_client_name_size (void);
60     EXPORT char* jack_get_client_name (jack_client_t *client);
61     EXPORT int jack_internal_client_new (const char *client_name,
62                                          const char *load_name,
63                                          const char *load_init);
64     EXPORT void jack_internal_client_close (const char *client_name);
65     EXPORT int jack_is_realtime (jack_client_t *client);
66     EXPORT void jack_on_shutdown (jack_client_t *client,
67                                   void (*function)(void *arg), void *arg);
68     EXPORT int jack_set_process_callback (jack_client_t *client,
69                                           JackProcessCallback process_callback,
70                                           void *arg);
71     EXPORT jack_nframes_t jack_thread_wait(jack_client_t *client, int status);
72
73     // new
74     EXPORT jack_nframes_t jack_cycle_wait (jack_client_t*);
75     EXPORT void jack_cycle_signal (jack_client_t*, int status);
76     EXPORT int jack_set_process_thread(jack_client_t* client, JackThreadCallback fun, void *arg);
77
78     EXPORT int jack_set_thread_init_callback (jack_client_t *client,
79             JackThreadInitCallback thread_init_callback,
80             void *arg);
81     EXPORT int jack_set_freewheel_callback (jack_client_t *client,
82                                             JackFreewheelCallback freewheel_callback,
83                                             void *arg);
84     EXPORT int jack_set_freewheel(jack_client_t* client, int onoff);
85     EXPORT int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes);
86     EXPORT int jack_set_buffer_size_callback (jack_client_t *client,
87             JackBufferSizeCallback bufsize_callback,
88             void *arg);
89     EXPORT int jack_set_sample_rate_callback (jack_client_t *client,
90             JackSampleRateCallback srate_callback,
91             void *arg);
92     EXPORT int jack_set_client_registration_callback (jack_client_t *,
93             JackClientRegistrationCallback
94             registration_callback, void *arg);
95     EXPORT int jack_set_port_registration_callback (jack_client_t *,
96             JackPortRegistrationCallback
97             registration_callback, void *arg);
98     EXPORT int jack_set_port_connect_callback (jack_client_t *,
99             JackPortConnectCallback
100             connect_callback, void *arg);
101     EXPORT int jack_set_graph_order_callback (jack_client_t *,
102             JackGraphOrderCallback graph_callback,
103             void *);
104     EXPORT int jack_set_xrun_callback (jack_client_t *,
105                                        JackXRunCallback xrun_callback, void *arg);
106     EXPORT int jack_activate (jack_client_t *client);
107     EXPORT int jack_deactivate (jack_client_t *client);
108     EXPORT jack_port_t * jack_port_register (jack_client_t *client,
109             const char *port_name,
110             const char *port_type,
111             unsigned long flags,
112             unsigned long buffer_size);
113     EXPORT int jack_port_unregister (jack_client_t *, jack_port_t *);
114     EXPORT void * jack_port_get_buffer (jack_port_t *, jack_nframes_t);
115     EXPORT const char * jack_port_name (const jack_port_t *port);
116     EXPORT const char * jack_port_short_name (const jack_port_t *port);
117     EXPORT int jack_port_flags (const jack_port_t *port);
118     EXPORT const char * jack_port_type (const jack_port_t *port);
119     EXPORT jack_port_type_id_t jack_port_type_id (const jack_port_t *port);
120     EXPORT int jack_port_is_mine (const jack_client_t *, const jack_port_t *port);
121     EXPORT int jack_port_connected (const jack_port_t *port);
122     EXPORT int jack_port_connected_to (const jack_port_t *port,
123                                        const char *port_name);
124     EXPORT const char ** jack_port_get_connections (const jack_port_t *port);
125     EXPORT const char ** jack_port_get_all_connections (const jack_client_t *client,
126             const jack_port_t *port);
127     EXPORT int jack_port_tie (jack_port_t *src, jack_port_t *dst);
128     EXPORT int jack_port_untie (jack_port_t *port);
129     EXPORT jack_nframes_t jack_port_get_latency (jack_port_t *port);
130     EXPORT jack_nframes_t jack_port_get_total_latency (jack_client_t *,
131             jack_port_t *port);
132     EXPORT void jack_port_set_latency (jack_port_t *, jack_nframes_t);
133     EXPORT int jack_recompute_total_latency (jack_client_t*, jack_port_t* port);
134     EXPORT int jack_recompute_total_latencies (jack_client_t*);
135     EXPORT int jack_port_set_name (jack_port_t *port, const char *port_name);
136     EXPORT int jack_port_set_alias (jack_port_t *port, const char *alias);
137     EXPORT int jack_port_unset_alias (jack_port_t *port, const char *alias);
138     EXPORT int jack_port_get_aliases (const jack_port_t *port, char* const aliases[2]);
139     EXPORT int jack_port_request_monitor (jack_port_t *port, int onoff);
140     EXPORT int jack_port_request_monitor_by_name (jack_client_t *client,
141             const char *port_name, int onoff);
142     EXPORT int jack_port_ensure_monitor (jack_port_t *port, int onoff);
143     EXPORT int jack_port_monitoring_input (jack_port_t *port);
144     EXPORT int jack_connect (jack_client_t *,
145                              const char *source_port,
146                              const char *destination_port);
147     EXPORT int jack_disconnect (jack_client_t *,
148                                 const char *source_port,
149                                 const char *destination_port);
150     EXPORT int jack_port_disconnect (jack_client_t *, jack_port_t *);
151     EXPORT int jack_port_name_size(void);
152     EXPORT int jack_port_type_size(void);
153     EXPORT jack_nframes_t jack_get_sample_rate (jack_client_t *);
154     EXPORT jack_nframes_t jack_get_buffer_size (jack_client_t *);
155     EXPORT const char ** jack_get_ports (jack_client_t *,
156                                          const char *port_name_pattern,
157                                          const char *type_name_pattern,
158                                          unsigned long flags);
159     EXPORT jack_port_t * jack_port_by_name (jack_client_t *, const char *port_name);
160     EXPORT jack_port_t * jack_port_by_id (jack_client_t *client,
161                                           jack_port_id_t port_id);
162     EXPORT int jack_engine_takeover_timebase (jack_client_t *);
163     EXPORT jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *);
164     EXPORT jack_time_t jack_get_time();
165     EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t time);
166     EXPORT jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t frames);
167     EXPORT jack_nframes_t jack_frame_time (const jack_client_t *);
168     EXPORT jack_nframes_t jack_last_frame_time (const jack_client_t *client);
169     EXPORT float jack_cpu_load (jack_client_t *client);
170     EXPORT pthread_t jack_client_thread_id (jack_client_t *);
171     EXPORT void jack_set_error_function (void (*func)(const char *));
172     EXPORT void jack_set_info_function (void (*func)(const char *));
173
174     EXPORT float jack_get_max_delayed_usecs (jack_client_t *client);
175     EXPORT float jack_get_xrun_delayed_usecs (jack_client_t *client);
176     EXPORT void jack_reset_max_delayed_usecs (jack_client_t *client);
177
178     EXPORT int jack_release_timebase (jack_client_t *client);
179     EXPORT int jack_set_sync_callback (jack_client_t *client,
180                                        JackSyncCallback sync_callback,
181                                        void *arg);
182     EXPORT int jack_set_sync_timeout (jack_client_t *client,
183                                       jack_time_t timeout);
184     EXPORT int jack_set_timebase_callback (jack_client_t *client,
185                                            int conditional,
186                                            JackTimebaseCallback timebase_callback,
187                                            void *arg);
188     EXPORT int jack_transport_locate (jack_client_t *client,
189                                       jack_nframes_t frame);
190     EXPORT jack_transport_state_t jack_transport_query (const jack_client_t *client,
191             jack_position_t *pos);
192     EXPORT jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client);
193     EXPORT int jack_transport_reposition (jack_client_t *client,
194                                           jack_position_t *pos);
195     EXPORT void jack_transport_start (jack_client_t *client);
196     EXPORT void jack_transport_stop (jack_client_t *client);
197     EXPORT void jack_get_transport_info (jack_client_t *client,
198                                          jack_transport_info_t *tinfo);
199     EXPORT void jack_set_transport_info (jack_client_t *client,
200                                          jack_transport_info_t *tinfo);
201
202     EXPORT int jack_acquire_real_time_scheduling (pthread_t thread, int priority);
203     EXPORT int jack_client_create_thread (jack_client_t* client,
204                                           pthread_t *thread,
205                                           int priority,
206                                           int realtime,         // boolean
207                                           void *(*start_routine)(void*),
208                                           void *arg);
209     EXPORT int jack_drop_real_time_scheduling (pthread_t thread);
210
211     EXPORT char * jack_get_internal_client_name (jack_client_t *client,
212             jack_intclient_t intclient);
213     EXPORT jack_intclient_t jack_internal_client_handle (jack_client_t *client,
214             const char *client_name,
215             jack_status_t *status);
216     EXPORT jack_intclient_t jack_internal_client_load (jack_client_t *client,
217             const char *client_name,
218             jack_options_t options,
219             jack_status_t *status, ...);
220     EXPORT jack_intclient_t jack_internal_client_load_aux (jack_client_t *client,
221             const char *client_name,
222             jack_options_t options,
223             jack_status_t *status, va_list ap);
224
225     EXPORT jack_status_t jack_internal_client_unload (jack_client_t *client,
226             jack_intclient_t intclient);
227
228 #ifdef __cplusplus
229 }
230 #endif
231
232 #ifdef WIN32
233 /* missing on Windows : see http://bugs.mysql.com/bug.php?id=15936 */
234 inline double rint(double nr)
235 {
236     double f = floor(nr);
237     double c = ceil(nr);
238     return (((c -nr) >= (nr - f)) ? f : c);
239 }
240 #endif
241
242 static inline bool CheckPort(jack_port_id_t port_index)
243 {
244     return (port_index > 0 && port_index < PORT_NUM);
245 }
246
247 static inline bool CheckBufferSize(jack_nframes_t buffer_size)
248 {
249     return (buffer_size <= BUFFER_SIZE_MAX);
250 }
251
252 static inline void WaitGraphChange()
253 {
254     JackGraphManager* manager = GetGraphManager();
255     JackEngineControl* control = GetEngineControl();
256
257     if (manager && control && manager->IsPendingChange()) {
258         jack_log("WaitGraphChange...");
259         JackSleep(int(control->fPeriodUsecs * 1.1f));
260     }
261 }
262
263 EXPORT void jack_set_error_function (void (*func)(const char *))
264 {
265     jack_error_callback = func;
266 }
267
268 EXPORT void jack_set_info_function (void (*func)(const char *))
269 {
270     jack_info_callback = func;
271 }
272
273 EXPORT jack_client_t* jack_client_new(const char* client_name)
274 {
275     jack_error("jack_client_new: deprecated");
276     int options = JackUseExactName;
277     if (getenv("JACK_START_SERVER") == NULL)
278         options |= JackNoStartServer;
279     return jack_client_open_aux(client_name, (jack_options_t)options, NULL, NULL);
280 }
281
282 EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
283 {
284 #ifdef __CLIENTDEBUG__
285     JackLibGlobals::CheckContext();
286 #endif
287     jack_port_id_t myport = (jack_port_id_t)port;
288     if (!CheckPort(myport)) {
289         jack_error("jack_port_get_buffer called with an incorrect port %ld", myport);
290         return NULL;
291     } else {
292         JackGraphManager* manager = GetGraphManager();
293         return (manager ? manager->GetBuffer(myport, frames) : NULL);
294     }
295 }
296
297 EXPORT const char* jack_port_name(const jack_port_t* port)
298 {
299 #ifdef __CLIENTDEBUG__
300     JackLibGlobals::CheckContext();
301 #endif
302     jack_port_id_t myport = (jack_port_id_t)port;
303     if (!CheckPort(myport)) {
304         jack_error("jack_port_name called with an incorrect port %ld", myport);
305         return NULL;
306     } else {
307         JackGraphManager* manager = GetGraphManager();
308         return (manager ? manager->GetPort(myport)->GetName() : NULL);
309     }
310 }
311
312 EXPORT const char* jack_port_short_name(const jack_port_t* port)
313 {
314 #ifdef __CLIENTDEBUG__
315     JackLibGlobals::CheckContext();
316 #endif
317     jack_port_id_t myport = (jack_port_id_t)port;
318     if (!CheckPort(myport)) {
319         jack_error("jack_port_short_name called with an incorrect port %ld", myport);
320         return NULL;
321     } else {
322         JackGraphManager* manager = GetGraphManager();
323         return (manager ? manager->GetPort(myport)->GetShortName() : NULL);
324     }
325 }
326
327 EXPORT int jack_port_flags(const jack_port_t* port)
328 {
329 #ifdef __CLIENTDEBUG__
330     JackLibGlobals::CheckContext();
331 #endif
332     jack_port_id_t myport = (jack_port_id_t)port;
333     if (!CheckPort(myport)) {
334         jack_error("jack_port_flags called with an incorrect port %ld", myport);
335         return -1;
336     } else {
337         JackGraphManager* manager = GetGraphManager();
338         return (manager ? manager->GetPort(myport)->GetFlags() : -1);
339     }
340 }
341
342 EXPORT const char* jack_port_type(const jack_port_t* port)
343 {
344 #ifdef __CLIENTDEBUG__
345     JackLibGlobals::CheckContext();
346 #endif
347     jack_port_id_t myport = (jack_port_id_t)port;
348     if (!CheckPort(myport)) {
349         jack_error("jack_port_flags called an incorrect port %ld", myport);
350         return NULL;
351     } else {
352         JackGraphManager* manager = GetGraphManager();
353         return (manager ? manager->GetPort(myport)->GetType() : NULL);
354     }
355 }
356
357 EXPORT jack_port_type_id_t jack_port_type_id (const jack_port_t *port)
358 {
359 #ifdef __CLIENTDEBUG__
360     JackLibGlobals::CheckContext();
361 #endif
362     jack_port_id_t myport = (jack_port_id_t)port;
363     if (!CheckPort(myport)) {
364         jack_error("jack_port_type_id called an incorrect port %ld", myport);
365         return 0;
366     } else {
367         JackGraphManager* manager = GetGraphManager();
368         return (manager ? GetPortTypeId(manager->GetPort(myport)->GetType()) : 0);
369     }
370 }
371
372 EXPORT int jack_port_connected(const jack_port_t* port)
373 {
374 #ifdef __CLIENTDEBUG__
375     JackLibGlobals::CheckContext();
376 #endif
377     jack_port_id_t myport = (jack_port_id_t)port;
378     if (!CheckPort(myport)) {
379         jack_error("jack_port_connected called with an incorrect port %ld", myport);
380         return -1;
381     } else {
382         WaitGraphChange();
383         JackGraphManager* manager = GetGraphManager();
384         return (manager ? manager->GetConnectionsNum(myport) : -1);
385     }
386 }
387
388 EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name)
389 {
390 #ifdef __CLIENTDEBUG__
391     JackLibGlobals::CheckContext();
392 #endif
393     jack_port_id_t src = (jack_port_id_t)port;
394     if (!CheckPort(src)) {
395         jack_error("jack_port_connected_to called with an incorrect port %ld", src);
396         return -1;
397     } else if (port_name == NULL) {
398         jack_error("jack_port_connected_to called with a NULL port name");
399         return -1;
400     } else {
401         WaitGraphChange();
402         JackGraphManager* manager = GetGraphManager();
403         jack_port_id_t dst = (manager ? manager->GetPort(port_name) : NO_PORT);
404         if (dst == NO_PORT) {
405             jack_error("Unknown destination port port_name = %s", port_name);
406             return 0;
407         } else {
408             return manager->IsConnected(src, dst);
409         }
410     }
411 }
412
413 EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst)
414 {
415 #ifdef __CLIENTDEBUG__
416     JackLibGlobals::CheckContext();
417 #endif
418     jack_port_id_t mysrc = (jack_port_id_t)src;
419     if (!CheckPort(mysrc)) {
420         jack_error("jack_port_tie called with a NULL src port");
421         return -1;
422     }
423     jack_port_id_t mydst = (jack_port_id_t)dst;
424     if (!CheckPort(mydst)) {
425         jack_error("jack_port_tie called with a NULL dst port");
426         return -1;
427     }
428     JackGraphManager* manager = GetGraphManager();
429     if (manager && manager->GetPort(mysrc)->GetRefNum() != manager->GetPort(mydst)->GetRefNum()) {
430         jack_error("jack_port_tie called with ports not belonging to the same client");
431         return -1;
432     } else {
433         return manager->GetPort(mydst)->Tie(mysrc);
434     }
435 }
436
437 EXPORT int jack_port_untie(jack_port_t* port)
438 {
439 #ifdef __CLIENTDEBUG__
440     JackLibGlobals::CheckContext();
441 #endif
442     jack_port_id_t myport = (jack_port_id_t)port;
443     if (!CheckPort(myport)) {
444         jack_error("jack_port_untie called with an incorrect port %ld", myport);
445         return -1;
446     } else {
447         JackGraphManager* manager = GetGraphManager();
448         return (manager ? manager->GetPort(myport)->UnTie() : -1);
449     }
450 }
451
452 EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port)
453 {
454 #ifdef __CLIENTDEBUG__
455     JackLibGlobals::CheckContext();
456 #endif
457     jack_port_id_t myport = (jack_port_id_t)port;
458     if (!CheckPort(myport)) {
459         jack_error("jack_port_get_latency called with an incorrect port %ld", myport);
460         return 0;
461     } else {
462         WaitGraphChange();
463         JackGraphManager* manager = GetGraphManager();
464         return (manager ? manager->GetPort(myport)->GetLatency() : 0);
465     }
466 }
467
468 EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames)
469 {
470 #ifdef __CLIENTDEBUG__
471     JackLibGlobals::CheckContext();
472 #endif
473     jack_port_id_t myport = (jack_port_id_t)port;
474     if (!CheckPort(myport)) {
475         jack_error("jack_port_set_latency called with an incorrect port %ld", myport);
476     } else {
477         JackGraphManager* manager = GetGraphManager();
478         if (manager)
479             manager->GetPort(myport)->SetLatency(frames);
480     }
481 }
482
483 EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port)
484 {
485 #ifdef __CLIENTDEBUG__
486     JackLibGlobals::CheckContext();
487 #endif
488
489     JackClient* client = (JackClient*)ext_client;
490     jack_port_id_t myport = (jack_port_id_t)port;
491     if (client == NULL) {
492         jack_error("jack_recompute_total_latencies called with a NULL client");
493         return -1;
494     } else if (!CheckPort(myport)) {
495         jack_error("jack_recompute_total_latencies called with a NULL port");
496         return -1;
497     } else {
498         WaitGraphChange();
499         JackGraphManager* manager = GetGraphManager();
500         return (manager ? manager->ComputeTotalLatency(myport) : -1);
501     }
502 }
503
504 EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client)
505 {
506 #ifdef __CLIENTDEBUG__
507     JackLibGlobals::CheckContext();
508 #endif
509
510     JackClient* client = (JackClient*)ext_client;
511     if (client == NULL) {
512         jack_error("jack_recompute_total_latencies called with a NULL client");
513         return -1;
514     } else {
515         WaitGraphChange();
516         JackGraphManager* manager = GetGraphManager();
517         return (manager ? manager->ComputeTotalLatencies() : -1);
518     }
519 }
520
521 EXPORT int jack_port_set_name(jack_port_t* port, const char* name)
522 {
523 #ifdef __CLIENTDEBUG__
524     JackLibGlobals::CheckContext();
525 #endif
526     jack_port_id_t myport = (jack_port_id_t)port;
527     if (!CheckPort(myport)) {
528         jack_error("jack_port_set_name called with an incorrect port %ld", myport);
529         return -1;
530     } else if (name == NULL) {
531         jack_error("jack_port_set_name called with a NULL port name");
532         return -1;
533     } else {
534         JackGraphManager* manager = GetGraphManager();
535         return (manager ? manager->GetPort(myport)->SetName(name) : -1);
536     }
537 }
538
539 EXPORT int jack_port_set_alias(jack_port_t* port, const char* name)
540 {
541 #ifdef __CLIENTDEBUG__
542     JackLibGlobals::CheckContext();
543 #endif
544     jack_port_id_t myport = (jack_port_id_t)port;
545     if (!CheckPort(myport)) {
546         jack_error("jack_port_set_alias called with an incorrect port %ld", myport);
547         return -1;
548     } else if (name == NULL) {
549         jack_error("jack_port_set_alias called with a NULL port name");
550         return -1;
551     } else {
552         JackGraphManager* manager = GetGraphManager();
553         return (manager ? manager->GetPort(myport)->SetAlias(name) : -1);
554     }
555 }
556
557 EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name)
558 {
559 #ifdef __CLIENTDEBUG__
560     JackLibGlobals::CheckContext();
561 #endif
562     jack_port_id_t myport = (jack_port_id_t)port;
563     if (!CheckPort(myport)) {
564         jack_error("jack_port_unset_alias called with an incorrect port %ld", myport);
565         return -1;
566     } else if (name == NULL) {
567         jack_error("jack_port_unset_alias called with a NULL port name");
568         return -1;
569     } else {
570         JackGraphManager* manager = GetGraphManager();
571         return (manager ? manager->GetPort(myport)->UnsetAlias(name) : -1);
572     }
573 }
574
575 EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2])
576 {
577 #ifdef __CLIENTDEBUG__
578     JackLibGlobals::CheckContext();
579 #endif
580     jack_port_id_t myport = (jack_port_id_t)port;
581     if (!CheckPort(myport)) {
582         jack_error("jack_port_get_aliases called with an incorrect port %ld", myport);
583         return -1;
584     } else {
585         JackGraphManager* manager = GetGraphManager();
586         return (manager ? manager->GetPort(myport)->GetAliases(aliases) : -1);
587     }
588 }
589
590 EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff)
591 {
592 #ifdef __CLIENTDEBUG__
593     JackLibGlobals::CheckContext();
594 #endif
595     jack_port_id_t myport = (jack_port_id_t)port;
596     if (!CheckPort(myport)) {
597         jack_error("jack_port_request_monitor called with an incorrect port %ld", myport);
598         return -1;
599     } else {
600         JackGraphManager* manager = GetGraphManager();
601         return (manager ? manager->RequestMonitor(myport, onoff) : -1);
602     }
603 }
604
605 EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff)
606 {
607 #ifdef __CLIENTDEBUG__
608     JackLibGlobals::CheckContext();
609 #endif
610     JackClient* client = (JackClient*)ext_client;
611     if (client == NULL) {
612         jack_error("jack_port_request_monitor_by_name called with a NULL client");
613         return -1;
614     } else {
615         JackGraphManager* manager = GetGraphManager();
616         if (!manager)
617             return -1;
618         jack_port_id_t myport = manager->GetPort(port_name);
619         if (!CheckPort(myport)) {
620             jack_error("jack_port_request_monitor_by_name called with an incorrect port %s", port_name);
621             return -1;
622         } else {
623             return manager->RequestMonitor(myport, onoff);
624         }
625     }
626 }
627
628 EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff)
629 {
630 #ifdef __CLIENTDEBUG__
631     JackLibGlobals::CheckContext();
632 #endif
633     jack_port_id_t myport = (jack_port_id_t)port;
634     if (!CheckPort(myport)) {
635         jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport);
636         return -1;
637     } else {
638         JackGraphManager* manager = GetGraphManager();
639         return (manager ? manager->GetPort(myport)->EnsureMonitor(onoff) : -1);
640     }
641 }
642
643 EXPORT int jack_port_monitoring_input(jack_port_t* port)
644 {
645 #ifdef __CLIENTDEBUG__
646     JackLibGlobals::CheckContext();
647 #endif
648     jack_port_id_t myport = (jack_port_id_t)port;
649     if (!CheckPort(myport)) {
650         jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport);
651         return -1;
652     } else {
653         JackGraphManager* manager = GetGraphManager();
654         return (manager ? manager->GetPort(myport)->MonitoringInput() : -1);
655     }
656 }
657
658 EXPORT int jack_is_realtime(jack_client_t* ext_client)
659 {
660 #ifdef __CLIENTDEBUG__
661     JackLibGlobals::CheckContext();
662 #endif
663     JackClient* client = (JackClient*)ext_client;
664     if (client == NULL) {
665         jack_error("jack_is_realtime called with a NULL client");
666         return -1;
667     } else {
668         JackEngineControl* control = GetEngineControl();
669         return (control ? control->fRealTime : -1);
670     }
671 }
672
673 EXPORT void jack_on_shutdown(jack_client_t* ext_client, void (*function)(void* arg), void* arg)
674 {
675 #ifdef __CLIENTDEBUG__
676     JackLibGlobals::CheckContext();
677 #endif
678     JackClient* client = (JackClient*)ext_client;
679     if (client == NULL) {
680         jack_error("jack_on_shutdown called with a NULL client");
681     } else {
682         client->OnShutdown(function, arg);
683     }
684 }
685
686 EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg)
687 {
688 #ifdef __CLIENTDEBUG__
689     JackLibGlobals::CheckContext();
690 #endif
691     JackClient* client = (JackClient*)ext_client;
692     if (client == NULL) {
693         jack_error("jack_set_process_callback called with a NULL client");
694         return -1;
695     } else {
696         return client->SetProcessCallback(callback, arg);
697     }
698 }
699
700 EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status)
701 {
702 #ifdef __CLIENTDEBUG__
703     JackLibGlobals::CheckContext();
704 #endif
705     JackClient* client = (JackClient*)ext_client;
706     if (client == NULL) {
707         jack_error("jack_thread_wait called with a NULL client");
708         return 0;
709     } else {
710         return client->Wait(status);
711     }
712 }
713
714 EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client)
715 {
716 #ifdef __CLIENTDEBUG__
717     JackLibGlobals::CheckContext();
718 #endif
719     JackClient* client = (JackClient*)ext_client;
720     if (client == NULL) {
721         jack_error("jack_cycle_wait called with a NULL client");
722         return 0;
723     } else {
724         return client->CycleWait();
725     }
726 }
727
728 EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status)
729 {
730 #ifdef __CLIENTDEBUG__
731     JackLibGlobals::CheckContext();
732 #endif
733     JackClient* client = (JackClient*)ext_client;
734     if (client == NULL) {
735         jack_error("jack_cycle_signal called with a NULL client");
736     } else {
737         client->CycleSignal(status);
738     }
739 }
740
741 EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback fun, void *arg)
742 {
743 #ifdef __CLIENTDEBUG__
744     JackLibGlobals::CheckContext();
745 #endif
746     JackClient* client = (JackClient*)ext_client;
747     if (client == NULL) {
748         jack_error("jack_set_process_thread called with a NULL client");
749         return -1;
750     } else {
751         return client->SetProcessThread(fun, arg);
752     }
753 }
754
755 EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg)
756 {
757 #ifdef __CLIENTDEBUG__
758     JackLibGlobals::CheckContext();
759 #endif
760     JackClient* client = (JackClient*)ext_client;
761     if (client == NULL) {
762         jack_error("jack_set_freewheel_callback called with a NULL client");
763         return -1;
764     } else {
765         return client->SetFreewheelCallback(freewheel_callback, arg);
766     }
767 }
768
769 EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff)
770 {
771 #ifdef __CLIENTDEBUG__
772     JackLibGlobals::CheckContext();
773 #endif
774     JackClient* client = (JackClient*)ext_client;
775     if (client == NULL) {
776         jack_error("jack_set_freewheel called with a NULL client");
777         return -1;
778     } else {
779         return client->SetFreeWheel(onoff);
780     }
781 }
782
783 EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size)
784 {
785 #ifdef __CLIENTDEBUG__
786     JackLibGlobals::CheckContext();
787 #endif
788     JackClient* client = (JackClient*)ext_client;
789     if (client == NULL) {
790         jack_error("jack_set_buffer_size called with a NULL client");
791         return -1;
792     } else if (!CheckBufferSize(buffer_size)) {
793         return -1;
794     } else {
795         return client->SetBufferSize(buffer_size);
796     }
797 }
798
799 EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg)
800 {
801 #ifdef __CLIENTDEBUG__
802     JackLibGlobals::CheckContext();
803 #endif
804     JackClient* client = (JackClient*)ext_client;
805     if (client == NULL) {
806         jack_error("jack_set_buffer_size_callback called with a NULL client");
807         return -1;
808     } else {
809         return client->SetBufferSizeCallback(bufsize_callback, arg);
810     }
811 }
812
813 EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg)
814 {
815 #ifdef __CLIENTDEBUG__
816     JackLibGlobals::CheckContext();
817 #endif
818     JackClient* client = (JackClient*)ext_client;
819     if (client == NULL) {
820         jack_error("jack_set_sample_rate_callback called with a NULL client");
821         return -1;
822     } else {
823         jack_error("jack_set_sample_rate_callback: deprecated");
824         return 0;
825     }
826 }
827
828 EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, JackClientRegistrationCallback registration_callback, void* arg)
829 {
830 #ifdef __CLIENTDEBUG__
831     JackLibGlobals::CheckContext();
832 #endif
833     JackClient* client = (JackClient*)ext_client;
834     if (client == NULL) {
835         jack_error("jack_set_client_registration_callback called with a NULL client");
836         return -1;
837     } else {
838         return client->SetClientRegistrationCallback(registration_callback, arg);
839     }
840 }
841
842 EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg)
843 {
844 #ifdef __CLIENTDEBUG__
845     JackLibGlobals::CheckContext();
846 #endif
847     JackClient* client = (JackClient*)ext_client;
848     if (client == NULL) {
849         jack_error("jack_set_port_registration_callback called with a NULL client");
850         return -1;
851     } else {
852         return client->SetPortRegistrationCallback(registration_callback, arg);
853     }
854 }
855
856 EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortConnectCallback portconnect_callback, void* arg)
857 {
858 #ifdef __CLIENTDEBUG__
859     JackLibGlobals::CheckContext();
860 #endif
861     JackClient* client = (JackClient*)ext_client;
862     if (client == NULL) {
863         jack_error("jack_set_port_connect_callback called with a NULL client");
864         return -1;
865     } else {
866         return client->SetPortConnectCallback(portconnect_callback, arg);
867     }
868 }
869
870 EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrderCallback graph_callback, void* arg)
871 {
872 #ifdef __CLIENTDEBUG__
873     JackLibGlobals::CheckContext();
874 #endif
875     JackClient* client = (JackClient*)ext_client;
876     jack_log("jack_set_graph_order_callback ext_client %x client %x ", ext_client, client);
877     if (client == NULL) {
878         jack_error("jack_set_graph_order_callback called with a NULL client");
879         return -1;
880     } else {
881         return client->SetGraphOrderCallback(graph_callback, arg);
882     }
883 }
884
885 EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xrun_callback, void* arg)
886 {
887 #ifdef __CLIENTDEBUG__
888     JackLibGlobals::CheckContext();
889 #endif
890     JackClient* client = (JackClient*)ext_client;
891     if (client == NULL) {
892         jack_error("jack_set_xrun_callback called with a NULL client");
893         return -1;
894     } else {
895         return client->SetXRunCallback(xrun_callback, arg);
896     }
897 }
898
899 EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg)
900 {
901 #ifdef __CLIENTDEBUG__
902     JackLibGlobals::CheckContext();
903 #endif
904     JackClient* client = (JackClient*)ext_client;
905     jack_log("jack_set_thread_init_callback ext_client %x client %x ", ext_client, client);
906     if (client == NULL) {
907         jack_error("jack_set_thread_init_callback called with a NULL client");
908         return -1;
909     } else {
910         return client->SetInitCallback(init_callback, arg);
911     }
912 }
913
914 EXPORT int jack_activate(jack_client_t* ext_client)
915 {
916 #ifdef __CLIENTDEBUG__
917     JackLibGlobals::CheckContext();
918 #endif
919     JackClient* client = (JackClient*)ext_client;
920     if (client == NULL) {
921         jack_error("jack_activate called with a NULL client");
922         return -1;
923     } else {
924         return client->Activate();
925     }
926 }
927
928 EXPORT int jack_deactivate(jack_client_t* ext_client)
929 {
930 #ifdef __CLIENTDEBUG__
931     JackLibGlobals::CheckContext();
932 #endif
933     JackClient* client = (JackClient*)ext_client;
934     if (client == NULL) {
935         jack_error("jack_deactivate called with a NULL client");
936         return -1;
937     } else {
938         return client->Deactivate();
939     }
940 }
941
942 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)
943 {
944 #ifdef __CLIENTDEBUG__
945     JackLibGlobals::CheckContext();
946 #endif
947     JackClient* client = (JackClient*)ext_client;
948     if (client == NULL) {
949         jack_error("jack_port_register called with a NULL client");
950         return NULL;
951     } else if ((port_name == NULL) || (port_type == NULL)) {
952         jack_error("jack_port_register called with a NULL port name or a NULL port_type");
953         return NULL;
954     } else {
955         return (jack_port_t *)client->PortRegister(port_name, port_type, flags, buffer_size);
956     }
957 }
958
959 EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port)
960 {
961 #ifdef __CLIENTDEBUG__
962     JackLibGlobals::CheckContext();
963 #endif
964     JackClient* client = (JackClient*)ext_client;
965     if (client == NULL) {
966         jack_error("jack_port_unregister called with a NULL client");
967         return -1;
968     }
969     jack_port_id_t myport = (jack_port_id_t)port;
970     if (!CheckPort(myport)) {
971         jack_error("jack_port_unregister called with an incorrect port %ld", myport);
972         return -1;
973     }
974     return client->PortUnRegister(myport);
975 }
976
977 EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* port)
978 {
979 #ifdef __CLIENTDEBUG__
980     JackLibGlobals::CheckContext();
981 #endif
982     JackClient* client = (JackClient*)ext_client;
983     if (client == NULL) {
984         jack_error("jack_port_is_mine called with a NULL client");
985         return -1;
986     }
987     jack_port_id_t myport = (jack_port_id_t)port;
988     if (!CheckPort(myport)) {
989         jack_error("jack_port_is_mine called with an incorrect port %ld", myport);
990         return -1;
991     }
992     return client->PortIsMine(myport);
993 }
994
995 EXPORT const char** jack_port_get_connections(const jack_port_t* port)
996 {
997 #ifdef __CLIENTDEBUG__
998     JackLibGlobals::CheckContext();
999 #endif
1000     jack_port_id_t myport = (jack_port_id_t)port;
1001     if (!CheckPort(myport)) {
1002         jack_error("jack_port_get_connections called with an incorrect port %ld", myport);
1003         return NULL;
1004     } else {
1005         WaitGraphChange();
1006         JackGraphManager* manager = GetGraphManager();
1007         return (manager ? manager->GetConnections(myport) : NULL);
1008     }
1009 }
1010
1011 // Calling client does not need to "own" the port
1012 EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_client, const jack_port_t* port)
1013 {
1014 #ifdef __CLIENTDEBUG__
1015     JackLibGlobals::CheckContext();
1016 #endif
1017     JackClient* client = (JackClient*)ext_client;
1018     if (client == NULL) {
1019         jack_error("jack_port_get_all_connections called with a NULL client");
1020         return NULL;
1021     }
1022
1023     jack_port_id_t myport = (jack_port_id_t)port;
1024     if (!CheckPort(myport)) {
1025         jack_error("jack_port_get_all_connections called with an incorrect port %ld", myport);
1026         return NULL;
1027     } else {
1028         WaitGraphChange();
1029         JackGraphManager* manager = GetGraphManager();
1030         return (manager ? manager->GetConnections(myport) : NULL);
1031     }
1032 }
1033
1034 EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jack_port_t* port)
1035 {
1036 #ifdef __CLIENTDEBUG__
1037     JackLibGlobals::CheckContext();
1038 #endif
1039     JackClient* client = (JackClient*)ext_client;
1040     if (client == NULL) {
1041         jack_error("jack_port_get_total_latency called with a NULL client");
1042         return 0;
1043     }
1044
1045     jack_port_id_t myport = (jack_port_id_t)port;
1046     if (!CheckPort(myport)) {
1047         jack_error("jack_port_get_total_latency called with an incorrect port %ld", myport);
1048         return 0;
1049     } else {
1050         WaitGraphChange();
1051         JackGraphManager* manager = GetGraphManager();
1052         if (manager) {
1053             manager->ComputeTotalLatency(myport);
1054             return manager->GetPort(myport)->GetTotalLatency();
1055         } else {
1056             return 0;
1057         }
1058     }
1059 }
1060
1061 EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* dst)
1062 {
1063 #ifdef __CLIENTDEBUG__
1064     JackLibGlobals::CheckContext();
1065 #endif
1066     JackClient* client = (JackClient*)ext_client;
1067     if (client == NULL) {
1068         jack_error("jack_connect called with a NULL client");
1069         return -1;
1070     } else if ((src == NULL) || (dst == NULL)) {
1071         jack_error("jack_connect called with a NULL port name");
1072         return -1;
1073     } else {
1074         return client->PortConnect(src, dst);
1075     }
1076 }
1077
1078 EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const char* dst)
1079 {
1080 #ifdef __CLIENTDEBUG__
1081     JackLibGlobals::CheckContext();
1082 #endif
1083     JackClient* client = (JackClient*)ext_client;
1084     if (client == NULL) {
1085         jack_error("jack_disconnect called with a NULL client");
1086         return -1;
1087     } else if ((src == NULL) || (dst == NULL)) {
1088         jack_error("jack_connect called with a NULL port name");
1089         return -1;
1090     } else {
1091         return client->PortDisconnect(src, dst);
1092     }
1093 }
1094
1095 EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src)
1096 {
1097 #ifdef __CLIENTDEBUG__
1098     JackLibGlobals::CheckContext();
1099 #endif
1100     JackClient* client = (JackClient*)ext_client;
1101     if (client == NULL) {
1102         jack_error("jack_port_disconnect called with a NULL client");
1103         return -1;
1104     }
1105     jack_port_id_t myport = (jack_port_id_t)src;
1106     if (!CheckPort(myport)) {
1107         jack_error("jack_port_disconnect called with an incorrect port %ld", myport);
1108         return -1;
1109     }
1110     return client->PortDisconnect(myport);
1111 }
1112
1113 EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client)
1114 {
1115 #ifdef __CLIENTDEBUG__
1116     JackLibGlobals::CheckContext();
1117 #endif
1118     JackClient* client = (JackClient*)ext_client;
1119     if (client == NULL) {
1120         jack_error("jack_get_sample_rate called with a NULL client");
1121         return 0;
1122     } else {
1123         JackEngineControl* control = GetEngineControl();
1124         return (control ? control->fSampleRate : 0);
1125     }
1126 }
1127
1128 EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client)
1129 {
1130 #ifdef __CLIENTDEBUG__
1131     JackLibGlobals::CheckContext();
1132 #endif
1133     JackClient* client = (JackClient*)ext_client;
1134     if (client == NULL) {
1135         jack_error("jack_get_buffer_size called with a NULL client");
1136         return 0;
1137     } else {
1138         JackEngineControl* control = GetEngineControl();
1139         return (control ? control->fBufferSize : 0);
1140     }
1141 }
1142
1143 EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
1144 {
1145 #ifdef __CLIENTDEBUG__
1146     JackLibGlobals::CheckContext();
1147 #endif
1148     JackClient* client = (JackClient*)ext_client;
1149     if (client == NULL) {
1150         jack_error("jack_get_ports called with a NULL client");
1151         return NULL;
1152     }
1153     JackGraphManager* manager = GetGraphManager();
1154     return (manager ? manager->GetPorts(port_name_pattern, type_name_pattern, flags) : NULL);
1155 }
1156
1157 EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* portname)
1158 {
1159 #ifdef __CLIENTDEBUG__
1160     JackLibGlobals::CheckContext();
1161 #endif
1162     JackClient* client = (JackClient*)ext_client;
1163     if (client == NULL) {
1164         jack_error("jack_get_ports called with a NULL client");
1165         return 0;
1166     }
1167
1168     if (portname == NULL) {
1169         jack_error("jack_port_by_name called with a NULL port name");
1170         return NULL;
1171     } else {
1172         JackGraphManager* manager = GetGraphManager();
1173         if (!manager)
1174             return NULL;
1175         int res = manager->GetPort(portname); // returns a port index at least > 1
1176         return (res == NO_PORT) ? NULL : (jack_port_t*)res;
1177     }
1178 }
1179
1180 EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id)
1181 {
1182 #ifdef __CLIENTDEBUG__
1183     JackLibGlobals::CheckContext();
1184 #endif
1185     /* jack_port_t* type is actually the port index */
1186     return (jack_port_t*)id;
1187 }
1188
1189 EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client)
1190 {
1191 #ifdef __CLIENTDEBUG__
1192     JackLibGlobals::CheckContext();
1193 #endif
1194     JackClient* client = (JackClient*)ext_client;
1195     if (client == NULL) {
1196         jack_error("jack_engine_takeover_timebase called with a NULL client");
1197         return -1;
1198     } else {
1199         jack_error("jack_engine_takeover_timebase: deprecated\n");
1200         return 0;
1201     }
1202 }
1203
1204 EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_client)
1205 {
1206 #ifdef __CLIENTDEBUG__
1207     JackLibGlobals::CheckContext();
1208 #endif
1209     JackTimer timer;
1210     JackEngineControl* control = GetEngineControl();
1211     if (!control)
1212         return 0;
1213     control->ReadFrameTime(&timer);
1214     return (jack_nframes_t) floor((((float)control->fSampleRate) / 1000000.0f) * (GetMicroSeconds() - timer.fCurrentCallback));
1215 }
1216
1217 EXPORT jack_time_t jack_get_time()
1218 {
1219     return GetMicroSeconds();
1220 }
1221
1222 EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nframes_t frames)
1223 {
1224 #ifdef __CLIENTDEBUG__
1225     JackLibGlobals::CheckContext();
1226 #endif
1227     JackClient* client = (JackClient*)ext_client;
1228     if (client == NULL) {
1229         jack_error("jack_frames_to_time called with a NULL client");
1230         return 0;
1231     } else {
1232         JackTimer timer;
1233         JackEngineControl* control = GetEngineControl();
1234         if (!control)
1235             return 0;
1236         control->ReadFrameTime(&timer);
1237         if (timer.fInitialized) {
1238             return timer.fCurrentWakeup +
1239                    (long) rint(((double) ((frames - timer.fFrames)) *
1240                                 ((jack_time_t)(timer.fNextWakeUp - timer.fCurrentWakeup))) / control->fBufferSize);
1241         } else {
1242             return 0;
1243         }
1244     }
1245 }
1246
1247 EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_time_t time)
1248 {
1249 #ifdef __CLIENTDEBUG__
1250     JackLibGlobals::CheckContext();
1251 #endif
1252     JackClient* client = (JackClient*)ext_client;
1253     if (client == NULL) {
1254         jack_error("jack_time_to_frames called with a NULL client");
1255         return 0;
1256     } else {
1257         JackTimer timer;
1258         JackEngineControl* control = GetEngineControl();
1259         if (!control)
1260             return 0;
1261         control->ReadFrameTime(&timer);
1262         if (timer.fInitialized) {
1263             return timer.fFrames +
1264                    (long) rint(((double) ((time - timer.fCurrentWakeup)) /
1265                                 ((jack_time_t)(timer.fNextWakeUp - timer.fCurrentWakeup))) * control->fBufferSize);
1266         } else {
1267             return 0;
1268         }
1269     }
1270 }
1271
1272 EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client)
1273 {
1274     return jack_time_to_frames(ext_client, GetMicroSeconds());
1275 }
1276
1277 EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client)
1278 {
1279 #ifdef __CLIENTDEBUG__
1280     JackLibGlobals::CheckContext();
1281 #endif
1282     JackTimer timer;
1283     JackEngineControl* control = GetEngineControl();
1284     if (control) {
1285         control->ReadFrameTime(&timer);
1286         return timer.fFrames;
1287     } else {
1288         return 0;
1289     }
1290 }
1291
1292 EXPORT float jack_cpu_load(jack_client_t* ext_client)
1293 {
1294 #ifdef __CLIENTDEBUG__
1295     JackLibGlobals::CheckContext();
1296 #endif
1297     JackClient* client = (JackClient*)ext_client;
1298     if (client == NULL) {
1299         jack_error("jack_cpu_load called with a NULL client");
1300         return 0.0f;
1301     } else {
1302         JackEngineControl* control = GetEngineControl();
1303         return (control ? control->fCPULoad :  0.0f);
1304     }
1305 }
1306
1307 EXPORT pthread_t jack_client_thread_id(jack_client_t* ext_client)
1308 {
1309 #ifdef __CLIENTDEBUG__
1310     JackLibGlobals::CheckContext();
1311 #endif
1312     JackClient* client = (JackClient*)ext_client;
1313     if (client == NULL) {
1314         jack_error("jack_client_thread_id called with a NULL client");
1315         return (pthread_t)NULL;
1316     } else {
1317         return client->GetThreadID();
1318     }
1319 }
1320
1321 EXPORT char* jack_get_client_name (jack_client_t* ext_client)
1322 {
1323 #ifdef __CLIENTDEBUG__
1324     JackLibGlobals::CheckContext();
1325 #endif
1326     JackClient* client = (JackClient*)ext_client;
1327     if (client == NULL) {
1328         jack_error("jack_get_client_name called with a NULL client");
1329         return NULL;
1330     } else {
1331         return client->GetClientControl()->fName;
1332     }
1333 }
1334
1335 EXPORT int jack_client_name_size(void)
1336 {
1337     return JACK_CLIENT_NAME_SIZE;
1338 }
1339
1340 EXPORT int jack_port_name_size(void)
1341 {
1342     return JACK_PORT_NAME_SIZE;
1343 }
1344
1345 EXPORT int jack_port_type_size(void)
1346 {
1347     return JACK_PORT_TYPE_SIZE;
1348 }
1349
1350 // transport.h
1351 EXPORT int jack_release_timebase(jack_client_t* ext_client)
1352 {
1353 #ifdef __CLIENTDEBUG__
1354     JackLibGlobals::CheckContext();
1355 #endif
1356     JackClient* client = (JackClient*)ext_client;
1357     if (client == NULL) {
1358         jack_error("jack_release_timebase called with a NULL client");
1359         return -1;
1360     } else {
1361         return client->ReleaseTimebase();
1362     }
1363 }
1364
1365 EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg)
1366 {
1367 #ifdef __CLIENTDEBUG__
1368     JackLibGlobals::CheckContext();
1369 #endif
1370     JackClient* client = (JackClient*)ext_client;
1371     if (client == NULL) {
1372         jack_error("jack_set_sync_callback called with a NULL client");
1373         return -1;
1374     } else {
1375         return client->SetSyncCallback(sync_callback, arg);
1376     }
1377 }
1378
1379 EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout)
1380 {
1381 #ifdef __CLIENTDEBUG__
1382     JackLibGlobals::CheckContext();
1383 #endif
1384     JackClient* client = (JackClient*)ext_client;
1385     if (client == NULL) {
1386         jack_error("jack_set_sync_timeout called with a NULL client");
1387         return -1;
1388     } else {
1389         return client->SetSyncTimeout(timeout);
1390     }
1391 }
1392
1393 EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg)
1394 {
1395 #ifdef __CLIENTDEBUG__
1396     JackLibGlobals::CheckContext();
1397 #endif
1398     JackClient* client = (JackClient*)ext_client;
1399     if (client == NULL) {
1400         jack_error("jack_set_timebase_callback called with a NULL client");
1401         return -1;
1402     } else {
1403         return client->SetTimebaseCallback(conditional, timebase_callback, arg);
1404     }
1405 }
1406
1407 EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame)
1408 {
1409 #ifdef __CLIENTDEBUG__
1410     JackLibGlobals::CheckContext();
1411 #endif
1412     JackClient* client = (JackClient*)ext_client;
1413     if (client == NULL) {
1414         jack_error("jack_transport_locate called with a NULL client");
1415         return -1;
1416     } else {
1417         return client->TransportLocate(frame);
1418     }
1419 }
1420
1421 EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos)
1422 {
1423 #ifdef __CLIENTDEBUG__
1424     JackLibGlobals::CheckContext();
1425 #endif
1426     JackClient* client = (JackClient*)ext_client;
1427     if (client == NULL) {
1428         jack_error("jack_transport_query called with a NULL client");
1429         return JackTransportStopped;
1430     } else {
1431         return client->TransportQuery(pos);
1432     }
1433 }
1434
1435 EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client)
1436 {
1437 #ifdef __CLIENTDEBUG__
1438     JackLibGlobals::CheckContext();
1439 #endif
1440     JackClient* client = (JackClient*)ext_client;
1441     if (client == NULL) {
1442         jack_error("jack_get_current_transport_frame called with a NULL client");
1443         return 0;
1444     } else {
1445         return client->GetCurrentTransportFrame();
1446     }
1447 }
1448
1449 EXPORT int jack_transport_reposition(jack_client_t* ext_client, jack_position_t* pos)
1450 {
1451 #ifdef __CLIENTDEBUG__
1452     JackLibGlobals::CheckContext();
1453 #endif
1454     JackClient* client = (JackClient*)ext_client;
1455     if (client == NULL) {
1456         jack_error("jack_transport_reposition called with a NULL client");
1457         return -1;
1458     } else {
1459         return client->TransportReposition(pos);
1460     }
1461 }
1462
1463 EXPORT void jack_transport_start(jack_client_t* ext_client)
1464 {
1465 #ifdef __CLIENTDEBUG__
1466     JackLibGlobals::CheckContext();
1467 #endif
1468     JackClient* client = (JackClient*)ext_client;
1469     if (client == NULL) {
1470         jack_error("jack_transport_start called with a NULL client");
1471     } else {
1472         client->TransportStart();
1473     }
1474 }
1475
1476 EXPORT void jack_transport_stop(jack_client_t* ext_client)
1477 {
1478 #ifdef __CLIENTDEBUG__
1479     JackLibGlobals::CheckContext();
1480 #endif
1481     JackClient* client = (JackClient*)ext_client;
1482     if (client == NULL) {
1483         jack_error("jack_transport_stop called with a NULL client");
1484     } else {
1485         client->TransportStop();
1486     }
1487 }
1488
1489 // deprecated
1490 EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
1491 {
1492     jack_error("jack_get_transport_info: deprecated");
1493     if (tinfo)
1494         memset(tinfo, 0, sizeof(jack_transport_info_t));
1495 }
1496
1497 EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
1498 {
1499     jack_error("jack_set_transport_info: deprecated");
1500     if (tinfo)
1501         memset(tinfo, 0, sizeof(jack_transport_info_t));
1502 }
1503
1504 // statistics.h
1505 EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client)
1506 {
1507 #ifdef __CLIENTDEBUG__
1508     JackLibGlobals::CheckContext();
1509 #endif
1510     jack_log("jack_get_max_delayed_usecs: not yet implemented");
1511     return 0.f;
1512 }
1513
1514 EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client)
1515 {
1516 #ifdef __CLIENTDEBUG__
1517     JackLibGlobals::CheckContext();
1518 #endif
1519     jack_log("jack_get_xrun_delayed_usecs: not yet implemented");
1520     return 0.f;
1521 }
1522
1523 EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client)
1524 {
1525 #ifdef __CLIENTDEBUG__
1526     JackLibGlobals::CheckContext();
1527 #endif
1528     jack_log("jack_reset_max_delayed_usecs: not yet implemented");
1529 }
1530
1531 // thread.h
1532 EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority)
1533 {
1534 #ifdef __APPLE__
1535     JackEngineControl* control = GetEngineControl();
1536     return (control ? JackMachThread::AcquireRealTimeImp(thread, GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint) : -1);
1537 #elif WIN32
1538     return JackWinThread::AcquireRealTimeImp(thread, priority);
1539 #else
1540     return JackPosixThread::AcquireRealTimeImp(thread, priority);
1541 #endif
1542 }
1543
1544 EXPORT int jack_client_create_thread(jack_client_t* client,
1545                                      pthread_t *thread,
1546                                      int priority,
1547                                      int realtime,      /* boolean */
1548                                      void *(*start_routine)(void*),
1549                                      void *arg)
1550 {
1551 #ifdef __APPLE__
1552     return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg);
1553 #elif WIN32
1554     return JackWinThread::StartImp(thread, priority, realtime, (ThreadCallback)start_routine, arg);
1555 #else
1556     return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg);
1557 #endif
1558 }
1559
1560 EXPORT int jack_drop_real_time_scheduling(pthread_t thread)
1561 {
1562 #ifdef __APPLE__
1563     return JackMachThread::DropRealTimeImp(thread);
1564 #elif WIN32
1565     return JackWinThread::DropRealTimeImp(thread);
1566 #else
1567     return JackPosixThread::DropRealTimeImp(thread);
1568 #endif
1569 }
1570
1571 // intclient.h
1572 EXPORT int jack_internal_client_new (const char *client_name,
1573                                      const char *load_name,
1574                                      const char *load_init)
1575 {
1576     jack_error("jack_internal_client_new: deprecated");
1577     return -1;
1578 }
1579
1580 EXPORT void jack_internal_client_close (const char *client_name)
1581 {
1582     jack_error("jack_internal_client_close: deprecated");
1583 }
1584
1585 EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient)
1586 {
1587 #ifdef __CLIENTDEBUG__
1588     JackLibGlobals::CheckContext();
1589 #endif
1590     JackClient* client = (JackClient*)ext_client;
1591     if (client == NULL) {
1592         jack_error("jack_get_internal_client_name called with a NULL client");
1593         return NULL;
1594     } else if (intclient < 0 || intclient >= CLIENT_NUM) {
1595         jack_error("jack_get_internal_client_name: incorrect client");
1596         return NULL;
1597     } else {
1598         return client->GetInternalClientName(intclient);
1599     }
1600 }
1601
1602 EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, const char* client_name, jack_status_t* status)
1603 {
1604 #ifdef __CLIENTDEBUG__
1605     JackLibGlobals::CheckContext();
1606 #endif
1607     JackClient* client = (JackClient*)ext_client;
1608     if (client == NULL) {
1609         jack_error("jack_internal_client_handle called with a NULL client");
1610         return 0;
1611     } else {
1612         jack_status_t my_status;
1613         if (status == NULL)             /* no status from caller? */
1614             status = &my_status;        /* use local status word */
1615         *status = (jack_status_t)0;
1616         return client->InternalClientHandle(client_name, status);
1617     }
1618 }
1619
1620 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)
1621 {
1622 #ifdef __CLIENTDEBUG__
1623     JackLibGlobals::CheckContext();
1624 #endif
1625     JackClient* client = (JackClient*)ext_client;
1626     if (client == NULL) {
1627         jack_error("jack_internal_client_load called with a NULL client");
1628         return 0;
1629     } else {
1630         jack_varargs_t va;
1631         jack_status_t my_status;
1632
1633         if (status == NULL)                     /* no status from caller? */
1634             status = &my_status;        /* use local status word */
1635         *status = (jack_status_t)0;
1636
1637         /* validate parameters */
1638         if ((options & ~JackLoadOptions)) {
1639             int my_status1 = *status | (JackFailure | JackInvalidOption);
1640             *status = (jack_status_t)my_status1;
1641             return 0;
1642         }
1643
1644         /* parse variable arguments */
1645         jack_varargs_parse(options, ap, &va);
1646         return client->InternalClientLoad(client_name, options, status, &va);
1647     }
1648 }
1649
1650 EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const char *client_name, jack_options_t options, jack_status_t *status, ...)
1651 {
1652     va_list ap;
1653     va_start(ap, status);
1654     jack_intclient_t res = jack_internal_client_load_aux(client, client_name, options, status, ap);
1655     va_end(ap);
1656     return res;
1657 }
1658
1659 EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack_intclient_t intclient)
1660 {
1661 #ifdef __CLIENTDEBUG__
1662     JackLibGlobals::CheckContext();
1663 #endif
1664     JackClient* client = (JackClient*)ext_client;
1665     if (client == NULL) {
1666         jack_error("jack_internal_client_unload called with a NULL client");
1667         return (jack_status_t)(JackNoSuchClient | JackFailure);
1668     } else if (intclient < 0 || intclient >= CLIENT_NUM) {
1669         jack_error("jack_internal_client_unload: incorrect client");
1670         return (jack_status_t)(JackNoSuchClient | JackFailure);
1671     } else {
1672         jack_status_t my_status;
1673         client->InternalClientUnload(intclient, &my_status);
1674         return my_status;
1675     }
1676 }
Note: See TracBrowser for help on using the browser.