~ubuntu-branches/debian/sid/python-pyo/sid

« back to all changes in this revision

Viewing changes to src/objects/delaymodule.c

  • Committer: Package Import Robot
  • Author(s): Tiago Bortoletto Vaz
  • Date: 2012-06-08 20:35:45 UTC
  • Revision ID: package-import@ubuntu.com-20120608203545-4z7kcf2lgvpsk18y
Tags: upstream-0.6.1
ImportĀ upstreamĀ versionĀ 0.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*************************************************************************
 
2
 * Copyright 2010 Olivier Belanger                                        *                  
 
3
 *                                                                        * 
 
4
 * This file is part of pyo, a python module to help digital signal       *
 
5
 * processing script creation.                                            *  
 
6
 *                                                                        * 
 
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.                                    * 
 
11
 *                                                                        *
 
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.                           *
 
16
 *                                                                        *
 
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
 *************************************************************************/
 
20
 
 
21
#include <Python.h>
 
22
#include "structmember.h"
 
23
#include <math.h>
 
24
#include "pyomodule.h"
 
25
#include "streammodule.h"
 
26
#include "servermodule.h"
 
27
#include "dummymodule.h"
 
28
 
 
29
typedef struct {
 
30
    pyo_audio_HEAD
 
31
    PyObject *input;
 
32
    Stream *input_stream;
 
33
    PyObject *delay;
 
34
    Stream *delay_stream;
 
35
    PyObject *feedback;
 
36
    Stream *feedback_stream;
 
37
    MYFLT maxdelay;
 
38
    long size;
 
39
    long in_count;
 
40
    int modebuffer[4];
 
41
    MYFLT *buffer; // samples memory
 
42
} Delay;
 
43
 
 
44
static void
 
45
Delay_process_ii(Delay *self) {
 
46
    MYFLT val, xind, frac;
 
47
    int i;
 
48
    long ind;
 
49
 
 
50
    MYFLT del = PyFloat_AS_DOUBLE(self->delay);
 
51
    MYFLT feed = PyFloat_AS_DOUBLE(self->feedback);
 
52
    
 
53
    if (del < 0.)
 
54
        del = 0.;
 
55
    else if (del > self->maxdelay)
 
56
        del = self->maxdelay;
 
57
    MYFLT sampdel = del * self->sr;
 
58
 
 
59
    if (feed < 0)
 
60
        feed = 0;
 
61
    else if (feed > 1)
 
62
        feed = 1;
 
63
    
 
64
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
65
    
 
66
    for (i=0; i<self->bufsize; i++) {
 
67
        xind = self->in_count - sampdel;
 
68
        if (xind < 0)
 
69
            xind += self->size;
 
70
        ind = (long)xind;
 
71
        frac = xind - ind;
 
72
        val = self->buffer[ind] * (1.0 - frac) + self->buffer[ind+1] * frac;
 
73
        self->data[i] = val;
 
74
        
 
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];
 
78
        self->in_count++;
 
79
        if (self->in_count >= self->size)
 
80
            self->in_count = 0;
 
81
    }
 
82
}
 
83
 
 
84
static void
 
85
Delay_process_ai(Delay *self) {
 
86
    MYFLT val, xind, frac, sampdel, del;
 
87
    int i;
 
88
    long ind;
 
89
 
 
90
    MYFLT *delobj = Stream_getData((Stream *)self->delay_stream);    
 
91
    MYFLT feed = PyFloat_AS_DOUBLE(self->feedback);
 
92
 
 
93
    if (feed < 0)
 
94
        feed = 0;
 
95
    else if (feed > 1)
 
96
        feed = 1;
 
97
    
 
98
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
99
    
 
100
    for (i=0; i<self->bufsize; i++) {
 
101
        del = delobj[i];
 
102
        if (del < 0.)
 
103
            del = 0.;
 
104
        else if (del > self->maxdelay)
 
105
            del = self->maxdelay;
 
106
        sampdel = del * self->sr;
 
107
        xind = self->in_count - sampdel;
 
108
        if (xind < 0)
 
109
            xind += self->size;
 
110
        ind = (long)xind;
 
111
        frac = xind - ind;
 
112
        val = self->buffer[ind] * (1.0 - frac) + self->buffer[ind+1] * frac;
 
113
        self->data[i] = val;
 
114
        
 
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];
 
118
        self->in_count++;
 
119
        if (self->in_count >= self->size)
 
120
            self->in_count = 0;
 
121
    }
 
122
}
 
123
 
 
124
static void
 
125
Delay_process_ia(Delay *self) {
 
126
    MYFLT val, xind, frac, feed;
 
127
    int i;
 
128
    long ind;
 
129
    
 
130
    MYFLT del = PyFloat_AS_DOUBLE(self->delay);
 
131
    MYFLT *fdb = Stream_getData((Stream *)self->feedback_stream);    
 
132
    
 
133
    if (del < 0.)
 
134
        del = 0.;
 
135
    else if (del > self->maxdelay)
 
136
        del = self->maxdelay;
 
137
    MYFLT sampdel = del * self->sr;
 
138
       
 
139
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
140
    
 
141
    for (i=0; i<self->bufsize; i++) {
 
142
        xind = self->in_count - sampdel;
 
143
        if (xind < 0)
 
144
            xind += self->size;
 
145
        ind = (long)xind;
 
146
        frac = xind - ind;
 
147
        val = self->buffer[ind] * (1.0 - frac) + self->buffer[ind+1] * frac;
 
148
        self->data[i] = val;
 
149
 
 
150
        feed = fdb[i];
 
151
        if (feed < 0)
 
152
            feed = 0;
 
153
        else if (feed > 1)
 
154
            feed = 1;
 
155
        
 
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];
 
159
        self->in_count++;
 
160
        if (self->in_count == self->size)
 
161
            self->in_count = 0;
 
162
    }
 
163
}
 
164
 
 
165
static void
 
166
Delay_process_aa(Delay *self) {
 
167
    MYFLT val, xind, frac, sampdel, feed, del;
 
168
    int i;
 
169
    long ind;
 
170
    
 
171
    MYFLT *delobj = Stream_getData((Stream *)self->delay_stream);    
 
172
    MYFLT *fdb = Stream_getData((Stream *)self->feedback_stream);    
 
173
  
 
174
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
175
    
 
176
    for (i=0; i<self->bufsize; i++) {
 
177
        del = delobj[i];
 
178
        if (del < 0.)
 
179
            del = 0.;
 
180
        else if (del > self->maxdelay)
 
181
            del = self->maxdelay;
 
182
        sampdel = del * self->sr;
 
183
        xind = self->in_count - sampdel;
 
184
        if (xind < 0)
 
185
            xind += self->size;
 
186
        ind = (long)xind;
 
187
        frac = xind - ind;
 
188
        val = self->buffer[ind] * (1.0 - frac) + self->buffer[ind+1] * frac;
 
189
        self->data[i] = val;
 
190
        
 
191
        feed = fdb[i];
 
192
        if (feed < 0)
 
193
            feed = 0;
 
194
        else if (feed > 1)
 
195
            feed = 1;
 
196
        
 
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];
 
200
        self->in_count++;
 
201
        if (self->in_count == self->size)
 
202
            self->in_count = 0;
 
203
    }
 
204
}
 
205
 
 
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 };
 
215
 
 
216
static void
 
217
Delay_setProcMode(Delay *self)
 
218
{
 
219
    int procmode, muladdmode;
 
220
    procmode = self->modebuffer[2] + self->modebuffer[3] * 10;
 
221
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
222
 
 
223
        switch (procmode) {
 
224
        case 0:    
 
225
            self->proc_func_ptr = Delay_process_ii;
 
226
            break;
 
227
        case 1:    
 
228
            self->proc_func_ptr = Delay_process_ai;
 
229
            break;
 
230
        case 10:    
 
231
            self->proc_func_ptr = Delay_process_ia;
 
232
            break;
 
233
        case 11:    
 
234
            self->proc_func_ptr = Delay_process_aa;
 
235
            break;
 
236
    } 
 
237
        switch (muladdmode) {
 
238
        case 0:        
 
239
            self->muladd_func_ptr = Delay_postprocessing_ii;
 
240
            break;
 
241
        case 1:    
 
242
            self->muladd_func_ptr = Delay_postprocessing_ai;
 
243
            break;
 
244
        case 2:    
 
245
            self->muladd_func_ptr = Delay_postprocessing_revai;
 
246
            break;
 
247
        case 10:        
 
248
            self->muladd_func_ptr = Delay_postprocessing_ia;
 
249
            break;
 
250
        case 11:    
 
251
            self->muladd_func_ptr = Delay_postprocessing_aa;
 
252
            break;
 
253
        case 12:    
 
254
            self->muladd_func_ptr = Delay_postprocessing_revaa;
 
255
            break;
 
256
        case 20:        
 
257
            self->muladd_func_ptr = Delay_postprocessing_ireva;
 
258
            break;
 
259
        case 21:    
 
260
            self->muladd_func_ptr = Delay_postprocessing_areva;
 
261
            break;
 
262
        case 22:    
 
263
            self->muladd_func_ptr = Delay_postprocessing_revareva;
 
264
            break;
 
265
    } 
 
266
}
 
267
 
 
268
static void
 
269
Delay_compute_next_data_frame(Delay *self)
 
270
{
 
271
    (*self->proc_func_ptr)(self); 
 
272
    (*self->muladd_func_ptr)(self);
 
273
}
 
274
 
 
275
static int
 
276
Delay_traverse(Delay *self, visitproc visit, void *arg)
 
277
{
 
278
    pyo_VISIT
 
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);    
 
285
    return 0;
 
286
}
 
287
 
 
288
static int 
 
289
Delay_clear(Delay *self)
 
290
{
 
291
    pyo_CLEAR
 
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);    
 
298
    return 0;
 
299
}
 
300
 
 
301
static void
 
302
Delay_dealloc(Delay* self)
 
303
{
 
304
    free(self->data);
 
305
    free(self->buffer);
 
306
    Delay_clear(self);
 
307
    self->ob_type->tp_free((PyObject*)self);
 
308
}
 
309
 
 
310
static PyObject * Delay_deleteStream(Delay *self) { DELETE_STREAM };
 
311
 
 
312
static PyObject *
 
