JackAPI.cpp 61.5 KB
Newer Older
sletz's avatar
sletz committed
1
2
/*
Copyright (C) 2001-2003 Paul Davis
sletz's avatar
sletz committed
3
Copyright (C) 2004-2008 Grame
sletz's avatar
sletz committed
4
5

This program is free software; you can redistribute it and/or modify
sletz's avatar
sletz committed
6
7
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
sletz's avatar
sletz committed
8
9
10
11
12
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
sletz's avatar
sletz committed
13
GNU Lesser General Public License for more details.
sletz's avatar
sletz committed
14

sletz's avatar
sletz committed
15
You should have received a copy of the GNU Lesser General Public License
sletz's avatar
sletz committed
16
along with this program; if not, write to the Free Software
sletz's avatar
sletz committed
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
sletz's avatar
sletz committed
18
19
20
21
22
23
24
25
26
27

*/

#include "JackClient.h"
#include "JackError.h"
#include "JackGraphManager.h"
#include "JackEngineControl.h"
#include "JackClientControl.h"
#include "JackGlobals.h"
#include "JackTime.h"
28
#include "JackCompilerDeps.h"
sletz's avatar
sletz committed
29
#include "JackPortType.h"
sletz's avatar
sletz committed
30
#include "JackPlatformPlug.h"
sletz's avatar
sletz committed
31
32
#include <math.h>

33
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
34
#include "JackLibGlobals.h"
35
36
#endif

sletz's avatar
sletz committed
37
38
39
40
41
42
43
using namespace Jack;

#ifdef __cplusplus
extern "C"
{
#endif

44
45
46
    typedef void (*print_function)(const char *);
    typedef void *(*thread_routine)(void*);

sletz's avatar
sletz committed
47
48
49
50
51
52
53
54
55
56
57
58
    EXPORT
    void
    jack_get_version(
        int *major_ptr,
        int *minor_ptr,
        int *micro_ptr,
        int *proto_ptr);

    EXPORT
    const char *
    jack_get_version_string();

59
    EXPORT jack_client_t * jack_client_open_aux (const char *client_name,
60
            jack_options_t options,
61
            jack_status_t *status, va_list ap);
62
    EXPORT jack_client_t * jack_client_open (const char *client_name,
sletz's avatar
Cleanup    
sletz committed
63
64
65
            jack_options_t options,
            jack_status_t *status, ...);
    EXPORT jack_client_t * jack_client_new (const char *client_name);
sletz's avatar
sletz committed
66
    EXPORT int jack_client_name_size (void);
sletz's avatar
sletz committed
67
68
69
70
71
    EXPORT char* jack_get_client_name (jack_client_t *client);
    EXPORT int jack_internal_client_new (const char *client_name,
                                         const char *load_name,
                                         const char *load_init);
    EXPORT void jack_internal_client_close (const char *client_name);
sletz's avatar
sletz committed
72
    EXPORT int jack_is_realtime (jack_client_t *client);
sletz's avatar
sletz committed
73
    EXPORT void jack_on_shutdown (jack_client_t *client,
74
                                  JackShutdownCallback shutdown_callback, void *arg);
sletz's avatar
sletz committed
75
76
77
    EXPORT int jack_set_process_callback (jack_client_t *client,
                                          JackProcessCallback process_callback,
                                          void *arg);
78
    EXPORT jack_nframes_t jack_thread_wait(jack_client_t *client, int status);
sletz's avatar
sletz committed
79
80
81
82
83
84
85

    // new
    EXPORT jack_nframes_t jack_cycle_wait (jack_client_t*);
    EXPORT void jack_cycle_signal (jack_client_t*, int status);
    EXPORT int jack_set_process_thread(jack_client_t* client, JackThreadCallback fun, void *arg);

    EXPORT int jack_set_thread_init_callback (jack_client_t *client,
sletz's avatar
sletz committed
86
87
88
89
90
91
92
93
94
95
96
97
98
            JackThreadInitCallback thread_init_callback,
            void *arg);
    EXPORT int jack_set_freewheel_callback (jack_client_t *client,
                                            JackFreewheelCallback freewheel_callback,
                                            void *arg);
    EXPORT int jack_set_freewheel(jack_client_t* client, int onoff);
    EXPORT int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes);
    EXPORT int jack_set_buffer_size_callback (jack_client_t *client,
            JackBufferSizeCallback bufsize_callback,
            void *arg);
    EXPORT int jack_set_sample_rate_callback (jack_client_t *client,
            JackSampleRateCallback srate_callback,
            void *arg);
sletz's avatar
sletz committed
99
100
101
    EXPORT int jack_set_client_registration_callback (jack_client_t *,
            JackClientRegistrationCallback
            registration_callback, void *arg);
