/*************************************************************************
* Copyright 2010 Olivier Belanger *
* *
* This file is part of pyo, a python module to help digital signal *
* processing script creation. *
* *
* pyo is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* pyo is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with pyo. If not, see . *
*************************************************************************/
#include
#include "structmember.h"
#include "pyomodule.h"
#include "streammodule.h"
#include "servermodule.h"
#include "dummymodule.h"
typedef struct {
pyo_audio_HEAD
PyObject *input;
Stream *input_stream;
long value;
MYFLT last_value;
int modebuffer[2]; // need at least 2 slots for mul & add
} Select;
static void
Select_selector(Select *self) {
MYFLT val, inval;
int i;
MYFLT *in = Stream_getData((Stream *)self->input_stream);
for (i=0; ibufsize; i++) {
inval = in[i];
if (inval == self->value && inval != self->last_value)
val = 1;
else
val = 0;
self->last_value = inval;
self->data[i] = val;
}
}
static void Select_postprocessing_ii(Select *self) { POST_PROCESSING_II };
static void Select_postprocessing_ai(Select *self) { POST_PROCESSING_AI };
static void Select_postprocessing_ia(Select *self) { POST_PROCESSING_IA };
static void Select_postprocessing_aa(Select *self) { POST_PROCESSING_AA };
static void Select_postprocessing_ireva(Select *self) { POST_PROCESSING_IREVA };
static void Select_postprocessing_areva(Select *self) { POST_PROCESSING_AREVA };
static void Select_postprocessing_revai(Select *self) { POST_PROCESSING_REVAI };
static void Select_postprocessing_revaa(Select *self) { POST_PROCESSING_REVAA };
static void Select_postprocessing_revareva(Select *self) { POST_PROCESSING_REVAREVA };
static void
Select_setProcMode(Select *self)
{
int muladdmode;
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
self->proc_func_ptr = Select_selector;
switch (muladdmode) {
case 0:
self->muladd_func_ptr = Select_postprocessing_ii;
break;
case 1:
self->muladd_func_ptr = Select_postprocessing_ai;
break;
case 2:
self->muladd_func_ptr = Select_postprocessing_revai;
break;
case 10:
self->muladd_func_ptr = Select_postprocessing_ia;
break;
case 11:
self->muladd_func_ptr = Select_postprocessing_aa;
break;
case 12:
self->muladd_func_ptr = Select_postprocessing_revaa;
break;
case 20:
self->muladd_func_ptr = Select_postprocessing_ireva;
break;
case 21:
self->muladd_func_ptr = Select_postprocessing_areva;
break;
case 22:
self->muladd_func_ptr = Select_postprocessing_revareva;
break;
}
}
static void
Select_compute_next_data_frame(Select *self)
{
(*self->proc_func_ptr)(self);
(*self->muladd_func_ptr)(self);
}
static int
Select_traverse(Select *self, visitproc visit, void *arg)
{
pyo_VISIT
Py_VISIT(self->input);
Py_VISIT(self->input_stream);
return 0;
}
static int
Select_clear(Select *self)
{
pyo_CLEAR
Py_CLEAR(self->input);
Py_CLEAR(self->input_stream);
return 0;
}
static void
Select_dealloc(Select* self)
{
pyo_DEALLOC
Select_clear(self);
self->ob_type->tp_free((PyObject*)self);
}
static PyObject *
Select_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
int i;
PyObject *inputtmp, *input_streamtmp, *multmp=NULL, *addtmp=NULL;
Select *self;
self = (Select *)type->tp_alloc(type, 0);
self->value = 0;
self->last_value = -99.0;
self->modebuffer[0] = 0;
self->modebuffer[1] = 0;
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, Select_compute_next_data_frame);
self->mode_func_ptr = Select_setProcMode;
static char *kwlist[] = {"input", "value", "mul", "add", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|iOO", kwlist, &inputtmp, &self->value, &multmp, &addtmp))
Py_RETURN_NONE;
INIT_INPUT_STREAM
if (multmp) {
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
}
if (addtmp) {
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
}
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
(*self->mode_func_ptr)(self);
return (PyObject *)self;
}
static PyObject * Select_getServer(Select* self) { GET_SERVER };
static PyObject * Select_getStream(Select* self) { GET_STREAM };
static PyObject * Select_setMul(Select *self, PyObject *arg) { SET_MUL };
static PyObject * Select_setAdd(Select *self, PyObject *arg) { SET_ADD };
static PyObject * Select_setSub(Select *self, PyObject *arg) { SET_SUB };
static PyObject * Select_setDiv(Select *self, PyObject *arg) { SET_DIV };
static PyObject * Select_play(Select *self, PyObject *args, PyObject *kwds) { PLAY };
static PyObject * Select_stop(Select *self) { STOP };
static PyObject * Select_multiply(Select *self, PyObject *arg) { MULTIPLY };
static PyObject * Select_inplace_multiply(Select *self, PyObject *arg) { INPLACE_MULTIPLY };
static PyObject * Select_add(Select *self, PyObject *arg) { ADD };
static PyObject * Select_inplace_add(Select *self, PyObject *arg) { INPLACE_ADD };
static PyObject * Select_sub(Select *self, PyObject *arg) { SUB };
static PyObject * Select_inplace_sub(Select *self, PyObject *arg) { INPLACE_SUB };
static PyObject * Select_div(Select *self, PyObject *arg) { DIV };
static PyObject * Select_inplace_div(Select *self, PyObject *arg) { INPLACE_DIV };
static PyObject *
Select_setValue(Select *self, PyObject *arg)
{
if (arg == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
if (PyLong_Check(arg) || PyInt_Check(arg)) {
self->value = PyLong_AsLong(arg);
}
Py_INCREF(Py_None);
return Py_None;
}
static PyMemberDef Select_members[] = {
{"server", T_OBJECT_EX, offsetof(Select, server), 0, "Pyo server."},
{"stream", T_OBJECT_EX, offsetof(Select, stream), 0, "Stream object."},
{"mul", T_OBJECT_EX, offsetof(Select, mul), 0, "Mul factor."},
{"add", T_OBJECT_EX, offsetof(Select, add), 0, "Add factor."},
{NULL} /* Sentinel */
};
static PyMethodDef Select_methods[] = {
{"getServer", (PyCFunction)Select_getServer, METH_NOARGS, "Returns server object."},
{"_getStream", (PyCFunction)Select_getStream, METH_NOARGS, "Returns stream object."},
{"play", (PyCFunction)Select_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
{"stop", (PyCFunction)Select_stop, METH_NOARGS, "Stops computing."},
{"setValue", (PyCFunction)Select_setValue, METH_O, "Sets value to select."},
{"setMul", (PyCFunction)Select_setMul, METH_O, "Sets mul factor."},
{"setAdd", (PyCFunction)Select_setAdd, METH_O, "Sets add factor."},
{"setSub", (PyCFunction)Select_setSub, METH_O, "Sets inverse add factor."},
{"setDiv", (PyCFunction)Select_setDiv, METH_O, "Sets inverse mul factor."},
{NULL} /* Sentinel */
};
static PyNumberMethods Select_as_number = {
(binaryfunc)Select_add, /*nb_add*/
(binaryfunc)Select_sub, /*nb_subtract*/
(binaryfunc)Select_multiply, /*nb_multiply*/
(binaryfunc)Select_div, /*nb_divide*/
0, /*nb_remainder*/
0, /*nb_divmod*/
0, /*nb_power*/
0, /*nb_neg*/
0, /*nb_pos*/
0, /*(unaryfunc)array_abs,*/
0, /*nb_nonzero*/
0, /*nb_invert*/
0, /*nb_lshift*/
0, /*nb_rshift*/
0, /*nb_and*/
0, /*nb_xor*/
0, /*nb_or*/
0, /*nb_coerce*/
0, /*nb_int*/
0, /*nb_long*/
0, /*nb_float*/
0, /*nb_oct*/
0, /*nb_hex*/
(binaryfunc)Select_inplace_add, /*inplace_add*/
(binaryfunc)Select_inplace_sub, /*inplace_subtract*/
(binaryfunc)Select_inplace_multiply, /*inplace_multiply*/
(binaryfunc)Select_inplace_div, /*inplace_divide*/
0, /*inplace_remainder*/
0, /*inplace_power*/
0, /*inplace_lshift*/
0, /*inplace_rshift*/
0, /*inplace_and*/
0, /*inplace_xor*/
0, /*inplace_or*/
0, /*nb_floor_divide*/
0, /*nb_true_divide*/
0, /*nb_inplace_floor_divide*/
0, /*nb_inplace_true_divide*/
0, /* nb_index */
};
PyTypeObject SelectType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"_pyo.Select_base", /*tp_name*/
sizeof(Select), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Select_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
&Select_as_number, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
"Select objects. Watch input and send a trig on a selected value.", /* tp_doc */
(traverseproc)Select_traverse, /* tp_traverse */
(inquiry)Select_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Select_methods, /* tp_methods */
Select_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
Select_new, /* tp_new */
};
typedef struct {
pyo_audio_HEAD
PyObject *input;
Stream *input_stream;
MYFLT last_value;
int modebuffer[2]; // need at least 2 slots for mul & add
} Change;
static void
Change_selector(Change *self) {
MYFLT val, inval;
int i;
MYFLT *in = Stream_getData((Stream *)self->input_stream);
for (i=0; ibufsize; i++) {
inval = in[i];
if (inval < (self->last_value - 0.00001) || inval > (self->last_value + 0.00001)) {
self->last_value = inval;
val = 1;
}
else
val = 0;
self->data[i] = val;
}
}
static void Change_postprocessing_ii(Change *self) { POST_PROCESSING_II };
static void Change_postprocessing_ai(Change *self) { POST_PROCESSING_AI };
static void Change_postprocessing_ia(Change *self) { POST_PROCESSING_IA };
static void Change_postprocessing_aa(Change *self) { POST_PROCESSING_AA };
static void Change_postprocessing_ireva(Change *self) { POST_PROCESSING_IREVA };
static void Change_postprocessing_areva(Change *self) { POST_PROCESSING_AREVA };
static void Change_postprocessing_revai(Change *self) { POST_PROCESSING_REVAI };
static void Change_postprocessing_revaa(Change *self) { POST_PROCESSING_REVAA };
static void Change_postprocessing_revareva(Change *self) { POST_PROCESSING_REVAREVA };
static void
Change_setProcMode(Change *self)
{
int muladdmode;
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
self->proc_func_ptr = Change_selector;
switch (muladdmode) {
case 0:
self->muladd_func_ptr = Change_postprocessing_ii;
break;
case 1:
self->muladd_func_ptr = Change_postprocessing_ai;
break;
case 2:
self->muladd_func_ptr = Change_postprocessing_revai;
break;
case 10:
self->muladd_func_ptr = Change_postprocessing_ia;
break;
case 11:
self->muladd_func_ptr = Change_postprocessing_aa;
break;
case 12:
self->muladd_func_ptr = Change_postprocessing_revaa;
break;
case 20:
self->muladd_func_ptr = Change_postprocessing_ireva;
break;
case 21:
self->muladd_func_ptr = Change_postprocessing_areva;
break;
case 22:
self->muladd_func_ptr = Change_postprocessing_revareva;
break;
}
}
static void
Change_compute_next_data_frame(Change *self)
{
(*self->proc_func_ptr)(self);
(*self->muladd_func_ptr)(self);
}
static int
Change_traverse(Change *self, visitproc visit, void *arg)
{
pyo_VISIT
Py_VISIT(self->input);
Py_VISIT(self->input_stream);
return 0;
}
static int
Change_clear(Change *self)
{
pyo_CLEAR
Py_CLEAR(self->input);
Py_CLEAR(self->input_stream);
return 0;
}
static void
Change_dealloc(Change* self)
{
pyo_DEALLOC
Change_clear(self);
self->ob_type->tp_free((PyObject*)self);
}
static PyObject *
Change_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
int i;
PyObject *inputtmp, *input_streamtmp, *multmp=NULL, *addtmp=NULL;
Change *self;
self = (Change *)type->tp_alloc(type, 0);
self->last_value = 0.0;
self->modebuffer[0] = 0;
self->modebuffer[1] = 0;
INIT_OBJECT_COMMON
Stream_setFunctionPtr(self->stream, Change_compute_next_data_frame);
self->mode_func_ptr = Change_setProcMode;
static char *kwlist[] = {"input", "mul", "add", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kwds, "OOO", kwlist, &inputtmp, &multmp, &addtmp))
Py_RETURN_NONE;
INIT_INPUT_STREAM
if (multmp) {
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
}
if (addtmp) {
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
}
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
(*self->mode_func_ptr)(self);
return (PyObject *)self;
}
static PyObject * Change_getServer(Change* self) { GET_SERVER };
static PyObject * Change_getStream(Change* self) { GET_STREAM };
static PyObject * Change_setMul(Change *self, PyObject *arg) { SET_MUL };
static PyObject * Change_setAdd(Change *self, PyObject *arg) { SET_ADD };
static PyObject * Change_setSub(Change *self, PyObject *arg) { SET_SUB };
static PyObject * Change_setDiv(Change *self, PyObject *arg) { SET_DIV };
static PyObject * Change_play(Change *self, PyObject *args, PyObject *kwds) { PLAY };
static PyObject * Change_stop(Change *self) { STOP };
static PyObject * Change_multiply(Change *self, PyObject *arg) { MULTIPLY };
static PyObject * Change_inplace_multiply(Change *self, PyObject *arg) { INPLACE_MULTIPLY };
static PyObject * Change_add(Change *self, PyObject *arg) { ADD };
static PyObject * Change_inplace_add(Change *self, PyObject *arg) { INPLACE_ADD };
static PyObject * Change_sub(Change *self, PyObject *arg) { SUB };
static PyObject * Change_inplace_sub(Change *self, PyObject *arg) { INPLACE_SUB };
static PyObject * Change_div(Change *self, PyObject *arg) { DIV };
static PyObject * Change_inplace_div(Change *self, PyObject *arg) { INPLACE_DIV };
static PyMemberDef Change_members[] = {
{"server", T_OBJECT_EX, offsetof(Change, server), 0, "Pyo server."},
{"stream", T_OBJECT_EX, offsetof(Change, stream), 0, "Stream object."},
{"mul", T_OBJECT_EX, offsetof(Change, mul), 0, "Mul factor."},
{"add", T_OBJECT_EX, offsetof(Change, add), 0, "Add factor."},
{NULL} /* Sentinel */
};
static PyMethodDef Change_methods[] = {
{"getServer", (PyCFunction)Change_getServer, METH_NOARGS, "Returns server object."},
{"_getStream", (PyCFunction)Change_getStream, METH_NOARGS, "Returns stream object."},
{"play", (PyCFunction)Change_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
{"stop", (PyCFunction)Change_stop, METH_NOARGS, "Stops computing."},
{"setMul", (PyCFunction)Change_setMul, METH_O, "Sets mul factor."},
{"setAdd", (PyCFunction)Change_setAdd, METH_O, "Sets add factor."},
{"setSub", (PyCFunction)Change_setSub, METH_O, "Sets inverse add factor."},
{"setDiv", (PyCFunction)Change_setDiv, METH_O, "Sets inverse mul factor."},
{NULL} /* Sentinel */
};
static PyNumberMethods Change_as_number = {
(binaryfunc)Change_add, /*nb_add*/
(binaryfunc)Change_sub, /*nb_subtract*/
(binaryfunc)Change_multiply, /*nb_multiply*/
(binaryfunc)Change_div, /*nb_divide*/
0, /*nb_remainder*/
0, /*nb_divmod*/
0, /*nb_power*/
0, /*nb_neg*/
0, /*nb_pos*/
0, /*(unaryfunc)array_abs,*/
0, /*nb_nonzero*/
0, /*nb_invert*/
0, /*nb_lshift*/
0, /*nb_rshift*/
0, /*nb_and*/
0, /*nb_xor*/
0, /*nb_or*/
0, /*nb_coerce*/
0, /*nb_int*/
0, /*nb_long*/
0, /*nb_float*/
0, /*nb_oct*/
0, /*nb_hex*/
(binaryfunc)Change_inplace_add, /*inplace_add*/
(binaryfunc)Change_inplace_sub, /*inplace_subtract*/
(binaryfunc)Change_inplace_multiply, /*inplace_multiply*/
(binaryfunc)Change_inplace_div, /*inplace_divide*/
0, /*inplace_remainder*/
0, /*inplace_power*/
0, /*inplace_lshift*/
0, /*inplace_rshift*/
0, /*inplace_and*/
0, /*inplace_xor*/
0, /*inplace_or*/
0, /*nb_floor_divide*/
0, /*nb_true_divide*/
0, /*nb_inplace_floor_divide*/
0, /*nb_inplace_true_divide*/
0, /* nb_index */
};
PyTypeObject ChangeType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"_pyo.Change_base", /*tp_name*/
sizeof(Change), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Change_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
&Change_as_number, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
"Change objects. Send a trig whenever input value changed.", /* tp_doc */
(traverseproc)Change_traverse, /* tp_traverse */
(inquiry)Change_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Change_methods, /* tp_methods */
Change_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
Change_new, /* tp_new */
};