1
/*************************************************************************
2
* Copyright 2010 Olivier Belanger *
4
* This file is part of pyo, a python module to help digital signal *
5
* processing script creation. *
7
* pyo is free software: you can redistribute it and/or modify *
8
* it under the terms of the GNU General Public License as published by *
9
* the Free Software Foundation, either version 3 of the License, or *
10
* (at your option) any later version. *
12
* pyo is distributed in the hope that it will be useful, *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
* GNU General Public License for more details. *
17
* You should have received a copy of the GNU General Public License *
18
* along with pyo. If not, see <http://www.gnu.org/licenses/>. *
19
*************************************************************************/
22
#include "structmember.h"
24
#include "pyomodule.h"
25
#include "streammodule.h"
26
#include "servermodule.h"
27
#include "dummymodule.h"
35
static void Mix_postprocessing_ii(Mix *self) { POST_PROCESSING_II };
36
static void Mix_postprocessing_ai(Mix *self) { POST_PROCESSING_AI };
37
static void Mix_postprocessing_ia(Mix *self) { POST_PROCESSING_IA };
38
static void Mix_postprocessing_aa(Mix *self) { POST_PROCESSING_AA };
39
static void Mix_postprocessing_ireva(Mix *self) { POST_PROCESSING_IREVA };
40
static void Mix_postprocessing_areva(Mix *self) { POST_PROCESSING_AREVA };
41
static void Mix_postprocessing_revai(Mix *self) { POST_PROCESSING_REVAI };
42
static void Mix_postprocessing_revaa(Mix *self) { POST_PROCESSING_REVAA };
43
static void Mix_postprocessing_revareva(Mix *self) { POST_PROCESSING_REVAREVA };
46
Mix_setProcMode(Mix *self)
49
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
53
self->muladd_func_ptr = Mix_postprocessing_ii;
56
self->muladd_func_ptr = Mix_postprocessing_ai;
59
self->muladd_func_ptr = Mix_postprocessing_revai;
62
self->muladd_func_ptr = Mix_postprocessing_ia;
65
self->muladd_func_ptr = Mix_postprocessing_aa;
68
self->muladd_func_ptr = Mix_postprocessing_revaa;
71
self->muladd_func_ptr = Mix_postprocessing_ireva;
74
self->muladd_func_ptr = Mix_postprocessing_areva;
77
self->muladd_func_ptr = Mix_postprocessing_revareva;
83
Mix_compute_next_data_frame(Mix *self)
88
Py_ssize_t lsize = PyList_Size(self->input);
90
MYFLT buffer[self->bufsize];
91
memset(&buffer, 0, sizeof(buffer));
93
for (i=0; i<lsize; i++) {
94
stream = PyObject_CallMethod((PyObject *)PyList_GET_ITEM(self->input, i), "_getStream", NULL);
95
MYFLT *in = Stream_getData((Stream *)stream);
96
for (j=0; j<self->bufsize; j++) {
98
buffer[j] = in[j] + old;
102
for (i=0; i<self->bufsize; i++) {
103
self->data[i] = buffer[i];
106
(*self->muladd_func_ptr)(self);
110
Mix_traverse(Mix *self, visitproc visit, void *arg)
124
Mix_dealloc(Mix* self)
128
self->ob_type->tp_free((PyObject*)self);
131
static PyObject * Mix_deleteStream(Mix *self) { DELETE_STREAM };
134
Mix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
138
self = (Mix *)type->tp_alloc(type, 0);
140
self->modebuffer[0] = 0;
141
self->modebuffer[1] = 0;
144
Stream_setFunctionPtr(self->stream, Mix_compute_next_data_frame);
145
self->mode_func_ptr = Mix_setProcMode;
147
return (PyObject *)self;
151
Mix_init(Mix *self, PyObject *args, PyObject *kwds)
153
PyObject *inputtmp=NULL, *multmp=NULL, *addtmp=NULL;
155
static char *kwlist[] = {"input", "mul", "add", NULL};
157
if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist, &inputtmp, &multmp, &addtmp))
161
Py_XDECREF(self->input);
162
self->input = inputtmp;
165
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
169
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
172
Py_INCREF(self->stream);
173
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
175
(*self->mode_func_ptr)(self);
181
static PyObject * Mix_getServer(Mix* self) { GET_SERVER };
182
static PyObject * Mix_getStream(Mix* self) { GET_STREAM };
183
static PyObject * Mix_setMul(Mix *self, PyObject *arg) { SET_MUL };
184
static PyObject * Mix_setAdd(Mix *self, PyObject *arg) { SET_ADD };
185
static PyObject * Mix_setSub(Mix *self, PyObject *arg) { SET_SUB };
186
static PyObject * Mix_setDiv(Mix *self, PyObject *arg) { SET_DIV };
188
static PyObject * Mix_play(Mix *self, PyObject *args, PyObject *kwds) { PLAY };
189
static PyObject * Mix_out(Mix *self, PyObject *args, PyObject *kwds) { OUT };
190
static PyObject * Mix_stop(Mix *self) { STOP };
192
static PyObject * Mix_multiply(Mix *self, PyObject *arg) { MULTIPLY };
193
static PyObject * Mix_inplace_multiply(Mix *self, PyObject *arg) { INPLACE_MULTIPLY };
194
static PyObject * Mix_add(Mix *self, PyObject *arg) { ADD };
195
static PyObject * Mix_inplace_add(Mix *self, PyObject *arg) { INPLACE_ADD };
196
static PyObject * Mix_sub(Mix *self, PyObject *arg) { SUB };
197
static PyObject * Mix_inplace_sub(Mix *self, PyObject *arg) { INPLACE_SUB };
198
static PyObject * Mix_div(Mix *self, PyObject *arg) { DIV };
199
static PyObject * Mix_inplace_div(Mix *self, PyObject *arg) { INPLACE_DIV };
201
static PyMemberDef Mix_members[] = {
202
{"server", T_OBJECT_EX, offsetof(Mix, server), 0, "Pyo server."},
203
{"stream", T_OBJECT_EX, offsetof(Mix, stream), 0, "Stream object."},
204
{"mul", T_OBJECT_EX, offsetof(Mix, mul), 0, "Mul factor."},
205
{"add", T_OBJECT_EX, offsetof(Mix, add), 0, "Add factor."},
206
{NULL} /* Sentinel */
209
static PyMethodDef Mix_methods[] = {
210
{"getServer", (PyCFunction)Mix_getServer, METH_NOARGS, "Returns server object."},
211
{"_getStream", (PyCFunction)Mix_getStream, METH_NOARGS, "Returns stream object."},
212
{"deleteStream", (PyCFunction)Mix_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
213
{"play", (PyCFunction)Mix_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
214
{"out", (PyCFunction)Mix_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
215
{"stop", (PyCFunction)Mix_stop, METH_NOARGS, "Stops computing."},
216
{"setMul", (PyCFunction)Mix_setMul, METH_O, "Sets oscillator mul factor."},
217
{"setAdd", (PyCFunction)Mix_setAdd, METH_O, "Sets oscillator add factor."},
218
{"setSub", (PyCFunction)Mix_setSub, METH_O, "Sets inverse add factor."},
219
{"setDiv", (PyCFunction)Mix_setDiv, METH_O, "Sets inverse mul factor."},
220
{NULL} /* Sentinel */
223
static PyNumberMethods Mix_as_number = {
224
(binaryfunc)Mix_add, /*nb_add*/
225
(binaryfunc)Mix_sub, /*nb_subtract*/
226
(binaryfunc)Mix_multiply, /*nb_multiply*/
227
(binaryfunc)Mix_div, /*nb_divide*/
233
0, /*(unaryfunc)array_abs,*/
247
(binaryfunc)Mix_inplace_add, /*inplace_add*/
248
(binaryfunc)Mix_inplace_sub, /*inplace_subtract*/
249
(binaryfunc)Mix_inplace_multiply, /*inplace_multiply*/
250
(binaryfunc)Mix_inplace_div, /*inplace_divide*/
251
0, /*inplace_remainder*/
253
0, /*inplace_lshift*/
254
0, /*inplace_rshift*/
258
0, /*nb_floor_divide*/
259
0, /*nb_true_divide*/
260
0, /*nb_inplace_floor_divide*/
261
0, /*nb_inplace_true_divide*/
265
PyTypeObject MixType = {
266
PyObject_HEAD_INIT(NULL)
268
"_pyo.Mix_base", /*tp_name*/
269
sizeof(Mix), /*tp_basicsize*/
271
(destructor)Mix_dealloc, /*tp_dealloc*/
277
&Mix_as_number, /*tp_as_number*/
278
0, /*tp_as_sequence*/
286
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
287
"Mix objects. Retreive audio from an input channel.", /* tp_doc */
288
(traverseproc)Mix_traverse, /* tp_traverse */
289
(inquiry)Mix_clear, /* tp_clear */
290
0, /* tp_richcompare */
291
0, /* tp_weaklistoffset */
294
Mix_methods, /* tp_methods */
295
Mix_members, /* tp_members */
299
0, /* tp_descr_get */
300
0, /* tp_descr_set */
301
0, /* tp_dictoffset */
302
(initproc)Mix_init, /* tp_init */
304
Mix_new, /* tp_new */