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
*************************************************************************/
21
#include "structmember.h"
23
#include "pyomodule.h"
24
#include "streammodule.h"
25
#include "servermodule.h"
26
#include "dummymodule.h"
37
int modebuffer[3]; // need at least 2 slots for mul & add
44
Follower_filters_i(Follower *self) {
48
MYFLT *in = Stream_getData((Stream *)self->input_stream);
49
freq = PyFloat_AS_DOUBLE(self->freq);
51
if (freq != self->last_freq) {
52
self->factor = MYEXP(-1.0 / (self->sr / freq));
53
self->last_freq = freq;
56
for (i=0; i<self->bufsize; i++) {
60
self->follow = self->data[i] = absin + self->factor * (self->follow - absin);
65
Follower_filters_a(Follower *self) {
69
MYFLT *in = Stream_getData((Stream *)self->input_stream);
70
MYFLT *fr = Stream_getData((Stream *)self->freq_stream);
72
for (i=0; i<self->bufsize; i++) {
74
if (freq != self->last_freq) {
75
self->factor = MYEXP(-1.0 / (self->sr / freq));
76
self->last_freq = freq;
81
self->follow = self->data[i] = absin + self->factor * (self->follow - absin);
85
static void Follower_postprocessing_ii(Follower *self) { POST_PROCESSING_II };
86
static void Follower_postprocessing_ai(Follower *self) { POST_PROCESSING_AI };
87
static void Follower_postprocessing_ia(Follower *self) { POST_PROCESSING_IA };
88
static void Follower_postprocessing_aa(Follower *self) { POST_PROCESSING_AA };
89
static void Follower_postprocessing_ireva(Follower *self) { POST_PROCESSING_IREVA };
90
static void Follower_postprocessing_areva(Follower *self) { POST_PROCESSING_AREVA };
91
static void Follower_postprocessing_revai(Follower *self) { POST_PROCESSING_REVAI };
92
static void Follower_postprocessing_revaa(Follower *self) { POST_PROCESSING_REVAA };
93
static void Follower_postprocessing_revareva(Follower *self) { POST_PROCESSING_REVAREVA };
96
Follower_setProcMode(Follower *self)
98
int procmode, muladdmode;
99
procmode = self->modebuffer[2];
100
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
104
self->proc_func_ptr = Follower_filters_i;
107
self->proc_func_ptr = Follower_filters_a;
110
switch (muladdmode) {
112
self->muladd_func_ptr = Follower_postprocessing_ii;
115
self->muladd_func_ptr = Follower_postprocessing_ai;
118
self->muladd_func_ptr = Follower_postprocessing_revai;
121
self->muladd_func_ptr = Follower_postprocessing_ia;
124
self->muladd_func_ptr = Follower_postprocessing_aa;
127
self->muladd_func_ptr = Follower_postprocessing_revaa;
130
self->muladd_func_ptr = Follower_postprocessing_ireva;
133
self->muladd_func_ptr = Follower_postprocessing_areva;
136
self->muladd_func_ptr = Follower_postprocessing_revareva;
142
Follower_compute_next_data_frame(Follower *self)
144
(*self->proc_func_ptr)(self);
145
(*self->muladd_func_ptr)(self);
149
Follower_traverse(Follower *self, visitproc visit, void *arg)
152
Py_VISIT(self->input);
153
Py_VISIT(self->input_stream);
154
Py_VISIT(self->freq);
155
Py_VISIT(self->freq_stream);
160
Follower_clear(Follower *self)
163
Py_CLEAR(self->input);
164
Py_CLEAR(self->input_stream);
165
Py_CLEAR(self->freq);
166
Py_CLEAR(self->freq_stream);
171
Follower_dealloc(Follower* self)
174
Follower_clear(self);
175
self->ob_type->tp_free((PyObject*)self);
178
static PyObject * Follower_deleteStream(Follower *self) { DELETE_STREAM };
181
Follower_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
185
self = (Follower *)type->tp_alloc(type, 0);
187
self->freq = PyFloat_FromDouble(20);
189
self->last_freq = -1.0;
191
self->modebuffer[0] = 0;
192
self->modebuffer[1] = 0;
193
self->modebuffer[2] = 0;
196
Stream_setFunctionPtr(self->stream, Follower_compute_next_data_frame);
197
self->mode_func_ptr = Follower_setProcMode;
198
return (PyObject *)self;
202
Follower_init(Follower *self, PyObject *args, PyObject *kwds)
204
PyObject *inputtmp, *input_streamtmp, *freqtmp=NULL, *multmp=NULL, *addtmp=NULL;
206
static char *kwlist[] = {"input", "freq", "mul", "add", NULL};
208
if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OOO", kwlist, &inputtmp, &freqtmp, &multmp, &addtmp))
214
PyObject_CallMethod((PyObject *)self, "setFreq", "O", freqtmp);
218
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
222
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
225
Py_INCREF(self->stream);
226
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
228
(*self->mode_func_ptr)(self);
234
static PyObject * Follower_getServer(Follower* self) { GET_SERVER };
235
static PyObject * Follower_getStream(Follower* self) { GET_STREAM };
236
static PyObject * Follower_setMul(Follower *self, PyObject *arg) { SET_MUL };
237
static PyObject * Follower_setAdd(Follower *self, PyObject *arg) { SET_ADD };
238
static PyObject * Follower_setSub(Follower *self, PyObject *arg) { SET_SUB };
239
static PyObject * Follower_setDiv(Follower *self, PyObject *arg) { SET_DIV };
241
static PyObject * Follower_play(Follower *self, PyObject *args, PyObject *kwds) { PLAY };
242
static PyObject * Follower_stop(Follower *self) { STOP };
244
static PyObject * Follower_multiply(Follower *self, PyObject *arg) { MULTIPLY };
245
static PyObject * Follower_inplace_multiply(Follower *self, PyObject *arg) { INPLACE_MULTIPLY };
246
static PyObject * Follower_add(Follower *self, PyObject *arg) { ADD };
247
static PyObject * Follower_inplace_add(Follower *self, PyObject *arg) { INPLACE_ADD };
248
static PyObject * Follower_sub(Follower *self, PyObject *arg) { SUB };
249
static PyObject * Follower_inplace_sub(Follower *self, PyObject *arg) { INPLACE_SUB };
250
static PyObject * Follower_div(Follower *self, PyObject *arg) { DIV };
251
static PyObject * Follower_inplace_div(Follower *self, PyObject *arg) { INPLACE_DIV };
254
Follower_setFreq(Follower *self, PyObject *arg)
256
PyObject *tmp, *streamtmp;
263
int isNumber = PyNumber_Check(arg);
267
Py_DECREF(self->freq);
269
self->freq = PyNumber_Float(tmp);
270
self->modebuffer[2] = 0;
274
streamtmp = PyObject_CallMethod((PyObject *)self->freq, "_getStream", NULL);
275
Py_INCREF(streamtmp);
276
Py_XDECREF(self->freq_stream);
277
self->freq_stream = (Stream *)streamtmp;
278
self->modebuffer[2] = 1;
281
(*self->mode_func_ptr)(self);
287
static PyMemberDef Follower_members[] = {
288
{"server", T_OBJECT_EX, offsetof(Follower, server), 0, "Pyo server."},
289
{"stream", T_OBJECT_EX, offsetof(Follower, stream), 0, "Stream object."},
290
{"input", T_OBJECT_EX, offsetof(Follower, input), 0, "Input sound object."},
291
{"freq", T_OBJECT_EX, offsetof(Follower, freq), 0, "Cutoff frequency in cycle per second."},
292
{"mul", T_OBJECT_EX, offsetof(Follower, mul), 0, "Mul factor."},
293
{"add", T_OBJECT_EX, offsetof(Follower, add), 0, "Add factor."},
294
{NULL} /* Sentinel */
297
static PyMethodDef Follower_methods[] = {
298
{"getServer", (PyCFunction)Follower_getServer, METH_NOARGS, "Returns server object."},
299
{"_getStream", (PyCFunction)Follower_getStream, METH_NOARGS, "Returns stream object."},
300
{"deleteStream", (PyCFunction)Follower_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
301
{"play", (PyCFunction)Follower_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
302
{"stop", (PyCFunction)Follower_stop, METH_NOARGS, "Stops computing."},
303
{"setFreq", (PyCFunction)Follower_setFreq, METH_O, "Sets filter cutoff frequency in cycle per second."},
304
{"setMul", (PyCFunction)Follower_setMul, METH_O, "Sets oscillator mul factor."},
305
{"setAdd", (PyCFunction)Follower_setAdd, METH_O, "Sets oscillator add factor."},
306
{"setSub", (PyCFunction)Follower_setSub, METH_O, "Sets inverse add factor."},
307
{"setDiv", (PyCFunction)Follower_setDiv, METH_O, "Sets inverse mul factor."},
308
{NULL} /* Sentinel */
311
static PyNumberMethods Follower_as_number = {
312
(binaryfunc)Follower_add, /*nb_add*/
313
(binaryfunc)Follower_sub, /*nb_subtract*/
314
(binaryfunc)Follower_multiply, /*nb_multiply*/
315
(binaryfunc)Follower_div, /*nb_divide*/
321
0, /*(unaryfunc)array_abs,*/
335
(binaryfunc)Follower_inplace_add, /*inplace_add*/
336
(binaryfunc)Follower_inplace_sub, /*inplace_subtract*/
337
(binaryfunc)Follower_inplace_multiply, /*inplace_multiply*/
338
(binaryfunc)Follower_inplace_div, /*inplace_divide*/
339
0, /*inplace_remainder*/
341
0, /*inplace_lshift*/
342
0, /*inplace_rshift*/
346
0, /*nb_floor_divide*/
347
0, /*nb_true_divide*/
348
0, /*nb_inplace_floor_divide*/
349
0, /*nb_inplace_true_divide*/
353
PyTypeObject FollowerType = {
354
PyObject_HEAD_INIT(NULL)
356
"_pyo.Follower_base", /*tp_name*/
357
sizeof(Follower), /*tp_basicsize*/
359
(destructor)Follower_dealloc, /*tp_dealloc*/
365
&Follower_as_number, /*tp_as_number*/
366
0, /*tp_as_sequence*/
374
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
375
"Follower objects. Envelope follower.", /* tp_doc */
376
(traverseproc)Follower_traverse, /* tp_traverse */
377
(inquiry)Follower_clear, /* tp_clear */
378
0, /* tp_richcompare */
379
0, /* tp_weaklistoffset */
382
Follower_methods, /* tp_methods */
383
Follower_members, /* tp_members */
387
0, /* tp_descr_get */
388
0, /* tp_descr_set */
389
0, /* tp_dictoffset */
390
(initproc)Follower_init, /* tp_init */
392
Follower_new, /* tp_new */
401
Stream *input_stream;
403
Stream *risetime_stream;
405
Stream *falltime_stream;
406
int modebuffer[4]; // need at least 2 slots for mul & add
415
Follower2_filters_ii(Follower2 *self) {
416
MYFLT absin, risetime, falltime;
419
MYFLT *in = Stream_getData((Stream *)self->input_stream);
420
risetime = PyFloat_AS_DOUBLE(self->risetime);
423
falltime = PyFloat_AS_DOUBLE(self->falltime);
427
if (risetime != self->last_risetime) {
428
self->risefactor = MYEXP(-1.0 / (self->sr * risetime));
429
self->last_risetime = risetime;
432
if (falltime != self->last_falltime) {
433
self->fallfactor = MYEXP(-1.0 / (self->sr * falltime));
434
self->last_falltime = falltime;
437
for (i=0; i<self->bufsize; i++) {
441
if (self->follow < absin)
442
self->follow = self->data[i] = absin + self->risefactor * (self->follow - absin);
444
self->follow = self->data[i] = absin + self->fallfactor * (self->follow - absin);
449
Follower2_filters_ai(Follower2 *self) {
450
MYFLT absin, risetime, falltime;
453
MYFLT *in = Stream_getData((Stream *)self->input_stream);
454
MYFLT *rise = Stream_getData((Stream *)self->risetime_stream);
455
falltime = PyFloat_AS_DOUBLE(self->falltime);
459
if (falltime != self->last_falltime) {
460
self->fallfactor = MYEXP(-1.0 / (self->sr * falltime));
461
self->last_falltime = falltime;
464
for (i=0; i<self->bufsize; i++) {
468
if (risetime != self->last_risetime) {
469
self->risefactor = MYEXP(-1.0 / (self->sr * risetime));
470
self->last_risetime = risetime;
475
if (self->follow < absin)
476
self->follow = self->data[i] = absin + self->risefactor * (self->follow - absin);
478
self->follow = self->data[i] = absin + self->fallfactor * (self->follow - absin);
483
Follower2_filters_ia(Follower2 *self) {
484
MYFLT absin, risetime, falltime;
487
MYFLT *in = Stream_getData((Stream *)self->input_stream);
488
risetime = PyFloat_AS_DOUBLE(self->risetime);
491
MYFLT *fall = Stream_getData((Stream *)self->falltime_stream);
493
if (risetime != self->last_risetime) {
494
self->risefactor = MYEXP(-1.0 / (self->sr * risetime));
495
self->last_risetime = risetime;
498
for (i=0; i<self->bufsize; i++) {
502
if (falltime != self->last_falltime) {
503
self->fallfactor = MYEXP(-1.0 / (self->sr * falltime));
504
self->last_falltime = falltime;
509
if (self->follow < absin)
510
self->follow = self->data[i] = absin + self->risefactor * (self->follow - absin);
512
self->follow = self->data[i] = absin + self->fallfactor * (self->follow - absin);
517
Follower2_filters_aa(Follower2 *self) {
518
MYFLT absin, risetime, falltime;
521
MYFLT *in = Stream_getData((Stream *)self->input_stream);
522
MYFLT *rise = Stream_getData((Stream *)self->risetime_stream);
523
MYFLT *fall = Stream_getData((Stream *)self->falltime_stream);
525
for (i=0; i<self->bufsize; i++) {
529
if (risetime != self->last_risetime) {
530
self->risefactor = MYEXP(-1.0 / (self->sr * risetime));
531
self->last_risetime = risetime;
536
if (falltime != self->last_falltime) {
537
self->fallfactor = MYEXP(-1.0 / (self->sr * falltime));
538
self->last_falltime = falltime;
543
if (self->follow < absin)
544
self->follow = self->data[i] = absin + self->risefactor * (self->follow - absin);
546
self->follow = self->data[i] = absin + self->fallfactor * (self->follow - absin);
550
static void Follower2_postprocessing_ii(Follower2 *self) { POST_PROCESSING_II };
551
static void Follower2_postprocessing_ai(Follower2 *self) { POST_PROCESSING_AI };
552
static void Follower2_postprocessing_ia(Follower2 *self) { POST_PROCESSING_IA };
553
static void Follower2_postprocessing_aa(Follower2 *self) { POST_PROCESSING_AA };
554
static void Follower2_postprocessing_ireva(Follower2 *self) { POST_PROCESSING_IREVA };
555
static void Follower2_postprocessing_areva(Follower2 *self) { POST_PROCESSING_AREVA };
556
static void Follower2_postprocessing_revai(Follower2 *self) { POST_PROCESSING_REVAI };
557
static void Follower2_postprocessing_revaa(Follower2 *self) { POST_PROCESSING_REVAA };
558
static void Follower2_postprocessing_revareva(Follower2 *self) { POST_PROCESSING_REVAREVA };
561
Follower2_setProcMode(Follower2 *self)
563
int procmode, muladdmode;
564
procmode = self->modebuffer[2] + self->modebuffer[3] * 10;
565
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
569
self->proc_func_ptr = Follower2_filters_ii;
572
self->proc_func_ptr = Follower2_filters_ai;
575
self->proc_func_ptr = Follower2_filters_ia;
578
self->proc_func_ptr = Follower2_filters_aa;
581
switch (muladdmode) {
583
self->muladd_func_ptr = Follower2_postprocessing_ii;
586
self->muladd_func_ptr = Follower2_postprocessing_ai;
589
self->muladd_func_ptr = Follower2_postprocessing_revai;
592
self->muladd_func_ptr = Follower2_postprocessing_ia;
595
self->muladd_func_ptr = Follower2_postprocessing_aa;
598
self->muladd_func_ptr = Follower2_postprocessing_revaa;
601
self->muladd_func_ptr = Follower2_postprocessing_ireva;
604
self->muladd_func_ptr = Follower2_postprocessing_areva;
607
self->muladd_func_ptr = Follower2_postprocessing_revareva;
613
Follower2_compute_next_data_frame(Follower2 *self)
615
(*self->proc_func_ptr)(self);
616
(*self->muladd_func_ptr)(self);
620
Follower2_traverse(Follower2 *self, visitproc visit, void *arg)
623
Py_VISIT(self->input);
624
Py_VISIT(self->input_stream);
625
Py_VISIT(self->risetime);
626
Py_VISIT(self->risetime_stream);
627
Py_VISIT(self->falltime);
628
Py_VISIT(self->falltime_stream);
633
Follower2_clear(Follower2 *self)
636
Py_CLEAR(self->input);
637
Py_CLEAR(self->input_stream);
638
Py_CLEAR(self->risetime);
639
Py_CLEAR(self->risetime_stream);
640
Py_CLEAR(self->falltime);
641
Py_CLEAR(self->falltime_stream);
646
Follower2_dealloc(Follower2* self)
649
Follower2_clear(self);
650
self->ob_type->tp_free((PyObject*)self);
653
static PyObject * Follower2_deleteStream(Follower2 *self) { DELETE_STREAM };
656
Follower2_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
660
self = (Follower2 *)type->tp_alloc(type, 0);
662
self->risetime = PyFloat_FromDouble(0.01);
663
self->falltime = PyFloat_FromDouble(0.1);
665
self->last_risetime = -1.0;
666
self->last_falltime = -1.0;
667
self->risefactor = self->fallfactor = 0.99;
668
self->modebuffer[0] = 0;
669
self->modebuffer[1] = 0;
670
self->modebuffer[2] = 0;
671
self->modebuffer[3] = 0;
674
Stream_setFunctionPtr(self->stream, Follower2_compute_next_data_frame);
675
self->mode_func_ptr = Follower2_setProcMode;
676
return (PyObject *)self;
680
Follower2_init(Follower2 *self, PyObject *args, PyObject *kwds)
682
PyObject *inputtmp, *input_streamtmp, *risetimetmp=NULL, *falltimetmp=NULL, *multmp=NULL, *addtmp=NULL;
684
static char *kwlist[] = {"input", "risetime", "falltime", "mul", "add", NULL};
686
if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OOOO", kwlist, &inputtmp, &risetimetmp, &falltimetmp, &multmp, &addtmp))
692
PyObject_CallMethod((PyObject *)self, "setRisetime", "O", risetimetmp);
696
PyObject_CallMethod((PyObject *)self, "setFalltime", "O", falltimetmp);
700
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
704
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
707
Py_INCREF(self->stream);
708
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
710
(*self->mode_func_ptr)(self);
716
static PyObject * Follower2_getServer(Follower2* self) { GET_SERVER };
717
static PyObject * Follower2_getStream(Follower2* self) { GET_STREAM };
718
static PyObject * Follower2_setMul(Follower2 *self, PyObject *arg) { SET_MUL };
719
static PyObject * Follower2_setAdd(Follower2 *self, PyObject *arg) { SET_ADD };
720
static PyObject * Follower2_setSub(Follower2 *self, PyObject *arg) { SET_SUB };
721
static PyObject * Follower2_setDiv(Follower2 *self, PyObject *arg) { SET_DIV };
723
static PyObject * Follower2_play(Follower2 *self, PyObject *args, PyObject *kwds) { PLAY };
724
static PyObject * Follower2_stop(Follower2 *self) { STOP };
726
static PyObject * Follower2_multiply(Follower2 *self, PyObject *arg) { MULTIPLY };
727
static PyObject * Follower2_inplace_multiply(Follower2 *self, PyObject *arg) { INPLACE_MULTIPLY };
728
static PyObject * Follower2_add(Follower2 *self, PyObject *arg) { ADD };
729
static PyObject * Follower2_inplace_add(Follower2 *self, PyObject *arg) { INPLACE_ADD };
730
static PyObject * Follower2_sub(Follower2 *self, PyObject *arg) { SUB };
731
static PyObject * Follower2_inplace_sub(Follower2 *self, PyObject *arg) { INPLACE_SUB };
732
static PyObject * Follower2_div(Follower2 *self, PyObject *arg) { DIV };
733
static PyObject * Follower2_inplace_div(Follower2 *self, PyObject *arg) { INPLACE_DIV };
736
Follower2_setRisetime(Follower2 *self, PyObject *arg)
738
PyObject *tmp, *streamtmp;
745
int isNumber = PyNumber_Check(arg);
749
Py_DECREF(self->risetime);
751
self->risetime = PyNumber_Float(tmp);
752
self->modebuffer[2] = 0;
755
self->risetime = tmp;
756
streamtmp = PyObject_CallMethod((PyObject *)self->risetime, "_getStream", NULL);
757
Py_INCREF(streamtmp);
758
Py_XDECREF(self->risetime_stream);
759
self->risetime_stream = (Stream *)streamtmp;
760
self->modebuffer[2] = 1;
763
(*self->mode_func_ptr)(self);
770
Follower2_setFalltime(Follower2 *self, PyObject *arg)
772
PyObject *tmp, *streamtmp;
779
int isNumber = PyNumber_Check(arg);
783
Py_DECREF(self->falltime);
785
self->falltime = PyNumber_Float(tmp);
786
self->modebuffer[3] = 0;
789
self->falltime = tmp;
790
streamtmp = PyObject_CallMethod((PyObject *)self->falltime, "_getStream", NULL);
791
Py_INCREF(streamtmp);
792
Py_XDECREF(self->falltime_stream);
793
self->falltime_stream = (Stream *)streamtmp;
794
self->modebuffer[3] = 1;
797
(*self->mode_func_ptr)(self);
803
static PyMemberDef Follower2_members[] = {
804
{"server", T_OBJECT_EX, offsetof(Follower2, server), 0, "Pyo server."},
805
{"stream", T_OBJECT_EX, offsetof(Follower2, stream), 0, "Stream object."},
806
{"input", T_OBJECT_EX, offsetof(Follower2, input), 0, "Input sound object."},
807
{"risetime", T_OBJECT_EX, offsetof(Follower2, risetime), 0, "Risetime in second."},
808
{"falltime", T_OBJECT_EX, offsetof(Follower2, falltime), 0, "Falltime in second."},
809
{"mul", T_OBJECT_EX, offsetof(Follower2, mul), 0, "Mul factor."},
810
{"add", T_OBJECT_EX, offsetof(Follower2, add), 0, "Add factor."},
811
{NULL} /* Sentinel */
814
static PyMethodDef Follower2_methods[] = {
815
{"getServer", (PyCFunction)Follower2_getServer, METH_NOARGS, "Returns server object."},
816
{"_getStream", (PyCFunction)Follower2_getStream, METH_NOARGS, "Returns stream object."},
817
{"deleteStream", (PyCFunction)Follower2_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
818
{"play", (PyCFunction)Follower2_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
819
{"stop", (PyCFunction)Follower2_stop, METH_NOARGS, "Stops computing."},
820
{"setRisetime", (PyCFunction)Follower2_setRisetime, METH_O, "Sets filter risetime in second."},
821
{"setFalltime", (PyCFunction)Follower2_setFalltime, METH_O, "Sets filter falltime in second."},
822
{"setMul", (PyCFunction)Follower2_setMul, METH_O, "Sets oscillator mul factor."},
823
{"setAdd", (PyCFunction)Follower2_setAdd, METH_O, "Sets oscillator add factor."},
824
{"setSub", (PyCFunction)Follower2_setSub, METH_O, "Sets inverse add factor."},
825
{"setDiv", (PyCFunction)Follower2_setDiv, METH_O, "Sets inverse mul factor."},
826
{NULL} /* Sentinel */
829
static PyNumberMethods Follower2_as_number = {
830
(binaryfunc)Follower2_add, /*nb_add*/
831
(binaryfunc)Follower2_sub, /*nb_subtract*/
832
(binaryfunc)Follower2_multiply, /*nb_multiply*/
833
(binaryfunc)Follower2_div, /*nb_divide*/
839
0, /*(unaryfunc)array_abs,*/
853
(binaryfunc)Follower2_inplace_add, /*inplace_add*/
854
(binaryfunc)Follower2_inplace_sub, /*inplace_subtract*/
855
(binaryfunc)Follower2_inplace_multiply, /*inplace_multiply*/
856
(binaryfunc)Follower2_inplace_div, /*inplace_divide*/
857
0, /*inplace_remainder*/
859
0, /*inplace_lshift*/
860
0, /*inplace_rshift*/
864
0, /*nb_floor_divide*/
865
0, /*nb_true_divide*/
866
0, /*nb_inplace_floor_divide*/
867
0, /*nb_inplace_true_divide*/
871
PyTypeObject Follower2Type = {
872
PyObject_HEAD_INIT(NULL)
874
"_pyo.Follower2_base", /*tp_name*/
875
sizeof(Follower2), /*tp_basicsize*/
877
(destructor)Follower2_dealloc, /*tp_dealloc*/
883
&Follower2_as_number, /*tp_as_number*/
884
0, /*tp_as_sequence*/
892
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
893
"Follower2 objects. Envelope follower.", /* tp_doc */
894
(traverseproc)Follower2_traverse, /* tp_traverse */
895
(inquiry)Follower2_clear, /* tp_clear */
896
0, /* tp_richcompare */
897
0, /* tp_weaklistoffset */
900
Follower2_methods, /* tp_methods */
901
Follower2_members, /* tp_members */
905
0, /* tp_descr_get */
906
0, /* tp_descr_set */
907
0, /* tp_dictoffset */
908
(initproc)Follower2_init, /* tp_init */
910
Follower2_new, /* tp_new */
919
Stream *input_stream;
923
int modebuffer[2]; // need at least 2 slots for mul & add
927
ZCross_process(ZCross *self) {
931
MYFLT *in = Stream_getData((Stream *)self->input_stream);
933
for (i=0; i<self->bufsize; i++) {
934
self->data[i] = self->lastValue;
936
if (self->lastSample >= 0.0) {
937
if (inval < 0.0 && (self->lastSample-inval) > self->thresh)
941
if (inval >= 0.0 && (inval-self->lastSample) > self->thresh)
944
self->lastSample = inval;
946
self->lastValue = (MYFLT)count / self->bufsize;
949
static void ZCross_postprocessing_ii(ZCross *self) { POST_PROCESSING_II };
950
static void ZCross_postprocessing_ai(ZCross *self) { POST_PROCESSING_AI };
951
static void ZCross_postprocessing_ia(ZCross *self) { POST_PROCESSING_IA };
952
static void ZCross_postprocessing_aa(ZCross *self) { POST_PROCESSING_AA };
953
static void ZCross_postprocessing_ireva(ZCross *self) { POST_PROCESSING_IREVA };
954
static void ZCross_postprocessing_areva(ZCross *self) { POST_PROCESSING_AREVA };
955
static void ZCross_postprocessing_revai(ZCross *self) { POST_PROCESSING_REVAI };
956
static void ZCross_postprocessing_revaa(ZCross *self) { POST_PROCESSING_REVAA };
957
static void ZCross_postprocessing_revareva(ZCross *self) { POST_PROCESSING_REVAREVA };
960
ZCross_setProcMode(ZCross *self)
963
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
965
self->proc_func_ptr = ZCross_process;
967
switch (muladdmode) {
969
self->muladd_func_ptr = ZCross_postprocessing_ii;
972
self->muladd_func_ptr = ZCross_postprocessing_ai;
975
self->muladd_func_ptr = ZCross_postprocessing_revai;
978
self->muladd_func_ptr = ZCross_postprocessing_ia;
981
self->muladd_func_ptr = ZCross_postprocessing_aa;
984
self->muladd_func_ptr = ZCross_postprocessing_revaa;
987
self->muladd_func_ptr = ZCross_postprocessing_ireva;
990
self->muladd_func_ptr = ZCross_postprocessing_areva;
993
self->muladd_func_ptr = ZCross_postprocessing_revareva;
999
ZCross_compute_next_data_frame(ZCross *self)
1001
(*self->proc_func_ptr)(self);
1002
(*self->muladd_func_ptr)(self);
1006
ZCross_traverse(ZCross *self, visitproc visit, void *arg)
1009
Py_VISIT(self->input);
1010
Py_VISIT(self->input_stream);
1015
ZCross_clear(ZCross *self)
1018
Py_CLEAR(self->input);
1019
Py_CLEAR(self->input_stream);
1024
ZCross_dealloc(ZCross* self)
1028
self->ob_type->tp_free((PyObject*)self);
1031
static PyObject * ZCross_deleteStream(ZCross *self) { DELETE_STREAM };
1034
ZCross_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1038
self = (ZCross *)type->tp_alloc(type, 0);
1041
self->lastValue = self->lastSample = 0.0;
1042
self->modebuffer[0] = 0;
1043
self->modebuffer[1] = 0;
1046
Stream_setFunctionPtr(self->stream, ZCross_compute_next_data_frame);
1047
self->mode_func_ptr = ZCross_setProcMode;
1048
return (PyObject *)self;
1052
ZCross_init(ZCross *self, PyObject *args, PyObject *kwds)
1054
PyObject *inputtmp, *input_streamtmp, *multmp=NULL, *addtmp=NULL;
1056
static char *kwlist[] = {"input", "thresh", "mul", "add", NULL};
1058
if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_FOO, kwlist, &inputtmp, &self->thresh, &multmp, &addtmp))
1064
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
1068
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
1071
Py_INCREF(self->stream);
1072
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
1074
(*self->mode_func_ptr)(self);
1080
static PyObject * ZCross_getServer(ZCross* self) { GET_SERVER };
1081
static PyObject * ZCross_getStream(ZCross* self) { GET_STREAM };
1082
static PyObject * ZCross_setMul(ZCross *self, PyObject *arg) { SET_MUL };
1083
static PyObject * ZCross_setAdd(ZCross *self, PyObject *arg) { SET_ADD };
1084
static PyObject * ZCross_setSub(ZCross *self, PyObject *arg) { SET_SUB };
1085
static PyObject * ZCross_setDiv(ZCross *self, PyObject *arg) { SET_DIV };
1087
static PyObject * ZCross_play(ZCross *self, PyObject *args, PyObject *kwds) { PLAY };
1088
static PyObject * ZCross_stop(ZCross *self) { STOP };
1090
static PyObject * ZCross_multiply(ZCross *self, PyObject *arg) { MULTIPLY };
1091
static PyObject * ZCross_inplace_multiply(ZCross *self, PyObject *arg) { INPLACE_MULTIPLY };
1092
static PyObject * ZCross_add(ZCross *self, PyObject *arg) { ADD };
1093
static PyObject * ZCross_inplace_add(ZCross *self, PyObject *arg) { INPLACE_ADD };
1094
static PyObject * ZCross_sub(ZCross *self, PyObject *arg) { SUB };
1095
static PyObject * ZCross_inplace_sub(ZCross *self, PyObject *arg) { INPLACE_SUB };
1096
static PyObject * ZCross_div(ZCross *self, PyObject *arg) { DIV };
1097
static PyObject * ZCross_inplace_div(ZCross *self, PyObject *arg) { INPLACE_DIV };
1100
ZCross_setThresh(ZCross *self, PyObject *arg)
1107
int isNumber = PyNumber_Check(arg);
1109
if (isNumber == 1) {
1110
self->thresh = PyFloat_AS_DOUBLE(PyNumber_Float(arg));
1117
static PyMemberDef ZCross_members[] = {
1118
{"server", T_OBJECT_EX, offsetof(ZCross, server), 0, "Pyo server."},
1119
{"stream", T_OBJECT_EX, offsetof(ZCross, stream), 0, "Stream object."},
1120
{"input", T_OBJECT_EX, offsetof(ZCross, input), 0, "Input sound object."},
1121
{"mul", T_OBJECT_EX, offsetof(ZCross, mul), 0, "Mul factor."},
1122
{"add", T_OBJECT_EX, offsetof(ZCross, add), 0, "Add factor."},
1123
{NULL} /* Sentinel */
1126
static PyMethodDef ZCross_methods[] = {
1127
{"getServer", (PyCFunction)ZCross_getServer, METH_NOARGS, "Returns server object."},
1128
{"_getStream", (PyCFunction)ZCross_getStream, METH_NOARGS, "Returns stream object."},
1129
{"deleteStream", (PyCFunction)ZCross_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
1130
{"play", (PyCFunction)ZCross_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
1131
{"stop", (PyCFunction)ZCross_stop, METH_NOARGS, "Stops computing."},
1132
{"setThresh", (PyCFunction)ZCross_setThresh, METH_O, "Sets the threshold factor."},
1133
{"setMul", (PyCFunction)ZCross_setMul, METH_O, "Sets oscillator mul factor."},
1134
{"setAdd", (PyCFunction)ZCross_setAdd, METH_O, "Sets oscillator add factor."},
1135
{"setSub", (PyCFunction)ZCross_setSub, METH_O, "Sets inverse add factor."},
1136
{"setDiv", (PyCFunction)ZCross_setDiv, METH_O, "Sets inverse mul factor."},
1137
{NULL} /* Sentinel */
1140
static PyNumberMethods ZCross_as_number = {
1141
(binaryfunc)ZCross_add, /*nb_add*/
1142
(binaryfunc)ZCross_sub, /*nb_subtract*/
1143
(binaryfunc)ZCross_multiply, /*nb_multiply*/
1144
(binaryfunc)ZCross_div, /*nb_divide*/
1150
0, /*(unaryfunc)array_abs,*/
1164
(binaryfunc)ZCross_inplace_add, /*inplace_add*/
1165
(binaryfunc)ZCross_inplace_sub, /*inplace_subtract*/
1166
(binaryfunc)ZCross_inplace_multiply, /*inplace_multiply*/
1167
(binaryfunc)ZCross_inplace_div, /*inplace_divide*/
1168
0, /*inplace_remainder*/
1169
0, /*inplace_power*/
1170
0, /*inplace_lshift*/
1171
0, /*inplace_rshift*/
1175
0, /*nb_floor_divide*/
1176
0, /*nb_true_divide*/
1177
0, /*nb_inplace_floor_divide*/
1178
0, /*nb_inplace_true_divide*/
1182
PyTypeObject ZCrossType = {
1183
PyObject_HEAD_INIT(NULL)
1185
"_pyo.ZCross_base", /*tp_name*/
1186
sizeof(ZCross), /*tp_basicsize*/
1188
(destructor)ZCross_dealloc, /*tp_dealloc*/
1194
&ZCross_as_number, /*tp_as_number*/
1195
0, /*tp_as_sequence*/
1196
0, /*tp_as_mapping*/
1203
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
1204
"ZCross objects. Returns number of zero crossing.", /* tp_doc */
1205
(traverseproc)ZCross_traverse, /* tp_traverse */
1206
(inquiry)ZCross_clear, /* tp_clear */
1207
0, /* tp_richcompare */
1208
0, /* tp_weaklistoffset */
1210
0, /* tp_iternext */
1211
ZCross_methods, /* tp_methods */
1212
ZCross_members, /* tp_members */
1216
0, /* tp_descr_get */
1217
0, /* tp_descr_set */
1218
0, /* tp_dictoffset */
1219
(initproc)ZCross_init, /* tp_init */
1221
ZCross_new, /* tp_new */