313
Delay_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
314
{
 
315
    int i;
 
316
    Delay *self;
 
317
    self = (Delay *)type->tp_alloc(type, 0);
 
318
 
 
319
    self->delay = PyFloat_FromDouble(0.25);
 
320
    self->feedback = PyFloat_FromDouble(0);
 
321
    self->maxdelay = 1;
 
322
    self->in_count = 0;
 
323
        self->modebuffer[0] = 0;
 
324
        self->modebuffer[1] = 0;
 
325
        self->modebuffer[2] = 0;
 
326
        self->modebuffer[3] = 0;
 
327
 
 
328
    INIT_OBJECT_COMMON
 
329
    Stream_setFunctionPtr(self->stream, Delay_compute_next_data_frame);
 
330
    self->mode_func_ptr = Delay_setProcMode;
 
331
    
 
332
    return (PyObject *)self;
 
333
}
 
334
 
 
335
static int
 
336
Delay_init(Delay *self, PyObject *args, PyObject *kwds)
 
337
{
 
338
    PyObject *inputtmp, *input_streamtmp, *delaytmp=NULL, *feedbacktmp=NULL, *multmp=NULL, *addtmp=NULL;
 
339
    int i;
 
340
    
 
341
    static char *kwlist[] = {"input", "delay", "feedback", "maxdelay", "mul", "add", NULL};
 
342
 
 
343
    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_OOFOO, kwlist, &inputtmp, &delaytmp, &feedbacktmp, &self->maxdelay, &multmp, &addtmp))
 
344
        return -1; 
 
345
 
 
346
    INIT_INPUT_STREAM
 
347
 
 
348
    if (delaytmp) {
 
349
        PyObject_CallMethod((PyObject *)self, "setDelay", "O", delaytmp);
 
350
    }
 
351
 
 
352
    if (feedbacktmp) {
 
353
        PyObject_CallMethod((PyObject *)self, "setFeedback", "O", feedbacktmp);
 
354
    }
 
355
    
 
356
    if (multmp) {
 
357
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
358
    }
 
359
 
 
360
    if (addtmp) {
 
361
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
362
    }
 
363
            
 
364
    Py_INCREF(self->stream);
 
365
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
366
 
 
367
    self->size = (long)(self->maxdelay * self->sr + 0.5);
 
368
 
 
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.;
 
372
    }    
 
373
 
 
374
    (*self->mode_func_ptr)(self);
 
375
 
 
376
    Py_INCREF(self);
 
377
    return 0;
 
378
}
 
379
 
 
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 }; 
 
386
 
 
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 };
 
390
 
 
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 };
 
399
 
 
400
static PyObject *
 
401
Delay_setDelay(Delay *self, PyObject *arg)
 
402
{
 
403
        PyObject *tmp, *streamtmp;
 
404
        
 
405
        if (arg == NULL) {
 
406
                Py_INCREF(Py_None);
 
407
                return Py_None;
 
408
        }
 
409
    
 
410
        int isNumber = PyNumber_Check(arg);
 
411
 
 
412
        tmp = arg;
 
413
        Py_INCREF(tmp);
 
414
        Py_DECREF(self->delay);
 
415
        if (isNumber == 1) {
 
416
                self->delay = PyNumber_Float(tmp);
 
417
        self->modebuffer[2] = 0;
 
418
        }
 
419
        else {
 
420
                self->delay = tmp;
 
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;
 
426
        }
 
427
    
 
428
    (*self->mode_func_ptr)(self);
 
429
    
 
430
        Py_INCREF(Py_None);
 
431
        return Py_None;
 
432
}       
 
433
 
 
434
static PyObject *
 
435
Delay_setFeedback(Delay *self, PyObject *arg)
 
436
{
 
437
        PyObject *tmp, *streamtmp;
 
438
        
 
439
        if (arg == NULL) {
 
440
                Py_INCREF(Py_None);
 
441
                return Py_None;
 
442
        }
 
443
    
 
444
        int isNumber = PyNumber_Check(arg);
 
445
    
 
446
        tmp = arg;
 
447
        Py_INCREF(tmp);
 
448
        Py_DECREF(self->feedback);
 
449
        if (isNumber == 1) {
 
450
                self->feedback = PyNumber_Float(tmp);
 
451
        self->modebuffer[3] = 0;
 
452
        }
 
453
        else {
 
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;
 
460
        }
 
461
    
 
462
    (*self->mode_func_ptr)(self);
 
463
    
 
464
        Py_INCREF(Py_None);
 
465
        return Py_None;
 
466
}       
 
467
 
 
468
static PyObject *
 
469
Delay_reset(Delay *self)
 
470
{
 
471
    int i;
 
472
    for (i=0; i<(self->size+1); i++) {
 
473
        self->buffer[i] = 0.;
 
474
    }    
 
475
        Py_INCREF(Py_None);
 
476
        return Py_None;
 
477
}
 
478
 
 
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 */
 
488
};
 
489
 
 
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 */
 
505
};
 
506
 
 
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*/
 
512
    0,                /*nb_remainder*/
 
513
    0,                   /*nb_divmod*/
 
514
    0,                   /*nb_power*/
 
515
    0,                  /*nb_neg*/
 
516
    0,                /*nb_pos*/
 
517
    0,                  /*(unaryfunc)array_abs,*/
 
518
    0,                    /*nb_nonzero*/
 
519
    0,                    /*nb_invert*/
 
520
    0,               /*nb_lshift*/
 
521
    0,              /*nb_rshift*/
 
522
    0,              /*nb_and*/
 
523
    0,              /*nb_xor*/
 
524
    0,               /*nb_or*/
 
525
    0,                                          /*nb_coerce*/
 
526
    0,                       /*nb_int*/
 
527
    0,                      /*nb_long*/
 
528
    0,                     /*nb_float*/
 
529
    0,                       /*nb_oct*/
 
530
    0,                       /*nb_hex*/
 
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*/
 
536
    0,           /*inplace_power*/
 
537
    0,       /*inplace_lshift*/
 
538
    0,      /*inplace_rshift*/
 
539
    0,      /*inplace_and*/
 
540
    0,      /*inplace_xor*/
 
541
    0,       /*inplace_or*/
 
542
    0,             /*nb_floor_divide*/
 
543
    0,              /*nb_true_divide*/
 
544
    0,     /*nb_inplace_floor_divide*/
 
545
    0,      /*nb_inplace_true_divide*/
 
546
    0,                     /* nb_index */
 
547
};
 
548
 
 
549
PyTypeObject DelayType = {
 
550
    PyObject_HEAD_INIT(NULL)
 
551
    0,                         /*ob_size*/
 
552
    "_pyo.Delay_base",         /*tp_name*/
 
553
    sizeof(Delay),         /*tp_basicsize*/
 
554
    0,                         /*tp_itemsize*/
 
555
    (destructor)Delay_dealloc, /*tp_dealloc*/
 
556
    0,                         /*tp_print*/
 
557
    0,                         /*tp_getattr*/
 
558
    0,                         /*tp_setattr*/
 
559
    0,                         /*tp_compare*/
 
560
    0,                         /*tp_repr*/
 
561
    &Delay_as_number,             /*tp_as_number*/
 
562
    0,                         /*tp_as_sequence*/
 
563
    0,                         /*tp_as_mapping*/
 
564
    0,                         /*tp_hash */
 
565
    0,                         /*tp_call*/
 
566
    0,                         /*tp_str*/
 
567
    0,                         /*tp_getattro*/
 
568
    0,                         /*tp_setattro*/
 
569
    0,                         /*tp_as_buffer*/
 
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 */
 
576
    0,                         /* tp_iter */
 
577
    0,                         /* tp_iternext */
 
578
    Delay_methods,             /* tp_methods */
 
579
    Delay_members,             /* tp_members */
 
580
    0,                      /* tp_getset */
 
581
    0,                         /* tp_base */
 
582
    0,                         /* tp_dict */
 
583
    0,                         /* tp_descr_get */
 
584
    0,                         /* tp_descr_set */
 
585
    0,                         /* tp_dictoffset */
 
586
    (initproc)Delay_init,      /* tp_init */
 
587
    0,                         /* tp_alloc */
 
588
    Delay_new,                 /* tp_new */
 
589
};
 
590
 
 
591
typedef struct {
 
592
    pyo_audio_HEAD
 
593
    PyObject *input;
 
594
    Stream *input_stream;
 
595
    PyObject *delay;
 
596
    Stream *delay_stream;
 
597
    MYFLT maxdelay;
 
598
    long size;
 
599
    long in_count;
 
600
    int modebuffer[3];
 
601
    MYFLT *buffer; // samples memory
 
602
} SDelay;
 
603
 
 
604
static void
 
605
SDelay_process_i(SDelay *self) {
 
606
    int i; 
 
607
    long ind;
 
608
    
 
609
    MYFLT del = PyFloat_AS_DOUBLE(self->delay);
 
610
    
 
611
    if (del < 0.)
 
612
        del = 0.;
 
613
    else if (del > self->maxdelay)
 
614
        del = self->maxdelay;
 
615
    long sampdel = (long)(del * self->sr);
 
616
 
 
617
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
618
 
 
619
    if (sampdel == 0) {
 
620
        for (i=0; i<self->bufsize; i++) {
 
621
            self->data[i] = self->buffer[self->in_count] = in[i];
 
622
            self->in_count++;
 
623
            if (self->in_count >= self->size)
 
624
                self->in_count = 0;
 
625
        }
 
626
    }
 
627
    else {    
 
628
        for (i=0; i<self->bufsize; i++) {
 
629
            ind = self->in_count - sampdel;
 
630
            if (ind < 0)
 
631
                ind += (self->size-1);
 
632
            self->data[i] = self->buffer[ind];
 
633
        
 
634
            self->buffer[self->in_count] = in[i];
 
635
            self->in_count++;
 
636
            if (self->in_count >= self->size)
 
637
                self->in_count = 0;
 
638
        }
 
639
    }
 
640
}
 
641
 
 
642
static void
 
643
SDelay_process_a(SDelay *self) {
 
644
    MYFLT del;
 
645
    int i; 
 
646
    long ind, sampdel;
 
647
    
 
648
    MYFLT *delobj = Stream_getData((Stream *)self->delay_stream);
 
649
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
650
    
 
651
    for (i=0; i<self->bufsize; i++) {
 
652
        del = delobj[i];
 
653
        if (del < 0.)
 
654
            del = 0.;
 
655
        else if (del > self->maxdelay)
 
656
            del = self->maxdelay;
 
657
        sampdel = (long)(del * self->sr);
 
658
        if (sampdel == 0) {
 
659
            self->data[i] = self->buffer[self->in_count] = in[i];
 
660
        }
 
661
        else {
 
662
            ind = self->in_count - sampdel;
 
663
            if (ind < 0)
 
664
                ind += (self->size-1);
 
665
            self->data[i] = self->buffer[ind];
 
666
        }
 
667
        self->buffer[self->in_count++] = in[i];
 
668
        if (self->in_count >= self->size)
 
669
            self->in_count = 0;
 
670
    }
 
671
}
 