sletz's avatar
sletz committed
102
103
104
    EXPORT int jack_set_port_registration_callback (jack_client_t *,
            JackPortRegistrationCallback
            registration_callback, void *arg);
sletz's avatar
sletz committed
105
106
107
    EXPORT int jack_set_port_connect_callback (jack_client_t *,
            JackPortConnectCallback
            connect_callback, void *arg);
108
109
110
    EXPORT int jack_set_port_rename_callback (jack_client_t *,
				    JackPortRenameCallback
				    rename_callback, void *arg);
sletz's avatar
sletz committed
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    EXPORT int jack_set_graph_order_callback (jack_client_t *,
            JackGraphOrderCallback graph_callback,
            void *);
    EXPORT int jack_set_xrun_callback (jack_client_t *,
                                       JackXRunCallback xrun_callback, void *arg);
    EXPORT int jack_activate (jack_client_t *client);
    EXPORT int jack_deactivate (jack_client_t *client);
    EXPORT jack_port_t * jack_port_register (jack_client_t *client,
            const char *port_name,
            const char *port_type,
            unsigned long flags,
            unsigned long buffer_size);
    EXPORT int jack_port_unregister (jack_client_t *, jack_port_t *);
    EXPORT void * jack_port_get_buffer (jack_port_t *, jack_nframes_t);
    EXPORT const char * jack_port_name (const jack_port_t *port);
    EXPORT const char * jack_port_short_name (const jack_port_t *port);
    EXPORT int jack_port_flags (const jack_port_t *port);
    EXPORT const char * jack_port_type (const jack_port_t *port);
sletz's avatar
sletz committed
129
    EXPORT jack_port_type_id_t jack_port_type_id (const jack_port_t *port);
sletz's avatar
sletz committed
130
131
132
133
134
135
136
137
138
139
    EXPORT int jack_port_is_mine (const jack_client_t *, const jack_port_t *port);
    EXPORT int jack_port_connected (const jack_port_t *port);
    EXPORT int jack_port_connected_to (const jack_port_t *port,
                                       const char *port_name);
    EXPORT const char ** jack_port_get_connections (const jack_port_t *port);
    EXPORT const char ** jack_port_get_all_connections (const jack_client_t *client,
            const jack_port_t *port);
    EXPORT int jack_port_tie (jack_port_t *src, jack_port_t *dst);
    EXPORT int jack_port_untie (jack_port_t *port);
    EXPORT jack_nframes_t jack_port_get_latency (jack_port_t *port);
sletz's avatar
sletz committed
140
    EXPORT jack_nframes_t jack_port_get_total_latency (jack_client_t *,
sletz's avatar
sletz committed
141
142
            jack_port_t *port);
    EXPORT void jack_port_set_latency (jack_port_t *, jack_nframes_t);
sletz's avatar
sletz committed
143
    EXPORT int jack_recompute_total_latency (jack_client_t*, jack_port_t* port);
sletz's avatar
sletz committed
144
145
    EXPORT int jack_recompute_total_latencies (jack_client_t*);
    EXPORT int jack_port_set_name (jack_port_t *port, const char *port_name);
sletz's avatar
sletz committed
146
147
148
    EXPORT int jack_port_set_alias (jack_port_t *port, const char *alias);
    EXPORT int jack_port_unset_alias (jack_port_t *port, const char *alias);
    EXPORT int jack_port_get_aliases (const jack_port_t *port, char* const aliases[2]);
sletz's avatar
sletz committed
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
    EXPORT int jack_port_request_monitor (jack_port_t *port, int onoff);
    EXPORT int jack_port_request_monitor_by_name (jack_client_t *client,
            const char *port_name, int onoff);
    EXPORT int jack_port_ensure_monitor (jack_port_t *port, int onoff);
    EXPORT int jack_port_monitoring_input (jack_port_t *port);
    EXPORT int jack_connect (jack_client_t *,
                             const char *source_port,
                             const char *destination_port);
    EXPORT int jack_disconnect (jack_client_t *,
                                const char *source_port,
                                const char *destination_port);
    EXPORT int jack_port_disconnect (jack_client_t *, jack_port_t *);
    EXPORT int jack_port_name_size(void);
    EXPORT int jack_port_type_size(void);
    EXPORT jack_nframes_t jack_get_sample_rate (jack_client_t *);
    EXPORT jack_nframes_t jack_get_buffer_size (jack_client_t *);
    EXPORT const char ** jack_get_ports (jack_client_t *,
                                         const char *port_name_pattern,
                                         const char *type_name_pattern,
                                         unsigned long flags);
    EXPORT jack_port_t * jack_port_by_name (jack_client_t *, const char *port_name);
