/************************************************************************* * 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 */ };