672
 
 
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 };
 
682
 
 
683
static void
 
684
SDelay_setProcMode(SDelay *self)
 
685
{
 
686
    int procmode, muladdmode;
 
687
    procmode = self->modebuffer[2];
 
688
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
689
    
 
690
        switch (procmode) {
 
691
        case 0:    
 
692
            self->proc_func_ptr = SDelay_process_i;
 
693
            break;
 
694
        case 1:    
 
695
            self->proc_func_ptr = SDelay_process_a;
 
696
            break;
 
697
    } 
 
698
        switch (muladdmode) {
 
699
        case 0:        
 
700
            self->muladd_func_ptr = SDelay_postprocessing_ii;
 
701
            break;
 
702
        case 1:    
 
703
            self->muladd_func_ptr = SDelay_postprocessing_ai;
 
704
            break;
 
705
        case 2:    
 
706
            self->muladd_func_ptr = SDelay_postprocessing_revai;
 
707
            break;
 
708
        case 10:        
 
709
            self->muladd_func_ptr = SDelay_postprocessing_ia;
 
710
            break;
 
711
        case 11:    
 
712
            self->muladd_func_ptr = SDelay_postprocessing_aa;
 
713
            break;
 
714
        case 12:    
 
715
            self->muladd_func_ptr = SDelay_postprocessing_revaa;
 
716
            break;
 
717
        case 20:        
 
718
            self->muladd_func_ptr = SDelay_postprocessing_ireva;
 
719
            break;
 
720
        case 21:    
 
721
            self->muladd_func_ptr = SDelay_postprocessing_areva;
 
722
            break;
 
723
        case 22:    
 
724
            self->muladd_func_ptr = SDelay_postprocessing_revareva;
 
725
            break;
 
726
    } 
 
727
}
 
728
 
 
729
static void
 
730
SDelay_compute_next_data_frame(SDelay *self)
 
731
{
 
732
    (*self->proc_func_ptr)(self); 
 
733
    (*self->muladd_func_ptr)(self);
 
734
}
 
735
 
 
736
static int
 
737
SDelay_traverse(SDelay *self, visitproc visit, void *arg)
 
738
{
 
739
    pyo_VISIT
 
740
    Py_VISIT(self->input);
 
741
    Py_VISIT(self->input_stream);    
 
742
    Py_VISIT(self->delay);    
 
743
    Py_VISIT(self->delay_stream);    
 
744
    return 0;
 
745
}
 
746
 
 
747
static int 
 
748
SDelay_clear(SDelay *self)
 
749
{
 
750
    pyo_CLEAR
 
751
    Py_CLEAR(self->input);
 
752
    Py_CLEAR(self->input_stream);    
 
753
    Py_CLEAR(self->delay);    
 
754
    Py_CLEAR(self->delay_stream);    
 
755
    return 0;
 
756
}
 
757
 
 
758
static void
 
759
SDelay_dealloc(SDelay* self)
 
760
{
 
761
    free(self->data);
 
762
    free(self->buffer);
 
763
    SDelay_clear(self);
 
764
    self->ob_type->tp_free((PyObject*)self);
 
765
}
 
766
 
 
767
static PyObject * SDelay_deleteStream(SDelay *self) { DELETE_STREAM };
 
768
 
 
769
static PyObject *
 
770
SDelay_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
771
{
 
772
    int i;
 
773
    SDelay *self;
 
774
    self = (SDelay *)type->tp_alloc(type, 0);
 
775
    
 
776
    self->delay = PyFloat_FromDouble(0.25);
 
777
    self->maxdelay = 1;
 
778
    self->in_count = 0;
 
779
        self->modebuffer[0] = 0;
 
780
        self->modebuffer[1] = 0;
 
781
        self->modebuffer[2] = 0;
 
782
    
 
783
    INIT_OBJECT_COMMON
 
784
    Stream_setFunctionPtr(self->stream, SDelay_compute_next_data_frame);
 
785
    self->mode_func_ptr = SDelay_setProcMode;
 
786
    
 
787
    return (PyObject *)self;
 
788
}
 
789
 
 
790
static int
 
791
SDelay_init(SDelay *self, PyObject *args, PyObject *kwds)
 
792
{
 
793
    PyObject *inputtmp, *input_streamtmp, *delaytmp=NULL, *multmp=NULL, *addtmp=NULL;
 
794
    int i;
 
795
    
 
796
    static char *kwlist[] = {"input", "delay", "maxdelay", "mul", "add", NULL};
 
797
    
 
798
    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_OFOO, kwlist, &inputtmp, &delaytmp, &self->maxdelay, &multmp, &addtmp))
 
799
        return -1; 
 
800
    
 
801
    INIT_INPUT_STREAM
 
802
    
 
803
    if (delaytmp) {
 
804
        PyObject_CallMethod((PyObject *)self, "setDelay", "O", delaytmp);
 
805
    }
 
806
    
 
807
    if (multmp) {
 
808
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
809
    }
 
810
    
 
811
    if (addtmp) {
 
812
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
813
    }
 
814
    
 
815
    Py_INCREF(self->stream);
 
816
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
817
    
 
818
    self->size = (long)(self->maxdelay * self->sr + 0.5);
 
819
    
 
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.;
 
823
    }    
 
824
    
 
825
    (*self->mode_func_ptr)(self);
 
826
    
 
827
    Py_INCREF(self);
 
828
    return 0;
 
829
}
 
830
 
 
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 };       
 
837
 
 
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 };
 
841
 
 
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 };
 
850
 
 
851
static PyObject *
 
852
SDelay_setDelay(SDelay *self, PyObject *arg)
 
853
{
 
854
        PyObject *tmp, *streamtmp;
 
855
        
 
856
        if (arg == NULL) {
 
857
                Py_INCREF(Py_None);
 
858
                return Py_None;
 
859
        }
 
860
    
 
861
        int isNumber = PyNumber_Check(arg);
 
862
    
 
863
        tmp = arg;
 
864
        Py_INCREF(tmp);
 
865
        Py_DECREF(self->delay);
 
866
        if (isNumber == 1) {
 
867
                self->delay = PyNumber_Float(tmp);
 
868
        self->modebuffer[2] = 0;
 
869
        }
 
870
        else {
 
871
                self->delay = tmp;
 
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;
 
877
        }
 
878
    
 
879
    (*self->mode_func_ptr)(self);
 
880
    
 
881
        Py_INCREF(Py_None);
 
882
        return Py_None;
 
883
}       
 
884
 
 
885
static PyObject *
 
886
SDelay_reset(SDelay *self)
 
887
{
 
888
    int i;
 
889
    for (i=0; i<(self->size+1); i++) {
 
890
        self->buffer[i] = 0.;
 
891
    }    
 
892
        Py_INCREF(Py_None);
 
893
        return Py_None;
 
894
}
 
895
 
 
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 */
 
904
};
 
905
 
 
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 */
 
920
};
 
921
 
 
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*/
 
927
    0,                /*nb_remainder*/
 
928
    0,                   /*nb_divmod*/
 
929
    0,                   /*nb_power*/
 
930
    0,                  /*nb_neg*/
 
931
    0,                /*nb_pos*/
 
932
    0,                  /*(unaryfunc)array_abs,*/
 
933
    0,                    /*nb_nonzero*/
 
934
    0,                    /*nb_invert*/
 
935
    0,               /*nb_lshift*/
 
936
    0,              /*nb_rshift*/
 
937
    0,              /*nb_and*/
 
938
    0,              /*nb_xor*/
 
939
    0,               /*nb_or*/
 
940
    0,                                          /*nb_coerce*/
 
941
    0,                       /*nb_int*/
 
942
    0,                      /*nb_long*/
 
943
    0,                     /*nb_float*/
 
944
    0,                       /*nb_oct*/
 
945
    0,                       /*nb_hex*/
 
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*/
 
951
    0,           /*inplace_power*/
 
952
    0,       /*inplace_lshift*/
 
953
    0,      /*inplace_rshift*/
 
954
    0,      /*inplace_and*/
 
955
    0,      /*inplace_xor*/
 
956
    0,       /*inplace_or*/
 
957
    0,             /*nb_floor_divide*/
 
958
    0,              /*nb_true_divide*/
 
959
    0,     /*nb_inplace_floor_divide*/
 
960
    0,      /*nb_inplace_true_divide*/
 
961
    0,                     /* nb_index */
 
962
};
 
963
 
 
964
PyTypeObject SDelayType = {
 
965
    PyObject_HEAD_INIT(NULL)
 
966
    0,                         /*ob_size*/
 
967
    "_pyo.SDelay_base",         /*tp_name*/
 
968
    sizeof(SDelay),         /*tp_basicsize*/
 
969
    0,                         /*tp_itemsize*/
 
970
    (destructor)SDelay_dealloc, /*tp_dealloc*/
 
971
    0,                         /*tp_print*/
 
972
    0,                         /*tp_getattr*/
 
973
    0,                         /*tp_setattr*/
 
974
    0,                         /*tp_compare*/
 
975
    0,                         /*tp_repr*/
 
976
    &SDelay_as_number,             /*tp_as_number*/
 
977
    0,                         /*tp_as_sequence*/
 
978
    0,                         /*tp_as_mapping*/
 
979
    0,                         /*tp_hash */
 
980
    0,                         /*tp_call*/
 
981
    0,                         /*tp_str*/
 
982
    0,                         /*tp_getattro*/
 
983
    0,                         /*tp_setattro*/
 
984
    0,                         /*tp_as_buffer*/
 
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 */
 
991
    0,                         /* tp_iter */
 
992
    0,                         /* tp_iternext */
 
993
    SDelay_methods,             /* tp_methods */
 
994
    SDelay_members,             /* tp_members */
 
995
    0,                      /* tp_getset */
 
996
    0,                         /* tp_base */
 
997
    0,                         /* tp_dict */
 
998
    0,                         /* tp_descr_get */
 
999
    0,                         /* tp_descr_set */
 
1000
    0,                         /* tp_dictoffset */
 
1001
    (initproc)SDelay_init,      /* tp_init */
 
1002
    0,                         /* tp_alloc */
 
1003
    SDelay_new,                 /* tp_new */
 
1004
};
 
1005
 
 
1006
/*********************/
 
1007
/***** Waveguide *****/
 
1008
/*********************/
 