sletz's avatar
sletz committed
170
    EXPORT jack_port_t * jack_port_by_id (jack_client_t *client,
sletz's avatar
sletz committed
171
172
173
                                          jack_port_id_t port_id);
    EXPORT int jack_engine_takeover_timebase (jack_client_t *);
    EXPORT jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *);
sletz's avatar
sletz committed
174
    EXPORT jack_time_t jack_get_time();
175
176
    EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t time);
    EXPORT jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t frames);
sletz's avatar
sletz committed
177
178
179
180
    EXPORT jack_nframes_t jack_frame_time (const jack_client_t *);
    EXPORT jack_nframes_t jack_last_frame_time (const jack_client_t *client);
    EXPORT float jack_cpu_load (jack_client_t *client);
    EXPORT pthread_t jack_client_thread_id (jack_client_t *);
181
182
    EXPORT void jack_set_error_function (print_function);
    EXPORT void jack_set_info_function (print_function);
sletz's avatar
sletz committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

    EXPORT float jack_get_max_delayed_usecs (jack_client_t *client);
    EXPORT float jack_get_xrun_delayed_usecs (jack_client_t *client);
    EXPORT void jack_reset_max_delayed_usecs (jack_client_t *client);

    EXPORT int jack_release_timebase (jack_client_t *client);
    EXPORT int jack_set_sync_callback (jack_client_t *client,
                                       JackSyncCallback sync_callback,
                                       void *arg);
    EXPORT int jack_set_sync_timeout (jack_client_t *client,
                                      jack_time_t timeout);
    EXPORT int jack_set_timebase_callback (jack_client_t *client,
                                           int conditional,
                                           JackTimebaseCallback timebase_callback,
                                           void *arg);
    EXPORT int jack_transport_locate (jack_client_t *client,
                                      jack_nframes_t frame);
    EXPORT jack_transport_state_t jack_transport_query (const jack_client_t *client,
            jack_position_t *pos);
    EXPORT jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client);
    EXPORT int jack_transport_reposition (jack_client_t *client,
                                          jack_position_t *pos);
    EXPORT void jack_transport_start (jack_client_t *client);
    EXPORT void jack_transport_stop (jack_client_t *client);
    EXPORT void jack_get_transport_info (jack_client_t *client,
                                         jack_transport_info_t *tinfo);
    EXPORT void jack_set_transport_info (jack_client_t *client,
                                         jack_transport_info_t *tinfo);

212
213
    EXPORT int jack_client_real_time_priority (jack_client_t*);
    EXPORT int jack_client_max_real_time_priority (jack_client_t*);
sletz's avatar
sletz committed
214
215
216
217
218
    EXPORT int jack_acquire_real_time_scheduling (pthread_t thread, int priority);
    EXPORT int jack_client_create_thread (jack_client_t* client,
                                          pthread_t *thread,
                                          int priority,
                                          int realtime, 	// boolean
219
                                          thread_routine routine,
sletz's avatar
sletz committed
220
221
                                          void *arg);
    EXPORT int jack_drop_real_time_scheduling (pthread_t thread);
sletz's avatar
sletz committed
222

223
224
    EXPORT int jack_client_stop_thread (jack_client_t* client, pthread_t thread);
    EXPORT int jack_client_kill_thread (jack_client_t* client, pthread_t thread);
sletz's avatar
sletz committed
225
226
227
#ifndef WIN32
    EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc);
#endif
sletz's avatar
sletz committed
228
229
230
231
232
233
234
235
236
    EXPORT char * jack_get_internal_client_name (jack_client_t *client,
            jack_intclient_t intclient);
    EXPORT jack_intclient_t jack_internal_client_handle (jack_client_t *client,
            const char *client_name,
            jack_status_t *status);
    EXPORT jack_intclient_t jack_internal_client_load (jack_client_t *client,
            const char *client_name,
            jack_options_t options,
            jack_status_t *status, ...);
237
    EXPORT jack_intclient_t jack_internal_client_load_aux (jack_client_t *client,
238
239
240
241
            const char *client_name,
            jack_options_t options,
            jack_status_t *status, va_list ap);

sletz's avatar
sletz committed
242
243
    EXPORT jack_status_t jack_internal_client_unload (jack_client_t *client,
            jack_intclient_t intclient);
244

sletz's avatar
sletz committed
245
246
247
248
249
250
#ifdef __cplusplus
}
#endif

static inline bool CheckPort(jack_port_id_t port_index)
{
sletz's avatar
sletz committed
251
    return (port_index > 0 && port_index < PORT_NUM);
sletz's avatar
sletz committed
252
253
}

254
255
256
257
258
static inline bool CheckBufferSize(jack_nframes_t buffer_size)
{
    return (buffer_size <= BUFFER_SIZE_MAX);
}

