1 #include <Python.h>
2 #include "ttl.h"
3 #include "ttldata.h"
4 #include <list>
5 #include <map>
6 #include <iostream>
7 #include <fstream>
8 #include <jack/jack.h>
9
10 //////////////////////////////////////////////////// PyJackClient
11
12 struct PyJackPort;
13
14 typedef std::map<jack_port_t *, PyJackPort *> PortHandleMap;
15
16 struct AsyncOperationInfo
17 {
18 enum OpCode { INVALID_OP, PORT_REGISTERED, PORT_UNREGISTERED, PORTS_CONNECTED, PORTS_DISCONNECTED };
19
20 OpCode opcode;
21 jack_port_id_t port, port2;
22
AsyncOperationInfoAsyncOperationInfo23 AsyncOperationInfo() { opcode = INVALID_OP; }
AsyncOperationInfoAsyncOperationInfo24 AsyncOperationInfo(OpCode _opcode, jack_port_id_t _port, jack_port_id_t _port2 = 0)
25 : opcode(_opcode), port(_port), port2(_port2) {}
argcAsyncOperationInfo26 inline int argc() {
27 if (opcode == PORT_REGISTERED || opcode == PORT_UNREGISTERED) return 1;
28 if (opcode == PORTS_CONNECTED || opcode == PORTS_DISCONNECTED) return 2;
29 return 0;
30 }
31 };
32
33 typedef std::list<AsyncOperationInfo> PortOperationList;
34
35 struct PyJackClient
36 {
37 PyObject_HEAD
38 jack_client_t *client;
39 PortHandleMap *port_handle_map;
40 pthread_mutex_t port_op_mutex;
41 PortOperationList *port_op_queue;
42 };
43
44 static PyTypeObject jackclient_type = {
45 PyObject_HEAD_INIT(NULL)
46 0, /*ob_size*/
47 "calfpytools.JackClient", /*tp_name*/
48 sizeof(PyJackClient), /*tp_basicsize*/
49 };
50
51 struct PyJackPort
52 {
53 PyObject_HEAD
54 PyJackClient *client;
55 jack_port_t *port;
56 };
57
58 static PyTypeObject jackport_type = {
59 PyObject_HEAD_INIT(NULL)
60 0, /*ob_size*/
61 "calfpytools.JackPort", /*tp_name*/
62 sizeof(PyJackPort), /*tp_basicsize*/
63 };
64
register_cb(jack_port_id_t port,int registered,void * arg)65 static void register_cb(jack_port_id_t port, int registered, void *arg)
66 {
67 PyJackClient *self = (PyJackClient *)arg;
68 pthread_mutex_lock(&self->port_op_mutex);
69 self->port_op_queue->push_back(AsyncOperationInfo(registered ? AsyncOperationInfo::PORT_REGISTERED : AsyncOperationInfo::PORT_UNREGISTERED, port));
70 pthread_mutex_unlock(&self->port_op_mutex);
71 }
72
connect_cb(jack_port_id_t port1,jack_port_id_t port2,int connected,void * arg)73 static void connect_cb(jack_port_id_t port1, jack_port_id_t port2, int connected, void *arg)
74 {
75 PyJackClient *self = (PyJackClient *)arg;
76 pthread_mutex_lock(&self->port_op_mutex);
77 self->port_op_queue->push_back(AsyncOperationInfo(connected ? AsyncOperationInfo::PORTS_CONNECTED : AsyncOperationInfo::PORTS_DISCONNECTED, port1, port2));
78 pthread_mutex_unlock(&self->port_op_mutex);
79 }
80
jackclient_open(PyJackClient * self,PyObject * args)81 static PyObject *jackclient_open(PyJackClient *self, PyObject *args)
82 {
83 const char *name;
84 int options = 0;
85 jack_status_t status = (jack_status_t)0;
86
87 if (!PyArg_ParseTuple(args, "s|i:open", &name, &options))
88 return NULL;
89
90 self->client = jack_client_open(name, (jack_options_t)options, &status);
91 self->port_handle_map = new PortHandleMap;
92 pthread_mutexattr_t attr;
93 pthread_mutexattr_init(&attr);
94 pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
95 pthread_mutex_init(&self->port_op_mutex, &attr);
96 self->port_op_queue = new PortOperationList;
97
98 jack_set_port_registration_callback(self->client, register_cb, self);
99 jack_set_port_connect_callback(self->client, connect_cb, self);
100 jack_activate(self->client);
101
102 return Py_BuildValue("i", status);
103 }
104
jackclient_dealloc(PyJackPort * self)105 static int jackclient_dealloc(PyJackPort *self)
106 {
107 if (self->client)
108 {
109 PyObject_CallMethod((PyObject *)self, strdup("close"), NULL);
110 assert(!self->client);
111 }
112
113 return 0;
114 }
115
116 #define CHECK_CLIENT if (!self->client) { PyErr_SetString(PyExc_ValueError, "Client not opened"); return NULL; }
117
118
jackclient_get_name(PyJackClient * self,PyObject * args)119 static PyObject *jackclient_get_name(PyJackClient *self, PyObject *args)
120 {
121 if (!PyArg_ParseTuple(args, ":get_name"))
122 return NULL;
123
124 CHECK_CLIENT
125
126 return Py_BuildValue("s", jack_get_client_name(self->client));
127 }
128
create_jack_port(PyJackClient * client,jack_port_t * port)129 static PyObject *create_jack_port(PyJackClient *client, jack_port_t *port)
130 {
131 PortHandleMap::iterator it = client->port_handle_map->find(port);
132 if (it != client->port_handle_map->end())
133 {
134 Py_INCREF(it->second);
135 return Py_BuildValue("O", it->second);
136 }
137 if (port)
138 {
139 PyObject *cobj = PyCObject_FromVoidPtr(port, NULL);
140 PyObject *args = Py_BuildValue("OO", client, cobj);
141 PyObject *newobj = _PyObject_New(&jackport_type);
142 jackport_type.tp_init(newobj, args, NULL);
143 (*client->port_handle_map)[port] = (PyJackPort *)newobj;
144 Py_DECREF(args);
145 return newobj;
146 }
147 Py_INCREF(Py_None);
148 return Py_None;
149 }
150
jackclient_register_port(PyJackClient * self,PyObject * args)151 static PyObject *jackclient_register_port(PyJackClient *self, PyObject *args)
152 {
153 const char *name, *type = JACK_DEFAULT_AUDIO_TYPE;
154 unsigned long flags = 0, buffer_size = 0;
155 if (!PyArg_ParseTuple(args, "s|sii:register_port", &name, &type, &flags, &buffer_size))
156 return NULL;
157
158 CHECK_CLIENT
159
160 jack_port_t *port = jack_port_register(self->client, name, type, flags, buffer_size);
161 return create_jack_port(self, port);
162 }
163
jackclient_get_port(PyJackClient * self,PyObject * args)164 static PyObject *jackclient_get_port(PyJackClient *self, PyObject *args)
165 {
166 const char *name;
167 if (!PyArg_ParseTuple(args, "s:get_port", &name))
168 return NULL;
169
170 CHECK_CLIENT
171
172 jack_port_t *port = jack_port_by_name(self->client, name);
173 return create_jack_port(self, port);
174 }
175
jackclient_get_cobj(PyJackClient * self,PyObject * args)176 static PyObject *jackclient_get_cobj(PyJackClient *self, PyObject *args)
177 {
178 if (!PyArg_ParseTuple(args, ":get_cobj"))
179 return NULL;
180
181 CHECK_CLIENT
182
183 return PyCObject_FromVoidPtr((void *)self->client, NULL);
184 }
185
jackclient_get_ports(PyJackClient * self,PyObject * args)186 static PyObject *jackclient_get_ports(PyJackClient *self, PyObject *args)
187 {
188 const char *name = NULL, *type = NULL;
189 unsigned long flags = 0;
190 if (!PyArg_ParseTuple(args, "|ssi:get_ports", &name, &type, &flags))
191 return NULL;
192
193 CHECK_CLIENT
194
195 const char **p = jack_get_ports(self->client, name, type, flags);
196 PyObject *res = PyList_New(0);
197 if (!p)
198 return res;
199
200 for (const char **q = p; *q; q++)
201 {
202 PyList_Append(res, PyString_FromString(*q));
203 // free(q);
204 }
205 free(p);
206
207 return res;
208 }
209
jackclient_connect(PyJackClient * self,PyObject * args)210 static PyObject *jackclient_connect(PyJackClient *self, PyObject *args)
211 {
212 char *from_port = NULL, *to_port = NULL;
213 if (!PyArg_ParseTuple(args, "ss:connect", &from_port, &to_port))
214 return NULL;
215
216 CHECK_CLIENT
217
218 int result = jack_connect(self->client, from_port, to_port);
219
220 switch(result)
221 {
222 case 0:
223 Py_INCREF(Py_True);
224 return Py_True;
225 case EEXIST:
226 Py_INCREF(Py_False);
227 return Py_False;
228 default:
229 PyErr_SetString(PyExc_RuntimeError, "Connection error");
230 return NULL;
231 }
232 }
233
create_jack_port_by_id(PyJackClient * self,jack_port_id_t id)234 static PyObject *create_jack_port_by_id(PyJackClient *self, jack_port_id_t id)
235 {
236 return create_jack_port(self, jack_port_by_id(self->client, id));
237 }
238
jackclient_get_message(PyJackClient * self,PyObject * args)239 static PyObject *jackclient_get_message(PyJackClient *self, PyObject *args)
240 {
241 if (!PyArg_ParseTuple(args, ":get_message"))
242 return NULL;
243
244 CHECK_CLIENT
245
246 PyObject *obj = NULL;
247 AsyncOperationInfo info;
248 pthread_mutex_lock(&self->port_op_mutex);
249 if (self->port_op_queue->empty())
250 {
251 obj = Py_None;
252 Py_INCREF(Py_None);
253 }
254 else
255 {
256 info = self->port_op_queue->front();
257 self->port_op_queue->pop_front();
258 }
259 pthread_mutex_unlock(&self->port_op_mutex);
260 if (!obj)
261 {
262 if (info.argc() == 1)
263 obj = Py_BuildValue("iO", info.opcode, create_jack_port_by_id(self, info.port));
264 else
265 if (info.argc() == 2)
266 obj = Py_BuildValue("iOO", info.opcode, create_jack_port_by_id(self, info.port), create_jack_port_by_id(self, info.port2));
267 }
268 return obj;
269 }
270
jackclient_disconnect(PyJackClient * self,PyObject * args)271 static PyObject *jackclient_disconnect(PyJackClient *self, PyObject *args)
272 {
273 char *from_port = NULL, *to_port = NULL;
274 if (!PyArg_ParseTuple(args, "ss:disconnect", &from_port, &to_port))
275 return NULL;
276
277 CHECK_CLIENT
278
279 int result = jack_disconnect(self->client, from_port, to_port);
280
281 switch(result)
282 {
283 case 0:
284 Py_INCREF(Py_None);
285 return Py_None;
286 default:
287 PyErr_SetString(PyExc_RuntimeError, "Disconnection error");
288 return NULL;
289 }
290 }
291
jackclient_close(PyJackClient * self,PyObject * args)292 static PyObject *jackclient_close(PyJackClient *self, PyObject *args)
293 {
294 if (!PyArg_ParseTuple(args, ":close"))
295 return NULL;
296
297 CHECK_CLIENT
298
299 jack_deactivate(self->client);
300 jack_client_close(self->client);
301 self->client = NULL;
302 delete self->port_handle_map;
303 delete self->port_op_queue;
304 pthread_mutex_destroy(&self->port_op_mutex);
305
306 Py_INCREF(Py_None);
307 return Py_None;
308 }
309
310 static PyMethodDef jackclient_methods[] = {
311 {"open", (PyCFunction)jackclient_open, METH_VARARGS, "Open a client"},
312 {"close", (PyCFunction)jackclient_close, METH_VARARGS, "Close a client"},
313 {"get_name", (PyCFunction)jackclient_get_name, METH_VARARGS, "Retrieve client name"},
314 {"get_port", (PyCFunction)jackclient_get_port, METH_VARARGS, "Create port object from name of existing JACK port"},
315 {"get_ports", (PyCFunction)jackclient_get_ports, METH_VARARGS, "Get a list of port names based on specified name, type and flag filters"},
316 {"register_port", (PyCFunction)jackclient_register_port, METH_VARARGS, "Register a new port and return an object that represents it"},
317 {"get_cobj", (PyCFunction)jackclient_get_cobj, METH_VARARGS, "Retrieve jack_client_t pointer for the client as CObject"},
318 {"get_message", (PyCFunction)jackclient_get_message, METH_VARARGS, "Retrieve next port registration/connection message from the message queue"},
319 {"connect", (PyCFunction)jackclient_connect, METH_VARARGS, "Connect two ports with given names"},
320 {"disconnect", (PyCFunction)jackclient_disconnect, METH_VARARGS, "Disconnect two ports with given names"},
321 {NULL, NULL, 0, NULL}
322 };
323
324 //////////////////////////////////////////////////// PyJackPort
325
jackport_init(PyJackPort * self,PyObject * args,PyObject * kwds)326 static int jackport_init(PyJackPort *self, PyObject *args, PyObject *kwds)
327 {
328 PyJackClient *client = NULL;
329 PyObject *cobj = NULL;
330
331 if (!PyArg_ParseTuple(args, "O!O:__init__", &jackclient_type, &client, &cobj))
332 return 0;
333 if (!PyCObject_Check(cobj))
334 {
335 PyErr_SetString(PyExc_TypeError, "Port constructor cannot be called explicitly");
336 return 0;
337 }
338 Py_INCREF(client);
339
340 self->client = client;
341 self->port = (jack_port_t *)PyCObject_AsVoidPtr(cobj);
342
343 return 0;
344 }
345
jackport_dealloc(PyJackPort * self)346 static int jackport_dealloc(PyJackPort *self)
347 {
348 // if not unregistered, decref (unregister decrefs automatically)
349 if (self->client) {
350 self->client->port_handle_map->erase(self->port);
351 Py_DECREF(self->client);
352 }
353
354 return 0;
355 }
356
357 #define CHECK_PORT_CLIENT if (!self->client || !self->client->client) { PyErr_SetString(PyExc_ValueError, "Client not opened"); return NULL; }
358 #define CHECK_PORT if (!self->port) { PyErr_SetString(PyExc_ValueError, "The port is not valid"); return NULL; }
359
jackport_strrepr(PyJackPort * self,int quotes)360 static PyObject *jackport_strrepr(PyJackPort *self, int quotes)
361 {
362 CHECK_PORT_CLIENT
363 CHECK_PORT
364
365 int flags = jack_port_flags(self->port);
366 int flags_io = flags & (JackPortIsInput | JackPortIsOutput);
367 return PyString_FromFormat("<calfpytools.JackPort, name=%s%s%s, flags=%s%s%s%s>",
368 quotes ? "\"" : "",
369 jack_port_name(self->port),
370 quotes ? "\"" : "",
371 (flags_io == JackPortIsInput) ? "in" : (flags_io == JackPortIsOutput ? "out" : "?"),
372 flags & JackPortIsPhysical ? "|physical" : "",
373 flags & JackPortCanMonitor ? "|can_monitor" : "",
374 flags & JackPortIsTerminal ? "|terminal" : "");
375 }
376
jackport_str(PyJackPort * self)377 static PyObject *jackport_str(PyJackPort *self)
378 {
379 return jackport_strrepr(self, 0);
380 }
381
jackport_repr(PyJackPort * self)382 static PyObject *jackport_repr(PyJackPort *self)
383 {
384 return jackport_strrepr(self, 1);
385 }
386
jackport_get_full_name(PyJackPort * self,PyObject * args)387 static PyObject *jackport_get_full_name(PyJackPort *self, PyObject *args)
388 {
389 if (!PyArg_ParseTuple(args, ":get_full_name"))
390 return NULL;
391
392 CHECK_PORT_CLIENT
393 CHECK_PORT
394
395 return Py_BuildValue("s", jack_port_name(self->port));
396 }
397
jackport_get_flags(PyJackPort * self,PyObject * args)398 static PyObject *jackport_get_flags(PyJackPort *self, PyObject *args)
399 {
400 if (!PyArg_ParseTuple(args, ":get_flags"))
401 return NULL;
402
403 CHECK_PORT_CLIENT
404 CHECK_PORT
405
406 return PyInt_FromLong(jack_port_flags(self->port));
407 }
408
jackport_is_valid(PyJackPort * self,PyObject * args)409 static PyObject *jackport_is_valid(PyJackPort *self, PyObject *args)
410 {
411 if (!PyArg_ParseTuple(args, ":is_valid"))
412 return NULL;
413
414 return PyBool_FromLong(self->client && self->client->client && self->port);
415 }
416
jackport_is_mine(PyJackPort * self,PyObject * args)417 static PyObject *jackport_is_mine(PyJackPort *self, PyObject *args)
418 {
419 if (!PyArg_ParseTuple(args, ":is_mine"))
420 return NULL;
421
422 CHECK_PORT_CLIENT
423 CHECK_PORT
424
425 return PyBool_FromLong(self->client && self->client->client && self->port && jack_port_is_mine(self->client->client, self->port));
426 }
427
jackport_get_name(PyJackPort * self,PyObject * args)428 static PyObject *jackport_get_name(PyJackPort *self, PyObject *args)
429 {
430 if (!PyArg_ParseTuple(args, ":get_name"))
431 return NULL;
432
433 CHECK_PORT_CLIENT
434 CHECK_PORT
435
436 return Py_BuildValue("s", jack_port_short_name(self->port));
437 }
438
jackport_get_type(PyJackPort * self,PyObject * args)439 static PyObject *jackport_get_type(PyJackPort *self, PyObject *args)
440 {
441 if (!PyArg_ParseTuple(args, ":get_type"))
442 return NULL;
443
444 CHECK_PORT_CLIENT
445 CHECK_PORT
446
447 return Py_BuildValue("s", jack_port_type(self->port));
448 }
449
jackport_get_cobj(PyJackPort * self,PyObject * args)450 static PyObject *jackport_get_cobj(PyJackPort *self, PyObject *args)
451 {
452 if (!PyArg_ParseTuple(args, ":get_cobj"))
453 return NULL;
454
455 CHECK_PORT_CLIENT
456 CHECK_PORT
457
458 return PyCObject_FromVoidPtr((void *)self->port, NULL);
459 }
460
jackport_get_aliases(PyJackPort * self,PyObject * args)461 static PyObject *jackport_get_aliases(PyJackPort *self, PyObject *args)
462 {
463 if (!PyArg_ParseTuple(args, ":get_aliases"))
464 return NULL;
465
466 CHECK_PORT_CLIENT
467 CHECK_PORT
468
469 char buf1[256], buf2[256];
470 char *const aliases[2] = { buf1, buf2 };
471 int count = jack_port_get_aliases(self->port, aliases);
472
473 PyObject *alist = PyList_New(0);
474 for (int i = 0; i < count; i++)
475 PyList_Append(alist, PyString_FromString(aliases[i]));
476 return alist;
477 }
478
jackport_get_connections(PyJackPort * self,PyObject * args)479 static PyObject *jackport_get_connections(PyJackPort *self, PyObject *args)
480 {
481 if (!PyArg_ParseTuple(args, ":get_aliases"))
482 return NULL;
483
484 CHECK_PORT_CLIENT
485 CHECK_PORT
486
487 const char **conns = jack_port_get_all_connections(self->client->client, self->port);
488
489 PyObject *res = PyList_New(0);
490 if (conns)
491 {
492 for (const char **p = conns; *p; p++)
493 PyList_Append(res, PyString_FromString(*p));
494 }
495
496 return res;
497 }
498
jackport_set_name(PyJackPort * self,PyObject * args)499 static PyObject *jackport_set_name(PyJackPort *self, PyObject *args)
500 {
501 const char *name;
502 if (!PyArg_ParseTuple(args, "s:set_name", &name))
503 return NULL;
504
505 CHECK_PORT
506
507 jack_port_set_name(self->port, name);
508
509 return Py_BuildValue("s", jack_port_short_name(self->port));
510 }
511
jackport_unregister(PyJackPort * self,PyObject * args)512 static PyObject *jackport_unregister(PyJackPort *self, PyObject *args)
513 {
514 if (!PyArg_ParseTuple(args, ":unregister"))
515 return NULL;
516
517 CHECK_PORT
518
519 PyJackClient *client = self->client;
520
521 client->port_handle_map->erase(self->port);
522 jack_port_unregister(self->client->client, self->port);
523 self->port = NULL;
524 self->client = NULL;
525
526 Py_DECREF(client);
527 client = NULL;
528 Py_INCREF(Py_None);
529 return Py_None;
530 }
531
532 static PyMethodDef jackport_methods[] = {
533 {"unregister", (PyCFunction)jackport_unregister, METH_VARARGS, "Unregister a port"},
534 {"is_valid", (PyCFunction)jackport_is_valid, METH_VARARGS, "Checks if the port object is valid (registered)"},
535 {"is_mine", (PyCFunction)jackport_is_mine, METH_VARARGS, "Checks if the port object is valid (registered)"},
536 {"get_full_name", (PyCFunction)jackport_get_full_name, METH_VARARGS, "Retrieve full port name (including client name)"},
537 {"get_name", (PyCFunction)jackport_get_name, METH_VARARGS, "Retrieve short port name (without client name)"},
538 {"get_type", (PyCFunction)jackport_get_type, METH_VARARGS, "Retrieve port type name"},
539 {"get_flags", (PyCFunction)jackport_get_flags, METH_VARARGS, "Retrieve port flags (defined in module, ie. calfpytools.JackPortIsInput)"},
540 {"set_name", (PyCFunction)jackport_set_name, METH_VARARGS, "Set short port name"},
541 {"get_aliases", (PyCFunction)jackport_get_aliases, METH_VARARGS, "Retrieve a list of port aliases"},
542 {"get_connections", (PyCFunction)jackport_get_connections, METH_VARARGS, "Retrieve a list of ports the port is connected to"},
543 {"get_cobj", (PyCFunction)jackport_get_cobj, METH_VARARGS, "Retrieve jack_port_t pointer for the port"},
544 {NULL, NULL, 0, NULL}
545 };
546
547
548 //////////////////////////////////////////////////// calfpytools
549
calfpytools_scan_ttl_file(PyObject * self,PyObject * args)550 static PyObject *calfpytools_scan_ttl_file(PyObject *self, PyObject *args)
551 {
552 char *ttl_name = NULL;
553 if (!PyArg_ParseTuple(args, "s:scan_ttl_file", &ttl_name))
554 return NULL;
555
556 std::ifstream istr(ttl_name, std::ifstream::in);
557 TTLLexer lexer(&istr);
558 lexer.yylex();
559 return lexer.grab();
560 }
561
calfpytools_scan_ttl_string(PyObject * self,PyObject * args)562 static PyObject *calfpytools_scan_ttl_string(PyObject *self, PyObject *args)
563 {
564 char *data = NULL;
565 if (!PyArg_ParseTuple(args, "s:scan_ttl_string", &data))
566 return NULL;
567
568 std::string data_str = data;
569 std::stringstream str(data_str);
570 TTLLexer lexer(&str);
571 lexer.yylex();
572 return lexer.grab();
573 }
574
575 static PyMethodDef module_methods[] = {
576 {"scan_ttl_file", calfpytools_scan_ttl_file, METH_VARARGS, "Scan a TTL file, return a list of token tuples"},
577 {"scan_ttl_string", calfpytools_scan_ttl_string, METH_VARARGS, "Scan a TTL string, return a list of token tuples"},
578 {NULL, NULL, 0, NULL}
579 };
580
initcalfpytools()581 PyMODINIT_FUNC initcalfpytools()
582 {
583 jackclient_type.tp_new = PyType_GenericNew;
584 jackclient_type.tp_flags = Py_TPFLAGS_DEFAULT;
585 jackclient_type.tp_doc = "JACK client object";
586 jackclient_type.tp_methods = jackclient_methods;
587 jackclient_type.tp_dealloc = (destructor)jackclient_dealloc;
588 if (PyType_Ready(&jackclient_type) < 0)
589 return;
590
591 jackport_type.tp_new = PyType_GenericNew;
592 jackport_type.tp_flags = Py_TPFLAGS_DEFAULT;
593 jackport_type.tp_doc = "JACK port object (created by client)";
594 jackport_type.tp_methods = jackport_methods;
595 jackport_type.tp_init = (initproc)jackport_init;
596 jackport_type.tp_dealloc = (destructor)jackport_dealloc;
597 jackport_type.tp_str = (reprfunc)jackport_str;
598 jackport_type.tp_repr = (reprfunc)jackport_repr;
599 if (PyType_Ready(&jackport_type) < 0)
600 return;
601
602 PyObject *mod = Py_InitModule3("calfpytools", module_methods, "Python utilities for Calf");
603 Py_INCREF(&jackclient_type);
604 Py_INCREF(&jackport_type);
605 PyModule_AddObject(mod, "JackClient", (PyObject *)&jackclient_type);
606 PyModule_AddObject(mod, "JackPort", (PyObject *)&jackport_type);
607
608 PyModule_AddObject(mod, "JackPortIsInput", PyInt_FromLong(JackPortIsInput));
609 PyModule_AddObject(mod, "JackPortIsOutput", PyInt_FromLong(JackPortIsOutput));
610 PyModule_AddObject(mod, "JackPortIsPhysical", PyInt_FromLong(JackPortIsPhysical));
611 PyModule_AddObject(mod, "JackPortCanMonitor", PyInt_FromLong(JackPortCanMonitor));
612 PyModule_AddObject(mod, "JackPortIsTerminal", PyInt_FromLong(JackPortIsTerminal));
613 PyModule_AddObject(mod, "JACK_DEFAULT_AUDIO_TYPE", PyString_FromString(JACK_DEFAULT_AUDIO_TYPE));
614 PyModule_AddObject(mod, "JACK_DEFAULT_MIDI_TYPE", PyString_FromString(JACK_DEFAULT_MIDI_TYPE));
615 }
616