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.
26 #include <structmember.h>
28 #include "jack_mixer.h"
35 jack_mixer_scale_t scale;
39 Scale_dealloc(ScaleObject *self)
42 scale_destroy(self->scale);
43 Py_TYPE(self)->tp_free((PyObject*)self);
47 Scale_init(ScaleObject *self, PyObject *args, PyObject *kwds)
49 self->scale = scale_create();
54 Scale_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
58 self = (ScaleObject*)type->tp_alloc(type, 0);
60 return (PyObject*)self;
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);
77 Scale_calculate_coefficients(ScaleObject *self, PyObject *args)
79 if (! PyArg_ParseTuple(args, "")) return NULL;
80 scale_calculate_coefficients(self->scale);
86 Scale_db_to_scale(ScaleObject *self, PyObject *args)
89 if (! PyArg_ParseTuple(args, "d", &db)) return NULL;
90 return PyFloat_FromDouble(scale_db_to_scale(self->scale, db));
94 Scale_scale_to_db(ScaleObject *self, PyObject *args)
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"},
110 static PyTypeObject ScaleType = {
111 PyVarObject_HEAD_INIT(NULL, 0)
112 "jack_mixer_c.Scale", /*tp_name*/
113 sizeof(ScaleObject), /*tp_basicsize*/
115 (destructor)Scale_dealloc, /*tp_dealloc*/
122 0, /*tp_as_sequence*/
130 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
131 "Scale objects", /* tp_doc */
134 0, /* tp_richcompare */
135 0, /* tp_weaklistoffset */
138 Scale_methods, /* tp_methods */
143 0, /* tp_descr_get */
144 0, /* tp_descr_set */
145 0, /* tp_dictoffset */
146 (initproc)Scale_init, /* tp_init */
148 Scale_new, /* tp_new */
156 PyObject *midi_change_callback;
157 jack_mixer_channel_t channel;
161 Channel_dealloc(ChannelObject *self)
163 Py_XDECREF(self->midi_change_callback);
164 Py_TYPE(self)->tp_free((PyObject*)self);
168 Channel_init(ChannelObject *self, PyObject *args, PyObject *kwds)
170 self->midi_change_callback = NULL;
175 Channel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
179 self = (ChannelObject*)type->tp_alloc(type, 0);
182 self->channel = NULL;
183 self->midi_change_callback = NULL;
186 return (PyObject*)self;
190 Channel_get_is_stereo(ChannelObject *self, void *closure)
194 bool is_stereo = channel_is_stereo(self->channel);
205 Channel_get_volume(ChannelObject *self, void *closure)
207 return PyFloat_FromDouble(channel_volume_read(self->channel));
211 Channel_set_volume(ChannelObject *self, PyObject *value, void *closure)
213 if (self->channel == NULL) {
214 PyErr_SetString(PyExc_RuntimeError, "unitialized channel");
217 channel_volume_write(self->channel, PyFloat_AsDouble(value));
218 channel_set_midi_cc_volume_picked_up(self->channel, false);
223 Channel_get_balance(ChannelObject *self, void *closure)
225 return PyFloat_FromDouble(channel_balance_read(self->channel));
229 Channel_set_balance(ChannelObject *self, PyObject *value, void *closure)
231 channel_balance_write(self->channel, PyFloat_AsDouble(value));
232 channel_set_midi_cc_balance_picked_up(self->channel, false);
237 Channel_get_out_mute(ChannelObject *self, void *closure)
241 if (channel_is_out_muted(self->channel)) {
251 Channel_set_out_mute(ChannelObject *self, PyObject *value, void *closure)
253 if (value == Py_True) {
254 channel_out_mute(self->channel);
256 channel_out_unmute(self->channel);
262 Channel_get_solo(ChannelObject *self, void *closure)
266 if (channel_is_soloed(self->channel)) {
276 Channel_set_solo(ChannelObject *self, PyObject *value, void *closure)
278 if (value == Py_True) {
279 channel_solo(self->channel);
281 channel_unsolo(self->channel);
287 Channel_get_meter(ChannelObject *self, void *closure)
292 if (channel_is_stereo(self->channel)) {
293 result = PyTuple_New(2);
294 channel_stereo_meter_read(self->channel, &left, &right);
295 PyTuple_SetItem(result, 0, PyFloat_FromDouble(left));
296 PyTuple_SetItem(result, 1, PyFloat_FromDouble(right));
298 result = PyTuple_New(1);
299 channel_mono_meter_read(self->channel, &left);
300 PyTuple_SetItem(result, 0, PyFloat_FromDouble(left));
306 Channel_get_kmeter(ChannelObject *self, void *closure)
309 double peak_left, peak_right, rms_left, rms_right;
311 if (channel_is_stereo(self->channel)) {
312 result = PyTuple_New(4);
313 channel_stereo_kmeter_read(self->channel, &peak_left, &peak_right, &rms_left, &rms_right);
314 PyTuple_SetItem(result, 0, PyFloat_FromDouble(peak_left));
315 PyTuple_SetItem(result, 1, PyFloat_FromDouble(peak_right));
316 PyTuple_SetItem(result, 2, PyFloat_FromDouble(rms_left));
317 PyTuple_SetItem(result, 3, PyFloat_FromDouble(rms_right));
319 result = PyTuple_New(2);
320 channel_mono_kmeter_read(self->channel, &peak_left, &rms_left);
321 PyTuple_SetItem(result, 0, PyFloat_FromDouble(peak_left));
322 PyTuple_SetItem(result, 1, PyFloat_FromDouble(rms_left));
328 Channel_get_abspeak(ChannelObject *self, void *closure)
330 return PyFloat_FromDouble(channel_abspeak_read(self->channel));
334 Channel_set_abspeak(ChannelObject *self, PyObject *value, void *closure)
336 if (value != Py_None) {
337 fprintf(stderr, "abspeak can only be reset (set to None)\n");
340 channel_abspeak_reset(self->channel);
345 Channel_set_midi_scale(ChannelObject *self, PyObject *value, void *closure)
347 ScaleObject *scale_object = (ScaleObject*)value; /* XXX: check */
349 channel_set_midi_scale(self->channel, scale_object->scale);
355 Channel_get_midi_change_callback(ChannelObject *self, void *closure)
357 if (self->midi_change_callback) {
358 Py_INCREF(self->midi_change_callback);
359 return self->midi_change_callback;
367 channel_midi_callback(void *userdata)
369 ChannelObject *self = (ChannelObject*)userdata;
370 PyGILState_STATE gstate;
372 gstate = PyGILState_Ensure();
373 PyObject_CallObject(self->midi_change_callback, NULL);
374 PyGILState_Release(gstate);
378 Channel_set_midi_change_callback(ChannelObject *self, PyObject *value, void *closure)
380 if (value == Py_None) {
381 self->midi_change_callback = NULL;
382 channel_set_midi_change_callback(self->channel, NULL, NULL);
384 if (!PyCallable_Check(value)) {
385 PyErr_SetString(PyExc_TypeError, "value must be callable");
388 if (self->midi_change_callback) {
389 Py_XDECREF(self->midi_change_callback);
392 self->midi_change_callback = value;
393 channel_set_midi_change_callback(self->channel,
394 channel_midi_callback, self);
401 Channel_get_name(ChannelObject *self, void *closure)
403 return PyUnicode_FromString(channel_get_name(self->channel));
407 Channel_set_name(ChannelObject *self, PyObject *value, void *closure)
409 channel_rename(self->channel, PyUnicode_AsUTF8(value));
414 Channel_get_balance_midi_cc(ChannelObject *self, void *closure)
416 return PyLong_FromLong(channel_get_balance_midi_cc(self->channel));
420 Channel_set_balance_midi_cc(ChannelObject *self, PyObject *value, void *closure)
425 new_cc = PyLong_AsLong(value);
426 result = channel_set_balance_midi_cc(self->channel, new_cc);
431 PyErr_SetString(PyExc_RuntimeError, "value out of range");
437 Channel_get_volume_midi_cc(ChannelObject *self, void *closure)
439 return PyLong_FromLong(channel_get_volume_midi_cc(self->channel));
443 Channel_set_volume_midi_cc(ChannelObject *self, PyObject *value, void *closure)
448 new_cc = PyLong_AsLong(value);
449 result = channel_set_volume_midi_cc(self->channel, new_cc);
454 PyErr_SetString(PyExc_RuntimeError, "value out of range");
460 Channel_get_mute_midi_cc(ChannelObject *self, void *closure)
462 return PyLong_FromLong(channel_get_mute_midi_cc(self->channel));
466 Channel_set_mute_midi_cc(ChannelObject *self, PyObject *value, void *closure)
471 new_cc = PyLong_AsLong(value);
472 result = channel_set_mute_midi_cc(self->channel, new_cc);
477 PyErr_SetString(PyExc_RuntimeError, "value out of range");
483 Channel_get_solo_midi_cc(ChannelObject *self, void *closure)
485 return PyLong_FromLong(channel_get_solo_midi_cc(self->channel));
489 Channel_set_solo_midi_cc(ChannelObject *self, PyObject *value, void *closure)
494 new_cc = PyLong_AsLong(value);
495 result = channel_set_solo_midi_cc(self->channel, new_cc);
500 PyErr_SetString(PyExc_RuntimeError, "value out of range");
506 Channel_get_midi_in_got_events(ChannelObject *self, void *closure)
510 if (channel_get_midi_in_got_events(self->channel)) {
519 static PyGetSetDef Channel_getseters[] = {
521 (getter)Channel_get_is_stereo, NULL,
522 "mono/stereo", NULL},
524 (getter)Channel_get_volume, (setter)Channel_set_volume,
527 (getter)Channel_get_balance, (setter)Channel_set_balance,
530 (getter)Channel_get_out_mute, (setter)Channel_set_out_mute,
533 (getter)Channel_get_solo, (setter)Channel_set_solo,
536 (getter)Channel_get_meter, NULL,
539 (getter)Channel_get_kmeter, NULL,
542 (getter)Channel_get_abspeak, (setter)Channel_set_abspeak,
545 NULL, (setter)Channel_set_midi_scale,
547 {"midi_change_callback",
548 (getter)Channel_get_midi_change_callback,
549 (setter)Channel_set_midi_change_callback,
550 "midi change callback", NULL},
552 (getter)Channel_get_name,
553 (setter)Channel_set_name,
556 (getter)Channel_get_balance_midi_cc,
557 (setter)Channel_set_balance_midi_cc,
558 "Balance MIDI CC", NULL},
560 (getter)Channel_get_volume_midi_cc,
561 (setter)Channel_set_volume_midi_cc,
562 "Volume MIDI CC", NULL},
564 (getter)Channel_get_mute_midi_cc,
565 (setter)Channel_set_mute_midi_cc,
566 "Mute MIDI CC", NULL},
568 (getter)Channel_get_solo_midi_cc,
569 (setter)Channel_set_solo_midi_cc,
570 "Mute MIDI CC", NULL},
571 {"midi_in_got_events",
572 (getter)Channel_get_midi_in_got_events, NULL,
573 "Got new MIDI IN events", NULL},
578 Channel_remove(ChannelObject *self, PyObject *args)
580 if (! PyArg_ParseTuple(args, "")) return NULL;
581 remove_channel(self->channel);
587 Channel_autoset_volume_midi_cc(ChannelObject *self, PyObject *args)
589 if (! PyArg_ParseTuple(args, "")) return NULL;
590 channel_autoset_volume_midi_cc(self->channel);
596 Channel_autoset_balance_midi_cc(ChannelObject *self, PyObject *args)
598 if (! PyArg_ParseTuple(args, "")) return NULL;
599 channel_autoset_balance_midi_cc(self->channel);
605 Channel_autoset_mute_midi_cc(ChannelObject *self, PyObject *args)
607 if (! PyArg_ParseTuple(args, "")) return NULL;
608 channel_autoset_mute_midi_cc(self->channel);
614 Channel_autoset_solo_midi_cc(ChannelObject *self, PyObject *args)
616 if (! PyArg_ParseTuple(args, "")) return NULL;
617 channel_autoset_solo_midi_cc(self->channel);
622 static PyMethodDef channel_methods[] = {
623 {"remove", (PyCFunction)Channel_remove, METH_VARARGS, "Remove"},
624 {"autoset_volume_midi_cc",
625 (PyCFunction)Channel_autoset_volume_midi_cc, METH_VARARGS, "Autoset Volume MIDI CC"},
626 {"autoset_balance_midi_cc",
627 (PyCFunction)Channel_autoset_balance_midi_cc, METH_VARARGS, "Autoset Balance MIDI CC"},
628 {"autoset_mute_midi_cc",
629 (PyCFunction)Channel_autoset_mute_midi_cc, METH_VARARGS, "Autoset Mute MIDI CC"},
630 {"autoset_solo_midi_cc",
631 (PyCFunction)Channel_autoset_solo_midi_cc, METH_VARARGS, "Autoset Solo MIDI CC"},
635 static PyTypeObject ChannelType = {
636 PyVarObject_HEAD_INIT(NULL, 0)
637 "jack_mixer_c.Channel", /*tp_name*/
638 sizeof(ChannelObject), /*tp_basicsize*/
640 (destructor)Channel_dealloc, /*tp_dealloc*/
647 0, /*tp_as_sequence*/
655 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
656 "Channel objects", /* tp_doc */
659 0, /* tp_richcompare */
660 0, /* tp_weaklistoffset */
663 channel_methods, /* tp_methods */
665 Channel_getseters, /* tp_getset */
668 0, /* tp_descr_get */
669 0, /* tp_descr_set */
670 0, /* tp_dictoffset */
671 (initproc)Channel_init, /* tp_init */
673 Channel_new, /* tp_new */
677 Channel_New(jack_mixer_channel_t channel)
680 self = (ChannelObject*)PyObject_NEW(ChannelObject, &ChannelType);
682 self->channel = channel;
683 self->midi_change_callback = NULL;
685 return (PyObject*)self;
688 /** Output Channel Type **/
692 PyObject *midi_change_callback;
693 jack_mixer_output_channel_t *output_channel;
694 } OutputChannelObject;
697 OutputChannel_set_prefader(OutputChannelObject *self, PyObject *value, void *closure)
699 if (value == Py_True) {
700 output_channel_set_prefader(self->output_channel, true);
702 output_channel_set_prefader(self->output_channel, false);
708 OutputChannel_get_prefader(OutputChannelObject *self, void *closure)
712 if (output_channel_is_prefader(self->output_channel)) {
721 static PyGetSetDef OutputChannel_getseters[] = {
723 (getter)OutputChannel_get_prefader, (setter)OutputChannel_set_prefader,
729 OutputChannel_remove(OutputChannelObject *self, PyObject *args)
731 if (! PyArg_ParseTuple(args, "")) return NULL;
732 remove_output_channel(self->output_channel);
738 OutputChannel_set_solo(OutputChannelObject *self, PyObject *args)
743 if (! PyArg_ParseTuple(args, "Ob", &channel, &solo)) return NULL;
745 output_channel_set_solo(self->output_channel,
746 ((ChannelObject*)channel)->channel,
754 OutputChannel_set_muted(OutputChannelObject *self, PyObject *args)
759 if (! PyArg_ParseTuple(args, "Ob", &channel, &muted)) return NULL;
761 output_channel_set_muted(self->output_channel,
762 ((ChannelObject*)channel)->channel,
770 OutputChannel_is_solo(OutputChannelObject *self, PyObject *args)
775 if (! PyArg_ParseTuple(args, "O", &channel)) return NULL;
777 if (output_channel_is_solo(self->output_channel,
778 ((ChannelObject*)channel)->channel)) {
789 OutputChannel_is_muted(OutputChannelObject *self, PyObject *args)
794 if (! PyArg_ParseTuple(args, "O", &channel)) return NULL;
796 if (output_channel_is_muted(self->output_channel,
797 ((ChannelObject*)channel)->channel)) {
808 OutputChannel_set_in_prefader(OutputChannelObject *self, PyObject *args)
811 unsigned char prefader;
813 if (! PyArg_ParseTuple(args, "Ob", &channel, &prefader)) return NULL;
815 output_channel_set_in_prefader(self->output_channel,
816 ((ChannelObject*)channel)->channel,
824 OutputChannel_is_in_prefader(OutputChannelObject *self, PyObject *args)
829 if (! PyArg_ParseTuple(args, "O", &channel)) return NULL;
831 if (output_channel_is_in_prefader(self->output_channel,
832 ((ChannelObject*)channel)->channel)) {
842 static PyMethodDef output_channel_methods[] = {
843 {"remove", (PyCFunction)OutputChannel_remove, METH_VARARGS, "Remove"},
844 {"set_solo", (PyCFunction)OutputChannel_set_solo, METH_VARARGS, "Set a channel as solo"},
845 {"set_muted", (PyCFunction)OutputChannel_set_muted, METH_VARARGS, "Set a channel as muted"},
846 {"is_solo", (PyCFunction)OutputChannel_is_solo, METH_VARARGS, "Is a channel set as solo"},
847 {"is_muted", (PyCFunction)OutputChannel_is_muted, METH_VARARGS, "Is a channel set as muted"},
848 {"set_in_prefader", (PyCFunction)OutputChannel_set_in_prefader, METH_VARARGS, "Set a channel as prefader"},
849 {"is_in_prefader", (PyCFunction)OutputChannel_is_in_prefader, METH_VARARGS, "Is a channel set as prefader"},
853 static PyTypeObject OutputChannelType = {
854 PyVarObject_HEAD_INIT(NULL, 0)
855 "jack_mixer_c.OutputChannel", /*tp_name*/
856 sizeof(OutputChannelObject), /*tp_basicsize*/
865 0, /*tp_as_sequence*/
873 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
874 "Output Channel objects", /* tp_doc */
877 0, /* tp_richcompare */
878 0, /* tp_weaklistoffset */
881 output_channel_methods, /* tp_methods */
883 OutputChannel_getseters, /* tp_getset */
884 &ChannelType, /* tp_base */
886 0, /* tp_descr_get */
887 0, /* tp_descr_set */
888 0, /* tp_dictoffset */
895 OutputChannel_New(jack_mixer_output_channel_t output_channel)
897 OutputChannelObject *self;
898 self = (OutputChannelObject*)PyObject_NEW(OutputChannelObject, &OutputChannelType);
900 self->midi_change_callback = NULL;
901 self->output_channel = output_channel;
903 return (PyObject*)self;
915 Mixer_dealloc(MixerObject *self)
918 destroy(self->mixer);
919 Py_TYPE(self)->tp_free((PyObject*)self);
923 Mixer_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
927 self = (MixerObject*)type->tp_alloc(type, 0);
933 return (PyObject*)self;
937 Mixer_init(MixerObject *self, PyObject *args, PyObject *kwds)
939 static char *kwlist[] = {"name", "stereo", NULL};
943 if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|b", kwlist, &name, &stereo))
946 self->mixer = create(name, (bool)stereo);
947 if (self->mixer == NULL) {
948 PyErr_SetString(PyExc_RuntimeError,
949 "error creating mixer, probably jack is not running");
956 static PyMemberDef Mixer_members[] = {
961 Mixer_get_channels_count(MixerObject *self, void *closure)
963 return PyLong_FromLong(get_channels_count(self->mixer));
967 Mixer_get_client_name(MixerObject *self, void *closure)
969 return PyUnicode_FromString(get_client_name(self->mixer));
973 Mixer_get_last_midi_channel(MixerObject *self, void *closure)
975 return PyLong_FromLong(get_last_midi_channel(self->mixer));
979 Mixer_set_last_midi_channel(MixerObject *self, PyObject *value, void *closure)
984 new_channel = PyLong_AsLong(value);
985 result = set_last_midi_channel(self->mixer, new_channel);
993 Mixer_get_midi_behavior_mode(MixerObject *self, void *closure)
995 return PyLong_FromLong(get_midi_behavior_mode(self->mixer));
999 Mixer_set_midi_behavior_mode(MixerObject *self, PyObject *value, void *closure)
1002 unsigned int result;
1004 mode = PyLong_AsLong(value);
1005 result = set_midi_behavior_mode(self->mixer, mode);
1014 static PyGetSetDef Mixer_getseters[] = {
1015 {"channels_count", (getter)Mixer_get_channels_count, NULL,
1016 "channels count", NULL},
1017 {"last_midi_channel", (getter)Mixer_get_last_midi_channel, (setter)Mixer_set_last_midi_channel,
1018 "last midi channel", NULL},
1019 {"midi_behavior_mode", (getter)Mixer_get_midi_behavior_mode, (setter)Mixer_set_midi_behavior_mode,
1020 "midi behavior mode", NULL},
1025 Mixer_add_channel(MixerObject *self, PyObject *args)
1029 jack_mixer_channel_t channel;
1031 if (! PyArg_ParseTuple(args, "si", &name, &stereo)) return NULL;
1033 channel = add_channel(self->mixer, name, (bool)stereo);
1035 if (channel == NULL) {
1036 PyErr_SetString(PyExc_RuntimeError, "error adding channel");
1040 return Channel_New(channel);
1044 Mixer_add_output_channel(MixerObject *self, PyObject *args)
1049 jack_mixer_output_channel_t channel;
1051 if (! PyArg_ParseTuple(args, "s|bb", &name, &stereo, &system)) return NULL;
1053 channel = add_output_channel(self->mixer, name, (bool)stereo, (bool)system);
1055 return OutputChannel_New(channel);
1059 Mixer_destroy(MixerObject *self, PyObject *args)
1062 destroy(self->mixer);
1069 static PyMethodDef Mixer_methods[] = {
1070 {"add_channel", (PyCFunction)Mixer_add_channel, METH_VARARGS, "Add a new channel"},
1071 {"add_output_channel", (PyCFunction)Mixer_add_output_channel, METH_VARARGS, "Add a new output channel"},
1072 {"destroy", (PyCFunction)Mixer_destroy, METH_VARARGS, "Destroy JACK Mixer"},
1073 {"client_name", (PyCFunction)Mixer_get_client_name, METH_VARARGS, "Get jack client name"},
1074 // {"remove_channel", (PyCFunction)Mixer_remove_channel, METH_VARARGS, "Remove a channel"},
1078 static PyTypeObject MixerType = {
1079 PyVarObject_HEAD_INIT(NULL, 0)
1080 "jack_mixer_c.Mixer", /*tp_name*/
1081 sizeof(MixerObject), /*tp_basicsize*/
1083 (destructor)Mixer_dealloc, /*tp_dealloc*/
1090 0, /*tp_as_sequence*/
1091 0, /*tp_as_mapping*/
1098 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1099 "Mixer objects", /* tp_doc */
1100 0, /* tp_traverse */
1102 0, /* tp_richcompare */
1103 0, /* tp_weaklistoffset */
1105 0, /* tp_iternext */
1106 Mixer_methods, /* tp_methods */
1107 Mixer_members, /* tp_members */
1108 Mixer_getseters, /* tp_getset */
1111 0, /* tp_descr_get */
1112 0, /* tp_descr_set */
1113 0, /* tp_dictoffset */
1114 (initproc)Mixer_init, /* tp_init */
1116 Mixer_new, /* tp_new */
1120 static PyMethodDef jack_mixer_methods[] = {
1121 {NULL, NULL, 0, NULL} /* Sentinel */
1125 static struct PyModuleDef moduledef = {
1126 PyModuleDef_HEAD_INIT,
1127 "jack_mixer_c", /* m_name */
1128 "Jack Mixer C Helper Module", /* m_doc */
1130 jack_mixer_methods, /* m_methods */
1131 NULL, /* m_reload */
1132 NULL, /* m_traverse */
1137 PyMODINIT_FUNC PyInit_jack_mixer_c(void)
1141 if (PyType_Ready(&MixerType) < 0)
1143 if (PyType_Ready(&ChannelType) < 0)
1145 if (PyType_Ready(&OutputChannelType) < 0)
1147 if (PyType_Ready(&ScaleType) < 0)
1150 m = PyModule_Create(&moduledef);
1151 //m = Py_InitModule3("jack_mixer_c", jack_mixer_methods, "module doc");
1153 Py_INCREF(&MixerType);
1154 PyModule_AddObject(m, "Mixer", (PyObject*)&MixerType);
1155 Py_INCREF(&ChannelType);
1156 PyModule_AddObject(m, "Channel", (PyObject*)&ChannelType);
1157 Py_INCREF(&OutputChannelType);
1158 PyModule_AddObject(m, "OutputChannel", (PyObject*)&OutputChannelType);
1159 Py_INCREF(&ScaleType);
1160 PyModule_AddObject(m, "Scale", (PyObject*)&ScaleType);