sletz's avatar
sletz committed
259
260
static inline void WaitGraphChange()
{
261
    /*
sletz's avatar
sletz committed
262
    TLS key that is set only in RT thread, so never waits for pending
263
264
    graph change in RT context (just read the current graph state).
    */
sletz's avatar
sletz committed
265

266
    if (jack_tls_get(JackGlobals::fRealTime) == NULL) {
267
268
269
270
271
272
273
274
        JackGraphManager* manager = GetGraphManager();
        JackEngineControl* control = GetEngineControl();
        assert(manager);
        assert(control);
        if (manager->IsPendingChange()) {
            jack_log("WaitGraphChange...");
            JackSleep(int(control->fPeriodUsecs * 1.1f));
        }
sletz's avatar
sletz committed
275
276
277
    }
}

278
EXPORT void jack_set_error_function (print_function func)
sletz's avatar
sletz committed
279
280
281
282
{
    jack_error_callback = func;
}

283
EXPORT void jack_set_info_function (print_function func)
284
285
286
287
{
    jack_info_callback = func;
}

sletz's avatar
Cleanup    
sletz committed
288
289
EXPORT jack_client_t* jack_client_new(const char* client_name)
{
290
291
    assert(JackGlobals::fOpenMutex);
    JackGlobals::fOpenMutex->Lock();
sletz's avatar
sletz committed
292
    jack_error("jack_client_new: deprecated");
sletz's avatar
Cleanup    
sletz committed
293
    int options = JackUseExactName;
sletz's avatar
sletz committed
294
    if (getenv("JACK_START_SERVER") == NULL)
sletz's avatar
Cleanup    
sletz committed
295
        options |= JackNoStartServer;
296
    jack_client_t* res = jack_client_open_aux(client_name, (jack_options_t)options, NULL, NULL);
297
    JackGlobals::fOpenMutex->Unlock();
298
    return res;
sletz's avatar
Cleanup    
sletz committed
299
300
}

sletz's avatar
sletz committed
301
302
EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
{
303
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
304
    JackLibGlobals::CheckContext();
305
#endif
306
307
308
309
310
311
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
312
313
314
315
    if (!CheckPort(myport)) {
        jack_error("jack_port_get_buffer called with an incorrect port %ld", myport);
        return NULL;
    } else {
sletz's avatar
sletz committed
316
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
sletz committed
317
        return (manager ? manager->GetBuffer(myport, frames) : NULL);
sletz's avatar
sletz committed
318
319
320
321
322
    }
}

EXPORT const char* jack_port_name(const jack_port_t* port)
{
323
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
324
    JackLibGlobals::CheckContext();
325
#endif
326
327
328
329
330
331
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
332
333
334
335
    if (!CheckPort(myport)) {
        jack_error("jack_port_name called with an incorrect port %ld", myport);
        return NULL;
    } else {
sletz's avatar
sletz committed
336
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
sletz committed
337
        return (manager ? manager->GetPort(myport)->GetName() : NULL);
sletz's avatar
sletz committed
338
339
340
341
342
    }
}

EXPORT const char* jack_port_short_name(const jack_port_t* port)
{
343
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
344
    JackLibGlobals::CheckContext();
345
#endif
346
347
348
349
350
351
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
352
353
354
355
    if (!CheckPort(myport)) {
        jack_error("jack_port_short_name called with an incorrect port %ld", myport);
        return NULL;
    } else {
sletz's avatar
sletz committed
356
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
Cleanup    
sletz committed
357
        return (manager ? manager->GetPort(myport)->GetShortName() : NULL);
sletz's avatar
sletz committed
358
359
360
361
362
    }
}

EXPORT int jack_port_flags(const jack_port_t* port)
{
363
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
364
    JackLibGlobals::CheckContext();
365
#endif
366
367
368
369
370
371
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
372
373
374
375
    if (!CheckPort(myport)) {
        jack_error("jack_port_flags called with an incorrect port %ld", myport);
        return -1;
    } else {
sletz's avatar
sletz committed
376
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
Cleanup    
sletz committed
377
        return (manager ? manager->GetPort(myport)->GetFlags() : -1);
sletz's avatar
sletz committed
378
379
380
381
382
    }
}

EXPORT const char* jack_port_type(const jack_port_t* port)
{
383
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
384
    JackLibGlobals::CheckContext();
385
#endif
386
387
388
389
390
391
392
 #if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
   if (!CheckPort(myport)) {
sletz's avatar
sletz committed
393
394
395
        jack_error("jack_port_flags called an incorrect port %ld", myport);
        return NULL;
    } else {
sletz's avatar
sletz committed
396
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
Cleanup    
sletz committed
397
        return (manager ? manager->GetPort(myport)->GetType() : NULL);
sletz's avatar
sletz committed
398
399
400
    }
}

