2 * pyjackc - C module implementation for pyjack
4 * Copyright 2003 Andrew W. Schmeder <andy@a2hd.com>
5 * Copyright 2010 Filipe Coelho (aka 'falkTX') <falktx@gmail.com>
7 * This source code is released under the terms of the GNU GPL v2.
8 * See LICENSE for the full text of these terms.
13 #include "numpy/arrayobject.h"
16 #include <jack/jack.h>
17 #include <jack/transport.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
30 - dettach on client on __del__
34 - user python callbacks for non-rt events
35 - make global client a python object
36 - eventually deprecate the global client api
37 - remove the attach and detach methods
40 // Global shared data for jack
42 /* Uncomment the next line if you have Jack2 */
46 #define PYJACK_MAX_PORTS 256
51 jack_client_t
* pjc
; // Client handle
52 int buffer_size
; // Buffer size
53 int num_inputs
; // Number of input ports registered
54 int num_outputs
; // Number of output ports registered
55 jack_port_t
* input_ports
[PYJACK_MAX_PORTS
]; // Input ports
56 jack_port_t
* output_ports
[PYJACK_MAX_PORTS
]; // Output ports
57 fd_set input_rfd
; // fdlist for select
58 fd_set output_rfd
; // fdlist for select
59 int input_pipe
[2]; // socket pair for input port data
60 int output_pipe
[2]; // socket pair for output port data
61 float* input_buffer_0
; // buffer used to transmit audio via slink...
62 float* output_buffer_0
; // buffer used to send audio via slink...
63 float* input_buffer_1
; // buffer used to transmit audio via slink...
64 float* output_buffer_1
; // buffer used to send audio via slink...
65 int input_buffer_size
; // buffer_size * num_inputs * sizeof(sample_t)
66 int output_buffer_size
; // buffer_size * num_outputs * sizeof(sample_t)
67 int iosync
; // true when the python side synchronizing properly...
68 int event_graph_ordering
; // true when a graph ordering event has occured
69 int event_port_registration
; // true when a port registration event has occured
70 int event_freewheel
; // true when a freewheel mode toggle event has occured
71 int event_buffer_size
; // true when a buffer size change has occured
72 int event_sample_rate
; // true when a sample rate change has occured
73 int event_xrun
; // true when a xrun occurs
74 int event_shutdown
; // true when the jack server is shutdown
75 int event_hangup
; // true when client got hangup signal
76 int freewheel
; // indicates if freewheel mode active
77 int active
; // indicates if the client is currently process-enabled
80 pyjack_client_t global_client
;
82 pyjack_client_t
* self_or_global_client(PyObject
* self
) {
83 if (!self
) return & global_client
;
84 return (pyjack_client_t
*) self
;
87 // Initialize global data
88 void pyjack_init(pyjack_client_t
* client
) {
92 client
->num_inputs
= 0;
93 client
->num_outputs
= 0;
94 client
->input_pipe
[R
] = 0;
95 client
->input_pipe
[W
] = 0;
96 client
->output_pipe
[R
] = 0;
97 client
->output_pipe
[W
] = 0;
99 // Initialize unamed, raw datagram-type sockets...
100 if (socketpair(PF_UNIX
, SOCK_DGRAM
, 0, client
->input_pipe
) == -1) {
101 printf("ERROR: Failed to create socketpair input_pipe!!\n");
103 if (socketpair(PF_UNIX
, SOCK_DGRAM
, 0, client
->output_pipe
) == -1) {
104 printf("ERROR: Failed to create socketpair output_pipe!!\n");
107 // Convention is that pipe[W=1] is the "write" end of the pipe, which is always non-blocking.
108 fcntl(client
->input_pipe
[W
], F_SETFL
, O_NONBLOCK
);
109 fcntl(client
->output_pipe
[W
], F_SETFL
, O_NONBLOCK
);
110 fcntl(client
->output_pipe
[R
], F_SETFL
, O_NONBLOCK
);
112 // The read end, pipe[R=0], is blocking, but we use a select() call to make sure that data is really there.
113 FD_ZERO(&client
->input_rfd
);
114 FD_ZERO(&client
->output_rfd
);
115 FD_SET(client
->input_pipe
[R
], &client
->input_rfd
);
116 FD_SET(client
->output_pipe
[R
], &client
->output_rfd
);
118 // Init buffers to null...
119 client
->input_buffer_size
= 0;
120 client
->output_buffer_size
= 0;
121 client
->input_buffer_0
= NULL
;
122 client
->output_buffer_0
= NULL
;
123 client
->input_buffer_1
= NULL
;
124 client
->output_buffer_1
= NULL
;
127 static void free_and_reset(float ** pointer
)
129 if (!*pointer
) return;
134 static void close_and_reset(int * fd
)
141 // Finalize global data
142 void pyjack_final(pyjack_client_t
* client
) {
145 client
->num_inputs
= 0;
146 client
->num_outputs
= 0;
147 client
->buffer_size
= 0;
148 free_and_reset(&client
->input_buffer_0
);
149 free_and_reset(&client
->input_buffer_1
);
150 free_and_reset(&client
->output_buffer_0
);
151 free_and_reset(&client
->output_buffer_1
);
153 close_and_reset(&client
->input_pipe
[R
]);
154 close_and_reset(&client
->input_pipe
[W
]);
155 close_and_reset(&client
->output_pipe
[R
]);
156 close_and_reset(&client
->output_pipe
[W
]);
159 // (Re)initialize socketpair buffers
160 void init_pipe_buffers(pyjack_client_t
* client
) {
161 // allocate buffers for send and recv
162 unsigned new_input_size
= client
->num_inputs
* client
->buffer_size
* sizeof(float);
163 if(client
->input_buffer_size
!= new_input_size
) {
164 client
->input_buffer_size
= new_input_size
;
165 client
->input_buffer_0
= realloc(client
->input_buffer_0
, new_input_size
);
166 client
->input_buffer_1
= realloc(client
->input_buffer_1
, new_input_size
);
167 //printf("Input buffer size %d bytes\n", input_buffer_size);
169 unsigned new_output_size
= client
->num_outputs
* client
->buffer_size
* sizeof(float);
170 if(client
->output_buffer_size
!= new_output_size
) {
171 client
->output_buffer_size
= new_output_size
;
172 client
->output_buffer_0
= realloc(client
->output_buffer_0
, new_output_size
);
173 client
->output_buffer_1
= realloc(client
->output_buffer_1
, new_output_size
);
174 //printf("Output buffer size %d bytes\n", output_buffer_size);
177 // set socket buffers to same size as snd/rcv buffers
178 setsockopt(client
->input_pipe
[R
], SOL_SOCKET
, SO_RCVBUF
, &client
->input_buffer_size
, sizeof(int));
179 setsockopt(client
->input_pipe
[R
], SOL_SOCKET
, SO_SNDBUF
, &client
->input_buffer_size
, sizeof(int));
180 setsockopt(client
->input_pipe
[W
], SOL_SOCKET
, SO_RCVBUF
, &client
->input_buffer_size
, sizeof(int));
181 setsockopt(client
->input_pipe
[W
], SOL_SOCKET
, SO_SNDBUF
, &client
->input_buffer_size
, sizeof(int));
183 setsockopt(client
->output_pipe
[R
], SOL_SOCKET
, SO_RCVBUF
, &client
->output_buffer_size
, sizeof(int));
184 setsockopt(client
->output_pipe
[R
], SOL_SOCKET
, SO_SNDBUF
, &client
->output_buffer_size
, sizeof(int));
185 setsockopt(client
->output_pipe
[W
], SOL_SOCKET
, SO_RCVBUF
, &client
->output_buffer_size
, sizeof(int));
186 setsockopt(client
->output_pipe
[W
], SOL_SOCKET
, SO_SNDBUF
, &client
->output_buffer_size
, sizeof(int));
189 // RT function called by jack
190 int pyjack_process(jack_nframes_t n
, void* arg
) {
192 pyjack_client_t
* client
= (pyjack_client_t
*) arg
;
195 // Send input data to python side (non-blocking!)
196 if (client
->num_inputs
) {
197 for(i
= 0; i
< client
->num_inputs
; i
++) {
199 &client
->input_buffer_0
[client
->buffer_size
* i
],
200 jack_port_get_buffer(client
->input_ports
[i
], n
),
201 (client
->buffer_size
* sizeof(float))
205 r
= write(client
->input_pipe
[W
], client
->input_buffer_0
, client
->input_buffer_size
);
209 } else if(r
== client
->input_buffer_size
) {
214 // Read data from python side (non-blocking!)
215 if (client
->num_outputs
) {
216 r
= read(client
->output_pipe
[R
], client
->output_buffer_0
, client
->output_buffer_size
);
217 if(r
!= client
->buffer_size
* sizeof(float) * client
->num_outputs
) {
218 //printf("not enough data; skipping output\n");
221 for(i
= 0; i
< client
->num_outputs
; i
++) {
223 jack_port_get_buffer(client
->output_ports
[i
], client
->buffer_size
),
224 client
->output_buffer_0
+ (client
->buffer_size
* i
),
225 client
->buffer_size
* sizeof(float)
233 // Event notification of buffer size change
234 int pyjack_buffer_size_changed(jack_nframes_t n
, void* arg
) {
235 pyjack_client_t
* client
= (pyjack_client_t
*) arg
;
236 client
->event_buffer_size
= 1;
240 // Event notification of sample rate change
241 int pyjack_sample_rate_changed(jack_nframes_t n
, void* arg
) {
242 pyjack_client_t
* client
= (pyjack_client_t
*) arg
;
243 client
->event_sample_rate
= 1;
247 // Event notification of freewheel mode toggle
248 void pyjack_freewheel_changed(int starting
, void* arg
) {
249 pyjack_client_t
* client
= (pyjack_client_t
*) arg
;
250 client
->event_freewheel
= 1;
251 client
->freewheel
= starting
;
254 // Event notification of graph connect/disconnection
255 int pyjack_graph_order(void* arg
) {
256 pyjack_client_t
* client
= (pyjack_client_t
*) arg
;
257 client
->event_graph_ordering
= 1;
261 // Event notification of xrun
262 int pyjack_xrun(void* arg
) {
263 pyjack_client_t
* client
= (pyjack_client_t
*) arg
;
264 client
->event_xrun
= 1;
268 // Event notification of port registration or drop
269 void pyjack_port_registration(jack_port_id_t pid
, int action
, void* arg
) {
270 pyjack_client_t
* client
= (pyjack_client_t
*) arg
;
271 client
->event_port_registration
= 1;
275 void pyjack_shutdown(void * arg
) {
276 pyjack_client_t
* client
= (pyjack_client_t
*) arg
;
277 client
->event_shutdown
= 1;
282 void pyjack_hangup(int signal
) {
283 // TODO: what to do with non global clients
284 global_client
.event_hangup
= 1;
285 global_client
.pjc
= NULL
;
288 // ------------- Python module stuff ---------------------
290 // Module exception object
291 static PyObject
* JackError
;
292 static PyObject
* JackNotConnectedError
;
293 static PyObject
* JackUsageError
;
294 static PyObject
* JackInputSyncError
;
295 static PyObject
* JackOutputSyncError
;
297 // Attempt to connect to the Jack server
298 static PyObject
* attach(PyObject
* self
, PyObject
* args
)
301 if (! PyArg_ParseTuple(args
, "s", &cname
))
304 pyjack_client_t
* client
= self_or_global_client(self
);
305 if(client
->pjc
!= NULL
) {
306 PyErr_SetString(JackUsageError
, "A connection is already established.");
310 jack_status_t status
;
311 client
->pjc
= jack_client_open(cname
, JackNoStartServer
, &status
);
312 if(client
->pjc
== NULL
) {
314 PyErr_SetString(JackNotConnectedError
, "Failed to connect to Jack audio server.");
318 jack_on_shutdown(client
->pjc
, pyjack_shutdown
, client
);
319 signal(SIGHUP
, pyjack_hangup
); // TODO: This just works with global clients
321 if(jack_set_process_callback(client
->pjc
, pyjack_process
, client
) != 0) {
322 PyErr_SetString(JackError
, "Failed to set jack process callback.");
326 if(jack_set_buffer_size_callback(client
->pjc
, pyjack_buffer_size_changed
, client
) != 0) {
327 PyErr_SetString(JackError
, "Failed to set jack buffer size callback.");
331 if(jack_set_sample_rate_callback(client
->pjc
, pyjack_sample_rate_changed
, client
) != 0) {
332 PyErr_SetString(JackError
, "Failed to set jack sample rate callback.");
336 if(jack_set_freewheel_callback(client
->pjc
, pyjack_freewheel_changed
, client
) != 0) {
337 PyErr_SetString(JackError
, "Failed to set jack sample rate callback.");
341 if(jack_set_port_registration_callback(client
->pjc
, pyjack_port_registration
, client
) != 0) {
342 PyErr_SetString(JackError
, "Failed to set jack port registration callback.");
346 if(jack_set_graph_order_callback(client
->pjc
, pyjack_graph_order
, client
) != 0) {
347 PyErr_SetString(JackError
, "Failed to set jack graph order callback.");
351 if(jack_set_xrun_callback(client
->pjc
, pyjack_xrun
, client
) != 0) {
352 PyErr_SetString(JackError
, "Failed to set jack xrun callback.");
357 client
->buffer_size
= jack_get_buffer_size(client
->pjc
);
364 // Detach client from the jack server (also destroys all connections)
365 static PyObject
* detach(PyObject
* self
, PyObject
* args
)
367 pyjack_client_t
* client
= self_or_global_client(self
);
369 if(client
->pjc
!= NULL
) {
370 jack_client_close(client
->pjc
);
371 pyjack_final(client
);
378 static PyObject
* unregister_port(PyObject
* self
, PyObject
* args
)
380 pyjack_client_t
* client
= self_or_global_client(self
);
382 if (! PyArg_ParseTuple(args
, "s", &port_name
))
385 if(client
->pjc
== NULL
) {
386 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
390 // if(client->active) {
391 // PyErr_SetString(JackUsageError, "Cannot unregister ports while client is active.");
396 for (i
=0;i
<client
->num_inputs
;i
++) {
397 if (strcmp(port_name
, jack_port_short_name(client
->input_ports
[i
]))) continue;
398 int error
= jack_port_unregister(client
->pjc
, client
->input_ports
[i
]);
400 PyErr_SetString(JackError
, "Unable to unregister input port.");
403 client
->num_inputs
--;
404 for (;i
<client
->num_inputs
;i
++) {
405 client
->input_ports
[i
] = client
->input_ports
[i
+1];
407 init_pipe_buffers(client
);
412 for (i
=0;i
<client
->num_outputs
;i
++) {
413 if (strcmp(port_name
, jack_port_short_name(client
->output_ports
[i
]))) continue;
414 int error
= jack_port_unregister(client
->pjc
, client
->output_ports
[i
]);
416 PyErr_SetString(JackError
, "Unable to unregister output port.");
419 client
->num_outputs
--;
420 for (;i
<client
->num_outputs
;i
++) {
421 client
->output_ports
[i
] = client
->output_ports
[i
+1];
423 init_pipe_buffers(client
);
427 PyErr_SetString(JackUsageError
, "Port not found.");
432 // Create a new port for this client
433 // Unregistration of ports is not supported; you must disconnect, reconnect, re-reg all ports instead.
434 static PyObject
* register_port(PyObject
* self
, PyObject
* args
)
436 pyjack_client_t
* client
= self_or_global_client(self
);
440 if (! PyArg_ParseTuple(args
, "si", &pname
, &flags
))
443 if(client
->pjc
== NULL
) {
444 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
448 // if(client->active) {
449 // PyErr_SetString(JackUsageError, "Cannot register ports while client is active.");
453 if(client
->num_inputs
>= PYJACK_MAX_PORTS
) {
454 PyErr_SetString(JackUsageError
, "Cannot create more than 256 ports. Sorry.");
458 jack_port_t
* jp
= jack_port_register(client
->pjc
, pname
, JACK_DEFAULT_AUDIO_TYPE
, flags
, 0);
460 PyErr_SetString(JackError
, "Failed to create port.");
464 // Store pointer to this port and increment counter
465 if(flags
& JackPortIsInput
) {
466 client
->input_ports
[client
->num_inputs
] = jp
;
467 client
->num_inputs
++;
469 if(flags
& JackPortIsOutput
) {
470 client
->output_ports
[client
->num_outputs
] = jp
;
471 client
->num_outputs
++;
474 init_pipe_buffers(client
);
479 // Returns a list of all port names registered in the Jack system
480 static PyObject
* get_ports(PyObject
* self
, PyObject
* args
)
486 pyjack_client_t
* client
= self_or_global_client(self
);
487 if(client
->pjc
== NULL
) {
488 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
492 jplist
= jack_get_ports(client
->pjc
, NULL
, NULL
, 0);
495 plist
= PyList_New(0);
497 while(jplist
[i
] != NULL
) {
498 PyList_Append(plist
, Py_BuildValue("s", jplist
[i
]));
499 //free(jplist[i]); // Memory leak or not??
508 // Return port flags (an integer)
509 static PyObject
* get_port_flags(PyObject
* self
, PyObject
* args
)
515 pyjack_client_t
* client
= self_or_global_client(self
);
516 if(client
->pjc
== NULL
) {
517 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
521 if (! PyArg_ParseTuple(args
, "s", &pname
))
524 jp
= jack_port_by_name(client
->pjc
, pname
);
526 PyErr_SetString(JackError
, "Bad port name.");
530 i
= jack_port_flags(jp
);
532 PyErr_SetString(JackError
, "Error getting port flags.");
536 return Py_BuildValue("i", i
);
539 // Return a list of full port names connected to the named port
540 // Port does not need to be owned by this client.
541 static PyObject
* get_connections(PyObject
* self
, PyObject
* args
)
549 pyjack_client_t
* client
= self_or_global_client(self
);
550 if(client
->pjc
== NULL
) {
551 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
555 if (! PyArg_ParseTuple(args
, "s", &pname
))
558 jp
= jack_port_by_name(client
->pjc
, pname
);
560 PyErr_SetString(JackError
, "Bad port name.");
564 jplist
= jack_port_get_all_connections(client
->pjc
, jp
);
567 plist
= PyList_New(0);
569 while(jplist
[i
] != NULL
) {
570 PyList_Append(plist
, Py_BuildValue("s", jplist
[i
]));
571 //free(jplist[i]); // memory leak or not?
581 static PyObject
* port_connect(PyObject
* self
, PyObject
* args
)
586 pyjack_client_t
* client
= self_or_global_client(self
);
587 if(client
->pjc
== NULL
) {
588 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
592 if (! PyArg_ParseTuple(args
, "ss", &src_name
, &dst_name
))
595 jack_port_t
* src
= jack_port_by_name(client
->pjc
, src_name
);
597 PyErr_SetString(JackUsageError
, "Non existing source port.");
600 jack_port_t
* dst
= jack_port_by_name(client
->pjc
, dst_name
);
602 PyErr_SetString(JackUsageError
, "Non existing destination port.");
605 if(! client
->active
) {
606 if(jack_port_is_mine(client
->pjc
, src
) || jack_port_is_mine(client
->pjc
, dst
)) {
607 PyErr_SetString(JackUsageError
, "Jack client must be activated to connect own ports.");
611 int error
= jack_connect(client
->pjc
, src_name
, dst_name
);
612 if (error
!=0 && error
!= EEXIST
) {
613 PyErr_SetString(JackError
, "Failed to connect ports.");
621 static int jack_port_connected_to_extern(const pyjack_client_t
* client
,
622 const jack_port_t
* src
,
623 const char* dst_name
)
625 // finds connections of src, then checks if dst is in there
626 const char ** existing_connections
= jack_port_get_all_connections(client
->pjc
, src
);
627 if (existing_connections
) {
628 int i
; // non C99 nonsense
629 for (i
= 0; existing_connections
[i
]; i
++) {
630 return strcmp(existing_connections
[i
], dst_name
) == 0;
637 static PyObject
* port_disconnect(PyObject
* self
, PyObject
* args
)
641 pyjack_client_t
* client
= self_or_global_client(self
);
643 if(client
->pjc
== NULL
) {
644 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
648 if (! PyArg_ParseTuple(args
, "ss", &src_name
, &dst_name
))
651 jack_port_t
* src
= jack_port_by_name(client
->pjc
, src_name
);
653 PyErr_SetString(JackUsageError
, "Non existing source port.");
657 jack_port_t
* dst
= jack_port_by_name(client
->pjc
, dst_name
);
659 PyErr_SetString(JackUsageError
, "Non existing destination port.");
663 if(jack_port_connected_to_extern(client
, src
, dst_name
)) {
664 if (jack_disconnect(client
->pjc
, src_name
, dst_name
)) {
665 PyErr_SetString(JackError
, "Failed to disconnect ports.");
675 static PyObject
* get_buffer_size(PyObject
* self
, PyObject
* args
)
677 pyjack_client_t
* client
= self_or_global_client(self
);
679 if(client
->pjc
== NULL
) {
680 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
684 int bs
= jack_get_buffer_size(client
->pjc
);
685 return Py_BuildValue("i", bs
);
689 static PyObject
* get_sample_rate(PyObject
* self
, PyObject
* args
)
691 pyjack_client_t
* client
= self_or_global_client(self
);
692 if(client
->pjc
== NULL
) {
693 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
697 int sr
= jack_get_sample_rate(client
->pjc
);
698 return Py_BuildValue("i", sr
);
702 static PyObject
* activate(PyObject
* self
, PyObject
* args
)
704 pyjack_client_t
* client
= self_or_global_client(self
);
705 if(client
->pjc
== NULL
) {
706 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
711 PyErr_SetString(JackUsageError
, "Client is already active.");
715 if(jack_activate(client
->pjc
) != 0) {
716 PyErr_SetString(JackUsageError
, "Could not activate client.");
726 static PyObject
* deactivate(PyObject
* self
, PyObject
* args
)
728 pyjack_client_t
* client
= self_or_global_client(self
);
729 if(client
->pjc
== NULL
) {
730 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
734 if(! client
->active
) {
735 PyErr_SetString(JackUsageError
, "Client is not active.");
739 if(jack_deactivate(client
->pjc
) != 0) {
740 PyErr_SetString(JackError
, "Could not deactivate client.");
750 static PyObject
* get_freewheel(PyObject
* self
, PyObject
* args
)
752 pyjack_client_t
* client
= self_or_global_client(self
);
754 if(client
->pjc
== NULL
) {
755 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
759 return Py_BuildValue("i", client
->freewheel
);
762 static PyObject
* get_client_name(PyObject
* self
, PyObject
* args
)
764 pyjack_client_t
* client
= self_or_global_client(self
);
765 if(client
->pjc
== NULL
) {
766 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
769 return Py_BuildValue("s", jack_get_client_name(client
->pjc
));
772 /** Commit a chunk of audio for the outgoing stream, if any.
773 * Return the next chunk of audio from the incoming stream, if any
775 static PyObject
* process(PyObject
* self
, PyObject
*args
)
778 PyArrayObject
*input_array
;
779 PyArrayObject
*output_array
;
781 pyjack_client_t
* client
= self_or_global_client(self
);
782 if(! client
->active
) {
783 PyErr_SetString(JackUsageError
, "Client is not active.");
787 // Import the first and only arg...
788 if (! PyArg_ParseTuple(args
, "O!O!", &PyArray_Type
, &output_array
, &PyArray_Type
, &input_array
))
791 if(input_array
->descr
->type_num
!= PyArray_FLOAT
|| output_array
->descr
->type_num
!= PyArray_FLOAT
) {
792 PyErr_SetString(PyExc_ValueError
, "arrays must be of type float");
795 if(input_array
->nd
!= 2 || output_array
->nd
!= 2) {
796 printf("%d, %d\n", input_array
->nd
, output_array
->nd
);
797 PyErr_SetString(PyExc_ValueError
, "arrays must be two dimensional");
800 if((client
->num_inputs
> 0 && input_array
->dimensions
[1] != client
->buffer_size
) ||
801 (client
->num_outputs
> 0 && output_array
->dimensions
[1] != client
->buffer_size
)) {
802 PyErr_SetString(PyExc_ValueError
, "columns of arrays must match buffer size.");
805 if(client
->num_inputs
> 0 && input_array
->dimensions
[0] != client
->num_inputs
) {
806 PyErr_SetString(PyExc_ValueError
, "rows for input array must match number of input ports");
809 if(client
->num_outputs
> 0 && output_array
->dimensions
[0] != client
->num_outputs
) {
810 PyErr_SetString(PyExc_ValueError
, "rows for output array must match number of output ports");
815 // If we are out of sync, there might be bad data in the buffer
816 // So we have to throw that away first...
817 if (client
->input_buffer_size
) {
818 r
= read(client
->input_pipe
[R
], client
->input_buffer_1
, client
->input_buffer_size
);
820 // Copy data into array...
821 for(c
= 0; c
< client
->num_inputs
; c
++) {
822 for(j
= 0; j
< client
->buffer_size
; j
++) {
824 input_array
->data
+ (c
*input_array
->strides
[0] + j
*input_array
->strides
[1]),
825 client
->input_buffer_1
+ j
+ (c
*client
->buffer_size
),
831 if(!client
->iosync
) {
832 PyErr_SetString(JackInputSyncError
, "Input data stream is not synchronized.");
837 if (client
->output_buffer_size
) {
838 // Copy output data into output buffer...
839 for(c
= 0; c
< client
->num_outputs
; c
++) {
840 for(j
= 0; j
< client
->buffer_size
; j
++) {
841 memcpy(&client
->output_buffer_1
[j
+ (c
*client
->buffer_size
)],
842 output_array
->data
+ c
*output_array
->strides
[0] + j
*output_array
->strides
[1],
848 // Send... raise an exception if the output data stream is full.
849 r
= write(client
->output_pipe
[W
], client
->output_buffer_1
, client
->output_buffer_size
);
851 if(r
!= client
->output_buffer_size
) {
852 PyErr_SetString(JackOutputSyncError
, "Failed to write output data.");
862 // Return event status numbers...
863 static PyObject
* check_events(PyObject
* self
, PyObject
*args
)
865 pyjack_client_t
* client
= self_or_global_client(self
);
869 if(d
== NULL
) return NULL
;
871 PyDict_SetItemString(d
, "graph_ordering", Py_BuildValue("i", client
->event_graph_ordering
));
872 PyDict_SetItemString(d
, "port_registration", Py_BuildValue("i", client
->event_port_registration
));
873 PyDict_SetItemString(d
, "xrun", Py_BuildValue("i", client
->event_xrun
));
874 PyDict_SetItemString(d
, "shutdown", Py_BuildValue("i", client
->event_shutdown
));
875 PyDict_SetItemString(d
, "hangup", Py_BuildValue("i", client
->event_hangup
));
878 client
->event_graph_ordering
= 0;
879 client
->event_port_registration
= 0;
880 client
->event_xrun
= 0;
881 client
->event_shutdown
= 0;
882 client
->event_hangup
= 0;
887 static PyObject
* get_frame_time(PyObject
* self
, PyObject
* args
)
889 pyjack_client_t
* client
= self_or_global_client(self
);
890 if(client
->pjc
== NULL
) {
891 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
895 int frt
= jack_frame_time(client
->pjc
);
896 return Py_BuildValue("i", frt
);
899 static PyObject
* get_current_transport_frame(PyObject
* self
, PyObject
* args
)
901 pyjack_client_t
* client
= self_or_global_client(self
);
902 if(client
->pjc
== NULL
) {
903 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
907 int ftr
= jack_get_current_transport_frame(client
->pjc
);
908 return Py_BuildValue("i", ftr
);
911 static PyObject
* transport_locate (PyObject
* self
, PyObject
* args
)
913 pyjack_client_t
* client
= self_or_global_client(self
);
914 jack_nframes_t newfr
;
916 if (! PyArg_ParseTuple(args
, "i", &newfr
))
919 if(client
->pjc
== NULL
) {
920 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
924 jack_transport_locate (client
->pjc
,newfr
);
928 static PyObject
* get_transport_state (PyObject
* self
, PyObject
* args
)
931 pyjack_client_t
* client
= self_or_global_client(self
);
932 if(client
->pjc
== NULL
) {
933 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
937 jack_transport_state_t transport_state
;
938 transport_state
= jack_transport_query (client
->pjc
, NULL
);
940 return Py_BuildValue("i", transport_state
);
944 static PyObject
* get_version(PyObject
* self
, PyObject
* args
)
946 int major
, minor
, micro
, proto
;
947 jack_get_version(&major
, &minor
, µ
, &proto
);
948 return Py_BuildValue("iiii", major
, minor
, micro
, proto
);
953 static PyObject
* get_version_string(PyObject
* self
, PyObject
* args
)
956 version
= jack_get_version_string();
957 return Py_BuildValue("s", version
);
961 static PyObject
* get_cpu_load(PyObject
* self
, PyObject
* args
)
963 pyjack_client_t
* client
= self_or_global_client(self
);
964 if(client
->pjc
== NULL
) {
965 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
969 float cpu_load
= jack_cpu_load(client
->pjc
);
971 return Py_BuildValue("f", cpu_load
);
974 static PyObject
* get_port_short_name(PyObject
* self
, PyObject
* args
)
978 if (! PyArg_ParseTuple(args
, "s", &port_name
))
981 if (port_name
== NULL
) {
982 PyErr_SetString(JackError
, "Port name cannot be empty.");
986 pyjack_client_t
* client
= self_or_global_client(self
);
987 if(client
->pjc
== NULL
) {
988 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
992 jack_port_t
* port
= jack_port_by_name(client
->pjc
, port_name
);
994 PyErr_SetString(JackError
, "Port name cannot be empty.");
997 const char * port_short_name
= jack_port_short_name(port
);
999 return Py_BuildValue("s", port_short_name
);
1002 static PyObject
* get_port_type(PyObject
* self
, PyObject
* args
)
1006 if (! PyArg_ParseTuple(args
, "s", &port_name
))
1009 if (port_name
== NULL
) {
1010 PyErr_SetString(JackError
, "Port name cannot be empty.");
1014 pyjack_client_t
* client
= self_or_global_client(self
);
1015 if(client
->pjc
== NULL
) {
1016 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
1020 jack_port_t
* port
= jack_port_by_name(client
->pjc
, port_name
);
1022 PyErr_SetString(JackError
, "Port name cannot be empty.");
1025 const char * port_type
= jack_port_type(port
);
1027 return Py_BuildValue("s", port_type
);
1031 static PyObject
* get_port_type_id(PyObject
* self
, PyObject
* args
)
1035 if (! PyArg_ParseTuple(args
, "s", &port_name
))
1038 if (port_name
== NULL
) {
1039 PyErr_SetString(JackError
, "Port name cannot be empty.");
1043 pyjack_client_t
* client
= self_or_global_client(self
);
1044 if(client
->pjc
== NULL
) {
1045 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
1049 jack_port_t
* port
= jack_port_by_name(client
->pjc
, port_name
);
1051 PyErr_SetString(JackError
, "Port name cannot be empty.");
1055 jack_port_type_id_t port_type_id
= jack_port_type_id(port
);
1057 int ret
= port_type_id
;
1058 return Py_BuildValue("i", ret
);
1062 static PyObject
* is_realtime(PyObject
* self
, PyObject
* args
)
1064 pyjack_client_t
* client
= self_or_global_client(self
);
1065 if(client
->pjc
== NULL
) {
1066 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
1070 int realtime
= jack_is_realtime(client
->pjc
);
1071 return Py_BuildValue("i", realtime
);
1074 static PyObject
* port_is_mine(PyObject
* self
, PyObject
* args
)
1078 if (! PyArg_ParseTuple(args
, "s", &port_name
))
1081 if (port_name
== NULL
) {
1082 PyErr_SetString(JackError
, "Port name cannot be empty.");
1086 pyjack_client_t
* client
= self_or_global_client(self
);
1087 if(client
->pjc
== NULL
) {
1088 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
1092 jack_port_t
* port
= jack_port_by_name(client
->pjc
, port_name
);
1094 PyErr_SetString(JackError
, "Port name cannot be empty.");
1098 int port_mine
= jack_port_is_mine(client
->pjc
, port
);
1099 return Py_BuildValue("i", port_mine
);
1103 static PyObject
* transport_stop (PyObject
* self
, PyObject
* args
)
1105 pyjack_client_t
* client
= self_or_global_client(self
);
1106 if(client
->pjc
== NULL
) {
1107 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
1111 jack_transport_stop (client
->pjc
);
1116 static PyObject
* transport_start (PyObject
* self
, PyObject
* args
)
1118 pyjack_client_t
* client
= self_or_global_client(self
);
1119 if(client
->pjc
== NULL
) {
1120 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
1124 jack_transport_start (client
->pjc
);
1129 static PyObject
* set_buffer_size(PyObject
* self
, PyObject
* args
)
1133 if (! PyArg_ParseTuple(args
, "i", &size
))
1136 pyjack_client_t
* client
= self_or_global_client(self
);
1137 if(client
->pjc
== NULL
) {
1138 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
1142 jack_nframes_t nsize
= size
;
1143 jack_set_buffer_size(client
->pjc
, nsize
);
1149 static PyObject
* set_freewheel(PyObject
* self
, PyObject
* args
)
1153 if (! PyArg_ParseTuple(args
, "i", &onoff
))
1156 pyjack_client_t
* client
= self_or_global_client(self
);
1157 if(client
->pjc
== NULL
) {
1158 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
1162 int ret
= jack_set_freewheel(client
->pjc
, onoff
);
1163 return Py_BuildValue("i", ret
);
1166 static PyObject
* set_sync_timeout(PyObject
* self
, PyObject
* args
)
1170 if (! PyArg_ParseTuple(args
, "i", &time
))
1173 pyjack_client_t
* client
= self_or_global_client(self
);
1174 if(client
->pjc
== NULL
) {
1175 PyErr_SetString(JackNotConnectedError
, "Jack connection has not yet been established.");
1179 jack_time_t timeout
= time
;
1180 jack_set_sync_timeout(client
->pjc
, timeout
);
1186 // Python Module definition ---------------------------------------------------
1188 static PyMethodDef pyjack_methods
[] = {
1189 {"attach", attach
, METH_VARARGS
, "attach(name):\n Attach client to the Jack server"},
1190 {"detach", detach
, METH_VARARGS
, "detach():\n Detach client from the Jack server"},
1191 {"activate", activate
, METH_VARARGS
, "activate():\n Activate audio processing"},
1192 {"deactivate", deactivate
, METH_VARARGS
, "deactivate():\n Deactivate audio processing"},
1193 {"connect", port_connect
, METH_VARARGS
, "connect(source, destination):\n Connect two ports, given by name"},
1194 {"disconnect", port_disconnect
, METH_VARARGS
, "disconnect(source, destination):\n Disconnect two ports, given by name"},
1195 {"process", process
, METH_VARARGS
, "process(output_array, input_array):\n Exchange I/O data with RT Jack thread"},
1196 {"get_client_name", get_client_name
, METH_VARARGS
, "client_name():\n Returns the actual name of the client"},
1197 {"register_port", register_port
, METH_VARARGS
, "register_port(name, flags):\n Register a new port for this client"},
1198 {"unregister_port", unregister_port
, METH_VARARGS
, "unregister_port(name):\n Unregister an existing port for this client"},
1199 {"get_ports", get_ports
, METH_VARARGS
, "get_ports():\n Get a list of all ports in the Jack graph"},
1200 {"get_port_flags", get_port_flags
, METH_VARARGS
, "get_port_flags(port):\n Return flags of a port (flags are bits in an integer)"},
1201 {"get_connections", get_connections
, METH_VARARGS
, "get_connections():\n Get a list of all ports connected to a port"},
1202 {"get_buffer_size", get_buffer_size
, METH_VARARGS
, "get_buffer_size():\n Get the buffer size currently in use"},
1203 {"get_sample_rate", get_sample_rate
, METH_VARARGS
, "get_sample_rate():\n Get the sample rate currently in use"},
1204 {"get_freewheel", get_freewheel
, METH_VARARGS
, "get_freewheel():\n Returns 1 if the JACK freewheel mode is started"},
1205 {"check_events", check_events
, METH_VARARGS
, "check_events():\n Check for event notifications"},
1206 {"get_frame_time", get_frame_time
, METH_VARARGS
, "get_frame_time():\n Returns the current frame time"},
1207 {"get_current_transport_frame", get_current_transport_frame
, METH_VARARGS
, "get_current_transport_frame():\n Returns the current transport frame"},
1208 {"transport_locate", transport_locate
, METH_VARARGS
, "transport_locate(frame):\n Sets the current transport frame"},
1209 {"get_transport_state",get_transport_state
, METH_VARARGS
, "get_transport_state():\n Returns the current transport state"},
1210 {"transport_stop", transport_stop
, METH_VARARGS
, "transport_stop():\n Stopping transport"},
1211 {"transport_start", transport_start
, METH_VARARGS
, "transport_start():\n Starting transport"},
1213 {"get_version", get_version
, METH_VARARGS
, "get_version():\n Returns the version of JACK, in form of several numbers"},
1214 {"get_version_string", get_version_string
, METH_VARARGS
, "get_version_string():\n Returns the version of JACK, in form of a string"},
1216 {"get_cpu_load", get_cpu_load
, METH_VARARGS
, "get_cpu_load():\n Returns the current CPU load estimated by JACK"},
1217 {"get_port_short_name",get_port_short_name
, METH_VARARGS
, "get_port_short_name(port):\n Returns the short name of the port (not including the \"client_name:\" prefix)"},
1218 {"get_port_type", get_port_type
, METH_VARARGS
, "get_port_type(port):\n Returns the port type (in a string)"},
1220 {"get_port_type_id", get_port_type_id
, METH_VARARGS
, "get_port_type_id(port):\n Returns the port type id"},
1222 {"is_realtime", is_realtime
, METH_VARARGS
, "is_realtime():\n Returns 1 if the JACK subsystem is running with -R (--realtime)"},
1223 {"port_is_mine", port_is_mine
, METH_VARARGS
, "port_is_mine(port):\n Returns 1 if port belongs to the running client"},
1224 {"set_buffer_size", set_buffer_size
, METH_VARARGS
, "set_buffer_size(size):\n Sets Jack Buffer Size (minimum appears to be 16)."},
1225 {"set_freewheel", set_freewheel
, METH_VARARGS
, "set_freewheel(onoff):\n Start/Stop JACK freewheel mode."},
1226 {"set_sync_timeout", set_sync_timeout
, METH_VARARGS
, "set_sync_timeout(time):\n Sets the delay (in microseconds) before the timeout expires."},
1231 Client_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1233 pyjack_client_t
*self
= (pyjack_client_t
*)type
->tp_alloc(type
, 0);
1234 if (self
== NULL
) return NULL
;
1238 return (PyObject
*)self
;
1242 Client_init(PyObject
*self
, PyObject
*args
, PyObject
*kwds
)
1245 if (!attach(self
, args
)) status
= -1;
1250 Client_dealloc(PyObject
* self
)
1252 puts("pyjack: dealloc");
1253 detach(self
, Py_None
);
1254 self
->ob_type
->tp_free(self
);
1258 static PyTypeObject pyjack_ClientType
= {
1259 PyObject_HEAD_INIT(NULL
)
1261 /*tp_name*/ "jack.Client",
1262 /*tp_basicsize*/ sizeof(pyjack_client_t
),
1264 /*tp_dealloc*/ Client_dealloc
,
1271 /*tp_as_sequence*/ 0,
1272 /*tp_as_mapping*/ 0,
1279 /*tp_flags*/ Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
,
1280 /* tp_doc */ "JACK client object.\n"
1281 "Instatiate a jack.Client to interact with a jack server.\n"
1283 /* tp_traverse */ 0,
1285 /* tp_richcompare */ 0,
1286 /* tp_weaklistoffset */ 0,
1288 /* tp_iternext */ 0,
1289 /* tp_methods */ pyjack_methods
,
1294 /* tp_descr_get */ 0,
1295 /* tp_descr_set */ 0,
1296 /* tp_dictoffset */ 0,
1297 /* tp_init */ Client_init
,
1299 /* tp_new */ Client_new
,
1304 #ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
1305 #define PyMODINIT_FUNC void
1312 if (PyType_Ready(&pyjack_ClientType
) < 0)
1314 m
= Py_InitModule3("jack", pyjack_methods
,
1315 "This module provides bindings to manage clients for the Jack Audio Connection Kit architecture");
1318 d
= PyModule_GetDict(m
);
1322 Py_INCREF(&pyjack_ClientType
);
1323 PyModule_AddObject(m
, "Client", (PyObject
*)&pyjack_ClientType
);
1326 JackError
= PyErr_NewException("jack.Error", NULL
, NULL
);
1327 JackNotConnectedError
= PyErr_NewException("jack.NotConnectedError", NULL
, NULL
);
1328 JackUsageError
= PyErr_NewException("jack.UsageError", NULL
, NULL
);
1329 JackInputSyncError
= PyErr_NewException("jack.InputSyncError", NULL
, NULL
);
1330 JackOutputSyncError
= PyErr_NewException("jack.OutputSyncError", NULL
, NULL
);
1332 PyDict_SetItemString(d
, "Error", JackError
);
1333 PyDict_SetItemString(d
, "NotConnectedError", JackNotConnectedError
);
1334 PyDict_SetItemString(d
, "UsageError", JackUsageError
);
1335 PyDict_SetItemString(d
, "InputSyncError", JackInputSyncError
);
1336 PyDict_SetItemString(d
, "OutputSyncError", JackOutputSyncError
);
1338 PyDict_SetItemString(d
, "IsInput", Py_BuildValue("i", JackPortIsInput
));
1339 PyDict_SetItemString(d
, "IsOutput", Py_BuildValue("i", JackPortIsOutput
));
1340 PyDict_SetItemString(d
, "IsTerminal", Py_BuildValue("i", JackPortIsTerminal
));
1341 PyDict_SetItemString(d
, "IsPhysical", Py_BuildValue("i", JackPortIsPhysical
));
1342 PyDict_SetItemString(d
, "CanMonitor", Py_BuildValue("i", JackPortCanMonitor
));
1343 PyDict_SetItemString(d
, "TransportStopped", Py_BuildValue("i", JackTransportStopped
));
1344 PyDict_SetItemString(d
, "TransportRolling", Py_BuildValue("i", JackTransportRolling
));
1345 PyDict_SetItemString(d
, "TransportStarting", Py_BuildValue("i", JackTransportStarting
));
1347 // Enable Numeric module
1350 if (PyErr_Occurred())
1353 // Init jack data structures
1354 pyjack_init(&global_client
);
1359 Py_FatalError("Failed to initialize module pyjack");