1009
typedef struct {
 
1010
    pyo_audio_HEAD
 
1011
    PyObject *input;
 
1012
    Stream *input_stream;
 
1013
    PyObject *freq;
 
1014
    Stream *freq_stream;
 
1015
    PyObject *dur;
 
1016
    Stream *dur_stream;
 
1017
    MYFLT minfreq;
 
1018
    MYFLT lastFreq;
 
1019
    MYFLT lastSampDel;
 
1020
    MYFLT lastDur;
 
1021
    MYFLT lastFeed;
 
1022
    long size;
 
1023
    int in_count;
 
1024
    MYFLT nyquist;
 
1025
    int modebuffer[4];
 
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
 
1032
} Waveguide;
 
1033
 
 
1034
static void
 
1035
Waveguide_process_ii(Waveguide *self) {
 
1036
    MYFLT val, x, y, sampdel, frac, feed, tmp;
 
1037
    int i, ind, isamp;
 
1038
    
 
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);
 
1042
 
 
1043
    /* Check boundaries */
 
1044
    if (fr < self->minfreq)
 
1045
        fr = self->minfreq;
 
1046
    else if (fr >= self->nyquist)
 
1047
        fr = self->nyquist;
 
1048
    
 
1049
    if (dur <= 0)
 
1050
        dur = 0.1;
 
1051
    
 
1052
    
 
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;
 
1067
        
 
1068
        self->lastDur = dur;
 
1069
        feed = MYPOW(100, -(1.0/fr)/dur);
 
1070
        self->lastFeed = feed;
 
1071
    } 
 
1072
    else if (dur != self->lastDur) {
 
1073
        self->lastDur = dur;
 
1074
        feed = MYPOW(100, -(1.0/fr)/dur);
 
1075
        self->lastFeed = feed;
 
1076
    }
 
1077
    
 
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;
 
1082
        if (ind < 0)
 
1083
            ind += self->size;
 
1084
        val = self->buffer[ind];
 
1085
        
 
1086
        /* simple lowpass filtering */
 
1087
        tmp = val;
 
1088
        val = (val + self->lpsamp) * 0.5;
 
1089
        self->lpsamp = tmp;
 
1090
 
 
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;
 
1098
 
 
1099
        /* DC filtering */
 
1100
        y = x - self->xn1 + 0.995 * self->yn1;
 
1101
        self->xn1 = x;
 
1102
        self->yn1 = y;
 
1103
 
 
1104
        self->data[i] = y;
 
1105
        
 
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];
 
1110
        self->in_count++;
 
1111
        if (self->in_count == self->size)
 
1112
            self->in_count = 0;
 
1113
    }
 
1114
}
 
1115
 
 
1116
static void
 
1117
Waveguide_process_ai(Waveguide *self) {
 
1118
    MYFLT val, x, y, sampdel, frac, feed, freq, tmp;
 
1119
    int i, ind, isamp;
 
1120
    
 
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);
 
1124
    
 
1125
    /* Check dur boundary */
 
1126
    if (dur <= 0)
 
1127
        dur = 0.1;
 
1128
 
 
1129
    for (i=0; i<self->bufsize; i++) {
 
1130
        freq = fr[i];
 
1131
        /* Check frequency boundary */
 
1132
        if (freq < self->minfreq)
 
1133
            freq = self->minfreq;
 
1134
        else if (freq >= self->nyquist)
 
1135
            freq = self->nyquist;
 
1136
 
 
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;
 
1151
            
 
1152
            self->lastDur = dur;
 
1153
            feed = MYPOW(100, -(1.0/freq)/dur);
 
1154
            self->lastFeed = feed;
 
1155
        }
 
1156
        else if (dur != self->lastDur) {
 
1157
            self->lastDur = dur;
 
1158
            feed = MYPOW(100, -(1.0/freq)/dur);
 
1159
            self->lastFeed = feed;
 
1160
        }
 
1161
 
 
1162
        /* pick a new value in th delay line */
 
1163
        isamp = (int)sampdel;        
 
1164
        
 
1165
        ind = self->in_count - isamp;
 
1166
        if (ind < 0)
 
1167
            ind += self->size;
 
1168
        val = self->buffer[ind];
 
1169
        
 
1170
        /* simple lowpass filtering */
 
1171
        tmp = val;
 
1172
        val = (val + self->lpsamp) * 0.5;
 
1173
        self->lpsamp = tmp;
 
1174
        
 
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;
 
1182
 
 
1183
        /* DC filtering */
 
1184
        y = x - self->xn1 + 0.995 * self->yn1;
 
1185
        self->xn1 = x;
 
1186
        self->yn1 = y;
 
1187
        
 
1188
        self->data[i] = y;
 
1189
        
 
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];
 
1194
        self->in_count++;
 
1195
        if (self->in_count == self->size)
 
1196
            self->in_count = 0;
 
1197
    }
 
1198
}
 
1199
 
 
1200
 
 
1201
static void
 
1202
Waveguide_process_ia(Waveguide *self) {
 
1203
    MYFLT val, x, y, sampdel, frac, feed, dur, tmp;
 
1204
    int i, ind, isamp;
 
1205
    
 
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);
 
1209
    
 
1210
    /* Check boundaries */
 
1211
    if (fr < self->minfreq)
 
1212
        fr = self->minfreq;
 
1213
    else if (fr >= self->nyquist)
 
1214
        fr = self->nyquist;
 
1215
 
 
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;
 
1229
    }
 
1230
    
 
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;
 
1235
        dur = du[i];
 
1236
        if (dur <= 0)
 
1237
            dur = 0.1;
 
1238
        if (dur != self->lastDur) {
 
1239
            self->lastDur = dur;
 
1240
            feed = MYPOW(100, -(1.0/fr)/dur);
 
1241
            self->lastFeed = feed;
 
1242
        }
 
1243
        ind = self->in_count - isamp;
 
1244
        if (ind < 0)
 
1245
            ind += self->size;
 
1246
        val = self->buffer[ind];
 
1247
        
 
1248
        /* simple lowpass filtering */
 
1249
        tmp = val;
 
1250
        val = (val + self->lpsamp) * 0.5;
 
1251
        self->lpsamp = tmp;
 
1252
        
 
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;
 
1260
 
 
1261
        /* DC filtering */
 
1262
        y = x - self->xn1 + 0.995 * self->yn1;
 
1263
        self->xn1 = x;
 
1264
        self->yn1 = y;
 
1265
        
 
1266
        self->data[i] = y;
 
1267
        
 
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];
 
1272
        self->in_count++;
 
1273
        if (self->in_count == self->size)
 
1274
            self->in_count = 0;
 
1275
    }
 
1276
}
 
1277
 
 
1278
 
 
1279
static void
 
1280
Waveguide_process_aa(Waveguide *self) {
 
1281
    MYFLT val, x, y, sampdel, frac, feed, freq, dur, tmp;
 
1282
    int i, ind, isamp;
 
1283
    
 
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);
 
1287
    
 
1288
    for (i=0; i<self->bufsize; i++) {
 
1289
        freq = fr[i];
 
1290
        dur = du[i];
 
1291
        /* Check boundaries */
 
1292
        if (freq < self->minfreq)
 
1293
            freq = self->minfreq;
 
1294
        else if (freq >= self->nyquist)
 
1295
            freq = self->nyquist;
 
1296
 
 
1297
        if (dur <= 0)
 
1298
            dur = 0.1;
 
1299
        
 
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;
 
1314
            
 
1315
            self->lastDur = dur;
 
1316
            feed = MYPOW(100, -(1.0/freq)/dur);
 
1317
            self->lastFeed = feed;
 
1318
        }
 
1319
        else if (dur != self->lastDur) {
 
1320
            self->lastDur = dur;
 
1321
            feed = MYPOW(100, -(1.0/freq)/dur);
 
1322
            self->lastFeed = feed;
 
1323
        }
 
1324
        
 
1325
        /* pick a new value in th delay line */
 
1326
        isamp = (int)sampdel;        
 
1327
        
 
1328
        ind = self->in_count - isamp;
 
1329
        if (ind < 0)
 
1330
            ind += self->size;
 
1331
        val = self->buffer[ind];
 
1332
        
 
1333
        /* simple lowpass filtering */
 
1334
        tmp = val;
 
1335
        val = (val + self->lpsamp) * 0.5;
 
1336
        self->lpsamp = tmp;
 
1337
        
 
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;
 
1345
  
 
1346
        /* DC filtering */
 
1347
        y = x - self->xn1 + 0.995 * self->yn1;
 
1348
        self->xn1 = x;
 
1349
        self->yn1 = y;
 
1350
        
 
1351
        self->data[i] = y;
 
1352
        
 
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];
 
1357
        self->in_count++;
 
1358
        if (self->in_count == self->size)
 
1359
            self->in_count = 0;
 
1360
    }
 
1361
}
 
1362
 
 
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 };
 
1372
 
 
1373
static void
 
1374
Waveguide_setProcMode(Waveguide *self)
 
1375
{
 
1376
    int procmode, muladdmode;
 
1377
    procmode = self->modebuffer[2] + self->modebuffer[3] * 10;
 
1378
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
1379
    
 
1380
        switch (procmode) {
 
1381
        case 0:    
 
1382
            self->proc_func_ptr = Waveguide_process_ii;
 
1383
            break;
 
1384
        case 1:    
 
1385
            self->proc_func_ptr = Waveguide_process_ai;
 
1386
            break;
 
1387
        case 10:    
 
1388
            self->proc_func_ptr = Waveguide_process_ia;
 
1389
            break;
 
1390
        case 11:    
 
1391
            self->proc_func_ptr = Waveguide_process_aa;
 
1392
            break;
 
1393
    } 
 
1394
        switch (muladdmode) {
 
1395
        case 0:        
 
1396
            self->muladd_func_ptr = Waveguide_postprocessing_ii;
 
1397
            break;
 
1398
        case 1:    
 
1399
            self->muladd_func_ptr = Waveguide_postprocessing_ai;
 
1400
            break;
 
1401
        case 2:    
 
1402
            self->muladd_func_ptr = Waveguide_postprocessing_revai;
 
1403
            break;
 
1404
        case 10:        
 
1405
            self->muladd_func_ptr = Waveguide_postprocessing_ia;
 
1406
            break;
 
1407
        case 11:    
 
1408
            self->muladd_func_ptr = Waveguide_postprocessing_aa;
 
1409
            break;
 
1410
        case 12:    
 
1411
            self->muladd_func_ptr = Waveguide_postprocessing_revaa;
 
1412
            break;
 
1413
        case 20:        
 
1414
            self->muladd_func_ptr = Waveguide_postprocessing_ireva;
 
1415
            break;
 
1416
        case 21:    
 
1417
            self->muladd_func_ptr = Waveguide_postprocessing_areva;
 
1418
            break;
 
1419
        case 22:    
 
1420
            self->muladd_func_ptr = Waveguide_postprocessing_revareva;
 
1421
            break;
 
1422
    } 
 
1423
}
 