401
EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port)
sletz's avatar
sletz committed
402
403
404
405
{
#ifdef __CLIENTDEBUG__
    JackLibGlobals::CheckContext();
#endif
406
407
408
409
410
411
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
412
413
414
415
416
417
418
419
420
    if (!CheckPort(myport)) {
        jack_error("jack_port_type_id called an incorrect port %ld", myport);
        return 0;
    } else {
        JackGraphManager* manager = GetGraphManager();
        return (manager ? GetPortTypeId(manager->GetPort(myport)->GetType()) : 0);
    }
}

sletz's avatar
sletz committed
421
422
EXPORT int jack_port_connected(const jack_port_t* port)
{
423
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
424
    JackLibGlobals::CheckContext();
425
#endif
426
427
428
429
430
431
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
432
433
434
435
436
    if (!CheckPort(myport)) {
        jack_error("jack_port_connected called with an incorrect port %ld", myport);
        return -1;
    } else {
        WaitGraphChange();
sletz's avatar
sletz committed
437
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
Cleanup    
sletz committed
438
        return (manager ? manager->GetConnectionsNum(myport) : -1);
sletz's avatar
sletz committed
439
440
441
    }
}

442
EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name)
sletz's avatar
sletz committed
443
{
444
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
445
    JackLibGlobals::CheckContext();
446
#endif
447
448
449
450
451
452
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t src = (jack_port_id_t)port_aux;
453
454
    if (!CheckPort(src)) {
        jack_error("jack_port_connected_to called with an incorrect port %ld", src);
sletz's avatar
sletz committed
455
        return -1;
456
    } else if (port_name == NULL) {
sletz's avatar
sletz committed
457
458
459
460
        jack_error("jack_port_connected_to called with a NULL port name");
        return -1;
    } else {
        WaitGraphChange();
sletz's avatar
sletz committed
461
462
463
464
465
466
467
468
        JackGraphManager* manager = GetGraphManager();
        jack_port_id_t dst = (manager ? manager->GetPort(port_name) : NO_PORT);
        if (dst == NO_PORT) {
            jack_error("Unknown destination port port_name = %s", port_name);
            return 0;
        } else {
            return manager->IsConnected(src, dst);
        }
sletz's avatar
sletz committed
469
470
471
472
473
    }
}

EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst)
{
474
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
475
    JackLibGlobals::CheckContext();
476
#endif
477
478
479
480
481
482
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t src_aux = (uint64_t)src;
#else
    uint32_t src_aux = (uint32_t)src;
#endif
    jack_port_id_t mysrc = (jack_port_id_t)src_aux;
sletz's avatar
sletz committed
483
484
485
486
    if (!CheckPort(mysrc)) {
        jack_error("jack_port_tie called with a NULL src port");
        return -1;
    }
487
488
489
490
491
492
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t dst_aux = (uint64_t)dst;
#else
    uint32_t dst_aux = (uint32_t)dst;
#endif
    jack_port_id_t mydst = (jack_port_id_t)dst_aux;
sletz's avatar
sletz committed
493
494
495
496
    if (!CheckPort(mydst)) {
        jack_error("jack_port_tie called with a NULL dst port");
        return -1;
    }
sletz's avatar
sletz committed
497
498
    JackGraphManager* manager = GetGraphManager();
    if (manager && manager->GetPort(mysrc)->GetRefNum() != manager->GetPort(mydst)->GetRefNum()) {
sletz's avatar
sletz committed
499
500
        jack_error("jack_port_tie called with ports not belonging to the same client");
        return -1;
sletz's avatar
sletz committed
501
    } else {
sletz's avatar
sletz committed
502
503
        return manager->GetPort(mydst)->Tie(mysrc);
    }
sletz's avatar
sletz committed
504
505
506
507
}

EXPORT int jack_port_untie(jack_port_t* port)
{
508
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
509
    JackLibGlobals::CheckContext();
510
#endif
511
512
513
514
515
516
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
517
518
519
520
    if (!CheckPort(myport)) {
        jack_error("jack_port_untie called with an incorrect port %ld", myport);
        return -1;
    } else {
sletz's avatar
sletz committed
521
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
sletz committed
522
        return (manager ? manager->GetPort(myport)->UnTie() : -1);
sletz's avatar
sletz committed
523
524
525
526
527
    }
}

EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port)
{
528
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
529
    JackLibGlobals::CheckContext();
530
#endif
531
532
533
534
535
536
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
537
538
539
540
541
    if (!CheckPort(myport)) {
        jack_error("jack_port_get_latency called with an incorrect port %ld", myport);
        return 0;
    } else {
        WaitGraphChange();
sletz's avatar
sletz committed
542
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
sletz committed
543
        return (manager ? manager->GetPort(myport)->GetLatency() : 0);
sletz's avatar
sletz committed
544
545
546
547
548
    }
}

EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames)
{
549
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
550
    JackLibGlobals::CheckContext();
551
#endif
552
553
554
555
556
557
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
558
559
560
    if (!CheckPort(myport)) {
        jack_error("jack_port_set_latency called with an incorrect port %ld", myport);
    } else {
sletz's avatar
sletz committed
561
562
563
        JackGraphManager* manager = GetGraphManager();
        if (manager)
            manager->GetPort(myport)->SetLatency(frames);
sletz's avatar
sletz committed
564
565
566
    }
}

567
EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port)
sletz's avatar
sletz committed
568
569
{
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
570
    JackLibGlobals::CheckContext();
sletz's avatar
sletz committed
571
572
#endif

sletz's avatar
sletz committed
573
    JackClient* client = (JackClient*)ext_client;
574
575
576
577
578
579
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
   
sletz committed
580
581
582
583
584
585
586
    if (client == NULL) {
        jack_error("jack_recompute_total_latencies called with a NULL client");
        return -1;
    } else if (!CheckPort(myport)) {
        jack_error("jack_recompute_total_latencies called with a NULL port");
        return -1;
    } else {
sletz's avatar
sletz committed
587
588
589
        WaitGraphChange();
        JackGraphManager* manager = GetGraphManager();
        return (manager ? manager->ComputeTotalLatency(myport) : -1);
sletz's avatar
   
sletz committed
590
    }
sletz's avatar
sletz committed
591
592
}

sletz's avatar
sletz committed
593
594
EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client)
{
sletz's avatar
sletz committed
595
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
596
    JackLibGlobals::CheckContext();
sletz's avatar
sletz committed
597
598
#endif

sletz's avatar
sletz committed
599
600
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
sletz's avatar
   
sletz committed
601
602
603
        jack_error("jack_recompute_total_latencies called with a NULL client");
        return -1;
    } else {
sletz's avatar
sletz committed
604
605
606
        WaitGraphChange();
        JackGraphManager* manager = GetGraphManager();
        return (manager ? manager->ComputeTotalLatencies() : -1);
sletz's avatar
   
sletz committed
607
    }
sletz's avatar
sletz committed
608
609
}

sletz's avatar
Cleanup    
sletz committed
610
611
612
613
/*
This is unsafe if case of concurrent access, and should be "serialized" doing a server call.
*/

sletz's avatar
sletz committed
614
615
EXPORT int jack_port_set_name(jack_port_t* port, const char* name)
{
616
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
617
    JackLibGlobals::CheckContext();
618
#endif
619
620
621
622
623
624
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
625
626
627
628
629
630
631
    if (!CheckPort(myport)) {
        jack_error("jack_port_set_name called with an incorrect port %ld", myport);
        return -1;
    } else if (name == NULL) {
        jack_error("jack_port_set_name called with a NULL port name");
        return -1;
    } else {
sletz's avatar
sletz committed
632
        JackGraphManager* manager = GetGraphManager();
633
634
        int refnum;
        if (manager && ((refnum = manager->GetPort(myport)->GetRefNum()) > 0)) {
635
            JackClient* client = JackGlobals::fClientTable[refnum];
636
637
638
639
640
            assert(client);
            return client->PortRename(myport, name);
        } else {
            return -1;
        }
sletz's avatar
sletz committed
641
642
643
    }
}

644
645
646
EXPORT int jack_port_set_alias(jack_port_t* port, const char* name)
{
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
647
    JackLibGlobals::CheckContext();
648
#endif
649
650
651
652
653
654
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
655
656
657
658
659
660
661
    if (!CheckPort(myport)) {
        jack_error("jack_port_set_alias called with an incorrect port %ld", myport);
        return -1;
    } else if (name == NULL) {
        jack_error("jack_port_set_alias called with a NULL port name");
        return -1;
    } else {
sletz's avatar
sletz committed
662
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
sletz committed
663
        return (manager ? manager->GetPort(myport)->SetAlias(name) : -1);
664
665
666
667
668
669
    }
}

EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name)
{
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
670
    JackLibGlobals::CheckContext();
671
#endif
672
673
674
675
676
677
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
678
679
680
681
682
683
684
    if (!CheckPort(myport)) {
        jack_error("jack_port_unset_alias called with an incorrect port %ld", myport);
        return -1;
    } else if (name == NULL) {
        jack_error("jack_port_unset_alias called with a NULL port name");
        return -1;
    } else {
sletz's avatar
sletz committed
685
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
sletz committed
686
        return (manager ? manager->GetPort(myport)->UnsetAlias(name) : -1);
687
688
689
690
691
692
    }
}

EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2])
{
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
693
    JackLibGlobals::CheckContext();
694
#endif
695
696
697
698
699
700
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
701
702
703
704
    if (!CheckPort(myport)) {
        jack_error("jack_port_get_aliases called with an incorrect port %ld", myport);
        return -1;
    } else {
sletz's avatar
sletz committed
705
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
sletz committed
706
        return (manager ? manager->GetPort(myport)->GetAliases(aliases) : -1);
707
708
709
    }
}

sletz's avatar
sletz committed
710
711
EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff)
{
712
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
713
    JackLibGlobals::CheckContext();
714
#endif
715
716
717
718
719
720
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
721
722
723
724
    if (!CheckPort(myport)) {
        jack_error("jack_port_request_monitor called with an incorrect port %ld", myport);
        return -1;
    } else {
sletz's avatar
sletz committed
725
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
sletz committed
726
        return (manager ? manager->RequestMonitor(myport, onoff) : -1);
sletz's avatar
sletz committed
727
728
729
730
731
    }
}

EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff)
{
732
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
733
    JackLibGlobals::CheckContext();
734
#endif
sletz's avatar
sletz committed
735
736
737
738
739
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_port_request_monitor_by_name called with a NULL client");
        return -1;
    } else {
sletz's avatar
sletz committed
740
741
742
        JackGraphManager* manager = GetGraphManager();
        if (!manager)
            return -1;
sletz's avatar
sletz committed
743
        jack_port_id_t myport = manager->GetPort(port_name);
sletz's avatar
sletz committed
744
745
746
747
        if (!CheckPort(myport)) {
            jack_error("jack_port_request_monitor_by_name called with an incorrect port %s", port_name);
            return -1;
        } else {
sletz's avatar
sletz committed
748
            return manager->RequestMonitor(myport, onoff);
sletz's avatar
sletz committed
749
750
751
752
753
754
        }
    }
}

EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff)
{
755
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
756
    JackLibGlobals::CheckContext();
757
#endif
758
759
760
761
762
763
 #if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
764
765
766
767
    if (!CheckPort(myport)) {
        jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport);
        return -1;
    } else {
sletz's avatar
sletz committed
768
769
        JackGraphManager* manager = GetGraphManager();
        return (manager ? manager->GetPort(myport)->EnsureMonitor(onoff) : -1);
sletz's avatar
sletz committed
770
771
772
773
774
    }
}

EXPORT int jack_port_monitoring_input(jack_port_t* port)
{
775
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
776
    JackLibGlobals::CheckContext();
777
#endif
778
779
780
781
782
783
#if defined(__x86_64__) || defined(__ppc64__)
    uint64_t port_aux = (uint64_t)port;
#else
    uint32_t port_aux = (uint32_t)port;
#endif
    jack_port_id_t myport = (jack_port_id_t)port_aux;
sletz's avatar
sletz committed
784
785
786
787
    if (!CheckPort(myport)) {
        jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport);
        return -1;
    } else {
sletz's avatar
sletz committed
788
        JackGraphManager* manager = GetGraphManager();
sletz's avatar
sletz committed
789
        return (manager ? manager->GetPort(myport)->MonitoringInput() : -1);
sletz's avatar
sletz committed
790
791
792
793
794
    }
}

EXPORT int jack_is_realtime(jack_client_t* ext_client)
{
795
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
796
    JackLibGlobals::CheckContext();
797
#endif
sletz's avatar
sletz committed
798
799
800
801
802
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_is_realtime called with a NULL client");
        return -1;
    } else {
sletz's avatar
sletz committed
803
        JackEngineControl* control = GetEngineControl();
sletz's avatar
sletz committed
804
        return (control ? control->fRealTime : -1);
sletz's avatar
sletz committed
805
806
807
    }
}

808
EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback callback, void* arg)
sletz's avatar
sletz committed
809
{
810
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
811
    JackLibGlobals::CheckContext();
812
#endif
sletz's avatar
sletz committed
813
814
815
816
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_on_shutdown called with a NULL client");
    } else {
817
        client->OnShutdown(callback, arg);
sletz's avatar
sletz committed
818
819
820
821
822
    }
}

EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg)
{
823
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
824
    JackLibGlobals::CheckContext();
825
#endif
sletz's avatar
sletz committed
826
827
828
829
830
831
832
833
834
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_set_process_callback called with a NULL client");
        return -1;
    } else {
        return client->SetProcessCallback(callback, arg);
    }
}

