Distribute pyjack with freewheel-related functionality
[jack_freewheel_button.git] / pyjack-0.5.2 / pyjack.c
blob711a8a82108fbaf78070788b85c5a6a93070214c
1 /**
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.
9 */
11 // Python includes
12 #include "Python.h"
13 #include "numpy/arrayobject.h"
15 // Jack
16 #include <jack/jack.h>
17 #include <jack/transport.h>
19 // C standard
20 #include <stdio.h>
21 #include <sys/time.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <signal.h>
29 TODO's:
30 - dettach on client on __del__
31 - free buffers
32 - close sockets
33 - hangup callback
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 */
43 // #define JACK2 1
46 #define PYJACK_MAX_PORTS 256
47 #define W 0
48 #define R 1
49 typedef struct {
50 PyObject_HEAD
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
78 } pyjack_client_t;
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) {
89 client->pjc = NULL;
90 client->active = 0;
91 client->iosync = 0;
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;
130 free(*pointer);
131 *pointer=0;
134 static void close_and_reset(int * fd)
136 if (!*fd) return;
137 close(*fd);
138 *fd=0;
141 // Finalize global data
142 void pyjack_final(pyjack_client_t * client) {
143 client->pjc = NULL;
144 // Free buffers...
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);
152 // Close socket...
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;
193 int i, r;
195 // Send input data to python side (non-blocking!)
196 if (client->num_inputs) {
197 for(i = 0; i < client->num_inputs; i++) {
198 memcpy(
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);
207 if(r < 0) {
208 client->iosync = 0;
209 } else if(r == client->input_buffer_size) {
210 client->iosync = 1;
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");
219 return 0;
221 for(i = 0; i < client->num_outputs; i++) {
222 memcpy(
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)
230 return 0;
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;
237 return 0;
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;
244 return 0;
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;
258 return 0;
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;
265 return 0;
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;
274 // Shutdown handler
275 void pyjack_shutdown(void * arg) {
276 pyjack_client_t * client = (pyjack_client_t*) arg;
277 client->event_shutdown = 1;
278 client->pjc = NULL;
281 // SIGHUP handler
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)
300 char* cname;
301 if (! PyArg_ParseTuple(args, "s", &cname))
302 return NULL;
304 pyjack_client_t * client = self_or_global_client(self);
305 if(client->pjc != NULL) {
306 PyErr_SetString(JackUsageError, "A connection is already established.");
307 return NULL;
310 jack_status_t status;
311 client->pjc = jack_client_open(cname, JackNoStartServer, &status);
312 if(client->pjc == NULL) {
313 //TODO check status
314 PyErr_SetString(JackNotConnectedError, "Failed to connect to Jack audio server.");
315 return NULL;
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.");
323 return NULL;
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.");
328 return NULL;
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.");
333 return NULL;
336 if(jack_set_freewheel_callback(client->pjc, pyjack_freewheel_changed, client) != 0) {
337 PyErr_SetString(JackError, "Failed to set jack sample rate callback.");
338 return NULL;
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.");
343 return NULL;
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.");
348 return NULL;
351 if(jack_set_xrun_callback(client->pjc, pyjack_xrun, client) != 0) {
352 PyErr_SetString(JackError, "Failed to set jack xrun callback.");
353 return NULL;
356 // Get buffer size
357 client->buffer_size = jack_get_buffer_size(client->pjc);
359 // Success!
360 Py_INCREF(Py_None);
361 return Py_None;
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);
374 Py_INCREF(Py_None);
375 return Py_None;
378 static PyObject* unregister_port(PyObject* self, PyObject* args)
380 pyjack_client_t * client = self_or_global_client(self);
381 char* port_name;
382 if (! PyArg_ParseTuple(args, "s", &port_name))
383 return NULL;
385 if(client->pjc == NULL) {
386 PyErr_SetString(JackNotConnectedError, "Jack connection has not yet been established.");
387 return NULL;
390 // if(client->active) {
391 // PyErr_SetString(JackUsageError, "Cannot unregister ports while client is active.");
392 // return NULL;
393 // }
395 int i = 0;
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]);
399 if (error) {
400 PyErr_SetString(JackError, "Unable to unregister input port.");
401 return NULL;
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);
408 Py_INCREF(Py_None);
409 return Py_None;
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]);
415 if (error) {
416 PyErr_SetString(JackError, "Unable to unregister output port.");
417 return NULL;
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);
424 Py_INCREF(Py_None);
425 return Py_None;
427 PyErr_SetString(JackUsageError, "Port not found.");
428 return NULL;
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);
438 int flags;
439 char* pname;
440 if (! PyArg_ParseTuple(args, "si", &pname, &flags))
441 return NULL;
443 if(client->pjc == NULL) {
444 PyErr_SetString(JackNotConnectedError, "Jack connection has not yet been established.");
445 return NULL;
448 // if(client->active) {
449 // PyErr_SetString(JackUsageError, "Cannot register ports while client is active.");
450 // return NULL;
451 // }
453 if(client->num_inputs >= PYJACK_MAX_PORTS) {
454 PyErr_SetString(JackUsageError, "Cannot create more than 256 ports. Sorry.");
455 return NULL;
458 jack_port_t* jp = jack_port_register(client->pjc, pname, JACK_DEFAULT_AUDIO_TYPE, flags, 0);
459 if(jp == NULL) {
460 PyErr_SetString(JackError, "Failed to create port.");
461 return NULL;
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);
475 Py_INCREF(Py_None);
476 return Py_None;
479 // Returns a list of all port names registered in the Jack system
480 static PyObject* get_ports(PyObject* self, PyObject* args)
482 PyObject* plist;
483 const char** jplist;
484 int i;
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.");
489 return NULL;
492 jplist = jack_get_ports(client->pjc, NULL, NULL, 0);
494 i = 0;
495 plist = PyList_New(0);
496 if(jplist != NULL) {
497 while(jplist[i] != NULL) {
498 PyList_Append(plist, Py_BuildValue("s", jplist[i]));
499 //free(jplist[i]); // Memory leak or not??
500 i++;
504 Py_INCREF(plist);
505 return plist;
508 // Return port flags (an integer)
509 static PyObject* get_port_flags(PyObject* self, PyObject* args)
511 char* pname;
512 jack_port_t* jp;
513 int i;
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.");
518 return NULL;
521 if (! PyArg_ParseTuple(args, "s", &pname))
522 return NULL;
524 jp = jack_port_by_name(client->pjc, pname);
525 if(jp == NULL) {
526 PyErr_SetString(JackError, "Bad port name.");
527 return NULL;
530 i = jack_port_flags(jp);
531 if(i < 0) {
532 PyErr_SetString(JackError, "Error getting port flags.");
533 return NULL;
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)
543 char* pname;
544 const char** jplist;
545 jack_port_t* jp;
546 PyObject* plist;
547 int i;
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.");
552 return NULL;
555 if (! PyArg_ParseTuple(args, "s", &pname))
556 return NULL;
558 jp = jack_port_by_name(client->pjc, pname);
559 if(jp == NULL) {
560 PyErr_SetString(JackError, "Bad port name.");
561 return NULL;
564 jplist = jack_port_get_all_connections(client->pjc, jp);
566 i = 0;
567 plist = PyList_New(0);
568 if(jplist != NULL) {
569 while(jplist[i] != NULL) {
570 PyList_Append(plist, Py_BuildValue("s", jplist[i]));
571 //free(jplist[i]); // memory leak or not?
572 i++;
576 Py_INCREF(plist);
577 return plist;
580 // connect_port
581 static PyObject* port_connect(PyObject* self, PyObject* args)
583 char* src_name;
584 char* dst_name;
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.");
589 return NULL;
592 if (! PyArg_ParseTuple(args, "ss", &src_name, &dst_name))
593 return NULL;
595 jack_port_t * src = jack_port_by_name(client->pjc, src_name);
596 if (!src) {
597 PyErr_SetString(JackUsageError, "Non existing source port.");
598 return NULL;
600 jack_port_t * dst = jack_port_by_name(client->pjc, dst_name);
601 if (!dst) {
602 PyErr_SetString(JackUsageError, "Non existing destination port.");
603 return NULL;
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.");
608 return NULL;
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.");
614 return NULL;
617 Py_INCREF(Py_None);
618 return Py_None;
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;
633 return 0;
636 // disconnect_port
637 static PyObject* port_disconnect(PyObject* self, PyObject* args)
639 char* src_name;
640 char* dst_name;
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.");
645 return NULL;
648 if (! PyArg_ParseTuple(args, "ss", &src_name, &dst_name))
649 return NULL;
651 jack_port_t * src = jack_port_by_name(client->pjc, src_name);
652 if (!src) {
653 PyErr_SetString(JackUsageError, "Non existing source port.");
654 return NULL;
657 jack_port_t * dst = jack_port_by_name(client->pjc, dst_name);
658 if (!dst) {
659 PyErr_SetString(JackUsageError, "Non existing destination port.");
660 return NULL;
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.");
666 return NULL;
670 Py_INCREF(Py_None);
671 return Py_None;
674 // get_buffer_size
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.");
681 return NULL;
684 int bs = jack_get_buffer_size(client->pjc);
685 return Py_BuildValue("i", bs);
688 // get_sample_rate
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.");
694 return NULL;
697 int sr = jack_get_sample_rate(client->pjc);
698 return Py_BuildValue("i", sr);
701 // activate
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.");
707 return NULL;
710 if(client->active) {
711 PyErr_SetString(JackUsageError, "Client is already active.");
712 return NULL;
715 if(jack_activate(client->pjc) != 0) {
716 PyErr_SetString(JackUsageError, "Could not activate client.");
717 return NULL;
720 client->active = 1;
721 Py_INCREF(Py_None);
722 return Py_None;
725 // deactivate
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.");
731 return NULL;
734 if(! client->active) {
735 PyErr_SetString(JackUsageError, "Client is not active.");
736 return NULL;
739 if(jack_deactivate(client->pjc) != 0) {
740 PyErr_SetString(JackError, "Could not deactivate client.");
741 return NULL;
744 client->active = 0;
745 Py_INCREF(Py_None);
746 return Py_None;
749 // get_buffer_size
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.");
756 return NULL;
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.");
767 return NULL;
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)
777 int j, c, r;
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.");
784 return NULL;
787 // Import the first and only arg...
788 if (! PyArg_ParseTuple(args, "O!O!", &PyArray_Type, &output_array, &PyArray_Type, &input_array))
789 return NULL;
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");
793 return NULL;
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");
798 return NULL;
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.");
803 return NULL;
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");
807 return NULL;
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");
811 return NULL;
814 // Get input data
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++) {
823 memcpy(
824 input_array->data + (c*input_array->strides[0] + j*input_array->strides[1]),
825 client->input_buffer_1 + j + (c*client->buffer_size),
826 sizeof(float)
831 if(!client->iosync) {
832 PyErr_SetString(JackInputSyncError, "Input data stream is not synchronized.");
833 return NULL;
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],
843 sizeof(float)
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.");
853 return NULL;
857 // Okay...
858 Py_INCREF(Py_None);
859 return Py_None;
862 // Return event status numbers...
863 static PyObject* check_events(PyObject* self, PyObject *args)
865 pyjack_client_t * client = self_or_global_client(self);
867 PyObject* d;
868 d = PyDict_New();
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));
877 // Reset all
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;
884 return d;
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.");
892 return NULL;
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.");
904 return NULL;
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))
917 return NULL;
919 if(client->pjc == NULL) {
920 PyErr_SetString(JackNotConnectedError, "Jack connection has not yet been established.");
921 return NULL;
924 jack_transport_locate (client->pjc,newfr);
925 return Py_None;
928 static PyObject* get_transport_state (PyObject* self, PyObject* args)
930 //int state;
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.");
934 return NULL;
937 jack_transport_state_t transport_state;
938 transport_state = jack_transport_query (client->pjc, NULL);
940 return Py_BuildValue("i", transport_state);
943 #ifdef JACK2
944 static PyObject* get_version(PyObject* self, PyObject* args)
946 int major, minor, micro, proto;
947 jack_get_version(&major, &minor, &micro, &proto);
948 return Py_BuildValue("iiii", major, minor, micro, proto);
950 #endif
952 #ifdef JACK2
953 static PyObject* get_version_string(PyObject* self, PyObject* args)
955 const char* version;
956 version = jack_get_version_string();
957 return Py_BuildValue("s", version);
959 #endif
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.");
966 return NULL;
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)
976 char * port_name;
978 if (! PyArg_ParseTuple(args, "s", &port_name))
979 return NULL;
981 if (port_name == NULL) {
982 PyErr_SetString(JackError, "Port name cannot be empty.");
983 return NULL;
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.");
989 return NULL;
992 jack_port_t * port = jack_port_by_name(client->pjc, port_name);
993 if (!port) {
994 PyErr_SetString(JackError, "Port name cannot be empty.");
995 return NULL;
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)
1004 char * port_name;
1006 if (! PyArg_ParseTuple(args, "s", &port_name))
1007 return NULL;
1009 if (port_name == NULL) {
1010 PyErr_SetString(JackError, "Port name cannot be empty.");
1011 return NULL;
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.");
1017 return NULL;
1020 jack_port_t * port = jack_port_by_name(client->pjc, port_name);
1021 if (!port) {
1022 PyErr_SetString(JackError, "Port name cannot be empty.");
1023 return NULL;
1025 const char * port_type = jack_port_type(port);
1027 return Py_BuildValue("s", port_type);
1030 #ifdef JACK2
1031 static PyObject* get_port_type_id(PyObject* self, PyObject* args)
1033 char * port_name;
1035 if (! PyArg_ParseTuple(args, "s", &port_name))
1036 return NULL;
1038 if (port_name == NULL) {
1039 PyErr_SetString(JackError, "Port name cannot be empty.");
1040 return NULL;
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.");
1046 return NULL;
1049 jack_port_t * port = jack_port_by_name(client->pjc, port_name);
1050 if (!port) {
1051 PyErr_SetString(JackError, "Port name cannot be empty.");
1052 return NULL;
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);
1060 #endif
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.");
1067 return NULL;
1070 int realtime = jack_is_realtime(client->pjc);
1071 return Py_BuildValue("i", realtime);
1074 static PyObject* port_is_mine(PyObject* self, PyObject* args)
1076 char * port_name;
1078 if (! PyArg_ParseTuple(args, "s", &port_name))
1079 return NULL;
1081 if (port_name == NULL) {
1082 PyErr_SetString(JackError, "Port name cannot be empty.");
1083 return NULL;
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.");
1089 return NULL;
1092 jack_port_t * port = jack_port_by_name(client->pjc, port_name);
1093 if (!port) {
1094 PyErr_SetString(JackError, "Port name cannot be empty.");
1095 return NULL;
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.");
1108 return NULL;
1111 jack_transport_stop (client->pjc);
1113 return Py_None;
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.");
1121 return NULL;
1124 jack_transport_start (client->pjc);
1126 return Py_None;
1129 static PyObject* set_buffer_size(PyObject* self, PyObject* args)
1131 int size;
1133 if (! PyArg_ParseTuple(args, "i", &size))
1134 return NULL;
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.");
1139 return NULL;
1142 jack_nframes_t nsize = size;
1143 jack_set_buffer_size(client->pjc, nsize);
1145 return Py_None;
1148 // set_buffer_size
1149 static PyObject* set_freewheel(PyObject* self, PyObject* args)
1151 int onoff;
1153 if (! PyArg_ParseTuple(args, "i", &onoff))
1154 return NULL;
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.");
1159 return NULL;
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)
1168 int time;
1170 if (! PyArg_ParseTuple(args, "i", &time))
1171 return NULL;
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.");
1176 return NULL;
1179 jack_time_t timeout = time;
1180 jack_set_sync_timeout(client->pjc, timeout);
1182 return Py_None;
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"},
1212 #ifdef JACK2
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"},
1215 #endif
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)"},
1219 #ifdef JACK2
1220 {"get_port_type_id", get_port_type_id, METH_VARARGS, "get_port_type_id(port):\n Returns the port type id"},
1221 #endif
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."},
1227 {NULL, NULL}
1230 static PyObject *
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;
1236 pyjack_init(self);
1238 return (PyObject *)self;
1241 static int
1242 Client_init(PyObject *self, PyObject *args, PyObject *kwds)
1244 int status = 0;
1245 if (!attach(self, args)) status = -1;
1246 return status;
1249 static void
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)
1260 /*ob_size*/ 0,
1261 /*tp_name*/ "jack.Client",
1262 /*tp_basicsize*/ sizeof(pyjack_client_t),
1263 /*tp_itemsize*/ 0,
1264 /*tp_dealloc*/ Client_dealloc,
1265 /*tp_print*/ 0,
1266 /*tp_getattr*/ 0,
1267 /*tp_setattr*/ 0,
1268 /*tp_compare*/ 0,
1269 /*tp_repr*/ 0,
1270 /*tp_as_number*/ 0,
1271 /*tp_as_sequence*/ 0,
1272 /*tp_as_mapping*/ 0,
1273 /*tp_hash */ 0,
1274 /*tp_call*/ 0,
1275 /*tp_str*/ 0,
1276 /*tp_getattro*/ 0,
1277 /*tp_setattro*/ 0,
1278 /*tp_as_buffer*/ 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,
1284 /* tp_clear */ 0,
1285 /* tp_richcompare */ 0,
1286 /* tp_weaklistoffset */ 0,
1287 /* tp_iter */ 0,
1288 /* tp_iternext */ 0,
1289 /* tp_methods */ pyjack_methods,
1290 /* tp_members */ 0,
1291 /* tp_getset */ 0,
1292 /* tp_base */ 0,
1293 /* tp_dict */ 0,
1294 /* tp_descr_get */ 0,
1295 /* tp_descr_set */ 0,
1296 /* tp_dictoffset */ 0,
1297 /* tp_init */ Client_init,
1298 /* tp_alloc */ 0,
1299 /* tp_new */ Client_new,
1304 #ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
1305 #define PyMODINIT_FUNC void
1306 #endif
1307 PyMODINIT_FUNC
1308 initjack(void)
1310 PyObject *m, *d;
1312 if (PyType_Ready(&pyjack_ClientType) < 0)
1313 return;
1314 m = Py_InitModule3("jack", pyjack_methods,
1315 "This module provides bindings to manage clients for the Jack Audio Connection Kit architecture");
1316 if (m == NULL)
1317 goto fail;
1318 d = PyModule_GetDict(m);
1319 if (d == NULL)
1320 goto fail;
1322 Py_INCREF(&pyjack_ClientType);
1323 PyModule_AddObject(m, "Client", (PyObject *)&pyjack_ClientType);
1325 // Jack errors
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);
1337 // Jack flags
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
1348 import_array();
1350 if (PyErr_Occurred())
1351 goto fail;
1353 // Init jack data structures
1354 pyjack_init(&global_client);
1356 return;
1358 fail:
1359 Py_FatalError("Failed to initialize module pyjack");