1424
 
 
1425
static void
 
1426
Waveguide_compute_next_data_frame(Waveguide *self)
 
1427
{
 
1428
    (*self->proc_func_ptr)(self); 
 
1429
    (*self->muladd_func_ptr)(self);
 
1430
}
 
1431
 
 
1432
static int
 
1433
Waveguide_traverse(Waveguide *self, visitproc visit, void *arg)
 
1434
{
 
1435
    pyo_VISIT
 
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);    
 
1442
    return 0;
 
1443
}
 
1444
 
 
1445
static int 
 
1446
Waveguide_clear(Waveguide *self)
 
1447
{
 
1448
    pyo_CLEAR
 
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);    
 
1455
    return 0;
 
1456
}
 
1457
 
 
1458
static void
 
1459
Waveguide_dealloc(Waveguide* self)
 
1460
{
 
1461
    free(self->data);
 
1462
    free(self->buffer);
 
1463
    Waveguide_clear(self);
 
1464
    self->ob_type->tp_free((PyObject*)self);
 
1465
}
 
1466
 
 
1467
static PyObject * Waveguide_deleteStream(Waveguide *self) { DELETE_STREAM };
 
1468
 
 
1469
static PyObject *
 
1470
Waveguide_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
1471
{
 
1472
    int i;
 
1473
    Waveguide *self;
 
1474
    self = (Waveguide *)type->tp_alloc(type, 0);
 
1475
    
 
1476
    self->freq = PyFloat_FromDouble(100);
 
1477
    self->dur = PyFloat_FromDouble(0.99);
 
1478
    self->minfreq = 20;
 
1479
    self->lastFreq = -1.0;
 
1480
    self->lastSampDel = -1.0;
 
1481
    self->lastDur = -1.0;
 
1482
    self->lastFeed = 0.0;
 
1483
    self->in_count = 0;
 
1484
    self->lpsamp = 0.0;
 
1485
    for(i=0; i<4; i++) {
 
1486
        self->lagrange[i] = 0.0;
 
1487
    }    
 
1488
    self->xn1 = 0.0;
 
1489
    self->yn1 = 0.0;
 
1490
        self->modebuffer[0] = 0;
 
1491
        self->modebuffer[1] = 0;
 
1492
        self->modebuffer[2] = 0;
 
1493
        self->modebuffer[3] = 0;
 
1494
    
 
1495
    INIT_OBJECT_COMMON
 
1496
    
 
1497
    self->nyquist = (MYFLT)self->sr * 0.45;
 
1498
 
 
1499
    Stream_setFunctionPtr(self->stream, Waveguide_compute_next_data_frame);
 
1500
    self->mode_func_ptr = Waveguide_setProcMode;
 
1501
    
 
1502
    return (PyObject *)self;
 
1503
}
 
1504
 
 
1505
static int
 
1506
Waveguide_init(Waveguide *self, PyObject *args, PyObject *kwds)
 
1507
{
 
1508
    PyObject *inputtmp, *input_streamtmp, *freqtmp=NULL, *durtmp=NULL, *multmp=NULL, *addtmp=NULL;
 
1509
    int i;
 
1510
    
 
1511
    static char *kwlist[] = {"input", "freq", "dur", "minfreq", "mul", "add", NULL};
 
1512
    
 
1513
    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_OOFOO, kwlist, &inputtmp, &freqtmp, &durtmp, &self->minfreq, &multmp, &addtmp))
 
1514
        return -1; 
 
1515
    
 
1516
    INIT_INPUT_STREAM
 
1517
    
 
1518
    if (freqtmp) {
 
1519
        PyObject_CallMethod((PyObject *)self, "setFreq", "O", freqtmp);
 
1520
    }
 
1521
    
 
1522
    if (durtmp) {
 
1523
        PyObject_CallMethod((PyObject *)self, "setDur", "O", durtmp);
 
1524
    }
 
1525
    
 
1526
    if (multmp) {
 
1527
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
1528
    }
 
1529
    
 
1530
    if (addtmp) {
 
1531
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
1532
    }
 
1533
    
 
1534
    Py_INCREF(self->stream);
 
1535
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
1536
    
 
1537
    self->size = (long)(1.0 / self->minfreq * self->sr + 0.5);
 
1538
    
 
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.;
 
1542
    }    
 
1543
    
 
1544
    (*self->mode_func_ptr)(self);
 
1545
        
 
1546
    Py_INCREF(self);
 
1547
    return 0;
 
1548
}
 
1549
 
 
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 }; 
 
1556
 
 
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 };
 
1560
 
 
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 };
 
1569
 
 
1570
static PyObject *
 
1571
Waveguide_setFreq(Waveguide *self, PyObject *arg)
 
1572
{
 
1573
        PyObject *tmp, *streamtmp;
 
1574
        
 
1575
        if (arg == NULL) {
 
1576
                Py_INCREF(Py_None);
 
1577
                return Py_None;
 
1578
        }
 
1579
    
 
1580
        int isNumber = PyNumber_Check(arg);
 
1581
    
 
1582
        tmp = arg;
 
1583
        Py_INCREF(tmp);
 
1584
        Py_DECREF(self->freq);
 
1585
        if (isNumber == 1) {
 
1586
                self->freq = PyNumber_Float(tmp);
 
1587
        self->modebuffer[2] = 0;
 
1588
        }
 
1589
        else {
 
1590
                self->freq = tmp;
 
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;
 
1596
        }
 
1597
    
 
1598
    (*self->mode_func_ptr)(self);
 
1599
    
 
1600
        Py_INCREF(Py_None);
 
1601
        return Py_None;
 
1602
}       
 
1603
 
 
1604
static PyObject *
 
1605
Waveguide_setDur(Waveguide *self, PyObject *arg)
 
1606
{
 
1607
        PyObject *tmp, *streamtmp;
 
1608
        
 
1609
        if (arg == NULL) {
 
1610
                Py_INCREF(Py_None);
 
1611
                return Py_None;
 
1612
        }
 
1613
    
 
1614
        int isNumber = PyNumber_Check(arg);
 
1615
    
 
1616
        tmp = arg;
 
1617
        Py_INCREF(tmp);
 
1618
        Py_DECREF(self->dur);
 
1619
        if (isNumber == 1) {
 
1620
                self->dur = PyNumber_Float(tmp);
 
1621
        self->modebuffer[3] = 0;
 
1622
        }
 
1623
        else {
 
1624
                self->dur = tmp;
 
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;
 
1630
        }
 
1631
    
 
1632
    (*self->mode_func_ptr)(self);
 
1633
    
 
1634
        Py_INCREF(Py_None);
 
1635
        return Py_None;
 
1636
}       
 
1637
 
 
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 */
 
1647
};
 
1648
 
 
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 */
 
1663
};
 
1664
 
 
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*/
 
1670
0,                /*nb_remainder*/
 
1671
0,                   /*nb_divmod*/
 
1672
0,                   /*nb_power*/
 
1673
0,                  /*nb_neg*/
 
1674
0,                /*nb_pos*/
 
1675
0,                  /*(unaryfunc)array_abs,*/
 
1676
0,                    /*nb_nonzero*/
 
1677
0,                    /*nb_invert*/
 
1678
0,               /*nb_lshift*/
 
1679
0,              /*nb_rshift*/
 
1680
0,              /*nb_and*/
 
1681
0,              /*nb_xor*/
 
1682
0,               /*nb_or*/
 
1683
0,                                          /*nb_coerce*/
 
1684
0,                       /*nb_int*/
 
1685
0,                      /*nb_long*/
 
1686
0,                     /*nb_float*/
 
1687
0,                       /*nb_oct*/
 
1688
0,                       /*nb_hex*/
 
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*/
 
1697
0,      /*inplace_and*/
 
1698
0,      /*inplace_xor*/
 
1699
0,       /*inplace_or*/
 
1700
0,             /*nb_floor_divide*/
 
1701
0,              /*nb_true_divide*/
 
1702
0,     /*nb_inplace_floor_divide*/
 
1703
0,      /*nb_inplace_true_divide*/
 
1704
0,                     /* nb_index */
 
1705
};
 
1706
 
 
1707
PyTypeObject WaveguideType = {
 
1708
PyObject_HEAD_INIT(NULL)
 
1709
0,                         /*ob_size*/
 
1710
"_pyo.Waveguide_base",         /*tp_name*/
 
1711
sizeof(Waveguide),         /*tp_basicsize*/
 
1712
0,                         /*tp_itemsize*/
 
1713
(destructor)Waveguide_dealloc, /*tp_dealloc*/
 
1714
0,                         /*tp_print*/
 
1715
0,                         /*tp_getattr*/
 
1716
0,                         /*tp_setattr*/
 
1717
0,                         /*tp_compare*/
 
1718
0,                         /*tp_repr*/
 
1719
&Waveguide_as_number,             /*tp_as_number*/
 
1720
0,                         /*tp_as_sequence*/
 
1721
0,                         /*tp_as_mapping*/
 
1722
0,                         /*tp_hash */
 
1723
0,                         /*tp_call*/
 
1724
0,                         /*tp_str*/
 
1725
0,                         /*tp_getattro*/
 
1726
0,                         /*tp_setattro*/
 
1727
0,                         /*tp_as_buffer*/
 
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 */
 
1734
0,                             /* tp_iter */
 
1735
0,                             /* tp_iternext */
 
1736
Waveguide_methods,             /* tp_methods */
 
1737
Waveguide_members,             /* tp_members */
 
1738
0,                      /* tp_getset */
 
1739
0,                         /* tp_base */
 
1740
0,                         /* tp_dict */
 
1741
0,                         /* tp_descr_get */
 
1742
0,                         /* tp_descr_set */
 
1743
0,                         /* tp_dictoffset */
 
1744
(initproc)Waveguide_init,      /* tp_init */
 
1745
0,                         /* tp_alloc */
 
1746
Waveguide_new,                 /* tp_new */
 
1747
};
 
1748
 
 
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;
 
1754
 
 
1755
typedef struct {
 
1756
    pyo_audio_HEAD
 
1757
    PyObject *input;
 
1758
    Stream *input_stream;
 
1759
    PyObject *freq;
 
1760
    Stream *freq_stream;
 
1761
    PyObject *feed;
 
1762
    Stream *feed_stream;
 
1763
    PyObject *detune;
 
1764
    Stream *detune_stream;
 
1765
    MYFLT minfreq;
 
1766
    MYFLT nyquist;
 
1767
    long size;
 
1768
    int alpsize;
 
1769
    int in_count;
 
1770
    int alp_in_count[3];
 
1771
    int modebuffer[5];
 
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
 
1776
} AllpassWG;
 