835
836
837
EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status)
{
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
838
    JackLibGlobals::CheckContext();
839
840
841
842
#endif
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_thread_wait called with a NULL client");
sletz's avatar
sletz committed
843
        return 0;
844
    } else {
sletz's avatar
sletz committed
845
846
        jack_error("jack_thread_wait: deprecated, use jack_cycle_wait/jack_cycle_signal");
        return -1;
847
848
849
    }
}

sletz's avatar
sletz committed
850
851
852
EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client)
{
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
853
    JackLibGlobals::CheckContext();
sletz's avatar
sletz committed
854
855
856
857
#endif
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_cycle_wait called with a NULL client");
sletz's avatar
sletz committed
858
        return 0;
sletz's avatar
sletz committed
859
860
861
862
863
864
865
866
    } else {
        return client->CycleWait();
    }
}

EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status)
{
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
867
    JackLibGlobals::CheckContext();
sletz's avatar
sletz committed
868
869
870
871
#endif
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_cycle_signal called with a NULL client");
sletz's avatar
sletz committed
872
    } else {
sletz's avatar
sletz committed
873
874
875
876
        client->CycleSignal(status);
    }
}

877
EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback fun, void *arg)
878
879
{
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
880
    JackLibGlobals::CheckContext();
881
882
883
884
#endif
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_set_process_thread called with a NULL client");
sletz's avatar
sletz committed
885
886
        return -1;
    } else {
887
888
889
890
        return client->SetProcessThread(fun, arg);
    }
}

sletz's avatar
sletz committed
891
892
EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg)
{
893
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
894
    JackLibGlobals::CheckContext();
895
#endif
sletz's avatar
sletz committed
896
897
898
899
900
901
902
903
904
905
906
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_set_freewheel_callback called with a NULL client");
        return -1;
    } else {
        return client->SetFreewheelCallback(freewheel_callback, arg);
    }
}

EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff)
{
907
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
908
    JackLibGlobals::CheckContext();
909
#endif
sletz's avatar
sletz committed
910
911
912
913
914
915
916
917
918
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_set_freewheel called with a NULL client");
        return -1;
    } else {
        return client->SetFreeWheel(onoff);
    }
}

919
EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size)
sletz's avatar
sletz committed
920
{
921
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
922
    JackLibGlobals::CheckContext();
923
#endif
sletz's avatar
sletz committed
924
925
926
927
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_set_buffer_size called with a NULL client");
        return -1;
928
    } else if (!CheckBufferSize(buffer_size)) {
sletz's avatar
sletz committed
929
930
        return -1;
    } else {
931
        return client->SetBufferSize(buffer_size);
sletz's avatar
sletz committed
932
933
934
935
936
    }
}

EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg)
{
937
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
938
    JackLibGlobals::CheckContext();
939
#endif
sletz's avatar
sletz committed
940
941
942
943
944
945
946
947
948
949
950
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_set_buffer_size_callback called with a NULL client");
        return -1;
    } else {
        return client->SetBufferSizeCallback(bufsize_callback, arg);
    }
}

EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg)
{
951
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
952
    JackLibGlobals::CheckContext();
953
#endif
sletz's avatar
sletz committed
954
955
956
957
958
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_set_sample_rate_callback called with a NULL client");
        return -1;
    } else {
959
        return client->SetSampleRateCallback(srate_callback, arg);
sletz's avatar
sletz committed
960
961
962
    }
}

963
964
965
EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, JackClientRegistrationCallback registration_callback, void* arg)
{
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
966
    JackLibGlobals::CheckContext();
967
968
969
970
971
972
#endif
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_set_client_registration_callback called with a NULL client");
        return -1;
    } else {
sletz's avatar
sletz committed
973
        return client->SetClientRegistrationCallback(registration_callback, arg);
974
975
976
    }
}

sletz's avatar
sletz committed
977
978
EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg)
{
979
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
980
    JackLibGlobals::CheckContext();
981
#endif
sletz's avatar
sletz committed
982
983
984
985
986
987
988
989
990
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_set_port_registration_callback called with a NULL client");
        return -1;
    } else {
        return client->SetPortRegistrationCallback(registration_callback, arg);
    }
}

sletz's avatar
sletz committed
991
992
993
EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortConnectCallback portconnect_callback, void* arg)
{
#ifdef __CLIENTDEBUG__
sletz's avatar
sletz committed
994
    JackLibGlobals::CheckContext();
sletz's avatar
sletz committed
995
996
997
998
999
1000
#endif
    JackClient* client = (JackClient*)ext_client;
    if (client == NULL) {
        jack_error("jack_set_port_connect_callback called with a NULL client");
        return -1;
    } else {
For faster browsing, not all history is shown. View entire blame