Pass height/width to cairo.Surface.create_similar as integers
[jack_mixer.git] / jack_mixer_c.c
bloba1c2e1baa96937f76fc457f608fd35193220ee7a
1 /*
2 * This file is part of jack_mixer
4 * Copyright (C) 2009 Frederic Peters <fpeters@0d.be>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <Python.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdbool.h>
26 #include <structmember.h>
28 #include "jack_mixer.h"
31 /** Scale Type **/
33 typedef struct {
34 PyObject_HEAD
35 jack_mixer_scale_t scale;
36 } ScaleObject;
38 static void
39 Scale_dealloc(ScaleObject *self)
41 if (self->scale)
42 scale_destroy(self->scale);
43 self->ob_type->tp_free((PyObject*)self);
46 static int
47 Scale_init(ScaleObject *self, PyObject *args, PyObject *kwds)
49 self->scale = scale_create();
50 return 0;
53 static PyObject*
54 Scale_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
56 ScaleObject *self;
58 self = (ScaleObject*)type->tp_alloc(type, 0);
60 return (PyObject*)self;
63 static PyObject*
64 Scale_add_threshold(ScaleObject *self, PyObject *args)
66 float db, scale_value;
68 if (! PyArg_ParseTuple(args, "ff", &db, &scale_value)) return NULL;
70 scale_add_threshold(self->scale, db, scale_value);
72 Py_INCREF(Py_None);
73 return Py_None;
76 static PyObject*
77 Scale_calculate_coefficients(ScaleObject *self, PyObject *args)
79 if (! PyArg_ParseTuple(args, "")) return NULL;
80 scale_calculate_coefficients(self->scale);
81 Py_INCREF(Py_None);
82 return Py_None;
85 static PyObject*
86 Scale_db_to_scale(ScaleObject *self, PyObject *args)
88 double db;
89 if (! PyArg_ParseTuple(args, "d", &db)) return NULL;
90 return PyFloat_FromDouble(scale_db_to_scale(self->scale, db));
93 static PyObject*
94 Scale_scale_to_db(ScaleObject *self, PyObject *args)
96 double scale_value;
97 if (! PyArg_ParseTuple(args, "d", &scale_value)) return NULL;
98 return PyFloat_FromDouble(scale_scale_to_db(self->scale, scale_value));
101 static PyMethodDef Scale_methods[] = {
102 {"add_threshold", (PyCFunction)Scale_add_threshold, METH_VARARGS, "Add threshold"},
103 {"calculate_coefficients", (PyCFunction)Scale_calculate_coefficients,
104 METH_VARARGS, "Calculate coefficients"},
105 {"db_to_scale", (PyCFunction)Scale_db_to_scale, METH_VARARGS, "dB to scale"},
106 {"scale_to_db", (PyCFunction)Scale_scale_to_db, METH_VARARGS, "scale to dB"},
107 {NULL}
110 static PyTypeObject ScaleType = {
111 PyObject_HEAD_INIT(NULL)
112 0, /*ob_size*/
113 "jack_mixer_c.Scale", /*tp_name*/
114 sizeof(ScaleObject), /*tp_basicsize*/
115 0, /*tp_itemsize*/
116 (destructor)Scale_dealloc, /*tp_dealloc*/
117 0, /*tp_print*/
118 0, /*tp_getattr*/
119 0, /*tp_setattr*/
120 0, /*tp_compare*/
121 0, /*tp_repr*/
122 0, /*tp_as_number*/
123 0, /*tp_as_sequence*/
124 0, /*tp_as_mapping*/
125 0, /*tp_hash */
126 0, /*tp_call*/
127 0, /*tp_str*/
128 0, /*tp_getattro*/
129 0, /*tp_setattro*/
130 0, /*tp_as_buffer*/
131 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
132 "Scale objects", /* tp_doc */
133 0, /* tp_traverse */
134 0, /* tp_clear */
135 0, /* tp_richcompare */
136 0, /* tp_weaklistoffset */
137 0, /* tp_iter */
138 0, /* tp_iternext */
139 Scale_methods, /* tp_methods */
140 0, /* tp_members */
141 0, /* tp_getset */
142 0, /* tp_base */
143 0, /* tp_dict */
144 0, /* tp_descr_get */
145 0, /* tp_descr_set */
146 0, /* tp_dictoffset */
147 (initproc)Scale_init, /* tp_init */
148 0, /* tp_alloc */
149 Scale_new, /* tp_new */
153 /** Channel Type **/
155 typedef struct {
156 PyObject_HEAD
157 PyObject *midi_change_callback;
158 jack_mixer_channel_t channel;
159 } ChannelObject;
161 static void
162 Channel_dealloc(ChannelObject *self)
164 Py_XDECREF(self->midi_change_callback);
165 self->ob_type->tp_free((PyObject*)self);
168 static int
169 Channel_init(ChannelObject *self, PyObject *args, PyObject *kwds)
171 self->midi_change_callback = NULL;
172 return 0;
175 static PyObject*
176 Channel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
178 ChannelObject *self;
180 self = (ChannelObject*)type->tp_alloc(type, 0);
182 if (self != NULL) {
183 self->channel = NULL;
184 self->midi_change_callback = NULL;
187 return (PyObject*)self;
190 static PyObject*
191 Channel_get_is_stereo(ChannelObject *self, void *closure)
193 PyObject *result;
195 bool is_stereo = channel_is_stereo(self->channel);
196 if (is_stereo) {
197 result = Py_True;
198 } else {
199 result = Py_False;
201 Py_INCREF(result);
202 return result;
205 static PyObject*
206 Channel_get_volume(ChannelObject *self, void *closure)
208 return PyFloat_FromDouble(channel_volume_read(self->channel));
211 static int
212 Channel_set_volume(ChannelObject *self, PyObject *value, void *closure)
214 channel_volume_write(self->channel, PyFloat_AsDouble(value));
215 return 0;
218 static PyObject*
219 Channel_get_balance(ChannelObject *self, void *closure)
221 return PyFloat_FromDouble(channel_balance_read(self->channel));
224 static int
225 Channel_set_balance(ChannelObject *self, PyObject *value, void *closure)
227 channel_balance_write(self->channel, PyFloat_AsDouble(value));
228 return 0;
231 static PyObject*
232 Channel_get_mute(ChannelObject *self, void *closure)
234 PyObject *result;
236 if (channel_is_muted(self->channel)) {
237 result = Py_True;
238 } else {
239 result = Py_False;
241 Py_INCREF(result);
242 return result;
245 static int
246 Channel_set_mute(ChannelObject *self, PyObject *value, void *closure)
248 if (value == Py_True) {
249 channel_mute(self->channel);
250 } else {
251 channel_unmute(self->channel);
253 return 0;
256 static PyObject*
257 Channel_get_solo(ChannelObject *self, void *closure)
259 PyObject *result;
261 if (channel_is_soloed(self->channel)) {
262 result = Py_True;
263 } else {
264 result = Py_False;
266 Py_INCREF(result);
267 return result;
270 static int
271 Channel_set_solo(ChannelObject *self, PyObject *value, void *closure)
273 if (value == Py_True) {
274 channel_solo(self->channel);
275 } else {
276 channel_unsolo(self->channel);
278 return 0;
281 static PyObject*
282 Channel_get_meter(ChannelObject *self, void *closure)
284 PyObject *result;
285 double left, right;
287 if (channel_is_stereo(self->channel)) {
288 result = PyTuple_New(2);
289 channel_stereo_meter_read(self->channel, &left, &right);
290 PyTuple_SetItem(result, 0, PyFloat_FromDouble(left));
291 PyTuple_SetItem(result, 1, PyFloat_FromDouble(right));
292 } else {
293 result = PyTuple_New(1);
294 channel_mono_meter_read(self->channel, &left);
295 PyTuple_SetItem(result, 0, PyFloat_FromDouble(left));
297 return result;
300 static PyObject*
301 Channel_get_abspeak(ChannelObject *self, void *closure)
303 return PyFloat_FromDouble(channel_abspeak_read(self->channel));
306 static int
307 Channel_set_abspeak(ChannelObject *self, PyObject *value, void *closure)
309 if (value != Py_None) {
310 fprintf(stderr, "abspeak can only be reset (set to None)\n");
311 return -1;
313 channel_abspeak_reset(self->channel);
314 return 0;
317 static int
318 Channel_set_midi_scale(ChannelObject *self, PyObject *value, void *closure)
320 ScaleObject *scale_object = (ScaleObject*)value; /* XXX: check */
322 channel_set_midi_scale(self->channel, scale_object->scale);
323 return 0;
327 static PyObject*
328 Channel_get_midi_change_callback(ChannelObject *self, void *closure)
330 if (self->midi_change_callback) {
331 Py_INCREF(self->midi_change_callback);
332 return self->midi_change_callback;
333 } else {
334 Py_INCREF(Py_None);
335 return Py_None;
339 static void
340 channel_midi_callback(void *userdata)
342 ChannelObject *self = (ChannelObject*)userdata;
343 PyGILState_STATE gstate;
345 gstate = PyGILState_Ensure();
346 PyObject_CallObject(self->midi_change_callback, NULL);
347 PyGILState_Release(gstate);
350 static int
351 Channel_set_midi_change_callback(ChannelObject *self, PyObject *value, void *closure)
353 if (value == Py_None) {
354 self->midi_change_callback = NULL;
355 channel_set_midi_change_callback(self->channel, NULL, NULL);
356 } else {
357 if (!PyCallable_Check(value)) {
358 PyErr_SetString(PyExc_TypeError, "value must be callable");
359 return -1;
361 if (self->midi_change_callback) {
362 Py_XDECREF(self->midi_change_callback);
364 Py_INCREF(value);
365 self->midi_change_callback = value;
366 channel_set_midi_change_callback(self->channel,
367 channel_midi_callback, self);
370 return 0;
373 static PyObject*
374 Channel_get_name(ChannelObject *self, void *closure)
376 return PyString_FromString(channel_get_name(self->channel));
379 static int
380 Channel_set_name(ChannelObject *self, PyObject *value, void *closure)
382 channel_rename(self->channel, PyString_AsString(value));
383 return 0;
386 static PyObject*
387 Channel_get_balance_midi_cc(ChannelObject *self, void *closure)
389 return PyInt_FromLong(channel_get_balance_midi_cc(self->channel));
392 static int
393 Channel_set_balance_midi_cc(ChannelObject *self, PyObject *value, void *closure)
395 unsigned int new_cc;
396 unsigned int result;
398 new_cc = PyInt_AsLong(value);
399 result = channel_set_balance_midi_cc(self->channel, new_cc);
400 if (result == 0) {
401 return 0;
403 if (result == 1) {
404 PyErr_SetString(PyExc_RuntimeError, "value already in use");
405 } else if (result == 2) {
406 PyErr_SetString(PyExc_RuntimeError, "value out of range");
408 return -1;
411 static PyObject*
412 Channel_get_volume_midi_cc(ChannelObject *self, void *closure)
414 return PyInt_FromLong(channel_get_volume_midi_cc(self->channel));
417 static int
418 Channel_set_volume_midi_cc(ChannelObject *self, PyObject *value, void *closure)
420 unsigned int new_cc;
421 unsigned int result;
423 new_cc = PyInt_AsLong(value);
424 result = channel_set_volume_midi_cc(self->channel, new_cc);
425 if (result == 0) {
426 return 0;
428 if (result == 1) {
429 PyErr_SetString(PyExc_RuntimeError, "value already in use");
430 } else if (result == 2) {
431 PyErr_SetString(PyExc_RuntimeError, "value out of range");
433 return -1;
436 static PyGetSetDef Channel_getseters[] = {
437 {"is_stereo",
438 (getter)Channel_get_is_stereo, NULL,
439 "mono/stereo", NULL},
440 {"volume",
441 (getter)Channel_get_volume, (setter)Channel_set_volume,
442 "volume", NULL},
443 {"balance",
444 (getter)Channel_get_balance, (setter)Channel_set_balance,
445 "balance", NULL},
446 {"mute",
447 (getter)Channel_get_mute, (setter)Channel_set_mute,
448 "mute", NULL},
449 {"solo",
450 (getter)Channel_get_solo, (setter)Channel_set_solo,
451 "solo", NULL},
452 {"meter",
453 (getter)Channel_get_meter, NULL,
454 "meter", NULL},
455 {"abspeak",
456 (getter)Channel_get_abspeak, (setter)Channel_set_abspeak,
457 "balance", NULL},
458 {"midi_scale",
459 NULL, (setter)Channel_set_midi_scale,
460 "midi scale", NULL},
461 {"midi_change_callback",
462 (getter)Channel_get_midi_change_callback,
463 (setter)Channel_set_midi_change_callback,
464 "midi change callback", NULL},
465 {"name",
466 (getter)Channel_get_name,
467 (setter)Channel_set_name,
468 "name", NULL},
469 {"balance_midi_cc",
470 (getter)Channel_get_balance_midi_cc,
471 (setter)Channel_set_balance_midi_cc,
472 "Balance MIDI CC", NULL},
473 {"volume_midi_cc",
474 (getter)Channel_get_volume_midi_cc,
475 (setter)Channel_set_volume_midi_cc,
476 "Volume MIDI CC", NULL},
477 {NULL}
480 static PyObject*
481 Channel_remove(ChannelObject *self, PyObject *args)
483 if (! PyArg_ParseTuple(args, "")) return NULL;
484 remove_channel(self->channel);
485 Py_INCREF(Py_None);
486 return Py_None;
489 static PyObject*
490 Channel_autoset_midi_cc(ChannelObject *self, PyObject *args)
492 if (! PyArg_ParseTuple(args, "")) return NULL;
493 channel_autoset_midi_cc(self->channel);
494 Py_INCREF(Py_None);
495 return Py_None;
498 static PyMethodDef channel_methods[] = {
499 {"remove", (PyCFunction)Channel_remove, METH_VARARGS, "Remove"},
500 {"autoset_midi_cc", (PyCFunction)Channel_autoset_midi_cc, METH_VARARGS, "Autoset MIDI CC"},
501 {NULL}
504 static PyTypeObject ChannelType = {
505 PyObject_HEAD_INIT(NULL)
506 0, /*ob_size*/
507 "jack_mixer_c.Channel", /*tp_name*/
508 sizeof(ChannelObject), /*tp_basicsize*/
509 0, /*tp_itemsize*/
510 (destructor)Channel_dealloc, /*tp_dealloc*/
511 0, /*tp_print*/
512 0, /*tp_getattr*/
513 0, /*tp_setattr*/
514 0, /*tp_compare*/
515 0, /*tp_repr*/
516 0, /*tp_as_number*/
517 0, /*tp_as_sequence*/
518 0, /*tp_as_mapping*/
519 0, /*tp_hash */
520 0, /*tp_call*/
521 0, /*tp_str*/
522 0, /*tp_getattro*/
523 0, /*tp_setattro*/
524 0, /*tp_as_buffer*/
525 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
526 "Channel objects", /* tp_doc */
527 0, /* tp_traverse */
528 0, /* tp_clear */
529 0, /* tp_richcompare */
530 0, /* tp_weaklistoffset */
531 0, /* tp_iter */
532 0, /* tp_iternext */
533 channel_methods, /* tp_methods */
534 0, /* tp_members */
535 Channel_getseters, /* tp_getset */
536 0, /* tp_base */
537 0, /* tp_dict */
538 0, /* tp_descr_get */
539 0, /* tp_descr_set */
540 0, /* tp_dictoffset */
541 (initproc)Channel_init, /* tp_init */
542 0, /* tp_alloc */
543 Channel_new, /* tp_new */
546 static PyObject*
547 Channel_New(jack_mixer_channel_t channel)
549 ChannelObject *self;
550 self = (ChannelObject*)PyObject_NEW(ChannelObject, &ChannelType);
551 if (self != NULL) {
552 self->channel = channel;
553 self->midi_change_callback = NULL;
555 return (PyObject*)self;
558 /** Output Channel Type **/
560 typedef struct {
561 PyObject_HEAD
562 PyObject *midi_change_callback;
563 jack_mixer_output_channel_t *output_channel;
564 } OutputChannelObject;
566 static PyObject*
567 OutputChannel_remove(OutputChannelObject *self, PyObject *args)
569 if (! PyArg_ParseTuple(args, "")) return NULL;
570 remove_output_channel(self->output_channel);
571 Py_INCREF(Py_None);
572 return Py_None;
575 static PyObject*
576 OutputChannel_set_solo(OutputChannelObject *self, PyObject *args)
578 PyObject *channel;
579 int solo;
581 if (! PyArg_ParseTuple(args, "Ob", &channel, &solo)) return NULL;
583 output_channel_set_solo(self->output_channel,
584 ((ChannelObject*)channel)->channel,
585 solo);
587 Py_INCREF(Py_None);
588 return Py_None;
591 static PyObject*
592 OutputChannel_set_muted(OutputChannelObject *self, PyObject *args)
594 PyObject *channel;
595 int muted;
597 if (! PyArg_ParseTuple(args, "Ob", &channel, &muted)) return NULL;
599 output_channel_set_muted(self->output_channel,
600 ((ChannelObject*)channel)->channel,
601 muted);
603 Py_INCREF(Py_None);
604 return Py_None;
609 static PyMethodDef output_channel_methods[] = {
610 {"remove", (PyCFunction)OutputChannel_remove, METH_VARARGS, "Remove"},
611 {"set_solo", (PyCFunction)OutputChannel_set_solo, METH_VARARGS, "Set a channel as solo"},
612 {"set_muted", (PyCFunction)OutputChannel_set_muted, METH_VARARGS, "Set a channel as muted"},
613 {NULL}
616 static PyTypeObject OutputChannelType = {
617 PyObject_HEAD_INIT(NULL)
618 0, /*ob_size*/
619 "jack_mixer_c.OutputChannel", /*tp_name*/
620 sizeof(OutputChannelObject), /*tp_basicsize*/
621 0, /*tp_itemsize*/
622 0, /*tp_dealloc*/
623 0, /*tp_print*/
624 0, /*tp_getattr*/
625 0, /*tp_setattr*/
626 0, /*tp_compare*/
627 0, /*tp_repr*/
628 0, /*tp_as_number*/
629 0, /*tp_as_sequence*/
630 0, /*tp_as_mapping*/
631 0, /*tp_hash */
632 0, /*tp_call*/
633 0, /*tp_str*/
634 0, /*tp_getattro*/
635 0, /*tp_setattro*/
636 0, /*tp_as_buffer*/
637 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
638 "Output Channel objects", /* tp_doc */
639 0, /* tp_traverse */
640 0, /* tp_clear */
641 0, /* tp_richcompare */
642 0, /* tp_weaklistoffset */
643 0, /* tp_iter */
644 0, /* tp_iternext */
645 output_channel_methods, /* tp_methods */
646 0, /* tp_members */
647 0, /* tp_getset */
648 &ChannelType, /* tp_base */
649 0, /* tp_dict */
650 0, /* tp_descr_get */
651 0, /* tp_descr_set */
652 0, /* tp_dictoffset */
653 0, /* tp_init */
654 0, /* tp_alloc */
655 0, /* tp_new */
658 static PyObject*
659 OutputChannel_New(jack_mixer_output_channel_t output_channel)
661 OutputChannelObject *self;
662 self = (OutputChannelObject*)PyObject_NEW(OutputChannelObject, &OutputChannelType);
663 if (self != NULL) {
664 self->midi_change_callback = NULL;
665 self->output_channel = output_channel;
667 return (PyObject*)self;
671 /** Mixer Type **/
673 typedef struct {
674 PyObject_HEAD
675 PyObject *main_mix_channel;
676 jack_mixer_t mixer;
677 } MixerObject;
679 static void
680 Mixer_dealloc(MixerObject *self)
682 Py_XDECREF(self->main_mix_channel);
683 if (self->mixer)
684 destroy(self->mixer);
685 self->ob_type->tp_free((PyObject*)self);
688 static PyObject*
689 Mixer_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
691 MixerObject *self;
693 self = (MixerObject*)type->tp_alloc(type, 0);
695 if (self != NULL) {
696 self->main_mix_channel = NULL;
697 self->mixer = NULL;
700 return (PyObject*)self;
703 static int
704 Mixer_init(MixerObject *self, PyObject *args, PyObject *kwds)
706 static char *kwlist[] = {"name", NULL};
707 char *name;
709 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &name))
710 return -1;
712 self->mixer = create(name);
713 if (self->mixer == NULL) {
714 PyErr_SetString(PyExc_RuntimeError,
715 "error creating mixer, probably jack is not running");
716 return -1;
719 self->main_mix_channel = Channel_New(get_main_mix_channel(self->mixer));
721 return 0;
724 static PyMemberDef Mixer_members[] = {
725 {"main_mix_channel", T_OBJECT, offsetof(MixerObject, main_mix_channel), 0, "main_mix_channel"},
726 {NULL}
729 static PyObject*
730 Mixer_get_channels_count(MixerObject *self, void *closure)
732 return PyInt_FromLong(get_channels_count(self->mixer));
735 static PyObject*
736 Mixer_get_last_midi_channel(MixerObject *self, void *closure)
738 return PyInt_FromLong(get_last_midi_channel(self->mixer));
742 static PyGetSetDef Mixer_getseters[] = {
743 {"channels_count", (getter)Mixer_get_channels_count, NULL,
744 "channels count", NULL},
745 {"last_midi_channel", (getter)Mixer_get_last_midi_channel, NULL,
746 "last midi channel", NULL},
747 {NULL}
750 static PyObject*
751 Mixer_add_channel(MixerObject *self, PyObject *args)
753 char *name;
754 int stereo;
755 jack_mixer_channel_t channel;
757 if (! PyArg_ParseTuple(args, "sb", &name, &stereo)) return NULL;
759 channel = add_channel(self->mixer, name, (bool)stereo);
761 if (channel == NULL) {
762 PyErr_SetString(PyExc_RuntimeError, "error adding channel");
763 return NULL;
766 return Channel_New(channel);
769 static PyObject*
770 Mixer_add_output_channel(MixerObject *self, PyObject *args)
772 char *name;
773 int stereo = 1;
774 int system = 0;
775 jack_mixer_output_channel_t channel;
777 if (! PyArg_ParseTuple(args, "s|bb", &name, &stereo, &system)) return NULL;
779 channel = add_output_channel(self->mixer, name, (bool)stereo, (bool)system);
781 return OutputChannel_New(channel);
785 static PyMethodDef Mixer_methods[] = {
786 {"add_channel", (PyCFunction)Mixer_add_channel, METH_VARARGS, "Add a new channel"},
787 {"add_output_channel", (PyCFunction)Mixer_add_output_channel, METH_VARARGS, "Add a new output channel"},
788 // {"remove_channel", (PyCFunction)Mixer_remove_channel, METH_VARARGS, "Remove a channel"},
789 {NULL}
792 static PyTypeObject MixerType = {
793 PyObject_HEAD_INIT(NULL)
794 0, /*ob_size*/
795 "jack_mixer_c.Mixer", /*tp_name*/
796 sizeof(MixerObject), /*tp_basicsize*/
797 0, /*tp_itemsize*/
798 (destructor)Mixer_dealloc, /*tp_dealloc*/
799 0, /*tp_print*/
800 0, /*tp_getattr*/
801 0, /*tp_setattr*/
802 0, /*tp_compare*/
803 0, /*tp_repr*/
804 0, /*tp_as_number*/
805 0, /*tp_as_sequence*/
806 0, /*tp_as_mapping*/
807 0, /*tp_hash */
808 0, /*tp_call*/
809 0, /*tp_str*/
810 0, /*tp_getattro*/
811 0, /*tp_setattro*/
812 0, /*tp_as_buffer*/
813 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
814 "Mixer objects", /* tp_doc */
815 0, /* tp_traverse */
816 0, /* tp_clear */
817 0, /* tp_richcompare */
818 0, /* tp_weaklistoffset */
819 0, /* tp_iter */
820 0, /* tp_iternext */
821 Mixer_methods, /* tp_methods */
822 Mixer_members, /* tp_members */
823 Mixer_getseters, /* tp_getset */
824 0, /* tp_base */
825 0, /* tp_dict */
826 0, /* tp_descr_get */
827 0, /* tp_descr_set */
828 0, /* tp_dictoffset */
829 (initproc)Mixer_init, /* tp_init */
830 0, /* tp_alloc */
831 Mixer_new, /* tp_new */
835 static PyMethodDef jack_mixer_methods[] = {
836 {NULL} /* Sentinel */
841 PyMODINIT_FUNC initjack_mixer_c(void)
843 PyObject *m;
845 if (PyType_Ready(&MixerType) < 0)
846 return;
847 if (PyType_Ready(&ChannelType) < 0)
848 return;
849 if (PyType_Ready(&OutputChannelType) < 0)
850 return;
851 if (PyType_Ready(&ScaleType) < 0)
852 return;
854 m = Py_InitModule3("jack_mixer_c", jack_mixer_methods, "Jack Mixer C Helper Module");
856 Py_INCREF(&MixerType);
857 PyModule_AddObject(m, "Mixer", (PyObject*)&MixerType);
858 Py_INCREF(&ChannelType);
859 PyModule_AddObject(m, "Channel", (PyObject*)&ChannelType);
860 Py_INCREF(&OutputChannelType);
861 PyModule_AddObject(m, "OutputChannel", (PyObject*)&OutputChannelType);
862 Py_INCREF(&ScaleType);
863 PyModule_AddObject(m, "Scale", (PyObject*)&ScaleType);