1777
 
 
1778
static void
 
1779
AllpassWG_process_iii(AllpassWG *self) {
 
1780
    int i, j;
 
1781
    long ind;
 
1782
    MYFLT val, y, xind, sampdel, frac, freqshift, alpsampdel, alpsampdelin, alpdetune;
 
1783
    
 
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);
 
1788
    
 
1789
    /* Check boundaries */
 
1790
    if (fr < self->minfreq)
 
1791
        fr = self->minfreq;
 
1792
    else if (fr >= self->nyquist)
 
1793
        fr = self->nyquist;
 
1794
    feed *= 0.4525;
 
1795
    if (feed > 0.4525)
 
1796
        feed = 0.4525;
 
1797
    else if (feed < 0)
 
1798
        feed = 0;
 
1799
    freqshift = detune * 0.5 + 1.;
 
1800
    detune = detune * 0.95 + 0.05;
 
1801
    if (detune < 0.05)
 
1802
        detune = 0.05;
 
1803
    else if (detune > 1.0)
 
1804
        detune = 1.0;
 
1805
    
 
1806
    sampdel = 1.0 / (fr * freqshift) * self->sr;
 
1807
    alpdetune = detune * self->alpsize;
 
1808
 
 
1809
    for (i=0; i<self->bufsize; i++) {
 
1810
        /* pick a new value in the delay line */
 
1811
        xind = self->in_count - sampdel;
 
1812
        if (xind < 0)
 
1813
            xind += self->size;
 
1814
        ind = (long)xind;
 
1815
        frac = xind - ind;
 
1816
        val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
 
1817
        
 
1818
        /* all-pass filter */
 
1819
        for (j=0; j<3; j++) {
 
1820
            xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
 
1821
            if (xind < 0)
 
1822
                xind += self->alpsize;
 
1823
            ind = (long)xind;
 
1824
            frac = xind - ind;
 
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;
 
1835
        }
 
1836
        
 
1837
        /* DC filtering and output */
 
1838
        y = val - self->xn1 + 0.995 * self->yn1;
 
1839
        self->xn1 = val;
 
1840
        self->data[i] = self->yn1 = y;
 
1841
        
 
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];
 
1846
        self->in_count++;
 
1847
        if (self->in_count == self->size)
 
1848
            self->in_count = 0;        
 
1849
    }
 
1850
}
 
1851
 
 
1852
static void
 
1853
AllpassWG_process_aii(AllpassWG *self) {
 
1854
    int i, j;
 
1855
    long ind;
 
1856
    MYFLT val, y, xind, sampdel, frac, fr, freqshift, alpsampdel, alpsampdelin, alpdetune;
 
1857
    
 
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);
 
1862
    
 
1863
    feed *= 0.4525;
 
1864
    if (feed > 0.4525)
 
1865
        feed = 0.4525;
 
1866
    else if (feed < 0)
 
1867
        feed = 0;
 
1868
    freqshift = detune * 0.5 + 1.;
 
1869
    detune = detune * 0.95 + 0.05;
 
1870
    if (detune < 0.05)
 
1871
        detune = 0.05;
 
1872
    else if (detune > 1.0)
 
1873
        detune = 1.0;
 
1874
    
 
1875
    alpdetune = detune * self->alpsize;
 
1876
    for (i=0; i<self->bufsize; i++) {
 
1877
        fr = freq[i];
 
1878
        if (fr < self->minfreq)
 
1879
            fr = self->minfreq;
 
1880
        else if (fr >= self->nyquist)
 
1881
            fr = self->nyquist;
 
1882
        
 
1883
        /* pick a new value in the delay line */
 
1884
        sampdel = 1.0 / (fr * freqshift) * self->sr;
 
1885
        xind = self->in_count - sampdel;
 
1886
        if (xind < 0)
 
1887
            xind += self->size;
 
1888
        ind = (long)xind;
 
1889
        frac = xind - ind;
 
1890
        val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
 
1891
        
 
1892
        /* all-pass filter */
 
1893
        for (j=0; j<3; j++) {
 
1894
            xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
 
1895
            if (xind < 0)
 
1896
                xind += self->alpsize;
 
1897
            ind = (long)xind;
 
1898
            frac = xind - ind;
 
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;
 
1909
        }
 
1910
        
 
1911
        /* DC filtering and output */
 
1912
        y = val - self->xn1 + 0.995 * self->yn1;
 
1913
        self->xn1 = val;
 
1914
        self->data[i] = self->yn1 = y;
 
1915
        
 
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];
 
1920
        self->in_count++;
 
1921
        if (self->in_count == self->size)
 
1922
            self->in_count = 0;        
 
1923
    }
 
1924
}
 
1925
 
 
1926
static void
 
1927
AllpassWG_process_iai(AllpassWG *self) {
 
1928
    int i, j;
 
1929
    long ind;
 
1930
    MYFLT val, y, xind, sampdel, frac, feed, freqshift, alpsampdel, alpsampdelin, alpdetune;
 
1931
    
 
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);
 
1936
    
 
1937
    /* Check boundaries */
 
1938
    if (fr < self->minfreq)
 
1939
        fr = self->minfreq;
 
1940
    else if (fr >= self->nyquist)
 
1941
        fr = self->nyquist;
 
1942
    freqshift = detune * 0.5 + 1.;
 
1943
    detune = detune * 0.95 + 0.05;
 
1944
    if (detune < 0.05)
 
1945
        detune = 0.05;
 
1946
    else if (detune > 1.0)
 
1947
        detune = 1.0;
 
1948
    
 
1949
    sampdel = 1.0 / (fr * freqshift) * self->sr;
 
1950
    alpdetune = detune * self->alpsize;
 
1951
    
 
1952
    for (i=0; i<self->bufsize; i++) {
 
1953
        feed = fdb[i] * 0.4525;
 
1954
        if (feed > 0.4525)
 
1955
            feed = 0.4525;
 
1956
        else if (feed < 0)
 
1957
            feed = 0;
 
1958
        /* pick a new value in the delay line */
 
1959
        xind = self->in_count - sampdel;
 
1960
        if (xind < 0)
 
1961
            xind += self->size;
 
1962
        ind = (long)xind;
 
1963
        frac = xind - ind;
 
1964
        val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
 
1965
        
 
1966
        /* all-pass filter */
 
1967
        for (j=0; j<3; j++) {
 
1968
            xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
 
1969
            if (xind < 0)
 
1970
                xind += self->alpsize;
 
1971
            ind = (long)xind;
 
1972
            frac = xind - ind;
 
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;
 
1983
        }
 
1984
        
 
1985
        /* DC filtering and output */
 
1986
        y = val - self->xn1 + 0.995 * self->yn1;
 
1987
        self->xn1 = val;
 
1988
        self->data[i] = self->yn1 = y;
 
1989
        
 
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];
 
1994
        self->in_count++;
 
1995
        if (self->in_count == self->size)
 
1996
            self->in_count = 0;        
 
1997
    }
 
1998
}
 
1999
 
 
2000
static void
 
2001
AllpassWG_process_aai(AllpassWG *self) {
 
2002
    int i, j;
 
2003
    long ind;
 
2004
    MYFLT val, y, xind, sampdel, frac, fr, feed, freqshift, alpsampdel, alpsampdelin, alpdetune;
 
2005
    
 
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);
 
2010
    
 
2011
    freqshift = detune * 0.5 + 1.;
 
2012
    detune = detune * 0.95 + 0.05;
 
2013
    if (detune < 0.05)
 
2014
        detune = 0.05;
 
2015
    else if (detune > 1.0)
 
2016
        detune = 1.0;
 
2017
    
 
2018
    alpdetune = detune * self->alpsize;
 
2019
    for (i=0; i<self->bufsize; i++) {
 
2020
        fr = freq[i];
 
2021
        if (fr < self->minfreq)
 
2022
            fr = self->minfreq;
 
2023
        else if (fr >= self->nyquist)
 
2024
            fr = self->nyquist;
 
2025
        feed = fdb[i] * 0.4525;
 
2026
        if (feed > 0.4525)
 
2027
            feed = 0.4525;
 
2028
        else if (feed < 0)
 
2029
            feed = 0;
 
2030
        
 
2031
        /* pick a new value in the delay line */
 
2032
        sampdel = 1.0 / (fr * freqshift) * self->sr;
 
2033
        xind = self->in_count - sampdel;
 
2034
        if (xind < 0)
 
2035
            xind += self->size;
 
2036
        ind = (long)xind;
 
2037
        frac = xind - ind;
 
2038
        val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
 
2039
        
 
2040
        /* all-pass filter */
 
2041
        for (j=0; j<3; j++) {
 
2042
            xind = self->alp_in_count[j] - (alpdetune * alp_chorus_factor[j]);
 
2043
            if (xind < 0)
 
2044
                xind += self->alpsize;
 
2045
            ind = (long)xind;
 
2046
            frac = xind - ind;
 
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;
 
2057
        }
 
2058
        
 
2059
        /* DC filtering and output */
 
2060
        y = val - self->xn1 + 0.995 * self->yn1;
 
2061
        self->xn1 = val;
 
2062
        self->data[i] = self->yn1 = y;
 
2063
        
 
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];
 
2068
        self->in_count++;
 
2069
        if (self->in_count == self->size)
 
2070
            self->in_count = 0;        
 
2071
    }
 
2072
}
 
2073
 
 
2074
static void
 
2075
AllpassWG_process_iia(AllpassWG *self) {
 
2076
    int i, j;
 
2077
    long ind;
 
2078
    MYFLT val, y, xind, sampdel, frac, detune, freqshift, alpsampdel, alpsampdelin, alpdetune;
 
2079
    
 
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);
 
2084
    
 
2085
    /* Check boundaries */
 
2086
    if (fr < self->minfreq)
 
2087
        fr = self->minfreq;
 
2088
    else if (fr >= self->nyquist)
 
2089
        fr = self->nyquist;
 
2090
    feed *= 0.4525;
 
2091
    if (feed > 0.4525)
 
2092
        feed = 0.4525;
 
2093
    else if (feed < 0)
 
2094
        feed = 0;
 
2095
    
 
2096
    for (i=0; i<self->bufsize; i++) {
 
2097
        detune = det[i];
 
2098
        freqshift = detune * 0.5 + 1.;
 
2099
        detune = detune * 0.95 + 0.05;
 
2100
        if (detune < 0.05)
 
2101
            detune = 0.05;
 
2102
        else if (detune > 1.0)
 
2103
            detune = 1.0;
 
2104
        
 
2105
        /* pick a new value in the delay line */
 
2106
        sampdel = 1.0 / (fr * freqshift) * self->sr;
 
2107
        xind = self->in_count - sampdel;
 
2108
        if (xind < 0)
 
2109
            xind += self->size;
 
2110
        ind = (long)xind;
 
2111
        frac = xind - ind;
 
2112
        val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
 
2113
        
 
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]);
 
