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
)
590 if (! PyArg_ParseTuple(args
, "")) return NULL
;
592 result
= channel_autoset_volume_midi_cc(self
->channel
);
595 PyErr_SetString(PyExc_RuntimeError
, "No free CC for channel volume.");
598 return PyLong_FromLong(result
);
602 Channel_autoset_balance_midi_cc(ChannelObject
*self
, PyObject
*args
)
605 if (! PyArg_ParseTuple(args
, "")) return NULL
;
607 result
= channel_autoset_balance_midi_cc(self
->channel
);
610 PyErr_SetString(PyExc_RuntimeError
, "No free CC for channel balance.");
613 return PyLong_FromLong(result
);
617 Channel_autoset_mute_midi_cc(ChannelObject
*self
, PyObject
*args
)
620 if (! PyArg_ParseTuple(args
, "")) return NULL
;
622 result
= channel_autoset_mute_midi_cc(self
->channel
);
625 PyErr_SetString(PyExc_RuntimeError
, "No free CC for channel mute.");
628 return PyLong_FromLong(result
);
632 Channel_autoset_solo_midi_cc(ChannelObject
*self
, PyObject
*args
)
635 if (! PyArg_ParseTuple(args
, "")) return NULL
;
637 result
= channel_autoset_solo_midi_cc(self
->channel
);
640 PyErr_SetString(PyExc_RuntimeError
, "No free CC channel solo.");
643 return PyLong_FromLong(result
);
646 static PyMethodDef channel_methods
[] = {
647 {"remove", (PyCFunction
)Channel_remove
, METH_VARARGS
, "Remove"},
648 {"autoset_volume_midi_cc",
649 (PyCFunction
)Channel_autoset_volume_midi_cc
, METH_VARARGS
, "Autoset Volume MIDI CC"},
650 {"autoset_balance_midi_cc",
651 (PyCFunction
)Channel_autoset_balance_midi_cc
, METH_VARARGS
, "Autoset Balance MIDI CC"},
652 {"autoset_mute_midi_cc",
653 (PyCFunction
)Channel_autoset_mute_midi_cc
, METH_VARARGS
, "Autoset Mute MIDI CC"},
654 {"autoset_solo_midi_cc",
655 (PyCFunction
)Channel_autoset_solo_midi_cc
, METH_VARARGS
, "Autoset Solo MIDI CC"},
659 static PyTypeObject ChannelType
= {
660 PyVarObject_HEAD_INIT(NULL
, 0)
661 "jack_mixer_c.Channel", /*tp_name*/
662 sizeof(ChannelObject
), /*tp_basicsize*/
664 (destructor
)Channel_dealloc
, /*tp_dealloc*/
671 0, /*tp_as_sequence*/
679 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /*tp_flags*/
680 "Channel objects", /* tp_doc */
683 0, /* tp_richcompare */
684 0, /* tp_weaklistoffset */
687 channel_methods
, /* tp_methods */
689 Channel_getseters
, /* tp_getset */
692 0, /* tp_descr_get */
693 0, /* tp_descr_set */
694 0, /* tp_dictoffset */
695 (initproc
)Channel_init
, /* tp_init */
697 Channel_new
, /* tp_new */
701 Channel_New(jack_mixer_channel_t channel
)
704 self
= (ChannelObject
*)PyObject_NEW(ChannelObject
, &ChannelType
);
706 self
->channel
= channel
;
707 self
->midi_change_callback
= NULL
;
709 return (PyObject
*)self
;
712 /** Output Channel Type **/
716 PyObject
*midi_change_callback
;
717 jack_mixer_output_channel_t
*output_channel
;
718 } OutputChannelObject
;
721 OutputChannel_set_prefader(OutputChannelObject
*self
, PyObject
*value
, void *closure
)
723 if (value
== Py_True
) {
724 output_channel_set_prefader(self
->output_channel
, true);
726 output_channel_set_prefader(self
->output_channel
, false);
732 OutputChannel_get_prefader(OutputChannelObject
*self
, void *closure
)
736 if (output_channel_is_prefader(self
->output_channel
)) {
745 static PyGetSetDef OutputChannel_getseters
[] = {
747 (getter
)OutputChannel_get_prefader
, (setter
)OutputChannel_set_prefader
,
753 OutputChannel_remove(OutputChannelObject
*self
, PyObject
*args
)
755 if (! PyArg_ParseTuple(args
, "")) return NULL
;
756 remove_output_channel(self
->output_channel
);
762 OutputChannel_set_solo(OutputChannelObject
*self
, PyObject
*args
)
767 if (! PyArg_ParseTuple(args
, "Ob", &channel
, &solo
)) return NULL
;
769 output_channel_set_solo(self
->output_channel
,
770 ((ChannelObject
*)channel
)->channel
,
778 OutputChannel_set_muted(OutputChannelObject
*self
, PyObject
*args
)
783 if (! PyArg_ParseTuple(args
, "Ob", &channel
, &muted
)) return NULL
;
785 output_channel_set_muted(self
->output_channel
,
786 ((ChannelObject
*)channel
)->channel
,
794 OutputChannel_is_solo(OutputChannelObject
*self
, PyObject
*args
)
799 if (! PyArg_ParseTuple(args
, "O", &channel
)) return NULL
;
801 if (output_channel_is_solo(self
->output_channel
,
802 ((ChannelObject
*)channel
)->channel
)) {
813 OutputChannel_is_muted(OutputChannelObject
*self
, PyObject
*args
)
818 if (! PyArg_ParseTuple(args
, "O", &channel
)) return NULL
;
820 if (output_channel_is_muted(self
->output_channel
,
821 ((ChannelObject
*)channel
)->channel
)) {
832 OutputChannel_set_in_prefader(OutputChannelObject
*self
, PyObject
*args
)
835 unsigned char prefader
;
837 if (! PyArg_ParseTuple(args
, "Ob", &channel
, &prefader
)) return NULL
;
839 output_channel_set_in_prefader(self
->output_channel
,
840 ((ChannelObject
*)channel
)->channel
,
848 OutputChannel_is_in_prefader(OutputChannelObject
*self
, PyObject
*args
)
853 if (! PyArg_ParseTuple(args
, "O", &channel
)) return NULL
;
855 if (output_channel_is_in_prefader(self
->output_channel
,
856 ((ChannelObject
*)channel
)->channel
)) {
866 static PyMethodDef output_channel_methods
[] = {
867 {"remove", (PyCFunction
)OutputChannel_remove
, METH_VARARGS
, "Remove"},
868 {"set_solo", (PyCFunction
)OutputChannel_set_solo
, METH_VARARGS
, "Set a channel as solo"},
869 {"set_muted", (PyCFunction
)OutputChannel_set_muted
, METH_VARARGS
, "Set a channel as muted"},
870 {"is_solo", (PyCFunction
)OutputChannel_is_solo
, METH_VARARGS
, "Is a channel set as solo"},
871 {"is_muted", (PyCFunction
)OutputChannel_is_muted
, METH_VARARGS
, "Is a channel set as muted"},
872 {"set_in_prefader", (PyCFunction
)OutputChannel_set_in_prefader
, METH_VARARGS
, "Set a channel as prefader"},
873 {"is_in_prefader", (PyCFunction
)OutputChannel_is_in_prefader
, METH_VARARGS
, "Is a channel set as prefader"},
877 static PyTypeObject OutputChannelType
= {
878 PyVarObject_HEAD_INIT(NULL
, 0)
879 "jack_mixer_c.OutputChannel", /*tp_name*/
880 sizeof(OutputChannelObject
), /*tp_basicsize*/
889 0, /*tp_as_sequence*/
897 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /*tp_flags*/
898 "Output Channel objects", /* tp_doc */
901 0, /* tp_richcompare */
902 0, /* tp_weaklistoffset */
905 output_channel_methods
, /* tp_methods */
907 OutputChannel_getseters
, /* tp_getset */
908 &ChannelType
, /* tp_base */
910 0, /* tp_descr_get */
911 0, /* tp_descr_set */
912 0, /* tp_dictoffset */
919 OutputChannel_New(jack_mixer_output_channel_t output_channel
)
921 OutputChannelObject
*self
;
922 self
= (OutputChannelObject
*)PyObject_NEW(OutputChannelObject
, &OutputChannelType
);
924 self
->midi_change_callback
= NULL
;
925 self
->output_channel
= output_channel
;
927 return (PyObject
*)self
;
939 Mixer_dealloc(MixerObject
*self
)
942 destroy(self
->mixer
);
943 Py_TYPE(self
)->tp_free((PyObject
*)self
);
947 Mixer_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
951 self
= (MixerObject
*)type
->tp_alloc(type
, 0);
957 return (PyObject
*)self
;
961 Mixer_init(MixerObject
*self
, PyObject
*args
, PyObject
*kwds
)
963 static char *kwlist
[] = {"name", "stereo", NULL
};
967 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "s|b", kwlist
, &name
, &stereo
))
970 self
->mixer
= create(name
, (bool)stereo
);
971 if (self
->mixer
== NULL
) {
972 PyErr_SetString(PyExc_RuntimeError
,
973 "error creating mixer, probably jack is not running");
980 static PyMemberDef Mixer_members
[] = {
985 Mixer_get_channels_count(MixerObject
*self
, void *closure
)
987 return PyLong_FromLong(get_channels_count(self
->mixer
));
991 Mixer_get_client_name(MixerObject
*self
, void *closure
)
993 return PyUnicode_FromString(get_client_name(self
->mixer
));
997 Mixer_get_last_midi_channel(MixerObject
*self
, void *closure
)
999 return PyLong_FromLong(get_last_midi_channel(self
->mixer
));
1003 Mixer_set_last_midi_channel(MixerObject
*self
, PyObject
*value
, void *closure
)
1006 unsigned int result
;
1008 new_channel
= PyLong_AsLong(value
);
1009 result
= set_last_midi_channel(self
->mixer
, new_channel
);
1017 Mixer_get_midi_behavior_mode(MixerObject
*self
, void *closure
)
1019 return PyLong_FromLong(get_midi_behavior_mode(self
->mixer
));
1023 Mixer_set_midi_behavior_mode(MixerObject
*self
, PyObject
*value
, void *closure
)
1026 unsigned int result
;
1028 mode
= PyLong_AsLong(value
);
1029 result
= set_midi_behavior_mode(self
->mixer
, mode
);
1038 static PyGetSetDef Mixer_getseters
[] = {
1039 {"channels_count", (getter
)Mixer_get_channels_count
, NULL
,
1040 "channels count", NULL
},
1041 {"last_midi_channel", (getter
)Mixer_get_last_midi_channel
, (setter
)Mixer_set_last_midi_channel
,
1042 "last midi channel", NULL
},
1043 {"midi_behavior_mode", (getter
)Mixer_get_midi_behavior_mode
, (setter
)Mixer_set_midi_behavior_mode
,
1044 "midi behavior mode", NULL
},
1049 Mixer_add_channel(MixerObject
*self
, PyObject
*args
)
1053 jack_mixer_channel_t channel
;
1055 if (! PyArg_ParseTuple(args
, "si", &name
, &stereo
)) return NULL
;
1057 channel
= add_channel(self
->mixer
, name
, (bool)stereo
);
1059 if (channel
== NULL
) {
1060 PyErr_SetString(PyExc_RuntimeError
, "error adding channel");
1064 return Channel_New(channel
);
1068 Mixer_add_output_channel(MixerObject
*self
, PyObject
*args
)
1073 jack_mixer_output_channel_t channel
;
1075 if (! PyArg_ParseTuple(args
, "s|bb", &name
, &stereo
, &system
)) return NULL
;
1077 channel
= add_output_channel(self
->mixer
, name
, (bool)stereo
, (bool)system
);
1079 return OutputChannel_New(channel
);
1083 Mixer_destroy(MixerObject
*self
, PyObject
*args
)
1086 destroy(self
->mixer
);
1093 static PyMethodDef Mixer_methods
[] = {
1094 {"add_channel", (PyCFunction
)Mixer_add_channel
, METH_VARARGS
, "Add a new channel"},
1095 {"add_output_channel", (PyCFunction
)Mixer_add_output_channel
, METH_VARARGS
, "Add a new output channel"},
1096 {"destroy", (PyCFunction
)Mixer_destroy
, METH_VARARGS
, "Destroy JACK Mixer"},
1097 {"client_name", (PyCFunction
)Mixer_get_client_name
, METH_VARARGS
, "Get jack client name"},
1098 // {"remove_channel", (PyCFunction)Mixer_remove_channel, METH_VARARGS, "Remove a channel"},
1102 static PyTypeObject MixerType
= {
1103 PyVarObject_HEAD_INIT(NULL
, 0)
1104 "jack_mixer_c.Mixer", /*tp_name*/
1105 sizeof(MixerObject
), /*tp_basicsize*/
1107 (destructor
)Mixer_dealloc
, /*tp_dealloc*/
1114 0, /*tp_as_sequence*/
1115 0, /*tp_as_mapping*/
1122 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /*tp_flags*/
1123 "Mixer objects", /* tp_doc */
1124 0, /* tp_traverse */
1126 0, /* tp_richcompare */
1127 0, /* tp_weaklistoffset */
1129 0, /* tp_iternext */
1130 Mixer_methods
, /* tp_methods */
1131 Mixer_members
, /* tp_members */
1132 Mixer_getseters
, /* tp_getset */
1135 0, /* tp_descr_get */
1136 0, /* tp_descr_set */
1137 0, /* tp_dictoffset */
1138 (initproc
)Mixer_init
, /* tp_init */
1140 Mixer_new
, /* tp_new */
1144 static PyMethodDef jack_mixer_methods
[] = {
1145 {NULL
, NULL
, 0, NULL
} /* Sentinel */
1149 static struct PyModuleDef moduledef
= {
1150 PyModuleDef_HEAD_INIT
,
1151 "jack_mixer_c", /* m_name */
1152 "Jack Mixer C Helper Module", /* m_doc */
1154 jack_mixer_methods
, /* m_methods */
1155 NULL
, /* m_reload */
1156 NULL
, /* m_traverse */
1161 PyMODINIT_FUNC
PyInit_jack_mixer_c(void)
1165 if (PyType_Ready(&MixerType
) < 0)
1167 if (PyType_Ready(&ChannelType
) < 0)
1169 if (PyType_Ready(&OutputChannelType
) < 0)
1171 if (PyType_Ready(&ScaleType
) < 0)
1174 m
= PyModule_Create(&moduledef
);
1175 //m = Py_InitModule3("jack_mixer_c", jack_mixer_methods, "module doc");
1177 Py_INCREF(&MixerType
);
1178 PyModule_AddObject(m
, "Mixer", (PyObject
*)&MixerType
);
1179 Py_INCREF(&ChannelType
);
1180 PyModule_AddObject(m
, "Channel", (PyObject
*)&ChannelType
);
1181 Py_INCREF(&OutputChannelType
);
1182 PyModule_AddObject(m
, "OutputChannel", (PyObject
*)&OutputChannelType
);
1183 Py_INCREF(&ScaleType
);
1184 PyModule_AddObject(m
, "Scale", (PyObject
*)&ScaleType
);