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"
36
Stream *feedback_stream;
41
MYFLT *buffer; // samples memory
45
Delay_process_ii(Delay *self) {
46
MYFLT val, xind, frac;
50
MYFLT del = PyFloat_AS_DOUBLE(self->delay);
51
MYFLT feed = PyFloat_AS_DOUBLE(self->feedback);
55
else if (del > self->maxdelay)
57
MYFLT sampdel = del * self->sr;
64
MYFLT *in = Stream_getData((Stream *)self->input_stream);
66
for (i=0; i<self->bufsize; i++) {
67
xind = self->in_count - sampdel;
72
val = self->buffer[ind] * (1.0 - frac) + self->buffer[ind+1] * frac;
75
self->buffer[self->in_count] = in[i] + (val * feed);
76
if (self->in_count == 0)
77
self->buffer[self->size] = self->buffer[self->in_count];
79
if (self->in_count >= self->size)
85
Delay_process_ai(Delay *self) {
86
MYFLT val, xind, frac, sampdel, del;
90
MYFLT *delobj = Stream_getData((Stream *)self->delay_stream);
91
MYFLT feed = PyFloat_AS_DOUBLE(self->feedback);
98
MYFLT *in = Stream_getData((Stream *)self->input_stream);
100
for (i=0; i<self->bufsize; i++) {
104
else if (del > self->maxdelay)
105
del = self->maxdelay;
106
sampdel = del * self->sr;
107
xind = self->in_count - sampdel;
112
val = self->buffer[ind] * (1.0 - frac) + self->buffer[ind+1] * frac;
115
self->buffer[self->in_count] = in[i] + (val * feed);
116
if (self->in_count == 0)
117
self->buffer[self->size] = self->buffer[self->in_count];
119
if (self->in_count >= self->size)
125
Delay_process_ia(Delay *self) {
126
MYFLT val, xind, frac, feed;
130
MYFLT del = PyFloat_AS_DOUBLE(self->delay);
131
MYFLT *fdb = Stream_getData((Stream *)self->feedback_stream);
135
else if (del > self->maxdelay)
136
del = self->maxdelay;
137
MYFLT sampdel = del * self->sr;
139
MYFLT *in = Stream_getData((Stream *)self->input_stream);
141
for (i=0; i<self->bufsize; i++) {
142
xind = self->in_count - sampdel;
147
val = self->buffer[ind] * (1.0 - frac) + self->buffer[ind+1] * frac;
156
self->buffer[self->in_count] = in[i] + (val * feed);
157
if (self->in_count == 0)
158
self->buffer[self->size] = self->buffer[self->in_count];
160
if (self->in_count == self->size)
166
Delay_process_aa(Delay *self) {
167
MYFLT val, xind, frac, sampdel, feed, del;
171
MYFLT *delobj = Stream_getData((Stream *)self->delay_stream);
172
MYFLT *fdb = Stream_getData((Stream *)self->feedback_stream);
174
MYFLT *in = Stream_getData((Stream *)self->input_stream);
176
for (i=0; i<self->bufsize; i++) {
180
else if (del > self->maxdelay)
181
del = self->maxdelay;
182
sampdel = del * self->sr;
183
xind = self->in_count - sampdel;
188
val = self->buffer[ind] * (1.0 - frac) + self->buffer[ind+1] * frac;
197
self->buffer[self->in_count] = in[i] + (val * feed);
198
if (self->in_count == 0)
199
self->buffer[self->size] = self->buffer[self->in_count];
201
if (self->in_count == self->size)
206
static void Delay_postprocessing_ii(Delay *self) { POST_PROCESSING_II };
207
static void Delay_postprocessing_ai(Delay *self) { POST_PROCESSING_AI };
208
static void Delay_postprocessing_ia(Delay *self) { POST_PROCESSING_IA };
209
static void Delay_postprocessing_aa(Delay *self) { POST_PROCESSING_AA };
210
static void Delay_postprocessing_ireva(Delay *self) { POST_PROCESSING_IREVA };
211
static void Delay_postprocessing_areva(Delay *self) { POST_PROCESSING_AREVA };
212
static void Delay_postprocessing_revai(Delay *self) { POST_PROCESSING_REVAI };
213
static void Delay_postprocessing_revaa(Delay *self) { POST_PROCESSING_REVAA };
214
static void Delay_postprocessing_revareva(Delay *self) { POST_PROCESSING_REVAREVA };
217
Delay_setProcMode(Delay *self)
219
int procmode, muladdmode;
220
procmode = self->modebuffer[2] + self->modebuffer[3] * 10;
221
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
225
self->proc_func_ptr = Delay_process_ii;
228
self->proc_func_ptr = Delay_process_ai;
231
self->proc_func_ptr = Delay_process_ia;
234
self->proc_func_ptr = Delay_process_aa;
237
switch (muladdmode) {
239
self->muladd_func_ptr = Delay_postprocessing_ii;
242
self->muladd_func_ptr = Delay_postprocessing_ai;
245
self->muladd_func_ptr = Delay_postprocessing_revai;
248
self->muladd_func_ptr = Delay_postprocessing_ia;
251
self->muladd_func_ptr = Delay_postprocessing_aa;
254
self->muladd_func_ptr = Delay_postprocessing_revaa;
257
self->muladd_func_ptr = Delay_postprocessing_ireva;
260
self->muladd_func_ptr = Delay_postprocessing_areva;
263
self->muladd_func_ptr = Delay_postprocessing_revareva;
269
Delay_compute_next_data_frame(Delay *self)
271
(*self->proc_func_ptr)(self);
272
(*self->muladd_func_ptr)(self);
276
Delay_traverse(Delay *self, visitproc visit, void *arg)
279
Py_VISIT(self->input);
280
Py_VISIT(self->input_stream);
281
Py_VISIT(self->delay);
282
Py_VISIT(self->delay_stream);
283
Py_VISIT(self->feedback);
284
Py_VISIT(self->feedback_stream);
289
Delay_clear(Delay *self)
292
Py_CLEAR(self->input);
293
Py_CLEAR(self->input_stream);
294
Py_CLEAR(self->delay);
295
Py_CLEAR(self->delay_stream);
296
Py_CLEAR(self->feedback);
297
Py_CLEAR(self->feedback_stream);
302
Delay_dealloc(Delay* self)
307
self->ob_type->tp_free((PyObject*)self);
310
static PyObject * Delay_deleteStream(Delay *self) { DELETE_STREAM };
313
Delay_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
317
self = (Delay *)type->tp_alloc(type, 0);
319
self->delay = PyFloat_FromDouble(0.25);
320
self->feedback = PyFloat_FromDouble(0);
323
self->modebuffer[0] = 0;
324
self->modebuffer[1] = 0;
325
self->modebuffer[2] = 0;
326
self->modebuffer[3] = 0;
329
Stream_setFunctionPtr(self->stream, Delay_compute_next_data_frame);
330
self->mode_func_ptr = Delay_setProcMode;
332
return (PyObject *)self;
336
Delay_init(Delay *self, PyObject *args, PyObject *kwds)
338
PyObject *inputtmp, *input_streamtmp, *delaytmp=NULL, *feedbacktmp=NULL, *multmp=NULL, *addtmp=NULL;
341
static char *kwlist[] = {"input", "delay", "feedback", "maxdelay", "mul", "add", NULL};
343
if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_OOFOO, kwlist, &inputtmp, &delaytmp, &feedbacktmp, &self->maxdelay, &multmp, &addtmp))
349
PyObject_CallMethod((PyObject *)self, "setDelay", "O", delaytmp);
353
PyObject_CallMethod((PyObject *)self, "setFeedback", "O", feedbacktmp);
357
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
361
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
364
Py_INCREF(self->stream);
365
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
367
self->size = (long)(self->maxdelay * self->sr + 0.5);
369
self->buffer = (MYFLT *)realloc(self->buffer, (self->size+1) * sizeof(MYFLT));
370
for (i=0; i<(self->size+1); i++) {
371
self->buffer[i] = 0.;
374
(*self->mode_func_ptr)(self);
380
static PyObject * Delay_getServer(Delay* self) { GET_SERVER };
381
static PyObject * Delay_getStream(Delay* self) { GET_STREAM };
382
static PyObject * Delay_setMul(Delay *self, PyObject *arg) { SET_MUL };
383
static PyObject * Delay_setAdd(Delay *self, PyObject *arg) { SET_ADD };
384
static PyObject * Delay_setSub(Delay *self, PyObject *arg) { SET_SUB };
385
static PyObject * Delay_setDiv(Delay *self, PyObject *arg) { SET_DIV };
387
static PyObject * Delay_play(Delay *self, PyObject *args, PyObject *kwds) { PLAY };
388
static PyObject * Delay_out(Delay *self, PyObject *args, PyObject *kwds) { OUT };
389
static PyObject * Delay_stop(Delay *self) { STOP };
391
static PyObject * Delay_multiply(Delay *self, PyObject *arg) { MULTIPLY };
392
static PyObject * Delay_inplace_multiply(Delay *self, PyObject *arg) { INPLACE_MULTIPLY };
393
static PyObject * Delay_add(Delay *self, PyObject *arg) { ADD };
394
static PyObject * Delay_inplace_add(Delay *self, PyObject *arg) { INPLACE_ADD };
395
static PyObject * Delay_sub(Delay *self, PyObject *arg) { SUB };
396
static PyObject * Delay_inplace_sub(Delay *self, PyObject *arg) { INPLACE_SUB };
397
static PyObject * Delay_div(Delay *self, PyObject *arg) { DIV };
398
static PyObject * Delay_inplace_div(Delay *self, PyObject *arg) { INPLACE_DIV };
401
Delay_setDelay(Delay *self, PyObject *arg)
403
PyObject *tmp, *streamtmp;
410
int isNumber = PyNumber_Check(arg);
414
Py_DECREF(self->delay);
416
self->delay = PyNumber_Float(tmp);
417
self->modebuffer[2] = 0;
421
streamtmp = PyObject_CallMethod((PyObject *)self->delay, "_getStream", NULL);
422
Py_INCREF(streamtmp);
423
Py_XDECREF(self->delay_stream);
424
self->delay_stream = (Stream *)streamtmp;
425
self->modebuffer[2] = 1;
428
(*self->mode_func_ptr)(self);
435
Delay_setFeedback(Delay *self, PyObject *arg)
437
PyObject *tmp, *streamtmp;
444
int isNumber = PyNumber_Check(arg);
448
Py_DECREF(self->feedback);
450
self->feedback = PyNumber_Float(tmp);
451
self->modebuffer[3] = 0;
454
self->feedback = tmp;
455
streamtmp = PyObject_CallMethod((PyObject *)self->feedback, "_getStream", NULL);
456
Py_INCREF(streamtmp);
457
Py_XDECREF(self->feedback_stream);
458
self->feedback_stream = (Stream *)streamtmp;
459
self->modebuffer[3] = 1;
462
(*self->mode_func_ptr)(self);
469
Delay_reset(Delay *self)
472
for (i=0; i<(self->size+1); i++) {
473
self->buffer[i] = 0.;
479
static PyMemberDef Delay_members[] = {
480
{"server", T_OBJECT_EX, offsetof(Delay, server), 0, "Pyo server."},
481
{"stream", T_OBJECT_EX, offsetof(Delay, stream), 0, "Stream object."},
482
{"input", T_OBJECT_EX, offsetof(Delay, input), 0, "Input sound object."},
483
{"delay", T_OBJECT_EX, offsetof(Delay, delay), 0, "Delay time in seconds."},
484
{"feedback", T_OBJECT_EX, offsetof(Delay, feedback), 0, "Feedback value."},
485
{"mul", T_OBJECT_EX, offsetof(Delay, mul), 0, "Mul factor."},
486
{"add", T_OBJECT_EX, offsetof(Delay, add), 0, "Add factor."},
487
{NULL} /* Sentinel */
490
static PyMethodDef Delay_methods[] = {
491
{"getServer", (PyCFunction)Delay_getServer, METH_NOARGS, "Returns server object."},
492
{"_getStream", (PyCFunction)Delay_getStream, METH_NOARGS, "Returns stream object."},
493
{"deleteStream", (PyCFunction)Delay_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
494
{"play", (PyCFunction)Delay_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
495
{"out", (PyCFunction)Delay_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
496
{"stop", (PyCFunction)Delay_stop, METH_NOARGS, "Stops computing."},
497
{"setDelay", (PyCFunction)Delay_setDelay, METH_O, "Sets delay time in seconds."},
498
{"setFeedback", (PyCFunction)Delay_setFeedback, METH_O, "Sets feedback value between 0 -> 1."},
499
{"reset", (PyCFunction)Delay_reset, METH_NOARGS, "Resets the memory buffer to zeros."},
500
{"setMul", (PyCFunction)Delay_setMul, METH_O, "Sets oscillator mul factor."},
501
{"setAdd", (PyCFunction)Delay_setAdd, METH_O, "Sets oscillator add factor."},
502
{"setSub", (PyCFunction)Delay_setSub, METH_O, "Sets inverse add factor."},
503
{"setDiv", (PyCFunction)Delay_setDiv, METH_O, "Sets inverse mul factor."},
504
{NULL} /* Sentinel */
507
static PyNumberMethods Delay_as_number = {
508
(binaryfunc)Delay_add, /*nb_add*/
509
(binaryfunc)Delay_sub, /*nb_subtract*/
510
(binaryfunc)Delay_multiply, /*nb_multiply*/
511
(binaryfunc)Delay_div, /*nb_divide*/
517
0, /*(unaryfunc)array_abs,*/
531
(binaryfunc)Delay_inplace_add, /*inplace_add*/
532
(binaryfunc)Delay_inplace_sub, /*inplace_subtract*/
533
(binaryfunc)Delay_inplace_multiply, /*inplace_multiply*/
534
(binaryfunc)Delay_inplace_div, /*inplace_divide*/
535
0, /*inplace_remainder*/
537
0, /*inplace_lshift*/
538
0, /*inplace_rshift*/
542
0, /*nb_floor_divide*/
543
0, /*nb_true_divide*/
544
0, /*nb_inplace_floor_divide*/
545
0, /*nb_inplace_true_divide*/
549
PyTypeObject DelayType = {
550
PyObject_HEAD_INIT(NULL)
552
"_pyo.Delay_base", /*tp_name*/
553
sizeof(Delay), /*tp_basicsize*/
555
(destructor)Delay_dealloc, /*tp_dealloc*/
561
&Delay_as_number, /*tp_as_number*/
562
0, /*tp_as_sequence*/
570
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
571
"Delay objects. Delay signal by x samples.", /* tp_doc */
572
(traverseproc)Delay_traverse, /* tp_traverse */
573
(inquiry)Delay_clear, /* tp_clear */
574
0, /* tp_richcompare */
575
0, /* tp_weaklistoffset */
578
Delay_methods, /* tp_methods */
579
Delay_members, /* tp_members */
583
0, /* tp_descr_get */
584
0, /* tp_descr_set */
585
0, /* tp_dictoffset */
586
(initproc)Delay_init, /* tp_init */
588
Delay_new, /* tp_new */
594
Stream *input_stream;
596
Stream *delay_stream;
601
MYFLT *buffer; // samples memory
605
SDelay_process_i(SDelay *self) {
609
MYFLT del = PyFloat_AS_DOUBLE(self->delay);
613
else if (del > self->maxdelay)
614
del = self->maxdelay;
615
long sampdel = (long)(del * self->sr);
617
MYFLT *in = Stream_getData((Stream *)self->input_stream);
620
for (i=0; i<self->bufsize; i++) {
621
self->data[i] = self->buffer[self->in_count] = in[i];
623
if (self->in_count >= self->size)
628
for (i=0; i<self->bufsize; i++) {
629
ind = self->in_count - sampdel;
631
ind += (self->size-1);
632
self->data[i] = self->buffer[ind];
634
self->buffer[self->in_count] = in[i];
636
if (self->in_count >= self->size)
643
SDelay_process_a(SDelay *self) {
648
MYFLT *delobj = Stream_getData((Stream *)self->delay_stream);
649
MYFLT *in = Stream_getData((Stream *)self->input_stream);
651
for (i=0; i<self->bufsize; i++) {
655
else if (del > self->maxdelay)
656
del = self->maxdelay;
657
sampdel = (long)(del * self->sr);
659
self->data[i] = self->buffer[self->in_count] = in[i];
662
ind = self->in_count - sampdel;
664
ind += (self->size-1);
665
self->data[i] = self->buffer[ind];
667
self->buffer[self->in_count++] = in[i];
668
if (self->in_count >= self->size)
673
static void SDelay_postprocessing_ii(SDelay *self) { POST_PROCESSING_II };
674
static void SDelay_postprocessing_ai(SDelay *self) { POST_PROCESSING_AI };
675
static void SDelay_postprocessing_ia(SDelay *self) { POST_PROCESSING_IA };
676
static void SDelay_postprocessing_aa(SDelay *self) { POST_PROCESSING_AA };
677
static void SDelay_postprocessing_ireva(SDelay *self) { POST_PROCESSING_IREVA };
678
static void SDelay_postprocessing_areva(SDelay *self) { POST_PROCESSING_AREVA };
679
static void SDelay_postprocessing_revai(SDelay *self) { POST_PROCESSING_REVAI };
680
static void SDelay_postprocessing_revaa(SDelay *self) { POST_PROCESSING_REVAA };
681
static void SDelay_postprocessing_revareva(SDelay *self) { POST_PROCESSING_REVAREVA };
684
SDelay_setProcMode(SDelay *self)
686
int procmode, muladdmode;
687
procmode = self->modebuffer[2];
688
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
692
self->proc_func_ptr = SDelay_process_i;
695
self->proc_func_ptr = SDelay_process_a;
698
switch (muladdmode) {
700
self->muladd_func_ptr = SDelay_postprocessing_ii;
703
self->muladd_func_ptr = SDelay_postprocessing_ai;
706
self->muladd_func_ptr = SDelay_postprocessing_revai;
709
self->muladd_func_ptr = SDelay_postprocessing_ia;
712
self->muladd_func_ptr = SDelay_postprocessing_aa;
715
self->muladd_func_ptr = SDelay_postprocessing_revaa;
718
self->muladd_func_ptr = SDelay_postprocessing_ireva;
721
self->muladd_func_ptr = SDelay_postprocessing_areva;
724
self->muladd_func_ptr = SDelay_postprocessing_revareva;
730
SDelay_compute_next_data_frame(SDelay *self)
732
(*self->proc_func_ptr)(self);
733
(*self->muladd_func_ptr)(self);
737
SDelay_traverse(SDelay *self, visitproc visit, void *arg)
740
Py_VISIT(self->input);
741
Py_VISIT(self->input_stream);
742
Py_VISIT(self->delay);
743
Py_VISIT(self->delay_stream);
748
SDelay_clear(SDelay *self)
751
Py_CLEAR(self->input);
752
Py_CLEAR(self->input_stream);
753
Py_CLEAR(self->delay);
754
Py_CLEAR(self->delay_stream);
759
SDelay_dealloc(SDelay* self)
764
self->ob_type->tp_free((PyObject*)self);
767
static PyObject * SDelay_deleteStream(SDelay *self) { DELETE_STREAM };
770
SDelay_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
774
self = (SDelay *)type->tp_alloc(type, 0);
776
self->delay = PyFloat_FromDouble(0.25);
779
self->modebuffer[0] = 0;
780
self->modebuffer[1] = 0;
781
self->modebuffer[2] = 0;
784
Stream_setFunctionPtr(self->stream, SDelay_compute_next_data_frame);
785
self->mode_func_ptr = SDelay_setProcMode;
787
return (PyObject *)self;
791
SDelay_init(SDelay *self, PyObject *args, PyObject *kwds)
793
PyObject *inputtmp, *input_streamtmp, *delaytmp=NULL, *multmp=NULL, *addtmp=NULL;
796
static char *kwlist[] = {"input", "delay", "maxdelay", "mul", "add", NULL};
798
if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_OFOO, kwlist, &inputtmp, &delaytmp, &self->maxdelay, &multmp, &addtmp))
804
PyObject_CallMethod((PyObject *)self, "setDelay", "O", delaytmp);
808
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
812
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
815
Py_INCREF(self->stream);
816
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
818
self->size = (long)(self->maxdelay * self->sr + 0.5);
820
self->buffer = (MYFLT *)realloc(self->buffer, (self->size+1) * sizeof(MYFLT));
821
for (i=0; i<(self->size+1); i++) {
822
self->buffer[i] = 0.;
825
(*self->mode_func_ptr)(self);
831
static PyObject * SDelay_getServer(SDelay* self) { GET_SERVER };
832
static PyObject * SDelay_getStream(SDelay* self) { GET_STREAM };
833
static PyObject * SDelay_setMul(SDelay *self, PyObject *arg) { SET_MUL };
834
static PyObject * SDelay_setAdd(SDelay *self, PyObject *arg) { SET_ADD };
835
static PyObject * SDelay_setSub(SDelay *self, PyObject *arg) { SET_SUB };
836
static PyObject * SDelay_setDiv(SDelay *self, PyObject *arg) { SET_DIV };
838
static PyObject * SDelay_play(SDelay *self, PyObject *args, PyObject *kwds) { PLAY };
839
static PyObject * SDelay_out(SDelay *self, PyObject *args, PyObject *kwds) { OUT };
840
static PyObject * SDelay_stop(SDelay *self) { STOP };
842
static PyObject * SDelay_multiply(SDelay *self, PyObject *arg) { MULTIPLY };
843
static PyObject * SDelay_inplace_multiply(SDelay *self, PyObject *arg) { INPLACE_MULTIPLY };
844
static PyObject * SDelay_add(SDelay *self, PyObject *arg) { ADD };
845
static PyObject * SDelay_inplace_add(SDelay *self, PyObject *arg) { INPLACE_ADD };
846
static PyObject * SDelay_sub(SDelay *self, PyObject *arg) { SUB };
847
static PyObject * SDelay_inplace_sub(SDelay *self, PyObject *arg) { INPLACE_SUB };
848
static PyObject * SDelay_div(SDelay *self, PyObject *arg) { DIV };
849
static PyObject * SDelay_inplace_div(SDelay *self, PyObject *arg) { INPLACE_DIV };
852
SDelay_setDelay(SDelay *self, PyObject *arg)
854
PyObject *tmp, *streamtmp;
861
int isNumber = PyNumber_Check(arg);
865
Py_DECREF(self->delay);
867
self->delay = PyNumber_Float(tmp);
868
self->modebuffer[2] = 0;
872
streamtmp = PyObject_CallMethod((PyObject *)self->delay, "_getStream", NULL);
873
Py_INCREF(streamtmp);
874
Py_XDECREF(self->delay_stream);
875
self->delay_stream = (Stream *)streamtmp;
876
self->modebuffer[2] = 1;
879
(*self->mode_func_ptr)(self);
886
SDelay_reset(SDelay *self)
889
for (i=0; i<(self->size+1); i++) {
890
self->buffer[i] = 0.;
896
static PyMemberDef SDelay_members[] = {
897
{"server", T_OBJECT_EX, offsetof(SDelay, server), 0, "Pyo server."},
898
{"stream", T_OBJECT_EX, offsetof(SDelay, stream), 0, "Stream object."},
899
{"input", T_OBJECT_EX, offsetof(SDelay, input), 0, "Input sound object."},
900
{"delay", T_OBJECT_EX, offsetof(SDelay, delay), 0, "Delay time in seconds."},
901
{"mul", T_OBJECT_EX, offsetof(SDelay, mul), 0, "Mul factor."},
902
{"add", T_OBJECT_EX, offsetof(SDelay, add), 0, "Add factor."},
903
{NULL} /* Sentinel */
906
static PyMethodDef SDelay_methods[] = {
907
{"getServer", (PyCFunction)SDelay_getServer, METH_NOARGS, "Returns server object."},
908
{"_getStream", (PyCFunction)SDelay_getStream, METH_NOARGS, "Returns stream object."},
909
{"deleteStream", (PyCFunction)SDelay_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
910
{"play", (PyCFunction)SDelay_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
911
{"out", (PyCFunction)SDelay_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
912
{"stop", (PyCFunction)SDelay_stop, METH_NOARGS, "Stops computing."},
913
{"setDelay", (PyCFunction)SDelay_setDelay, METH_O, "Sets delay time in seconds."},
914
{"reset", (PyCFunction)SDelay_reset, METH_NOARGS, "Resets the memory buffer to zeros."},
915
{"setMul", (PyCFunction)SDelay_setMul, METH_O, "Sets oscillator mul factor."},
916
{"setAdd", (PyCFunction)SDelay_setAdd, METH_O, "Sets oscillator add factor."},
917
{"setSub", (PyCFunction)SDelay_setSub, METH_O, "Sets inverse add factor."},
918
{"setDiv", (PyCFunction)SDelay_setDiv, METH_O, "Sets inverse mul factor."},
919
{NULL} /* Sentinel */
922
static PyNumberMethods SDelay_as_number = {
923
(binaryfunc)SDelay_add, /*nb_add*/
924
(binaryfunc)SDelay_sub, /*nb_subtract*/
925
(binaryfunc)SDelay_multiply, /*nb_multiply*/
926
(binaryfunc)SDelay_div, /*nb_divide*/
932
0, /*(unaryfunc)array_abs,*/
946
(binaryfunc)SDelay_inplace_add, /*inplace_add*/
947
(binaryfunc)SDelay_inplace_sub, /*inplace_subtract*/
948
(binaryfunc)SDelay_inplace_multiply, /*inplace_multiply*/
949
(binaryfunc)SDelay_inplace_div, /*inplace_divide*/
950
0, /*inplace_remainder*/
952
0, /*inplace_lshift*/
953
0, /*inplace_rshift*/
957
0, /*nb_floor_divide*/
958
0, /*nb_true_divide*/
959
0, /*nb_inplace_floor_divide*/
960
0, /*nb_inplace_true_divide*/
964
PyTypeObject SDelayType = {
965
PyObject_HEAD_INIT(NULL)
967
"_pyo.SDelay_base", /*tp_name*/
968
sizeof(SDelay), /*tp_basicsize*/
970
(destructor)SDelay_dealloc, /*tp_dealloc*/
976
&SDelay_as_number, /*tp_as_number*/
977
0, /*tp_as_sequence*/
985
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
986
"SDelay objects. Simple Delay with no interpolation and no feedback.", /* tp_doc */
987
(traverseproc)SDelay_traverse, /* tp_traverse */
988
(inquiry)SDelay_clear, /* tp_clear */
989
0, /* tp_richcompare */
990
0, /* tp_weaklistoffset */
993
SDelay_methods, /* tp_methods */
994
SDelay_members, /* tp_members */
998
0, /* tp_descr_get */
999
0, /* tp_descr_set */
1000
0, /* tp_dictoffset */
1001
(initproc)SDelay_init, /* tp_init */
1003
SDelay_new, /* tp_new */
1006
/*********************/
1007
/***** Waveguide *****/
1008
/*********************/
1012
Stream *input_stream;
1014
Stream *freq_stream;
1026
MYFLT lpsamp; // lowpass sample memory
1027
MYFLT coeffs[5]; // lagrange coefficients
1028
MYFLT lagrange[4]; // lagrange samples memories
1029
MYFLT xn1; // dc block input delay
1030
MYFLT yn1; // dc block output delay
1031
MYFLT *buffer; // samples memory
1035
Waveguide_process_ii(Waveguide *self) {
1036
MYFLT val, x, y, sampdel, frac, feed, tmp;
1039
MYFLT fr = PyFloat_AS_DOUBLE(self->freq);
1040
MYFLT dur = PyFloat_AS_DOUBLE(self->dur);
1041
MYFLT *in = Stream_getData((Stream *)self->input_stream);
1043
/* Check boundaries */
1044
if (fr < self->minfreq)
1046
else if (fr >= self->nyquist)
1053
sampdel = self->lastSampDel;
1054
feed = self->lastFeed;
1055
/* lagrange coeffs and feedback coeff */
1056
if (fr != self->lastFreq) {
1057
self->lastFreq = fr;
1058
sampdel = 1.0 / fr * self->sr - 0.5;
1059
self->lastSampDel = sampdel;
1060
isamp = (int)sampdel;
1061
frac = sampdel - isamp;
1062
self->coeffs[0] = (frac-1)*(frac-2)*(frac-3)*(frac-4)/24.0;
1063
self->coeffs[1] = -frac*(frac-2)*(frac-3)*(frac-4)/6.0;
1064
self->coeffs[2] = frac*(frac-1)*(frac-3)*(frac-4)/4.0;
1065
self->coeffs[3] = -frac*(frac-1)*(frac-2)*(frac-4)/6.0;
1066
self->coeffs[4] = frac*(frac-1)*(frac-2)*(frac-3)/24.0;
1068
self->lastDur = dur;
1069
feed = MYPOW(100, -(1.0/fr)/dur);
1070
self->lastFeed = feed;
1072
else if (dur != self->lastDur) {
1073
self->lastDur = dur;
1074
feed = MYPOW(100, -(1.0/fr)/dur);
1075
self->lastFeed = feed;
1078
/* pick a new value in th delay line */
1079
isamp = (int)sampdel;
1080
for (i=0; i<self->bufsize; i++) {
1081
ind = self->in_count - isamp;
1084
val = self->buffer[ind];
1086
/* simple lowpass filtering */
1088
val = (val + self->lpsamp) * 0.5;
1091
/* lagrange filtering */
1092
x = (val*self->coeffs[0])+(self->lagrange[0]*self->coeffs[1])+(self->lagrange[1]*self->coeffs[2])+
1093
(self->lagrange[2]*self->coeffs[3])+(self->lagrange[3]*self->coeffs[4]);
1094
self->lagrange[3] = self->lagrange[2];
1095
self->lagrange[2] = self->lagrange[1];
1096
self->lagrange[1] = self->lagrange[0];
1097
self->lagrange[0] = val;
1100
y = x - self->xn1 + 0.995 * self->yn1;
1106
/* write current value in the delay line */
1107
self->buffer[self->in_count] = in[i] + (x * feed);
1108
if (self->in_count == 0)
1109
self->buffer[self->size] = self->buffer[0];
1111
if (self->in_count == self->size)
1117
Waveguide_process_ai(Waveguide *self) {
1118
MYFLT val, x, y, sampdel, frac, feed, freq, tmp;
1121
MYFLT *fr =Stream_getData((Stream *)self->freq_stream);
1122
MYFLT dur = PyFloat_AS_DOUBLE(self->dur);
1123
MYFLT *in = Stream_getData((Stream *)self->input_stream);
1125
/* Check dur boundary */
1129
for (i=0; i<self->bufsize; i++) {
1131
/* Check frequency boundary */
1132
if (freq < self->minfreq)
1133
freq = self->minfreq;
1134
else if (freq >= self->nyquist)
1135
freq = self->nyquist;
1137
sampdel = self->lastSampDel;
1138
feed = self->lastFeed;
1139
/* lagrange coeffs and feedback coeff */
1140
if (freq != self->lastFreq) {
1141
self->lastFreq = freq;
1142
sampdel = 1.0 / freq * self->sr - 0.5;
1143
self->lastSampDel = sampdel;
1144
isamp = (int)sampdel;
1145
frac = sampdel - isamp;
1146
self->coeffs[0] = (frac-1)*(frac-2)*(frac-3)*(frac-4)/24.0;
1147
self->coeffs[1] = -frac*(frac-2)*(frac-3)*(frac-4)/6.0;
1148
self->coeffs[2] = frac*(frac-1)*(frac-3)*(frac-4)/4.0;
1149
self->coeffs[3] = -frac*(frac-1)*(frac-2)*(frac-4)/6.0;
1150
self->coeffs[4] = frac*(frac-1)*(frac-2)*(frac-3)/24.0;
1152
self->lastDur = dur;
1153
feed = MYPOW(100, -(1.0/freq)/dur);
1154
self->lastFeed = feed;
1156
else if (dur != self->lastDur) {
1157
self->lastDur = dur;
1158
feed = MYPOW(100, -(1.0/freq)/dur);
1159
self->lastFeed = feed;
1162
/* pick a new value in th delay line */
1163
isamp = (int)sampdel;
1165
ind = self->in_count - isamp;
1168
val = self->buffer[ind];
1170
/* simple lowpass filtering */
1172
val = (val + self->lpsamp) * 0.5;
1175
/* lagrange filtering */
1176
x = (val*self->coeffs[0])+(self->lagrange[0]*self->coeffs[1])+(self->lagrange[1]*self->coeffs[2])+
1177
(self->lagrange[2]*self->coeffs[3])+(self->lagrange[3]*self->coeffs[4]);
1178
self->lagrange[3] = self->lagrange[2];
1179
self->lagrange[2] = self->lagrange[1];
1180
self->lagrange[1] = self->lagrange[0];
1181
self->lagrange[0] = val;
1184
y = x - self->xn1 + 0.995 * self->yn1;
1190
/* write current value in the delay line */
1191
self->buffer[self->in_count] = in[i] + (x * feed);
1192
if (self->in_count == 0)
1193
self->buffer[self->size] = self->buffer[0];
1195
if (self->in_count == self->size)
1202
Waveguide_process_ia(Waveguide *self) {
1203
MYFLT val, x, y, sampdel, frac, feed, dur, tmp;
1206
MYFLT fr = PyFloat_AS_DOUBLE(self->freq);
1207
MYFLT *du = Stream_getData((Stream *)self->dur_stream);
1208
MYFLT *in = Stream_getData((Stream *)self->input_stream);
1210
/* Check boundaries */
1211
if (fr < self->minfreq)
1213
else if (fr >= self->nyquist)
1216
sampdel = self->lastSampDel;
1217
/* lagrange coeffs and feedback coeff */
1218
if (fr != self->lastFreq) {
1219
self->lastFreq = fr;
1220
sampdel = 1.0 / fr * self->sr - 0.5;
1221
self->lastSampDel = sampdel;
1222
isamp = (int)sampdel;
1223
frac = sampdel - isamp;
1224
self->coeffs[0] = (frac-1)*(frac-2)*(frac-3)*(frac-4)/24.0;
1225
self->coeffs[1] = -frac*(frac-2)*(frac-3)*(frac-4)/6.0;
1226
self->coeffs[2] = frac*(frac-1)*(frac-3)*(frac-4)/4.0;
1227
self->coeffs[3] = -frac*(frac-1)*(frac-2)*(frac-4)/6.0;
1228
self->coeffs[4] = frac*(frac-1)*(frac-2)*(frac-3)/24.0;
1231
/* pick a new value in th delay line */
1232
isamp = (int)sampdel;
1233
for (i=0; i<self->bufsize; i++) {
1234
feed = self->lastFeed;
1238
if (dur != self->lastDur) {
1239
self->lastDur = dur;
1240
feed = MYPOW(100, -(1.0/fr)/dur);
1241
self->lastFeed = feed;
1243
ind = self->in_count - isamp;
1246
val = self->buffer[ind];
1248
/* simple lowpass filtering */
1250
val = (val + self->lpsamp) * 0.5;
1253
/* lagrange filtering */
1254
x = (val*self->coeffs[0])+(self->lagrange[0]*self->coeffs[1])+(self->lagrange[1]*self->coeffs[2])+
1255
(self->lagrange[2]*self->coeffs[3])+(self->lagrange[3]*self->coeffs[4]);
1256
self->lagrange[3] = self->lagrange[2];
1257
self->lagrange[2] = self->lagrange[1];
1258
self->lagrange[1] = self->lagrange[0];
1259
self->lagrange[0] = val;
1262
y = x - self->xn1 + 0.995 * self->yn1;
1268
/* write current value in the delay line */
1269
self->buffer[self->in_count] = in[i] + (x * feed);
1270
if (self->in_count == 0)
1271
self->buffer[self->size] = self->buffer[0];
1273
if (self->in_count == self->size)
1280
Waveguide_process_aa(Waveguide *self) {
1281
MYFLT val, x, y, sampdel, frac, feed, freq, dur, tmp;
1284
MYFLT *fr = Stream_getData((Stream *)self->freq_stream);
1285
MYFLT *du = Stream_getData((Stream *)self->dur_stream);
1286
MYFLT *in = Stream_getData((Stream *)self->input_stream);
1288
for (i=0; i<self->bufsize; i++) {
1291
/* Check boundaries */
1292
if (freq < self->minfreq)
1293
freq = self->minfreq;
1294
else if (freq >= self->nyquist)
1295
freq = self->nyquist;
1300
sampdel = self->lastSampDel;
1301
feed = self->lastFeed;
1302
/* lagrange coeffs and feedback coeff */
1303
if (freq != self->lastFreq) {
1304
self->lastFreq = freq;
1305
sampdel = 1.0 / freq * self->sr - 0.5;
1306
self->lastSampDel = sampdel;
1307
isamp = (int)sampdel;
1308
frac = sampdel - isamp;
1309
self->coeffs[0] = (frac-1)*(frac-2)*(frac-3)*(frac-4)/24.0;
1310
self->coeffs[1] = -frac*(frac-2)*(frac-3)*(frac-4)/6.0;
1311
self->coeffs[2] = frac*(frac-1)*(frac-3)*(frac-4)/4.0;
1312
self->coeffs[3] = -frac*(frac-1)*(frac-2)*(frac-4)/6.0;
1313
self->coeffs[4] = frac*(frac-1)*(frac-2)*(frac-3)/24.0;
1315
self->lastDur = dur;
1316
feed = MYPOW(100, -(1.0/freq)/dur);
1317
self->lastFeed = feed;
1319
else if (dur != self->lastDur) {
1320
self->lastDur = dur;
1321
feed = MYPOW(100, -(1.0/freq)/dur);
1322
self->lastFeed = feed;
1325
/* pick a new value in th delay line */
1326
isamp = (int)sampdel;
1328
ind = self->in_count - isamp;
1331
val = self->buffer[ind];
1333
/* simple lowpass filtering */
1335
val = (val + self->lpsamp) * 0.5;
1338
/* lagrange filtering */
1339
x = (val*self->coeffs[0])+(self->lagrange[0]*self->coeffs[1])+(self->lagrange[1]*self->coeffs[2])+
1340
(self->lagrange[2]*self->coeffs[3])+(self->lagrange[3]*self->coeffs[4]);
1341
self->lagrange[3] = self->lagrange[2];
1342
self->lagrange[2] = self->lagrange[1];
1343
self->lagrange[1] = self->lagrange[0];
1344
self->lagrange[0] = val;
1347
y = x - self->xn1 + 0.995 * self->yn1;
1353
/* write current value in the delay line */
1354
self->buffer[self->in_count] = in[i] + (x * feed);
1355
if (self->in_count == 0)
1356
self->buffer[self->size] = self->buffer[0];
1358
if (self->in_count == self->size)
1363
static void Waveguide_postprocessing_ii(Waveguide *self) { POST_PROCESSING_II };
1364
static void Waveguide_postprocessing_ai(Waveguide *self) { POST_PROCESSING_AI };
1365
static void Waveguide_postprocessing_ia(Waveguide *self) { POST_PROCESSING_IA };
1366
static void Waveguide_postprocessing_aa(Waveguide *self) { POST_PROCESSING_AA };
1367
static void Waveguide_postprocessing_ireva(Waveguide *self) { POST_PROCESSING_IREVA };
1368
static void Waveguide_postprocessing_areva(Waveguide *self) { POST_PROCESSING_AREVA };
1369
static void Waveguide_postprocessing_revai(Waveguide *self) { POST_PROCESSING_REVAI };
1370
static void Waveguide_postprocessing_revaa(Waveguide *self) { POST_PROCESSING_REVAA };
1371
static void Waveguide_postprocessing_revareva(Waveguide *self) { POST_PROCESSING_REVAREVA };
1374
Waveguide_setProcMode(Waveguide *self)
1376
int procmode, muladdmode;
1377
procmode = self->modebuffer[2] + self->modebuffer[3] * 10;
1378
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
1382
self->proc_func_ptr = Waveguide_process_ii;
1385
self->proc_func_ptr = Waveguide_process_ai;
1388
self->proc_func_ptr = Waveguide_process_ia;
1391
self->proc_func_ptr = Waveguide_process_aa;
1394
switch (muladdmode) {
1396
self->muladd_func_ptr = Waveguide_postprocessing_ii;
1399
self->muladd_func_ptr = Waveguide_postprocessing_ai;
1402
self->muladd_func_ptr = Waveguide_postprocessing_revai;
1405
self->muladd_func_ptr = Waveguide_postprocessing_ia;
1408
self->muladd_func_ptr = Waveguide_postprocessing_aa;
1411
self->muladd_func_ptr = Waveguide_postprocessing_revaa;
1414
self->muladd_func_ptr = Waveguide_postprocessing_ireva;
1417
self->muladd_func_ptr = Waveguide_postprocessing_areva;
1420
self->muladd_func_ptr = Waveguide_postprocessing_revareva;
1426
Waveguide_compute_next_data_frame(Waveguide *self)
1428
(*self->proc_func_ptr)(self);
1429
(*self->muladd_func_ptr)(self);
1433
Waveguide_traverse(Waveguide *self, visitproc visit, void *arg)
1436
Py_VISIT(self->input);
1437
Py_VISIT(self->input_stream);
1438
Py_VISIT(self->freq);
1439
Py_VISIT(self->freq_stream);
1440
Py_VISIT(self->dur);
1441
Py_VISIT(self->dur_stream);
1446
Waveguide_clear(Waveguide *self)
1449
Py_CLEAR(self->input);
1450
Py_CLEAR(self->input_stream);
1451
Py_CLEAR(self->freq);
1452
Py_CLEAR(self->freq_stream);
1453
Py_CLEAR(self->dur);
1454
Py_CLEAR(self->dur_stream);
1459
Waveguide_dealloc(Waveguide* self)
1463
Waveguide_clear(self);
1464
self->ob_type->tp_free((PyObject*)self);
1467
static PyObject * Waveguide_deleteStream(Waveguide *self) { DELETE_STREAM };
1470
Waveguide_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1474
self = (Waveguide *)type->tp_alloc(type, 0);
1476
self->freq = PyFloat_FromDouble(100);
1477
self->dur = PyFloat_FromDouble(0.99);
1479
self->lastFreq = -1.0;
1480
self->lastSampDel = -1.0;
1481
self->lastDur = -1.0;
1482
self->lastFeed = 0.0;
1485
for(i=0; i<4; i++) {
1486
self->lagrange[i] = 0.0;
1490
self->modebuffer[0] = 0;
1491
self->modebuffer[1] = 0;
1492
self->modebuffer[2] = 0;
1493
self->modebuffer[3] = 0;
1497
self->nyquist = (MYFLT)self->sr * 0.45;
1499
Stream_setFunctionPtr(self->stream, Waveguide_compute_next_data_frame);
1500
self->mode_func_ptr = Waveguide_setProcMode;
1502
return (PyObject *)self;
1506
Waveguide_init(Waveguide *self, PyObject *args, PyObject *kwds)
1508
PyObject *inputtmp, *input_streamtmp, *freqtmp=NULL, *durtmp=NULL, *multmp=NULL, *addtmp=NULL;
1511
static char *kwlist[] = {"input", "freq", "dur", "minfreq", "mul", "add", NULL};
1513
if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_OOFOO, kwlist, &inputtmp, &freqtmp, &durtmp, &self->minfreq, &multmp, &addtmp))
1519
PyObject_CallMethod((PyObject *)self, "setFreq", "O", freqtmp);
1523
PyObject_CallMethod((PyObject *)self, "setDur", "O", durtmp);
1527
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
1531
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
1534
Py_INCREF(self->stream);
1535
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
1537
self->size = (long)(1.0 / self->minfreq * self->sr + 0.5);
1539
self->buffer = (MYFLT *)realloc(self->buffer, (self->size+1) * sizeof(MYFLT));
1540
for (i=0; i<(self->size+1); i++) {
1541
self->buffer[i] = 0.;
1544
(*self->mode_func_ptr)(self);
1550
static PyObject * Waveguide_getServer(Waveguide* self) { GET_SERVER };
1551
static PyObject * Waveguide_getStream(Waveguide* self) { GET_STREAM };
1552
static PyObject * Waveguide_setMul(Waveguide *self, PyObject *arg) { SET_MUL };
1553
static PyObject * Waveguide_setAdd(Waveguide *self, PyObject *arg) { SET_ADD };
1554
static PyObject * Waveguide_setSub(Waveguide *self, PyObject *arg) { SET_SUB };
1555
static PyObject * Waveguide_setDiv(Waveguide *self, PyObject *arg) { SET_DIV };
1557
static PyObject * Waveguide_play(Waveguide *self, PyObject *args, PyObject *kwds) { PLAY };
1558
static PyObject * Waveguide_out(Waveguide *self, PyObject *args, PyObject *kwds) { OUT };
1559
static PyObject * Waveguide_stop(Waveguide *self) { STOP };
1561
static PyObject * Waveguide_multiply(Waveguide *self, PyObject *arg) { MULTIPLY };
1562
static PyObject * Waveguide_inplace_multiply(Waveguide *self, PyObject *arg) { INPLACE_MULTIPLY };
1563
static PyObject * Waveguide_add(Waveguide *self, PyObject *arg) { ADD };
1564
static PyObject * Waveguide_inplace_add(Waveguide *self, PyObject *arg) { INPLACE_ADD };
1565
static PyObject * Waveguide_sub(Waveguide *self, PyObject *arg) { SUB };
1566
static PyObject * Waveguide_inplace_sub(Waveguide *self, PyObject *arg) { INPLACE_SUB };
1567
static PyObject * Waveguide_div(Waveguide *self, PyObject *arg) { DIV };
1568
static PyObject * Waveguide_inplace_div(Waveguide *self, PyObject *arg) { INPLACE_DIV };
1571
Waveguide_setFreq(Waveguide *self, PyObject *arg)
1573
PyObject *tmp, *streamtmp;
1580
int isNumber = PyNumber_Check(arg);
1584
Py_DECREF(self->freq);
1585
if (isNumber == 1) {
1586
self->freq = PyNumber_Float(tmp);
1587
self->modebuffer[2] = 0;
1591
streamtmp = PyObject_CallMethod((PyObject *)self->freq, "_getStream", NULL);
1592
Py_INCREF(streamtmp);
1593
Py_XDECREF(self->freq_stream);
1594
self->freq_stream = (Stream *)streamtmp;
1595
self->modebuffer[2] = 1;
1598
(*self->mode_func_ptr)(self);
1605
Waveguide_setDur(Waveguide *self, PyObject *arg)
1607
PyObject *tmp, *streamtmp;
1614
int isNumber = PyNumber_Check(arg);
1618
Py_DECREF(self->dur);
1619
if (isNumber == 1) {
1620
self->dur = PyNumber_Float(tmp);
1621
self->modebuffer[3] = 0;
1625
streamtmp = PyObject_CallMethod((PyObject *)self->dur, "_getStream", NULL);
1626
Py_INCREF(streamtmp);
1627
Py_XDECREF(self->dur_stream);
1628
self->dur_stream = (Stream *)streamtmp;
1629
self->modebuffer[3] = 1;
1632
(*self->mode_func_ptr)(self);
1638
static PyMemberDef Waveguide_members[] = {
1639
{"server", T_OBJECT_EX, offsetof(Waveguide, server), 0, "Pyo server."},
1640
{"stream", T_OBJECT_EX, offsetof(Waveguide, stream), 0, "Stream object."},
1641
{"input", T_OBJECT_EX, offsetof(Waveguide, input), 0, "Input sound object."},
1642
{"freq", T_OBJECT_EX, offsetof(Waveguide, freq), 0, "Waveguide time in seconds."},
1643
{"dur", T_OBJECT_EX, offsetof(Waveguide, dur), 0, "Feedback value."},
1644
{"mul", T_OBJECT_EX, offsetof(Waveguide, mul), 0, "Mul factor."},
1645
{"add", T_OBJECT_EX, offsetof(Waveguide, add), 0, "Add factor."},
1646
{NULL} /* Sentinel */
1649
static PyMethodDef Waveguide_methods[] = {
1650
{"getServer", (PyCFunction)Waveguide_getServer, METH_NOARGS, "Returns server object."},
1651
{"_getStream", (PyCFunction)Waveguide_getStream, METH_NOARGS, "Returns stream object."},
1652
{"deleteStream", (PyCFunction)Waveguide_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
1653
{"play", (PyCFunction)Waveguide_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
1654
{"out", (PyCFunction)Waveguide_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
1655
{"stop", (PyCFunction)Waveguide_stop, METH_NOARGS, "Stops computing."},
1656
{"setFreq", (PyCFunction)Waveguide_setFreq, METH_O, "Sets freq time in seconds."},
1657
{"setDur", (PyCFunction)Waveguide_setDur, METH_O, "Sets dur value between 0 -> 1."},
1658
{"setMul", (PyCFunction)Waveguide_setMul, METH_O, "Sets oscillator mul factor."},
1659
{"setAdd", (PyCFunction)Waveguide_setAdd, METH_O, "Sets oscillator add factor."},
1660
{"setSub", (PyCFunction)Waveguide_setSub, METH_O, "Sets inverse add factor."},
1661
{"setDiv", (PyCFunction)Waveguide_setDiv, METH_O, "Sets inverse mul factor."},
1662
{NULL} /* Sentinel */
1665
static PyNumberMethods Waveguide_as_number = {
1666
(binaryfunc)Waveguide_add, /*nb_add*/
1667
(binaryfunc)Waveguide_sub, /*nb_subtract*/
1668
(binaryfunc)Waveguide_multiply, /*nb_multiply*/
1669
(binaryfunc)Waveguide_div, /*nb_divide*/
1675
0, /*(unaryfunc)array_abs,*/
1689
(binaryfunc)Waveguide_inplace_add, /*inplace_add*/
1690
(binaryfunc)Waveguide_inplace_sub, /*inplace_subtract*/
1691
(binaryfunc)Waveguide_inplace_multiply, /*inplace_multiply*/
1692
(binaryfunc)Waveguide_inplace_div, /*inplace_divide*/
1693
0, /*inplace_remainder*/
1694
0, /*inplace_power*/
1695
0, /*inplace_lshift*/
1696
0, /*inplace_rshift*/
1700
0, /*nb_floor_divide*/
1701
0, /*nb_true_divide*/
1702
0, /*nb_inplace_floor_divide*/
1703
0, /*nb_inplace_true_divide*/
1707
PyTypeObject WaveguideType = {
1708
PyObject_HEAD_INIT(NULL)
1710
"_pyo.Waveguide_base", /*tp_name*/
1711
sizeof(Waveguide), /*tp_basicsize*/
1713
(destructor)Waveguide_dealloc, /*tp_dealloc*/
1719
&Waveguide_as_number, /*tp_as_number*/
1720
0, /*tp_as_sequence*/
1721
0, /*tp_as_mapping*/
1728
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
1729
"Waveguide objects. Waveguide signal by x samples.", /* tp_doc */
1730
(traverseproc)Waveguide_traverse, /* tp_traverse */
1731
(inquiry)Waveguide_clear, /* tp_clear */
1732
0, /* tp_richcompare */
1733
0, /* tp_weaklistoffset */
1735
0, /* tp_iternext */
1736
Waveguide_methods, /* tp_methods */
1737
Waveguide_members, /* tp_members */
1741
0, /* tp_descr_get */
1742
0, /* tp_descr_set */
1743
0, /* tp_dictoffset */
1744
(initproc)Waveguide_init, /* tp_init */
1746
Waveguide_new, /* tp_new */
1749
/*********************/
1750
/***** AllpassWG *****/
1751
/*********************/
1752
static const MYFLT alp_chorus_factor[3] = {1.0, 0.9981, 0.9957};
1753
static const MYFLT alp_feedback = 0.3;
1758
Stream *input_stream;
1760
Stream *freq_stream;
1762
Stream *feed_stream;
1764
Stream *detune_stream;
1770
int alp_in_count[3];
1772
MYFLT *alpbuffer[3]; // allpass samples memories
1773
MYFLT xn1; // dc block input delay
1774
MYFLT yn1; // dc block output delay
1775
MYFLT *buffer; // samples memory
1779
AllpassWG_process_iii(AllpassWG *self) {
1782
MYFLT val, y, xind, sampdel, frac, freqshift, alpsampdel, alpsampdelin, alpdetune;
1784
MYFLT *in = Stream_getData((Stream *)self->input_stream);
1785
MYFLT fr = PyFloat_AS_DOUBLE(self->freq);
1786
MYFLT feed = PyFloat_AS_DOUBLE(self->feed);
1787
MYFLT detune = PyFloat_AS_DOUBLE(self->detune);
1789
/* Check boundaries */
1790
if (fr < self->minfreq)
1792
else if (fr >= self->nyquist)
1799
freqshift = detune * 0.5 + 1.;
1800
detune = detune * 0.95 + 0.05;
1803
else if (detune > 1.0)
1806
sampdel = 1.0 / (fr * freqshift) * self->sr;
1807
alpdetune = detune * self->alpsize;
1809
for (i=0; i<self->bufsize; i++) {
1810
/* pick a new value in the delay line */
1811
xind = self->in_count - sampdel;
1816
val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
1818
/* all-pass filter */
1819
for (j=0; j<3; j++) {
1820
xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
1822
xind += self->alpsize;
1825
alpsampdel = self->alpbuffer[j][ind] + (self->alpbuffer[j][ind+1] - self->alpbuffer[j][ind]) * frac;
1826
alpsampdelin = val + ((val - alpsampdel) * alp_feedback);
1827
val = alpsampdelin * alp_feedback + alpsampdel;
1828
/* write current allpass value in the allpass delay line */
1829
self->alpbuffer[j][self->alp_in_count[j]] = alpsampdelin;
1830
if (self->alp_in_count[j] == 0)
1831
self->alpbuffer[j][self->alpsize] = alpsampdelin;
1832
self->alp_in_count[j]++;
1833
if (self->alp_in_count[j] == self->alpsize)
1834
self->alp_in_count[j] = 0;
1837
/* DC filtering and output */
1838
y = val - self->xn1 + 0.995 * self->yn1;
1840
self->data[i] = self->yn1 = y;
1842
/* write current value in the delay line */
1843
self->buffer[self->in_count] = in[i] + val * feed;
1844
if (self->in_count == 0)
1845
self->buffer[self->size] = self->buffer[0];
1847
if (self->in_count == self->size)
1853
AllpassWG_process_aii(AllpassWG *self) {
1856
MYFLT val, y, xind, sampdel, frac, fr, freqshift, alpsampdel, alpsampdelin, alpdetune;
1858
MYFLT *in = Stream_getData((Stream *)self->input_stream);
1859
MYFLT *freq = Stream_getData((Stream *)self->freq_stream);
1860
MYFLT feed = PyFloat_AS_DOUBLE(self->feed);
1861
MYFLT detune = PyFloat_AS_DOUBLE(self->detune);
1868
freqshift = detune * 0.5 + 1.;
1869
detune = detune * 0.95 + 0.05;
1872
else if (detune > 1.0)
1875
alpdetune = detune * self->alpsize;
1876
for (i=0; i<self->bufsize; i++) {
1878
if (fr < self->minfreq)
1880
else if (fr >= self->nyquist)
1883
/* pick a new value in the delay line */
1884
sampdel = 1.0 / (fr * freqshift) * self->sr;
1885
xind = self->in_count - sampdel;
1890
val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
1892
/* all-pass filter */
1893
for (j=0; j<3; j++) {
1894
xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
1896
xind += self->alpsize;
1899
alpsampdel = self->alpbuffer[j][ind] + (self->alpbuffer[j][ind+1] - self->alpbuffer[j][ind]) * frac;
1900
alpsampdelin = val + ((val - alpsampdel) * alp_feedback);
1901
val = alpsampdelin * alp_feedback + alpsampdel;
1902
/* write current allpass value in the allpass delay line */
1903
self->alpbuffer[j][self->alp_in_count[j]] = alpsampdelin;
1904
if (self->alp_in_count[j] == 0)
1905
self->alpbuffer[j][self->alpsize] = alpsampdelin;
1906
self->alp_in_count[j]++;
1907
if (self->alp_in_count[j] == self->alpsize)
1908
self->alp_in_count[j] = 0;
1911
/* DC filtering and output */
1912
y = val - self->xn1 + 0.995 * self->yn1;
1914
self->data[i] = self->yn1 = y;
1916
/* write current value in the delay line */
1917
self->buffer[self->in_count] = in[i] + val * feed;
1918
if (self->in_count == 0)
1919
self->buffer[self->size] = self->buffer[0];
1921
if (self->in_count == self->size)
1927
AllpassWG_process_iai(AllpassWG *self) {
1930
MYFLT val, y, xind, sampdel, frac, feed, freqshift, alpsampdel, alpsampdelin, alpdetune;
1932
MYFLT *in = Stream_getData((Stream *)self->input_stream);
1933
MYFLT fr = PyFloat_AS_DOUBLE(self->freq);
1934
MYFLT *fdb = Stream_getData((Stream *)self->feed_stream);
1935
MYFLT detune = PyFloat_AS_DOUBLE(self->detune);
1937
/* Check boundaries */
1938
if (fr < self->minfreq)
1940
else if (fr >= self->nyquist)
1942
freqshift = detune * 0.5 + 1.;
1943
detune = detune * 0.95 + 0.05;
1946
else if (detune > 1.0)
1949
sampdel = 1.0 / (fr * freqshift) * self->sr;
1950
alpdetune = detune * self->alpsize;
1952
for (i=0; i<self->bufsize; i++) {
1953
feed = fdb[i] * 0.4525;
1958
/* pick a new value in the delay line */
1959
xind = self->in_count - sampdel;
1964
val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
1966
/* all-pass filter */
1967
for (j=0; j<3; j++) {
1968
xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
1970
xind += self->alpsize;
1973
alpsampdel = self->alpbuffer[j][ind] + (self->alpbuffer[j][ind+1] - self->alpbuffer[j][ind]) * frac;
1974
alpsampdelin = val + ((val - alpsampdel) * alp_feedback);
1975
val = alpsampdelin * alp_feedback + alpsampdel;
1976
/* write current allpass value in the allpass delay line */
1977
self->alpbuffer[j][self->alp_in_count[j]] = alpsampdelin;
1978
if (self->alp_in_count[j] == 0)
1979
self->alpbuffer[j][self->alpsize] = alpsampdelin;
1980
self->alp_in_count[j]++;
1981
if (self->alp_in_count[j] == self->alpsize)
1982
self->alp_in_count[j] = 0;
1985
/* DC filtering and output */
1986
y = val - self->xn1 + 0.995 * self->yn1;
1988
self->data[i] = self->yn1 = y;
1990
/* write current value in the delay line */
1991
self->buffer[self->in_count] = in[i] + val * feed;
1992
if (self->in_count == 0)
1993
self->buffer[self->size] = self->buffer[0];
1995
if (self->in_count == self->size)
2001
AllpassWG_process_aai(AllpassWG *self) {
2004
MYFLT val, y, xind, sampdel, frac, fr, feed, freqshift, alpsampdel, alpsampdelin, alpdetune;
2006
MYFLT *in = Stream_getData((Stream *)self->input_stream);
2007
MYFLT *freq = Stream_getData((Stream *)self->freq_stream);
2008
MYFLT *fdb = Stream_getData((Stream *)self->feed_stream);
2009
MYFLT detune = PyFloat_AS_DOUBLE(self->detune);
2011
freqshift = detune * 0.5 + 1.;
2012
detune = detune * 0.95 + 0.05;
2015
else if (detune > 1.0)
2018
alpdetune = detune * self->alpsize;
2019
for (i=0; i<self->bufsize; i++) {
2021
if (fr < self->minfreq)
2023
else if (fr >= self->nyquist)
2025
feed = fdb[i] * 0.4525;
2031
/* pick a new value in the delay line */
2032
sampdel = 1.0 / (fr * freqshift) * self->sr;
2033
xind = self->in_count - sampdel;
2038
val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
2040
/* all-pass filter */
2041
for (j=0; j<3; j++) {
2042
xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
2044
xind += self->alpsize;
2047
alpsampdel = self->alpbuffer[j][ind] + (self->alpbuffer[j][ind+1] - self->alpbuffer[j][ind]) * frac;
2048
alpsampdelin = val + ((val - alpsampdel) * alp_feedback);
2049
val = alpsampdelin * alp_feedback + alpsampdel;
2050
/* write current allpass value in the allpass delay line */
2051
self->alpbuffer[j][self->alp_in_count[j]] = alpsampdelin;
2052
if (self->alp_in_count[j] == 0)
2053
self->alpbuffer[j][self->alpsize] = alpsampdelin;
2054
self->alp_in_count[j]++;
2055
if (self->alp_in_count[j] == self->alpsize)
2056
self->alp_in_count[j] = 0;
2059
/* DC filtering and output */
2060
y = val - self->xn1 + 0.995 * self->yn1;
2062
self->data[i] = self->yn1 = y;
2064
/* write current value in the delay line */
2065
self->buffer[self->in_count] = in[i] + val * feed;
2066
if (self->in_count == 0)
2067
self->buffer[self->size] = self->buffer[0];
2069
if (self->in_count == self->size)
2075
AllpassWG_process_iia(AllpassWG *self) {
2078
MYFLT val, y, xind, sampdel, frac, detune, freqshift, alpsampdel, alpsampdelin, alpdetune;
2080
MYFLT *in = Stream_getData((Stream *)self->input_stream);
2081
MYFLT fr = PyFloat_AS_DOUBLE(self->freq);
2082
MYFLT feed = PyFloat_AS_DOUBLE(self->feed);
2083
MYFLT *det = Stream_getData((Stream *)self->detune_stream);
2085
/* Check boundaries */
2086
if (fr < self->minfreq)
2088
else if (fr >= self->nyquist)
2096
for (i=0; i<self->bufsize; i++) {
2098
freqshift = detune * 0.5 + 1.;
2099
detune = detune * 0.95 + 0.05;
2102
else if (detune > 1.0)
2105
/* pick a new value in the delay line */
2106
sampdel = 1.0 / (fr * freqshift) * self->sr;
2107
xind = self->in_count - sampdel;
2112
val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
2114
/* all-pass filter */
2115
alpdetune = detune * self->alpsize;
2116
for (j=0; j<3; j++) {
2117
xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
2119
xind += self->alpsize;
2122
alpsampdel = self->alpbuffer[j][ind] + (self->alpbuffer[j][ind+1] - self->alpbuffer[j][ind]) * frac;
2123
alpsampdelin = val + ((val - alpsampdel) * alp_feedback);
2124
val = alpsampdelin * alp_feedback + alpsampdel;
2125
/* write current allpass value in the allpass delay line */
2126
self->alpbuffer[j][self->alp_in_count[j]] = alpsampdelin;
2127
if (self->alp_in_count[j] == 0)
2128
self->alpbuffer[j][self->alpsize] = alpsampdelin;
2129
self->alp_in_count[j]++;
2130
if (self->alp_in_count[j] == self->alpsize)
2131
self->alp_in_count[j] = 0;
2134
/* DC filtering and output */
2135
y = val - self->xn1 + 0.995 * self->yn1;
2137
self->data[i] = self->yn1 = y;
2139
/* write current value in the delay line */
2140
self->buffer[self->in_count] = in[i] + val * feed;
2141
if (self->in_count == 0)
2142
self->buffer[self->size] = self->buffer[0];
2144
if (self->in_count == self->size)
2150
AllpassWG_process_aia(AllpassWG *self) {
2153
MYFLT val, y, xind, sampdel, frac, fr, detune, freqshift, alpsampdel, alpsampdelin, alpdetune;
2155
MYFLT *in = Stream_getData((Stream *)self->input_stream);
2156
MYFLT *freq = Stream_getData((Stream *)self->freq_stream);
2157
MYFLT feed = PyFloat_AS_DOUBLE(self->feed);
2158
MYFLT *det = Stream_getData((Stream *)self->detune_stream);
2166
for (i=0; i<self->bufsize; i++) {
2168
if (fr < self->minfreq)
2170
else if (fr >= self->nyquist)
2173
freqshift = detune * 0.5 + 1.;
2174
detune = detune * 0.95 + 0.05;
2177
else if (detune > 1.0)
2180
/* pick a new value in the delay line */
2181
sampdel = 1.0 / (fr * freqshift) * self->sr;
2182
xind = self->in_count - sampdel;
2187
val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
2189
/* all-pass filter */
2190
alpdetune = detune * self->alpsize;
2191
for (j=0; j<3; j++) {
2192
xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
2194
xind += self->alpsize;
2197
alpsampdel = self->alpbuffer[j][ind] + (self->alpbuffer[j][ind+1] - self->alpbuffer[j][ind]) * frac;
2198
alpsampdelin = val + ((val - alpsampdel) * alp_feedback);
2199
val = alpsampdelin * alp_feedback + alpsampdel;
2200
/* write current allpass value in the allpass delay line */
2201
self->alpbuffer[j][self->alp_in_count[j]] = alpsampdelin;
2202
if (self->alp_in_count[j] == 0)
2203
self->alpbuffer[j][self->alpsize] = alpsampdelin;
2204
self->alp_in_count[j]++;
2205
if (self->alp_in_count[j] == self->alpsize)
2206
self->alp_in_count[j] = 0;
2209
/* DC filtering and output */
2210
y = val - self->xn1 + 0.995 * self->yn1;
2212
self->data[i] = self->yn1 = y;
2214
/* write current value in the delay line */
2215
self->buffer[self->in_count] = in[i] + val * feed;
2216
if (self->in_count == 0)
2217
self->buffer[self->size] = self->buffer[0];
2219
if (self->in_count == self->size)
2225
AllpassWG_process_iaa(AllpassWG *self) {
2228
MYFLT val, y, xind, sampdel, frac, feed, detune, freqshift, alpsampdel, alpsampdelin, alpdetune;
2230
MYFLT *in = Stream_getData((Stream *)self->input_stream);
2231
MYFLT fr = PyFloat_AS_DOUBLE(self->freq);
2232
MYFLT *fdb = Stream_getData((Stream *)self->feed_stream);
2233
MYFLT *det = Stream_getData((Stream *)self->detune_stream);
2235
/* Check boundaries */
2236
if (fr < self->minfreq)
2238
else if (fr >= self->nyquist)
2241
for (i=0; i<self->bufsize; i++) {
2242
feed = fdb[i] * 0.4525;
2248
freqshift = detune * 0.5 + 1.;
2249
detune = detune * 0.95 + 0.05;
2252
else if (detune > 1.0)
2255
/* pick a new value in the delay line */
2256
sampdel = 1.0 / (fr * freqshift) * self->sr;
2257
xind = self->in_count - sampdel;
2262
val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
2264
/* all-pass filter */
2265
alpdetune = detune * self->alpsize;
2266
for (j=0; j<3; j++) {
2267
xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
2269
xind += self->alpsize;
2272
alpsampdel = self->alpbuffer[j][ind] + (self->alpbuffer[j][ind+1] - self->alpbuffer[j][ind]) * frac;
2273
alpsampdelin = val + ((val - alpsampdel) * alp_feedback);
2274
val = alpsampdelin * alp_feedback + alpsampdel;
2275
/* write current allpass value in the allpass delay line */
2276
self->alpbuffer[j][self->alp_in_count[j]] = alpsampdelin;
2277
if (self->alp_in_count[j] == 0)
2278
self->alpbuffer[j][self->alpsize] = alpsampdelin;
2279
self->alp_in_count[j]++;
2280
if (self->alp_in_count[j] == self->alpsize)
2281
self->alp_in_count[j] = 0;
2284
/* DC filtering and output */
2285
y = val - self->xn1 + 0.995 * self->yn1;
2287
self->data[i] = self->yn1 = y;
2289
/* write current value in the delay line */
2290
self->buffer[self->in_count] = in[i] + val * feed;
2291
if (self->in_count == 0)
2292
self->buffer[self->size] = self->buffer[0];
2294
if (self->in_count == self->size)
2300
AllpassWG_process_aaa(AllpassWG *self) {
2303
MYFLT val, y, xind, sampdel, frac, fr, feed, detune, freqshift, alpsampdel, alpsampdelin, alpdetune;
2305
MYFLT *in = Stream_getData((Stream *)self->input_stream);
2306
MYFLT *freq = Stream_getData((Stream *)self->freq_stream);
2307
MYFLT *fdb = Stream_getData((Stream *)self->feed_stream);
2308
MYFLT *det = Stream_getData((Stream *)self->detune_stream);
2310
for (i=0; i<self->bufsize; i++) {
2312
if (fr < self->minfreq)
2314
else if (fr >= self->nyquist)
2316
feed = fdb[i] * 0.4525;
2322
freqshift = detune * 0.5 + 1.;
2323
detune = detune * 0.95 + 0.05;
2326
else if (detune > 1.0)
2329
/* pick a new value in the delay line */
2330
sampdel = 1.0 / (fr * freqshift) * self->sr;
2331
xind = self->in_count - sampdel;
2336
val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
2338
/* all-pass filter */
2339
alpdetune = detune * self->alpsize;
2340
for (j=0; j<3; j++) {
2341
xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
2343
xind += self->alpsize;
2346
alpsampdel = self->alpbuffer[j][ind] + (self->alpbuffer[j][ind+1] - self->alpbuffer[j][ind]) * frac;
2347
alpsampdelin = val + ((val - alpsampdel) * alp_feedback);
2348
val = alpsampdelin * alp_feedback + alpsampdel;
2349
/* write current allpass value in the allpass delay line */
2350
self->alpbuffer[j][self->alp_in_count[j]] = alpsampdelin;
2351
if (self->alp_in_count[j] == 0)
2352
self->alpbuffer[j][self->alpsize] = alpsampdelin;
2353
self->alp_in_count[j]++;
2354
if (self->alp_in_count[j] == self->alpsize)
2355
self->alp_in_count[j] = 0;
2358
/* DC filtering and output */
2359
y = val - self->xn1 + 0.995 * self->yn1;
2361
self->data[i] = self->yn1 = y;
2363
/* write current value in the delay line */
2364
self->buffer[self->in_count] = in[i] + val * feed;
2365
if (self->in_count == 0)
2366
self->buffer[self->size] = self->buffer[0];
2368
if (self->in_count == self->size)
2373
static void AllpassWG_postprocessing_ii(AllpassWG *self) { POST_PROCESSING_II };
2374
static void AllpassWG_postprocessing_ai(AllpassWG *self) { POST_PROCESSING_AI };
2375
static void AllpassWG_postprocessing_ia(AllpassWG *self) { POST_PROCESSING_IA };
2376
static void AllpassWG_postprocessing_aa(AllpassWG *self) { POST_PROCESSING_AA };
2377
static void AllpassWG_postprocessing_ireva(AllpassWG *self) { POST_PROCESSING_IREVA };
2378
static void AllpassWG_postprocessing_areva(AllpassWG *self) { POST_PROCESSING_AREVA };
2379
static void AllpassWG_postprocessing_revai(AllpassWG *self) { POST_PROCESSING_REVAI };
2380
static void AllpassWG_postprocessing_revaa(AllpassWG *self) { POST_PROCESSING_REVAA };
2381
static void AllpassWG_postprocessing_revareva(AllpassWG *self) { POST_PROCESSING_REVAREVA };
2384
AllpassWG_setProcMode(AllpassWG *self)
2386
int procmode, muladdmode;
2387
procmode = self->modebuffer[2] + self->modebuffer[3] * 10 + self->modebuffer[4] * 100;
2388
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
2392
self->proc_func_ptr = AllpassWG_process_iii;
2395
self->proc_func_ptr = AllpassWG_process_aii;
2398
self->proc_func_ptr = AllpassWG_process_iai;
2401
self->proc_func_ptr = AllpassWG_process_aai;
2404
self->proc_func_ptr = AllpassWG_process_iia;
2407
self->proc_func_ptr = AllpassWG_process_aia;
2410
self->proc_func_ptr = AllpassWG_process_iaa;
2413
self->proc_func_ptr = AllpassWG_process_aaa;
2416
switch (muladdmode) {
2418
self->muladd_func_ptr = AllpassWG_postprocessing_ii;
2421
self->muladd_func_ptr = AllpassWG_postprocessing_ai;
2424
self->muladd_func_ptr = AllpassWG_postprocessing_revai;
2427
self->muladd_func_ptr = AllpassWG_postprocessing_ia;
2430
self->muladd_func_ptr = AllpassWG_postprocessing_aa;
2433
self->muladd_func_ptr = AllpassWG_postprocessing_revaa;
2436
self->muladd_func_ptr = AllpassWG_postprocessing_ireva;
2439
self->muladd_func_ptr = AllpassWG_postprocessing_areva;
2442
self->muladd_func_ptr = AllpassWG_postprocessing_revareva;
2448
AllpassWG_compute_next_data_frame(AllpassWG *self)
2450
(*self->proc_func_ptr)(self);
2451
(*self->muladd_func_ptr)(self);
2455
AllpassWG_traverse(AllpassWG *self, visitproc visit, void *arg)
2458
Py_VISIT(self->input);
2459
Py_VISIT(self->input_stream);
2460
Py_VISIT(self->freq);
2461
Py_VISIT(self->freq_stream);
2462
Py_VISIT(self->feed);
2463
Py_VISIT(self->feed_stream);
2464
Py_VISIT(self->detune);
2465
Py_VISIT(self->detune_stream);
2470
AllpassWG_clear(AllpassWG *self)
2473
Py_CLEAR(self->input);
2474
Py_CLEAR(self->input_stream);
2475
Py_CLEAR(self->freq);
2476
Py_CLEAR(self->freq_stream);
2477
Py_CLEAR(self->feed);
2478
Py_CLEAR(self->feed_stream);
2479
Py_CLEAR(self->detune);
2480
Py_CLEAR(self->detune_stream);
2485
AllpassWG_dealloc(AllpassWG* self)
2490
for(i=0; i<3; i++) {
2491
free(self->alpbuffer[i]);
2493
AllpassWG_clear(self);
2494
self->ob_type->tp_free((PyObject*)self);
2497
static PyObject * AllpassWG_deleteStream(AllpassWG *self) { DELETE_STREAM };
2500
AllpassWG_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2504
self = (AllpassWG *)type->tp_alloc(type, 0);
2506
self->freq = PyFloat_FromDouble(100);
2507
self->feed = PyFloat_FromDouble(0.);
2508
self->detune = PyFloat_FromDouble(0.5);
2510
self->in_count = self->alp_in_count[0] = self->alp_in_count[1] = self->alp_in_count[2] = 0;
2513
self->modebuffer[0] = 0;
2514
self->modebuffer[1] = 0;
2515
self->modebuffer[2] = 0;
2516
self->modebuffer[3] = 0;
2517
self->modebuffer[4] = 0;
2521
self->nyquist = (MYFLT)self->sr * 0.45;
2523
Stream_setFunctionPtr(self->stream, AllpassWG_compute_next_data_frame);
2524
self->mode_func_ptr = AllpassWG_setProcMode;
2526
return (PyObject *)self;
2530
AllpassWG_init(AllpassWG *self, PyObject *args, PyObject *kwds)
2532
PyObject *inputtmp, *input_streamtmp, *freqtmp=NULL, *feedtmp=NULL, *detunetmp=NULL, *multmp=NULL, *addtmp=NULL;
2535
static char *kwlist[] = {"input", "freq", "feed", "detune", "minfreq", "mul", "add", NULL};
2537
if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_OOOFOO, kwlist, &inputtmp, &freqtmp, &feedtmp, &detunetmp, &self->minfreq, &multmp, &addtmp))
2543
PyObject_CallMethod((PyObject *)self, "setFreq", "O", freqtmp);
2547
PyObject_CallMethod((PyObject *)self, "setFeed", "O", feedtmp);
2550
PyObject_CallMethod((PyObject *)self, "setDetune", "O", detunetmp);
2554
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
2558
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
2561
Py_INCREF(self->stream);
2562
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
2564
self->size = (long)(1.0 / self->minfreq * self->sr + 0.5);
2565
self->buffer = (MYFLT *)realloc(self->buffer, (self->size+1) * sizeof(MYFLT));
2566
for (i=0; i<(self->size+1); i++) {
2567
self->buffer[i] = 0.;
2570
self->alpsize = (int)(self->sr * 0.0025);
2571
for (i=0; i<3; i++) {
2572
self->alpbuffer[i] = (MYFLT *)realloc(self->alpbuffer[i], (self->alpsize+1) * sizeof(MYFLT));
2573
for (j=0; j<(self->alpsize+1); j++) {
2574
self->alpbuffer[i][j] = 0.;
2578
(*self->mode_func_ptr)(self);
2584
static PyObject * AllpassWG_getServer(AllpassWG* self) { GET_SERVER };
2585
static PyObject * AllpassWG_getStream(AllpassWG* self) { GET_STREAM };
2586
static PyObject * AllpassWG_setMul(AllpassWG *self, PyObject *arg) { SET_MUL };
2587
static PyObject * AllpassWG_setAdd(AllpassWG *self, PyObject *arg) { SET_ADD };
2588
static PyObject * AllpassWG_setSub(AllpassWG *self, PyObject *arg) { SET_SUB };
2589
static PyObject * AllpassWG_setDiv(AllpassWG *self, PyObject *arg) { SET_DIV };
2591
static PyObject * AllpassWG_play(AllpassWG *self, PyObject *args, PyObject *kwds) { PLAY };
2592
static PyObject * AllpassWG_out(AllpassWG *self, PyObject *args, PyObject *kwds) { OUT };
2593
static PyObject * AllpassWG_stop(AllpassWG *self) { STOP };
2595
static PyObject * AllpassWG_multiply(AllpassWG *self, PyObject *arg) { MULTIPLY };
2596
static PyObject * AllpassWG_inplace_multiply(AllpassWG *self, PyObject *arg) { INPLACE_MULTIPLY };
2597
static PyObject * AllpassWG_add(AllpassWG *self, PyObject *arg) { ADD };
2598
static PyObject * AllpassWG_inplace_add(AllpassWG *self, PyObject *arg) { INPLACE_ADD };
2599
static PyObject * AllpassWG_sub(AllpassWG *self, PyObject *arg) { SUB };
2600
static PyObject * AllpassWG_inplace_sub(AllpassWG *self, PyObject *arg) { INPLACE_SUB };
2601
static PyObject * AllpassWG_div(AllpassWG *self, PyObject *arg) { DIV };
2602
static PyObject * AllpassWG_inplace_div(AllpassWG *self, PyObject *arg) { INPLACE_DIV };
2605
AllpassWG_setFreq(AllpassWG *self, PyObject *arg)
2607
PyObject *tmp, *streamtmp;
2614
int isNumber = PyNumber_Check(arg);
2618
Py_DECREF(self->freq);
2619
if (isNumber == 1) {
2620
self->freq = PyNumber_Float(tmp);
2621
self->modebuffer[2] = 0;
2625
streamtmp = PyObject_CallMethod((PyObject *)self->freq, "_getStream", NULL);
2626
Py_INCREF(streamtmp);
2627
Py_XDECREF(self->freq_stream);
2628
self->freq_stream = (Stream *)streamtmp;
2629
self->modebuffer[2] = 1;
2632
(*self->mode_func_ptr)(self);
2639
AllpassWG_setFeed(AllpassWG *self, PyObject *arg)
2641
PyObject *tmp, *streamtmp;
2648
int isNumber = PyNumber_Check(arg);
2652
Py_DECREF(self->feed);
2653
if (isNumber == 1) {
2654
self->feed = PyNumber_Float(tmp);
2655
self->modebuffer[3] = 0;
2659
streamtmp = PyObject_CallMethod((PyObject *)self->feed, "_getStream", NULL);
2660
Py_INCREF(streamtmp);
2661
Py_XDECREF(self->feed_stream);
2662
self->feed_stream = (Stream *)streamtmp;
2663
self->modebuffer[3] = 1;
2666
(*self->mode_func_ptr)(self);
2673
AllpassWG_setDetune(AllpassWG *self, PyObject *arg)
2675
PyObject *tmp, *streamtmp;
2682
int isNumber = PyNumber_Check(arg);
2686
Py_DECREF(self->detune);
2687
if (isNumber == 1) {
2688
self->detune = PyNumber_Float(tmp);
2689
self->modebuffer[4] = 0;
2693
streamtmp = PyObject_CallMethod((PyObject *)self->detune, "_getStream", NULL);
2694
Py_INCREF(streamtmp);
2695
Py_XDECREF(self->detune_stream);
2696
self->detune_stream = (Stream *)streamtmp;
2697
self->modebuffer[4] = 1;
2700
(*self->mode_func_ptr)(self);
2706
static PyMemberDef AllpassWG_members[] = {
2707
{"server", T_OBJECT_EX, offsetof(AllpassWG, server), 0, "Pyo server."},
2708
{"stream", T_OBJECT_EX, offsetof(AllpassWG, stream), 0, "Stream object."},
2709
{"input", T_OBJECT_EX, offsetof(AllpassWG, input), 0, "Input sound object."},
2710
{"freq", T_OBJECT_EX, offsetof(AllpassWG, freq), 0, "AllpassWG time in seconds."},
2711
{"feed", T_OBJECT_EX, offsetof(AllpassWG, feed), 0, "Feedback value."},
2712
{"detune", T_OBJECT_EX, offsetof(AllpassWG, detune), 0, "Detune value between 0 and 1."},
2713
{"mul", T_OBJECT_EX, offsetof(AllpassWG, mul), 0, "Mul factor."},
2714
{"add", T_OBJECT_EX, offsetof(AllpassWG, add), 0, "Add factor."},
2715
{NULL} /* Sentinel */
2718
static PyMethodDef AllpassWG_methods[] = {
2719
{"getServer", (PyCFunction)AllpassWG_getServer, METH_NOARGS, "Returns server object."},
2720
{"_getStream", (PyCFunction)AllpassWG_getStream, METH_NOARGS, "Returns stream object."},
2721
{"deleteStream", (PyCFunction)AllpassWG_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
2722
{"play", (PyCFunction)AllpassWG_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
2723
{"out", (PyCFunction)AllpassWG_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
2724
{"stop", (PyCFunction)AllpassWG_stop, METH_NOARGS, "Stops computing."},
2725
{"setFreq", (PyCFunction)AllpassWG_setFreq, METH_O, "Sets freq time in seconds."},
2726
{"setFeed", (PyCFunction)AllpassWG_setFeed, METH_O, "Sets feed value between 0 -> 1."},
2727
{"setDetune", (PyCFunction)AllpassWG_setDetune, METH_O, "Sets detune value between 0 -> 1."},
2728
{"setMul", (PyCFunction)AllpassWG_setMul, METH_O, "Sets oscillator mul factor."},
2729
{"setAdd", (PyCFunction)AllpassWG_setAdd, METH_O, "Sets oscillator add factor."},
2730
{"setSub", (PyCFunction)AllpassWG_setSub, METH_O, "Sets inverse add factor."},
2731
{"setDiv", (PyCFunction)AllpassWG_setDiv, METH_O, "Sets inverse mul factor."},
2732
{NULL} /* Sentinel */
2735
static PyNumberMethods AllpassWG_as_number = {
2736
(binaryfunc)AllpassWG_add, /*nb_add*/
2737
(binaryfunc)AllpassWG_sub, /*nb_subtract*/
2738
(binaryfunc)AllpassWG_multiply, /*nb_multiply*/
2739
(binaryfunc)AllpassWG_div, /*nb_divide*/
2745
0, /*(unaryfunc)array_abs,*/
2759
(binaryfunc)AllpassWG_inplace_add, /*inplace_add*/
2760
(binaryfunc)AllpassWG_inplace_sub, /*inplace_subtract*/
2761
(binaryfunc)AllpassWG_inplace_multiply, /*inplace_multiply*/
2762
(binaryfunc)AllpassWG_inplace_div, /*inplace_divide*/
2763
0, /*inplace_remainder*/
2764
0, /*inplace_power*/
2765
0, /*inplace_lshift*/
2766
0, /*inplace_rshift*/
2770
0, /*nb_floor_divide*/
2771
0, /*nb_true_divide*/
2772
0, /*nb_inplace_floor_divide*/
2773
0, /*nb_inplace_true_divide*/
2777
PyTypeObject AllpassWGType = {
2778
PyObject_HEAD_INIT(NULL)
2780
"_pyo.AllpassWG_base", /*tp_name*/
2781
sizeof(AllpassWG), /*tp_basicsize*/
2783
(destructor)AllpassWG_dealloc, /*tp_dealloc*/
2789
&AllpassWG_as_number, /*tp_as_number*/
2790
0, /*tp_as_sequence*/
2791
0, /*tp_as_mapping*/
2798
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
2799
"AllpassWG objects. Waveguide model with builtin allpass circuit to detune resonance frequencies.", /* tp_doc */
2800
(traverseproc)AllpassWG_traverse, /* tp_traverse */
2801
(inquiry)AllpassWG_clear, /* tp_clear */
2802
0, /* tp_richcompare */
2803
0, /* tp_weaklistoffset */
2805
0, /* tp_iternext */
2806
AllpassWG_methods, /* tp_methods */
2807
AllpassWG_members, /* tp_members */
2811
0, /* tp_descr_get */
2812
0, /* tp_descr_set */
2813
0, /* tp_dictoffset */
2814
(initproc)AllpassWG_init, /* tp_init */
2816
AllpassWG_new, /* tp_new */