2118
            if (xind < 0)
 
2119
                xind += self->alpsize;
 
2120
            ind = (long)xind;
 
2121
            frac = xind - ind;
 
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;
 
2132
        }
 
2133
 
 
2134
        /* DC filtering and output */
 
2135
        y = val - self->xn1 + 0.995 * self->yn1;
 
2136
        self->xn1 = val;
 
2137
        self->data[i] = self->yn1 = y;
 
2138
 
 
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];
 
2143
        self->in_count++;
 
2144
        if (self->in_count == self->size)
 
2145
            self->in_count = 0;        
 
2146
    }
 
2147
}
 
2148
 
 
2149
static void
 
2150
AllpassWG_process_aia(AllpassWG *self) {
 
2151
    int i, j;
 
2152
    long ind;
 
2153
    MYFLT val, y, xind, sampdel, frac, fr, detune, freqshift, alpsampdel, alpsampdelin, alpdetune;
 
2154
    
 
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);
 
2159
    
 
2160
    feed *= 0.4525;
 
2161
    if (feed > 0.4525)
 
2162
        feed = 0.4525;
 
2163
    else if (feed < 0)
 
2164
        feed = 0;
 
2165
    
 
2166
    for (i=0; i<self->bufsize; i++) {
 
2167
        fr = freq[i];
 
2168
        if (fr < self->minfreq)
 
2169
            fr = self->minfreq;
 
2170
        else if (fr >= self->nyquist)
 
2171
            fr = self->nyquist;
 
2172
        detune = det[i];
 
2173
        freqshift = detune * 0.5 + 1.;
 
2174
        detune = detune * 0.95 + 0.05;
 
2175
        if (detune < 0.05)
 
2176
            detune = 0.05;
 
2177
        else if (detune > 1.0)
 
2178
            detune = 1.0;
 
2179
        
 
2180
        /* pick a new value in the delay line */
 
2181
        sampdel = 1.0 / (fr * freqshift) * self->sr;
 
2182
        xind = self->in_count - sampdel;
 
2183
        if (xind < 0)
 
2184
            xind += self->size;
 
2185
        ind = (long)xind;
 
2186
        frac = xind - ind;
 
2187
        val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
 
2188
        
 
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]);
 
2193
            if (xind < 0)
 
2194
                xind += self->alpsize;
 
2195
            ind = (long)xind;
 
2196
            frac = xind - ind;
 
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;
 
2207
        }
 
2208
        
 
2209
        /* DC filtering and output */
 
2210
        y = val - self->xn1 + 0.995 * self->yn1;
 
2211
        self->xn1 = val;
 
2212
        self->data[i] = self->yn1 = y;
 
2213
        
 
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];
 
2218
        self->in_count++;
 
2219
        if (self->in_count == self->size)
 
2220
            self->in_count = 0;        
 
2221
    }
 
2222
}
 
2223
 
 
2224
static void
 
2225
AllpassWG_process_iaa(AllpassWG *self) {
 
2226
    int i, j;
 
2227
    long ind;
 
2228
    MYFLT val, y, xind, sampdel, frac, feed, detune, freqshift, alpsampdel, alpsampdelin, alpdetune;
 
2229
    
 
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);
 
2234
    
 
2235
    /* Check boundaries */
 
2236
    if (fr < self->minfreq)
 
2237
        fr = self->minfreq;
 
2238
    else if (fr >= self->nyquist)
 
2239
        fr = self->nyquist;
 
2240
    
 
2241
    for (i=0; i<self->bufsize; i++) {
 
2242
        feed = fdb[i] * 0.4525;
 
2243
        if (feed > 0.4525)
 
2244
            feed = 0.4525;
 
2245
        else if (feed < 0)
 
2246
            feed = 0;
 
2247
        detune = det[i];
 
2248
        freqshift = detune * 0.5 + 1.;
 
2249
        detune = detune * 0.95 + 0.05;
 
2250
        if (detune < 0.05)
 
2251
            detune = 0.05;
 
2252
        else if (detune > 1.0)
 
2253
            detune = 1.0;
 
2254
        
 
2255
        /* pick a new value in the delay line */
 
2256
        sampdel = 1.0 / (fr * freqshift) * self->sr;
 
2257
        xind = self->in_count - sampdel;
 
2258
        if (xind < 0)
 
2259
            xind += self->size;
 
2260
        ind = (long)xind;
 
2261
        frac = xind - ind;
 
2262
        val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
 
2263
        
 
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]);
 
2268
            if (xind < 0)
 
2269
                xind += self->alpsize;
 
2270
            ind = (long)xind;
 
2271
            frac = xind - ind;
 
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;
 
2282
        }
 
2283
        
 
2284
        /* DC filtering and output */
 
2285
        y = val - self->xn1 + 0.995 * self->yn1;
 
2286
        self->xn1 = val;
 
2287
        self->data[i] = self->yn1 = y;
 
2288
        
 
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];
 
2293
        self->in_count++;
 
2294
        if (self->in_count == self->size)
 
2295
            self->in_count = 0;        
 
2296
    }
 
2297
}
 
2298
 
 
2299
static void
 
2300
AllpassWG_process_aaa(AllpassWG *self) {
 
2301
    int i, j;
 
2302
    long ind;
 
2303
    MYFLT val, y, xind, sampdel, frac, fr, feed, detune, freqshift, alpsampdel, alpsampdelin, alpdetune;
 
2304
    
 
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);
 
2309
 
 
2310
    for (i=0; i<self->bufsize; i++) {
 
2311
        fr = freq[i];
 
2312
        if (fr < self->minfreq)
 
2313
            fr = self->minfreq;
 
2314
        else if (fr >= self->nyquist)
 
2315
            fr = self->nyquist;
 
2316
        feed = fdb[i] * 0.4525;
 
2317
        if (feed > 0.4525)
 
2318
            feed = 0.4525;
 
2319
        else if (feed < 0)
 
2320
            feed = 0;
 
2321
        detune = det[i];
 
2322
        freqshift = detune * 0.5 + 1.;
 
2323
        detune = detune * 0.95 + 0.05;
 
2324
        if (detune < 0.05)
 
2325
            detune = 0.05;
 
2326
        else if (detune > 1.0)
 
2327
            detune = 1.0;
 
2328
        
 
2329
        /* pick a new value in the delay line */
 
2330
        sampdel = 1.0 / (fr * freqshift) * self->sr;
 
2331
        xind = self->in_count - sampdel;
 
2332
        if (xind < 0)
 
2333
            xind += self->size;
 
2334
        ind = (long)xind;
 
2335
        frac = xind - ind;
 
2336
        val = self->buffer[ind] + (self->buffer[ind+1] - self->buffer[ind]) * frac;
 
2337
        
 
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]);
 
2342
            if (xind < 0)
 
2343
                xind += self->alpsize;
 
2344
            ind = (long)xind;
 
2345
            frac = xind - ind;
 
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;
 
2356
        }
 
2357
        
 
2358
        /* DC filtering and output */
 
2359
        y = val - self->xn1 + 0.995 * self->yn1;
 
2360
        self->xn1 = val;
 
2361
        self->data[i] = self->yn1 = y;
 
2362
        
 
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];
 
2367
        self->in_count++;
 
2368
        if (self->in_count == self->size)
 
2369
            self->in_count = 0;        
 
2370
    }
 
2371
}
 
2372
 
 
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 };
 
2382
 
 
2383
static void
 
2384
AllpassWG_setProcMode(AllpassWG *self)
 
2385
{
 
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;
 
2389
    
 
2390
        switch (procmode) {
 
2391
        case 0:    
 
2392
            self->proc_func_ptr = AllpassWG_process_iii;
 
2393
            break;
 
2394
        case 1:    
 
2395
            self->proc_func_ptr = AllpassWG_process_aii;
 
2396
            break;
 
2397
        case 10:    
 
2398
            self->proc_func_ptr = AllpassWG_process_iai;
 
2399
            break;
 
2400
        case 11:    
 
2401
            self->proc_func_ptr = AllpassWG_process_aai;
 
2402
            break;
 
2403
        case 100:    
 
2404
            self->proc_func_ptr = AllpassWG_process_iia;
 
2405
            break;
 
2406
        case 101:    
 
2407
            self->proc_func_ptr = AllpassWG_process_aia;
 
2408
            break;
 
2409
        case 110:    
 
2410
            self->proc_func_ptr = AllpassWG_process_iaa;
 
2411
            break;
 
2412
        case 111:    
 
2413
            self->proc_func_ptr = AllpassWG_process_aaa;
 
2414
            break;
 
2415
    } 
 
2416
        switch (muladdmode) {
 
2417
        case 0:        
 
2418
            self->muladd_func_ptr = AllpassWG_postprocessing_ii;
 
2419
            break;
 
2420
        case 1:    
 
2421
            self->muladd_func_ptr = AllpassWG_postprocessing_ai;
 
2422
            break;
 
2423
        case 2:    
 
2424
            self->muladd_func_ptr = AllpassWG_postprocessing_revai;
 
2425
            break;
 
2426
        case 10:        
 
2427
            self->muladd_func_ptr = AllpassWG_postprocessing_ia;
 
2428
            break;
 
2429
        case 11:    
 
2430
            self->muladd_func_ptr = AllpassWG_postprocessing_aa;
 
2431
            break;
 
2432
        case 12:    
 
2433
            self->muladd_func_ptr = AllpassWG_postprocessing_revaa;
 
2434
            break;
 
2435
        case 20:        
 
2436
            self->muladd_func_ptr = AllpassWG_postprocessing_ireva;
 
2437
            break;
 
2438
        case 21:    
 
2439
            self->muladd_func_ptr = AllpassWG_postprocessing_areva;
 
2440
            break;
 
2441
        case 22:    
 
2442
            self->muladd_func_ptr = AllpassWG_postprocessing_revareva;
 
2443
            break;
 
2444
    } 
 
2445
}
 
2446
 
 
2447
static void
 
2448
AllpassWG_compute_next_data_frame(AllpassWG *self)
 
2449
{
 
2450
    (*self->proc_func_ptr)(self); 
 
2451
    (*self->muladd_func_ptr)(self);
 
2452
}
 
2453
 
 
2454
static int
 
2455
AllpassWG_traverse(AllpassWG *self, visitproc visit, void *arg)
 
2456
{
 
2457
    pyo_VISIT
 
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);    
 
2466
    return 0;
 
2467
}
 
2468
 
 
2469
static int 
 
2470
AllpassWG_clear(AllpassWG *self)
 
2471
{
 
2472
    pyo_CLEAR
 
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);    
 
2481
    return 0;
 
2482
}
 
2483
 
 
2484
static void
 
2485
AllpassWG_dealloc(AllpassWG* self)
 
2486
{
 
2487
    int i;
 
2488
    free(self->data);
 
2489
    free(self->buffer);
 
2490
    for(i=0; i<3; i++) {
 
2491
        free(self->alpbuffer[i]);
 
2492
    }
 
2493
    AllpassWG_clear(self);
 
2494
    self->ob_type->tp_free((PyObject*)self);
 
2495
}
 
2496
 
 
2497
static PyObject * AllpassWG_deleteStream(AllpassWG *self) { DELETE_STREAM };
 
2498
 
 
2499
static PyObject *
 
2500
AllpassWG_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
2501
{
 
2502
    int i;
 
2503
    AllpassWG *self;
 
2504
    self = (AllpassWG *)type->tp_alloc(type, 0);
 
2505
    
 
2506
    self->freq = PyFloat_FromDouble(100);
 
2507
    self->feed = PyFloat_FromDouble(0.);
 
2508
    self->detune = PyFloat_FromDouble(0.5);
 
2509
    self->minfreq = 20;
 
2510
    self->in_count = self->alp_in_count[0] = self->alp_in_count[1] = self->alp_in_count[2] = 0;
 
2511
    self->xn1 = 0.0;
 
2512
    self->yn1 = 0.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;
 
2518
    
 
2519
    INIT_OBJECT_COMMON
 
2520
    
 
2521
    self->nyquist = (MYFLT)self->sr * 0.45;
 
2522
 
 
2523
    Stream_setFunctionPtr(self->stream, AllpassWG_compute_next_data_frame);
 
2524
    self->mode_func_ptr = AllpassWG_setProcMode;
 
2525
    
 
2526
    return (PyObject *)self;
 
2527
}
 
2528
 
 
2529
static int
 
2530
AllpassWG_init(AllpassWG *self, PyObject *args, PyObject *kwds)
 
2531
{
 
2532
    PyObject *inputtmp, *input_streamtmp, *freqtmp=NULL, *feedtmp=NULL, *detunetmp=NULL, *multmp=NULL, *addtmp=NULL;
 
2533
    int i, j;
 
2534
    
 
2535
    static char *kwlist[] = {"input", "freq", "feed", "detune", "minfreq", "mul", "add", NULL};
 
2536
    
 
2537
    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_OOOFOO, kwlist, &inputtmp, &freqtmp, &feedtmp, &detunetmp, &self->minfreq, &multmp, &addtmp))
 
2538
        return -1; 
 
2539
    
 
2540
    INIT_INPUT_STREAM
 
2541
    
 
2542
    if (freqtmp) {
 
2543
        PyObject_CallMethod((PyObject *)self, "setFreq", "O", freqtmp);
 
2544
    }
 
2545
    
 
2546
    if (feedtmp) {
 
2547
        PyObject_CallMethod((PyObject *)self, "setFeed", "O", feedtmp);
 
2548
    }
 
2549
    if (detunetmp) {
 
2550
        PyObject_CallMethod((PyObject *)self, "setDetune", "O", detunetmp);
 
2551
    }
 
2552
    
 
2553
    if (multmp) {
 
2554
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
2555
    }
 
2556
    
 
2557
    if (addtmp) {
 
2558
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
2559
    }
 
2560
    
 
2561
    Py_INCREF(self->stream);
 
2562
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
2563
    
 
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.;
 
2568
    }    
 
2569
 
 
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.;
 
2575
        }
 
2576
    }    
 
2577
    
 
2578
    (*self->mode_func_ptr)(self);
 
2579
    
 
2580
    Py_INCREF(self);
 
2581
    return 0;
 
2582
}
 
2583
 
 
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 }; 
 
2590
 
 
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 };
 
2594
 
 
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 };
 
2603
 
 
2604
static PyObject *
 
2605
AllpassWG_setFreq(AllpassWG *self, PyObject *arg)
 
2606
{
 
2607
        PyObject *tmp, *streamtmp;
 
2608
        
 
2609
        if (arg == NULL) {
 
2610
                Py_INCREF(Py_None);
 
2611
                return Py_None;
 
2612
        }
 
2613
    
 
2614
        int isNumber = PyNumber_Check(arg);
 
2615
    
 
2616
        tmp = arg;
 
2617
        Py_INCREF(tmp);
 
2618
        Py_DECREF(self->freq);
 
2619
        if (isNumber == 1) {
 
2620
                self->freq = PyNumber_Float(tmp);
 
2621
        self->modebuffer[2] = 0;
 
2622
        }
 
2623
        else {
 
2624
                self->freq = tmp;
 
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;
 
2630
        }
 
2631
    
 
2632
    (*self->mode_func_ptr)(self);
 
2633
    
 
2634
        Py_INCREF(Py_None);
 
2635
        return Py_None;
 
2636
}       
 
2637
 
 
2638
static PyObject *
 
2639
AllpassWG_setFeed(AllpassWG *self, PyObject *arg)
 
2640
{
 
2641
        PyObject *tmp, *streamtmp;
 
2642
        
 
2643
        if (arg == NULL) {
 
2644
                Py_INCREF(Py_None);
 
2645
                return Py_None;
 
2646
        }
 
2647
    
 
2648
        int isNumber = PyNumber_Check(arg);
 
2649
    
 
2650
        tmp = arg;
 
2651
        Py_INCREF(tmp);
 
2652
        Py_DECREF(self->feed);
 
2653
        if (isNumber == 1) {
 
2654
                self->feed = PyNumber_Float(tmp);
 
2655
        self->modebuffer[3] = 0;
 
2656
        }
 
2657
        else {
 
2658
                self->feed = tmp;
 
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;
 
2664
        }
 
2665
    
 
2666
    (*self->mode_func_ptr)(self);
 
2667
    
 
2668
        Py_INCREF(Py_None);
 
2669
        return Py_None;
 
2670
}       
 
2671
 
 
2672
static PyObject *
 
2673
AllpassWG_setDetune(AllpassWG *self, PyObject *arg)
 
2674
{
 
2675
        PyObject *tmp, *streamtmp;
 
2676
        
 
2677
        if (arg == NULL) {
 
2678
                Py_INCREF(Py_None);
 
2679
                return Py_None;
 
2680
        }
 
2681
    
 
2682
        int isNumber = PyNumber_Check(arg);
 
2683
    
 
2684
        tmp = arg;
 
2685
        Py_INCREF(tmp);
 
2686
        Py_DECREF(self->detune);
 
2687
        if (isNumber == 1) {
 
2688
                self->detune = PyNumber_Float(tmp);
 
2689
        self->modebuffer[4] = 0;
 
2690
        }
 
2691
        else {
 
2692
                self->detune = tmp;
 
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;
 
2698
        }
 
2699
    
 
2700
    (*self->mode_func_ptr)(self);
 
2701
    
 
2702
        Py_INCREF(Py_None);
 
2703
        return Py_None;
 
2704
}       
 
2705
 
 
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 */
 
2716
};
 
2717
 
 
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 */
 
2733
};
 
2734
 
 
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*/
 
2740
    0,                /*nb_remainder*/
 
2741
    0,                   /*nb_divmod*/
 
2742
    0,                   /*nb_power*/
 
2743
    0,                  /*nb_neg*/
 
2744
    0,                /*nb_pos*/
 
2745
    0,                  /*(unaryfunc)array_abs,*/
 
2746
    0,                    /*nb_nonzero*/
 
2747
    0,                    /*nb_invert*/
 
2748
    0,               /*nb_lshift*/
 
2749
    0,              /*nb_rshift*/
 
2750
    0,              /*nb_and*/
 
2751
    0,              /*nb_xor*/
 
2752
    0,               /*nb_or*/
 
2753
    0,                                          /*nb_coerce*/
 
2754
    0,                       /*nb_int*/
 
2755
    0,                      /*nb_long*/
 
2756
    0,                     /*nb_float*/
 
2757
    0,                       /*nb_oct*/
 
2758
    0,                       /*nb_hex*/
 
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*/
 
2767
    0,      /*inplace_and*/
 
2768
    0,      /*inplace_xor*/
 
2769
    0,       /*inplace_or*/
 
2770
    0,             /*nb_floor_divide*/
 
2771
    0,              /*nb_true_divide*/
 
2772
    0,     /*nb_inplace_floor_divide*/
 
2773
    0,      /*nb_inplace_true_divide*/
 
2774
    0,                     /* nb_index */
 
2775
};
 
2776
 
 
2777
PyTypeObject AllpassWGType = {
 
2778
    PyObject_HEAD_INIT(NULL)
 
2779
    0,                         /*ob_size*/
 
2780
    "_pyo.AllpassWG_base",         /*tp_name*/
 
2781
    sizeof(AllpassWG),         /*tp_basicsize*/
 
2782
    0,                         /*tp_itemsize*/
 
2783
    (destructor)AllpassWG_dealloc, /*tp_dealloc*/
 
2784
    0,                         /*tp_print*/
 
2785
    0,                         /*tp_getattr*/
 
2786
    0,                         /*tp_setattr*/
 
2787
    0,                         /*tp_compare*/
 
2788
    0,                         /*tp_repr*/
 
2789
    &AllpassWG_as_number,             /*tp_as_number*/
 
2790
    0,                         /*tp_as_sequence*/
 
2791
    0,                         /*tp_as_mapping*/
 
2792
    0,                         /*tp_hash */
 
2793
    0,                         /*tp_call*/
 
2794
    0,                         /*tp_str*/
 
2795
    0,                         /*tp_getattro*/
 
2796
    0,                         /*tp_setattro*/
 
2797
    0,                         /*tp_as_buffer*/
 
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 */
 
2804
    0,                         /* tp_iter */
 
2805
    0,                         /* tp_iternext */
 
2806
    AllpassWG_methods,             /* tp_methods */
 
2807
    AllpassWG_members,             /* tp_members */
 
2808
    0,                      /* tp_getset */
 
2809
    0,                         /* tp_base */
 
2810
    0,                         /* tp_dict */
 
2811
    0,                         /* tp_descr_get */
 
2812
    0,                         /* tp_descr_set */
 
2813
    0,                         /* tp_dictoffset */
 
2814
    (initproc)AllpassWG_init,      /* tp_init */
 
2815
    0,                         /* tp_alloc */
 
2816
    AllpassWG_new,                 /* tp_new */
 
2817
};