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

« back to all changes in this revision

Viewing changes to src/objects/trigmodule.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 "pyomodule.h"
 
24
#include "streammodule.h"
 
25
#include "servermodule.h"
 
26
#include "dummymodule.h"
 
27
#include "tablemodule.h"
 
28
#include "interpolation.h"
 
29
 
 
30
typedef struct {
 
31
    pyo_audio_HEAD
 
32
    PyObject *input;
 
33
    Stream *input_stream;
 
34
    PyObject *max;
 
35
    Stream *max_stream;
 
36
    MYFLT value;
 
37
    int modebuffer[3]; // need at least 2 slots for mul & add 
 
38
} TrigRandInt;
 
39
 
 
40
static void
 
41
TrigRandInt_generate_i(TrigRandInt *self) {
 
42
    int i;
 
43
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
44
    MYFLT ma = PyFloat_AS_DOUBLE(self->max);
 
45
    
 
46
    for (i=0; i<self->bufsize; i++) {
 
47
        if (in[i] == 1)
 
48
            self->value = (MYFLT)((int)(rand()/((MYFLT)(RAND_MAX)+1)*ma));
 
49
        
 
50
        self->data[i] = self->value;
 
51
    }
 
52
}
 
53
 
 
54
static void
 
55
TrigRandInt_generate_a(TrigRandInt *self) {
 
56
    int i;
 
57
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
58
    MYFLT *ma = Stream_getData((Stream *)self->max_stream);
 
59
    
 
60
    for (i=0; i<self->bufsize; i++) {
 
61
        if (in[i] == 1)
 
62
            self->value = (MYFLT)((int)(rand()/((MYFLT)(RAND_MAX)+1)*ma[i]));
 
63
        
 
64
        self->data[i] = self->value;
 
65
    }
 
66
}
 
67
 
 
68
static void TrigRandInt_postprocessing_ii(TrigRandInt *self) { POST_PROCESSING_II };
 
69
static void TrigRandInt_postprocessing_ai(TrigRandInt *self) { POST_PROCESSING_AI };
 
70
static void TrigRandInt_postprocessing_ia(TrigRandInt *self) { POST_PROCESSING_IA };
 
71
static void TrigRandInt_postprocessing_aa(TrigRandInt *self) { POST_PROCESSING_AA };
 
72
static void TrigRandInt_postprocessing_ireva(TrigRandInt *self) { POST_PROCESSING_IREVA };
 
73
static void TrigRandInt_postprocessing_areva(TrigRandInt *self) { POST_PROCESSING_AREVA };
 
74
static void TrigRandInt_postprocessing_revai(TrigRandInt *self) { POST_PROCESSING_REVAI };
 
75
static void TrigRandInt_postprocessing_revaa(TrigRandInt *self) { POST_PROCESSING_REVAA };
 
76
static void TrigRandInt_postprocessing_revareva(TrigRandInt *self) { POST_PROCESSING_REVAREVA };
 
77
 
 
78
static void
 
79
TrigRandInt_setProcMode(TrigRandInt *self)
 
80
{
 
81
    int procmode, muladdmode;
 
82
    procmode = self->modebuffer[2];
 
83
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
84
    
 
85
        switch (procmode) {
 
86
        case 0:    
 
87
            self->proc_func_ptr = TrigRandInt_generate_i;
 
88
            break;
 
89
        case 1:    
 
90
            self->proc_func_ptr = TrigRandInt_generate_a;
 
91
            break;
 
92
    } 
 
93
        switch (muladdmode) {
 
94
        case 0:        
 
95
            self->muladd_func_ptr = TrigRandInt_postprocessing_ii;
 
96
            break;
 
97
        case 1:    
 
98
            self->muladd_func_ptr = TrigRandInt_postprocessing_ai;
 
99
            break;
 
100
        case 2:    
 
101
            self->muladd_func_ptr = TrigRandInt_postprocessing_revai;
 
102
            break;
 
103
        case 10:        
 
104
            self->muladd_func_ptr = TrigRandInt_postprocessing_ia;
 
105
            break;
 
106
        case 11:    
 
107
            self->muladd_func_ptr = TrigRandInt_postprocessing_aa;
 
108
            break;
 
109
        case 12:    
 
110
            self->muladd_func_ptr = TrigRandInt_postprocessing_revaa;
 
111
            break;
 
112
        case 20:        
 
113
            self->muladd_func_ptr = TrigRandInt_postprocessing_ireva;
 
114
            break;
 
115
        case 21:    
 
116
            self->muladd_func_ptr = TrigRandInt_postprocessing_areva;
 
117
            break;
 
118
        case 22:    
 
119
            self->muladd_func_ptr = TrigRandInt_postprocessing_revareva;
 
120
            break;
 
121
    }  
 
122
}
 
123
 
 
124
static void
 
125
TrigRandInt_compute_next_data_frame(TrigRandInt *self)
 
126
{
 
127
    (*self->proc_func_ptr)(self); 
 
128
    (*self->muladd_func_ptr)(self);
 
129
}
 
130
 
 
131
static int
 
132
TrigRandInt_traverse(TrigRandInt *self, visitproc visit, void *arg)
 
133
{
 
134
    pyo_VISIT
 
135
    Py_VISIT(self->input);
 
136
    Py_VISIT(self->input_stream);
 
137
    Py_VISIT(self->max);    
 
138
    Py_VISIT(self->max_stream);    
 
139
    return 0;
 
140
}
 
141
 
 
142
static int 
 
143
TrigRandInt_clear(TrigRandInt *self)
 
144
{
 
145
    pyo_CLEAR
 
146
    Py_CLEAR(self->input);
 
147
    Py_CLEAR(self->input_stream);
 
148
    Py_CLEAR(self->max);    
 
149
    Py_CLEAR(self->max_stream);    
 
150
    return 0;
 
151
}
 
152
 
 
153
static void
 
154
TrigRandInt_dealloc(TrigRandInt* self)
 
155
{
 
156
    free(self->data);
 
157
    TrigRandInt_clear(self);
 
158
    self->ob_type->tp_free((PyObject*)self);
 
159
}
 
160
 
 
161
static PyObject * TrigRandInt_deleteStream(TrigRandInt *self) { DELETE_STREAM };
 
162
 
 
163
static PyObject *
 
164
TrigRandInt_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
165
{
 
166
    int i;
 
167
    TrigRandInt *self;
 
168
    self = (TrigRandInt *)type->tp_alloc(type, 0);
 
169
    
 
170
    self->max = PyFloat_FromDouble(100.);
 
171
    self->value = 0.;
 
172
        self->modebuffer[0] = 0;
 
173
        self->modebuffer[1] = 0;
 
174
        self->modebuffer[2] = 0;
 
175
    
 
176
    INIT_OBJECT_COMMON
 
177
    Stream_setFunctionPtr(self->stream, TrigRandInt_compute_next_data_frame);
 
178
    self->mode_func_ptr = TrigRandInt_setProcMode;
 
179
    return (PyObject *)self;
 
180
}
 
181
 
 
182
static int
 
183
TrigRandInt_init(TrigRandInt *self, PyObject *args, PyObject *kwds)
 
184
{
 
185
    MYFLT ma;
 
186
    PyObject *inputtmp, *input_streamtmp, *maxtmp=NULL, *multmp=NULL, *addtmp=NULL;
 
187
    
 
188
    static char *kwlist[] = {"input", "max", "mul", "add", NULL};
 
189
    
 
190
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OOO", kwlist, &inputtmp, &maxtmp, &multmp, &addtmp))
 
191
        return -1; 
 
192
    
 
193
    INIT_INPUT_STREAM
 
194
 
 
195
    if (maxtmp) {
 
196
        PyObject_CallMethod((PyObject *)self, "setMax", "O", maxtmp);
 
197
    }
 
198
    
 
199
    if (multmp) {
 
200
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
201
    }
 
202
    
 
203
    if (addtmp) {
 
204
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
205
    }
 
206
    
 
207
    Py_INCREF(self->stream);
 
208
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
209
    
 
210
    Server_generateSeed((Server *)self->server, TRIGRANDINT_ID);
 
211
 
 
212
    if (self->modebuffer[2] == 0)
 
213
        ma = PyFloat_AS_DOUBLE(PyNumber_Float(self->max));
 
214
    else
 
215
        ma = Stream_getData((Stream *)self->max_stream)[0];
 
216
    self->value = (MYFLT)((int)(rand()/((MYFLT)(RAND_MAX)+1)*ma));
 
217
 
 
218
    (*self->mode_func_ptr)(self);
 
219
    
 
220
    Py_INCREF(self);
 
221
    return 0;
 
222
}
 
223
 
 
224
static PyObject * TrigRandInt_getServer(TrigRandInt* self) { GET_SERVER };
 
225
static PyObject * TrigRandInt_getStream(TrigRandInt* self) { GET_STREAM };
 
226
static PyObject * TrigRandInt_setMul(TrigRandInt *self, PyObject *arg) { SET_MUL };     
 
227
static PyObject * TrigRandInt_setAdd(TrigRandInt *self, PyObject *arg) { SET_ADD };     
 
228
static PyObject * TrigRandInt_setSub(TrigRandInt *self, PyObject *arg) { SET_SUB };     
 
229
static PyObject * TrigRandInt_setDiv(TrigRandInt *self, PyObject *arg) { SET_DIV };     
 
230
 
 
231
static PyObject * TrigRandInt_play(TrigRandInt *self, PyObject *args, PyObject *kwds) { PLAY };
 
232
static PyObject * TrigRandInt_out(TrigRandInt *self, PyObject *args, PyObject *kwds) { OUT };
 
233
static PyObject * TrigRandInt_stop(TrigRandInt *self) { STOP };
 
234
 
 
235
static PyObject * TrigRandInt_multiply(TrigRandInt *self, PyObject *arg) { MULTIPLY };
 
236
static PyObject * TrigRandInt_inplace_multiply(TrigRandInt *self, PyObject *arg) { INPLACE_MULTIPLY };
 
237
static PyObject * TrigRandInt_add(TrigRandInt *self, PyObject *arg) { ADD };
 
238
static PyObject * TrigRandInt_inplace_add(TrigRandInt *self, PyObject *arg) { INPLACE_ADD };
 
239
static PyObject * TrigRandInt_sub(TrigRandInt *self, PyObject *arg) { SUB };
 
240
static PyObject * TrigRandInt_inplace_sub(TrigRandInt *self, PyObject *arg) { INPLACE_SUB };
 
241
static PyObject * TrigRandInt_div(TrigRandInt *self, PyObject *arg) { DIV };
 
242
static PyObject * TrigRandInt_inplace_div(TrigRandInt *self, PyObject *arg) { INPLACE_DIV };
 
243
 
 
244
static PyObject *
 
245
TrigRandInt_setMax(TrigRandInt *self, PyObject *arg)
 
246
{
 
247
        PyObject *tmp, *streamtmp;
 
248
        
 
249
        if (arg == NULL) {
 
250
                Py_INCREF(Py_None);
 
251
                return Py_None;
 
252
        }
 
253
    
 
254
        int isNumber = PyNumber_Check(arg);
 
255
        
 
256
        tmp = arg;
 
257
        Py_INCREF(tmp);
 
258
        Py_DECREF(self->max);
 
259
        if (isNumber == 1) {
 
260
                self->max = PyNumber_Float(tmp);
 
261
        self->modebuffer[2] = 0;
 
262
        }
 
263
        else {
 
264
                self->max = tmp;
 
265
        streamtmp = PyObject_CallMethod((PyObject *)self->max, "_getStream", NULL);
 
266
        Py_INCREF(streamtmp);
 
267
        Py_XDECREF(self->max_stream);
 
268
        self->max_stream = (Stream *)streamtmp;
 
269
                self->modebuffer[2] = 1;
 
270
        }
 
271
    
 
272
    (*self->mode_func_ptr)(self);
 
273
    
 
274
        Py_INCREF(Py_None);
 
275
        return Py_None;
 
276
}       
 
277
 
 
278
static PyMemberDef TrigRandInt_members[] = {
 
279
    {"server", T_OBJECT_EX, offsetof(TrigRandInt, server), 0, "Pyo server."},
 
280
    {"stream", T_OBJECT_EX, offsetof(TrigRandInt, stream), 0, "Stream object."},
 
281
    {"input", T_OBJECT_EX, offsetof(TrigRandInt, input), 0, "Input sound object."},
 
282
    {"max", T_OBJECT_EX, offsetof(TrigRandInt, max), 0, "Maximum possible value."},
 
283
    {"mul", T_OBJECT_EX, offsetof(TrigRandInt, mul), 0, "Mul factor."},
 
284
    {"add", T_OBJECT_EX, offsetof(TrigRandInt, add), 0, "Add factor."},
 
285
    {NULL}  /* Sentinel */
 
286
};
 
287
 
 
288
static PyMethodDef TrigRandInt_methods[] = {
 
289
    {"getServer", (PyCFunction)TrigRandInt_getServer, METH_NOARGS, "Returns server object."},
 
290
    {"_getStream", (PyCFunction)TrigRandInt_getStream, METH_NOARGS, "Returns stream object."},
 
291
    {"deleteStream", (PyCFunction)TrigRandInt_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
292
    {"play", (PyCFunction)TrigRandInt_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
293
    {"out", (PyCFunction)TrigRandInt_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
 
294
    {"stop", (PyCFunction)TrigRandInt_stop, METH_NOARGS, "Stops computing."},
 
295
    {"setMax", (PyCFunction)TrigRandInt_setMax, METH_O, "Sets maximum possible value."},
 
296
    {"setMul", (PyCFunction)TrigRandInt_setMul, METH_O, "Sets oscillator mul factor."},
 
297
    {"setAdd", (PyCFunction)TrigRandInt_setAdd, METH_O, "Sets oscillator add factor."},
 
298
    {"setSub", (PyCFunction)TrigRandInt_setSub, METH_O, "Sets inverse add factor."},
 
299
    {"setDiv", (PyCFunction)TrigRandInt_setDiv, METH_O, "Sets inverse mul factor."},
 
300
    {NULL}  /* Sentinel */
 
301
};
 
302
 
 
303
static PyNumberMethods TrigRandInt_as_number = {
 
304
    (binaryfunc)TrigRandInt_add,                         /*nb_add*/
 
305
    (binaryfunc)TrigRandInt_sub,                         /*nb_subtract*/
 
306
    (binaryfunc)TrigRandInt_multiply,                    /*nb_multiply*/
 
307
    (binaryfunc)TrigRandInt_div,                                              /*nb_divide*/
 
308
    0,                                              /*nb_remainder*/
 
309
    0,                                              /*nb_divmod*/
 
310
    0,                                              /*nb_power*/
 
311
    0,                                              /*nb_neg*/
 
312
    0,                                              /*nb_pos*/
 
313
    0,                                              /*(unaryfunc)array_abs,*/
 
314
    0,                                              /*nb_nonzero*/
 
315
    0,                                              /*nb_invert*/
 
316
    0,                                              /*nb_lshift*/
 
317
    0,                                              /*nb_rshift*/
 
318
    0,                                              /*nb_and*/
 
319
    0,                                              /*nb_xor*/
 
320
    0,                                              /*nb_or*/
 
321
    0,                                              /*nb_coerce*/
 
322
    0,                                              /*nb_int*/
 
323
    0,                                              /*nb_long*/
 
324
    0,                                              /*nb_float*/
 
325
    0,                                              /*nb_oct*/
 
326
    0,                                              /*nb_hex*/
 
327
    (binaryfunc)TrigRandInt_inplace_add,                 /*inplace_add*/
 
328
    (binaryfunc)TrigRandInt_inplace_sub,                 /*inplace_subtract*/
 
329
    (binaryfunc)TrigRandInt_inplace_multiply,            /*inplace_multiply*/
 
330
    (binaryfunc)TrigRandInt_inplace_div,                                              /*inplace_divide*/
 
331
    0,                                              /*inplace_remainder*/
 
332
    0,                                              /*inplace_power*/
 
333
    0,                                              /*inplace_lshift*/
 
334
    0,                                              /*inplace_rshift*/
 
335
    0,                                              /*inplace_and*/
 
336
    0,                                              /*inplace_xor*/
 
337
    0,                                              /*inplace_or*/
 
338
    0,                                              /*nb_floor_divide*/
 
339
    0,                                              /*nb_true_divide*/
 
340
    0,                                              /*nb_inplace_floor_divide*/
 
341
    0,                                              /*nb_inplace_true_divide*/
 
342
    0,                                              /* nb_index */
 
343
};
 
344
 
 
345
PyTypeObject TrigRandIntType = {
 
346
    PyObject_HEAD_INIT(NULL)
 
347
    0,                                              /*ob_size*/
 
348
    "_pyo.TrigRandInt_base",                                   /*tp_name*/
 
349
    sizeof(TrigRandInt),                                 /*tp_basicsize*/
 
350
    0,                                              /*tp_itemsize*/
 
351
    (destructor)TrigRandInt_dealloc,                     /*tp_dealloc*/
 
352
    0,                                              /*tp_print*/
 
353
    0,                                              /*tp_getattr*/
 
354
    0,                                              /*tp_setattr*/
 
355
    0,                                              /*tp_compare*/
 
356
    0,                                              /*tp_repr*/
 
357
    &TrigRandInt_as_number,                              /*tp_as_number*/
 
358
    0,                                              /*tp_as_sequence*/
 
359
    0,                                              /*tp_as_mapping*/
 
360
    0,                                              /*tp_hash */
 
361
    0,                                              /*tp_call*/
 
362
    0,                                              /*tp_str*/
 
363
    0,                                              /*tp_getattro*/
 
364
    0,                                              /*tp_setattro*/
 
365
    0,                                              /*tp_as_buffer*/
 
366
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
367
    "TrigRandInt objects. Generates a new random integer value on a trigger signal.",           /* tp_doc */
 
368
    (traverseproc)TrigRandInt_traverse,                  /* tp_traverse */
 
369
    (inquiry)TrigRandInt_clear,                          /* tp_clear */
 
370
    0,                                              /* tp_richcompare */
 
371
    0,                                              /* tp_weaklistoffset */
 
372
    0,                                              /* tp_iter */
 
373
    0,                                              /* tp_iternext */
 
374
    TrigRandInt_methods,                                 /* tp_methods */
 
375
    TrigRandInt_members,                                 /* tp_members */
 
376
    0,                                              /* tp_getset */
 
377
    0,                                              /* tp_base */
 
378
    0,                                              /* tp_dict */
 
379
    0,                                              /* tp_descr_get */
 
380
    0,                                              /* tp_descr_set */
 
381
    0,                                              /* tp_dictoffset */
 
382
    (initproc)TrigRandInt_init,                          /* tp_init */
 
383
    0,                                              /* tp_alloc */
 
384
    TrigRandInt_new,                                     /* tp_new */
 
385
};
 
386
 
 
387
typedef struct {
 
388
    pyo_audio_HEAD
 
389
    PyObject *input;
 
390
    Stream *input_stream;
 
391
    PyObject *min;
 
392
    PyObject *max;
 
393
    Stream *min_stream;
 
394
    Stream *max_stream;
 
395
    MYFLT value;
 
396
    MYFLT currentValue;
 
397
    MYFLT time;
 
398
    int timeStep;
 
399
    MYFLT stepVal;
 
400
    int timeCount;
 
401
    int modebuffer[4]; // need at least 2 slots for mul & add 
 
402
} TrigRand;
 
403
 
 
404
static void
 
405
TrigRand_generate_ii(TrigRand *self) {
 
406
    int i;
 
407
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
408
    MYFLT mi = PyFloat_AS_DOUBLE(self->min);
 
409
    MYFLT ma = PyFloat_AS_DOUBLE(self->max);
 
410
    MYFLT range = ma - mi;
 
411
    
 
412
    for (i=0; i<self->bufsize; i++) {
 
413
        if (in[i] == 1) {
 
414
            self->timeCount = 0;
 
415
            self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
 
416
            if (self->time <= 0.0)
 
417
                self->currentValue = self->value;
 
418
            else
 
419
                self->stepVal = (self->value - self->currentValue) / self->timeStep;
 
420
        }
 
421
        
 
422
        if (self->timeCount == (self->timeStep - 1)) {
 
423
            self->currentValue = self->value;
 
424
            self->timeCount++;
 
425
        }
 
426
        else if (self->timeCount < self->timeStep) {
 
427
            self->currentValue += self->stepVal;
 
428
            self->timeCount++;
 
429
        }
 
430
        
 
431
        self->data[i] = self->currentValue;
 
432
    }
 
433
}
 
434
 
 
435
static void
 
436
TrigRand_generate_ai(TrigRand *self) {
 
437
    int i;
 
438
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
439
    MYFLT *mi = Stream_getData((Stream *)self->min_stream);
 
440
    MYFLT ma = PyFloat_AS_DOUBLE(self->max);
 
441
    
 
442
    for (i=0; i<self->bufsize; i++) {
 
443
        MYFLT range = ma - mi[i];
 
444
        if (in[i] == 1) {
 
445
            self->timeCount = 0;
 
446
            self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
 
447
            if (self->time <= 0.0)
 
448
                self->currentValue = self->value;
 
449
            else
 
450
                self->stepVal = (self->value - self->currentValue) / self->timeStep;
 
451
        }
 
452
 
 
453
        if (self->timeCount == (self->timeStep - 1)) {
 
454
            self->currentValue = self->value;
 
455
            self->timeCount++;
 
456
        }
 
457
        else if (self->timeCount < self->timeStep) {
 
458
            self->currentValue += self->stepVal;
 
459
            self->timeCount++;
 
460
        }
 
461
        
 
462
        self->data[i] = self->currentValue;        
 
463
    }
 
464
}
 
465
 
 
466
static void
 
467
TrigRand_generate_ia(TrigRand *self) {
 
468
    int i;
 
469
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
470
    MYFLT mi = PyFloat_AS_DOUBLE(self->min);
 
471
    MYFLT *ma = Stream_getData((Stream *)self->max_stream);
 
472
    
 
473
    for (i=0; i<self->bufsize; i++) {
 
474
        MYFLT range = ma[i] - mi;
 
475
        if (in[i] == 1) {
 
476
            self->timeCount = 0;
 
477
            self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi;
 
478
            if (self->time <= 0.0)
 
479
                self->currentValue = self->value;
 
480
            else
 
481
                self->stepVal = (self->value - self->currentValue) / self->timeStep;
 
482
        }
 
483
        
 
484
        if (self->timeCount == (self->timeStep - 1)) {
 
485
            self->currentValue = self->value;
 
486
            self->timeCount++;
 
487
        }
 
488
        else if (self->timeCount < self->timeStep) {
 
489
            self->currentValue += self->stepVal;
 
490
            self->timeCount++;
 
491
        }
 
492
        
 
493
        self->data[i] = self->currentValue;
 
494
    }
 
495
}
 
496
 
 
497
static void
 
498
TrigRand_generate_aa(TrigRand *self) {
 
499
    int i;
 
500
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
501
    MYFLT *mi = Stream_getData((Stream *)self->min_stream);
 
502
    MYFLT *ma = Stream_getData((Stream *)self->max_stream);
 
503
    
 
504
    for (i=0; i<self->bufsize; i++) {
 
505
        MYFLT range = ma[i] - mi[i];
 
506
        if (in[i] == 1) {
 
507
            self->timeCount = 0;
 
508
            self->value = range * (rand()/((MYFLT)(RAND_MAX)+1)) + mi[i];
 
509
            if (self->time <= 0.0)
 
510
                self->currentValue = self->value;
 
511
            else
 
512
                self->stepVal = (self->value - self->currentValue) / self->timeStep;
 
513
        }
 
514
        
 
515
        if (self->timeCount == (self->timeStep - 1)) {
 
516
            self->currentValue = self->value;
 
517
            self->timeCount++;
 
518
        }
 
519
        else if (self->timeCount < self->timeStep) {
 
520
            self->currentValue += self->stepVal;
 
521
            self->timeCount++;
 
522
        }
 
523
        
 
524
        self->data[i] = self->currentValue;
 
525
    }
 
526
}
 
527
 
 
528
static void TrigRand_postprocessing_ii(TrigRand *self) { POST_PROCESSING_II };
 
529
static void TrigRand_postprocessing_ai(TrigRand *self) { POST_PROCESSING_AI };
 
530
static void TrigRand_postprocessing_ia(TrigRand *self) { POST_PROCESSING_IA };
 
531
static void TrigRand_postprocessing_aa(TrigRand *self) { POST_PROCESSING_AA };
 
532
static void TrigRand_postprocessing_ireva(TrigRand *self) { POST_PROCESSING_IREVA };
 
533
static void TrigRand_postprocessing_areva(TrigRand *self) { POST_PROCESSING_AREVA };
 
534
static void TrigRand_postprocessing_revai(TrigRand *self) { POST_PROCESSING_REVAI };
 
535
static void TrigRand_postprocessing_revaa(TrigRand *self) { POST_PROCESSING_REVAA };
 
536
static void TrigRand_postprocessing_revareva(TrigRand *self) { POST_PROCESSING_REVAREVA };
 
537
 
 
538
static void
 
539
TrigRand_setProcMode(TrigRand *self)
 
540
{
 
541
    int procmode, muladdmode;
 
542
    procmode = self->modebuffer[2] + self->modebuffer[3] * 10;
 
543
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
544
    
 
545
        switch (procmode) {
 
546
        case 0:    
 
547
            self->proc_func_ptr = TrigRand_generate_ii;
 
548
            break;
 
549
        case 1:    
 
550
            self->proc_func_ptr = TrigRand_generate_ai;
 
551
            break;
 
552
        case 10:    
 
553
            self->proc_func_ptr = TrigRand_generate_ia;
 
554
            break;
 
555
        case 11:    
 
556
            self->proc_func_ptr = TrigRand_generate_aa;
 
557
            break;
 
558
    } 
 
559
        switch (muladdmode) {
 
560
        case 0:        
 
561
            self->muladd_func_ptr = TrigRand_postprocessing_ii;
 
562
            break;
 
563
        case 1:    
 
564
            self->muladd_func_ptr = TrigRand_postprocessing_ai;
 
565
            break;
 
566
        case 2:    
 
567
            self->muladd_func_ptr = TrigRand_postprocessing_revai;
 
568
            break;
 
569
        case 10:        
 
570
            self->muladd_func_ptr = TrigRand_postprocessing_ia;
 
571
            break;
 
572
        case 11:    
 
573
            self->muladd_func_ptr = TrigRand_postprocessing_aa;
 
574
            break;
 
575
        case 12:    
 
576
            self->muladd_func_ptr = TrigRand_postprocessing_revaa;
 
577
            break;
 
578
        case 20:        
 
579
            self->muladd_func_ptr = TrigRand_postprocessing_ireva;
 
580
            break;
 
581
        case 21:    
 
582
            self->muladd_func_ptr = TrigRand_postprocessing_areva;
 
583
            break;
 
584
        case 22:    
 
585
            self->muladd_func_ptr = TrigRand_postprocessing_revareva;
 
586
            break;
 
587
    }  
 
588
}
 
589
 
 
590
static void
 
591
TrigRand_compute_next_data_frame(TrigRand *self)
 
592
{
 
593
    (*self->proc_func_ptr)(self); 
 
594
    (*self->muladd_func_ptr)(self);
 
595
}
 
596
 
 
597
static int
 
598
TrigRand_traverse(TrigRand *self, visitproc visit, void *arg)
 
599
{
 
600
    pyo_VISIT
 
601
    Py_VISIT(self->input);
 
602
    Py_VISIT(self->input_stream);
 
603
    Py_VISIT(self->min);    
 
604
    Py_VISIT(self->min_stream);    
 
605
    Py_VISIT(self->max);    
 
606
    Py_VISIT(self->max_stream);    
 
607
    return 0;
 
608
}
 
609
 
 
610
static int 
 
611
TrigRand_clear(TrigRand *self)
 
612
{
 
613
    pyo_CLEAR
 
614
    Py_CLEAR(self->input);
 
615
    Py_CLEAR(self->input_stream);
 
616
    Py_CLEAR(self->min);    
 
617
    Py_CLEAR(self->min_stream);    
 
618
    Py_CLEAR(self->max);    
 
619
    Py_CLEAR(self->max_stream);    
 
620
    return 0;
 
621
}
 
622
 
 
623
static void
 
624
TrigRand_dealloc(TrigRand* self)
 
625
{
 
626
    free(self->data);
 
627
    TrigRand_clear(self);
 
628
    self->ob_type->tp_free((PyObject*)self);
 
629
}
 
630
 
 
631
static PyObject * TrigRand_deleteStream(TrigRand *self) { DELETE_STREAM };
 
632
 
 
633
static PyObject *
 
634
TrigRand_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
635
{
 
636
    int i;
 
637
    TrigRand *self;
 
638
    self = (TrigRand *)type->tp_alloc(type, 0);
 
639
    
 
640
    self->min = PyFloat_FromDouble(0.);
 
641
    self->max = PyFloat_FromDouble(1.);
 
642
    self->value = self->currentValue = 0.;
 
643
    self->time = 0.0;
 
644
    self->timeCount = 0;
 
645
    self->stepVal = 0.0;
 
646
        self->modebuffer[0] = 0;
 
647
        self->modebuffer[1] = 0;
 
648
        self->modebuffer[2] = 0;
 
649
        self->modebuffer[3] = 0;
 
650
    
 
651
    INIT_OBJECT_COMMON
 
652
    Stream_setFunctionPtr(self->stream, TrigRand_compute_next_data_frame);
 
653
    self->mode_func_ptr = TrigRand_setProcMode;
 
654
    return (PyObject *)self;
 
655
}
 
656
 
 
657
static int
 
658
TrigRand_init(TrigRand *self, PyObject *args, PyObject *kwds)
 
659
{
 
660
    MYFLT inittmp = 0.0;
 
661
    PyObject *inputtmp, *input_streamtmp, *mintmp=NULL, *maxtmp=NULL, *multmp=NULL, *addtmp=NULL;
 
662
    
 
663
    static char *kwlist[] = {"input", "min", "max", "port", "init", "mul", "add", NULL};
 
664
    
 
665
    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_O_OOFFOO, kwlist, &inputtmp, &mintmp, &maxtmp, &self->time, &inittmp, &multmp, &addtmp))
 
666
        return -1; 
 
667
    
 
668
    INIT_INPUT_STREAM
 
669
    
 
670
    if (mintmp) {
 
671
        PyObject_CallMethod((PyObject *)self, "setMin", "O", mintmp);
 
672
    }
 
673
    
 
674
    if (maxtmp) {
 
675
        PyObject_CallMethod((PyObject *)self, "setMax", "O", maxtmp);
 
676
    }
 
677
    
 
678
    if (multmp) {
 
679
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
680
    }
 
681
    
 
682
    if (addtmp) {
 
683
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
684
    }
 
685
    
 
686
    Py_INCREF(self->stream);
 
687
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
688
 
 
689
    Server_generateSeed((Server *)self->server, TRIGRAND_ID);
 
690
 
 
691
    self->value = self->currentValue = inittmp;
 
692
    self->timeStep = (int)(self->time * self->sr);
 
693
 
 
694
    (*self->mode_func_ptr)(self);
 
695
        
 
696
    Py_INCREF(self);
 
697
    return 0;
 
698
}
 
699
 
 
700
static PyObject * TrigRand_getServer(TrigRand* self) { GET_SERVER };
 
701
static PyObject * TrigRand_getStream(TrigRand* self) { GET_STREAM };
 
702
static PyObject * TrigRand_setMul(TrigRand *self, PyObject *arg) { SET_MUL };   
 
703
static PyObject * TrigRand_setAdd(TrigRand *self, PyObject *arg) { SET_ADD };   
 
704
static PyObject * TrigRand_setSub(TrigRand *self, PyObject *arg) { SET_SUB };   
 
705
static PyObject * TrigRand_setDiv(TrigRand *self, PyObject *arg) { SET_DIV };   
 
706
 
 
707
static PyObject * TrigRand_play(TrigRand *self, PyObject *args, PyObject *kwds) { PLAY };
 
708
static PyObject * TrigRand_out(TrigRand *self, PyObject *args, PyObject *kwds) { OUT };
 
709
static PyObject * TrigRand_stop(TrigRand *self) { STOP };
 
710
 
 
711
static PyObject * TrigRand_multiply(TrigRand *self, PyObject *arg) { MULTIPLY };
 
712
static PyObject * TrigRand_inplace_multiply(TrigRand *self, PyObject *arg) { INPLACE_MULTIPLY };
 
713
static PyObject * TrigRand_add(TrigRand *self, PyObject *arg) { ADD };
 
714
static PyObject * TrigRand_inplace_add(TrigRand *self, PyObject *arg) { INPLACE_ADD };
 
715
static PyObject * TrigRand_sub(TrigRand *self, PyObject *arg) { SUB };
 
716
static PyObject * TrigRand_inplace_sub(TrigRand *self, PyObject *arg) { INPLACE_SUB };
 
717
static PyObject * TrigRand_div(TrigRand *self, PyObject *arg) { DIV };
 
718
static PyObject * TrigRand_inplace_div(TrigRand *self, PyObject *arg) { INPLACE_DIV };
 
719
 
 
720
static PyObject *
 
721
TrigRand_setMin(TrigRand *self, PyObject *arg)
 
722
{
 
723
        PyObject *tmp, *streamtmp;
 
724
        
 
725
        if (arg == NULL) {
 
726
                Py_INCREF(Py_None);
 
727
                return Py_None;
 
728
        }
 
729
    
 
730
        int isNumber = PyNumber_Check(arg);
 
731
        
 
732
        tmp = arg;
 
733
        Py_INCREF(tmp);
 
734
        Py_DECREF(self->min);
 
735
        if (isNumber == 1) {
 
736
                self->min = PyNumber_Float(tmp);
 
737
        self->modebuffer[2] = 0;
 
738
        }
 
739
        else {
 
740
                self->min = tmp;
 
741
        streamtmp = PyObject_CallMethod((PyObject *)self->min, "_getStream", NULL);
 
742
        Py_INCREF(streamtmp);
 
743
        Py_XDECREF(self->min_stream);
 
744
        self->min_stream = (Stream *)streamtmp;
 
745
                self->modebuffer[2] = 1;
 
746
        }
 
747
    
 
748
    (*self->mode_func_ptr)(self);
 
749
    
 
750
        Py_INCREF(Py_None);
 
751
        return Py_None;
 
752
}       
 
753
 
 
754
static PyObject *
 
755
TrigRand_setMax(TrigRand *self, PyObject *arg)
 
756
{
 
757
        PyObject *tmp, *streamtmp;
 
758
        
 
759
        if (arg == NULL) {
 
760
                Py_INCREF(Py_None);
 
761
                return Py_None;
 
762
        }
 
763
    
 
764
        int isNumber = PyNumber_Check(arg);
 
765
        
 
766
        tmp = arg;
 
767
        Py_INCREF(tmp);
 
768
        Py_DECREF(self->max);
 
769
        if (isNumber == 1) {
 
770
                self->max = PyNumber_Float(tmp);
 
771
        self->modebuffer[3] = 0;
 
772
        }
 
773
        else {
 
774
                self->max = tmp;
 
775
        streamtmp = PyObject_CallMethod((PyObject *)self->max, "_getStream", NULL);
 
776
        Py_INCREF(streamtmp);
 
777
        Py_XDECREF(self->max_stream);
 
778
        self->max_stream = (Stream *)streamtmp;
 
779
                self->modebuffer[3] = 1;
 
780
        }
 
781
    
 
782
    (*self->mode_func_ptr)(self);
 
783
    
 
784
        Py_INCREF(Py_None);
 
785
        return Py_None;
 
786
}       
 
787
 
 
788
static PyObject *
 
789
TrigRand_setPort(TrigRand *self, PyObject *arg)
 
790
{
 
791
        PyObject *tmp;
 
792
        
 
793
        if (arg == NULL) {
 
794
                Py_INCREF(Py_None);
 
795
                return Py_None;
 
796
        }
 
797
    
 
798
        int isNumber = PyNumber_Check(arg);
 
799
        
 
800
        tmp = arg;
 
801
        Py_INCREF(tmp);
 
802
        if (isNumber == 1) {
 
803
                self->time = PyFloat_AS_DOUBLE(PyNumber_Float(tmp));
 
804
        self->timeStep = (int)(self->time * self->sr);
 
805
        }
 
806
    
 
807
        Py_INCREF(Py_None);
 
808
        return Py_None;
 
809
}       
 
810
 
 
811
static PyMemberDef TrigRand_members[] = {
 
812
{"server", T_OBJECT_EX, offsetof(TrigRand, server), 0, "Pyo server."},
 
813
{"stream", T_OBJECT_EX, offsetof(TrigRand, stream), 0, "Stream object."},
 
814
{"input", T_OBJECT_EX, offsetof(TrigRand, input), 0, "Input sound object."},
 
815
{"min", T_OBJECT_EX, offsetof(TrigRand, min), 0, "Minimum possible value."},
 
816
{"max", T_OBJECT_EX, offsetof(TrigRand, max), 0, "Maximum possible value."},
 
817
{"mul", T_OBJECT_EX, offsetof(TrigRand, mul), 0, "Mul factor."},
 
818
{"add", T_OBJECT_EX, offsetof(TrigRand, add), 0, "Add factor."},
 
819
{NULL}  /* Sentinel */
 
820
};
 
821
 
 
822
static PyMethodDef TrigRand_methods[] = {
 
823
{"getServer", (PyCFunction)TrigRand_getServer, METH_NOARGS, "Returns server object."},
 
824
{"_getStream", (PyCFunction)TrigRand_getStream, METH_NOARGS, "Returns stream object."},
 
825
{"deleteStream", (PyCFunction)TrigRand_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
826
{"play", (PyCFunction)TrigRand_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
827
{"out", (PyCFunction)TrigRand_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
 
828
{"stop", (PyCFunction)TrigRand_stop, METH_NOARGS, "Stops computing."},
 
829
{"setMin", (PyCFunction)TrigRand_setMin, METH_O, "Sets minimum possible value."},
 
830
{"setMax", (PyCFunction)TrigRand_setMax, METH_O, "Sets maximum possible value."},
 
831
{"setPort", (PyCFunction)TrigRand_setPort, METH_O, "Sets a new ramp time value."},
 
832
{"setMul", (PyCFunction)TrigRand_setMul, METH_O, "Sets oscillator mul factor."},
 
833
{"setAdd", (PyCFunction)TrigRand_setAdd, METH_O, "Sets oscillator add factor."},
 
834
{"setSub", (PyCFunction)TrigRand_setSub, METH_O, "Sets inverse add factor."},
 
835
{"setDiv", (PyCFunction)TrigRand_setDiv, METH_O, "Sets inverse mul factor."},
 
836
{NULL}  /* Sentinel */
 
837
};
 
838
 
 
839
static PyNumberMethods TrigRand_as_number = {
 
840
(binaryfunc)TrigRand_add,                         /*nb_add*/
 
841
(binaryfunc)TrigRand_sub,                         /*nb_subtract*/
 
842
(binaryfunc)TrigRand_multiply,                    /*nb_multiply*/
 
843
(binaryfunc)TrigRand_div,                                              /*nb_divide*/
 
844
0,                                              /*nb_remainder*/
 
845
0,                                              /*nb_divmod*/
 
846
0,                                              /*nb_power*/
 
847
0,                                              /*nb_neg*/
 
848
0,                                              /*nb_pos*/
 
849
0,                                              /*(unaryfunc)array_abs,*/
 
850
0,                                              /*nb_nonzero*/
 
851
0,                                              /*nb_invert*/
 
852
0,                                              /*nb_lshift*/
 
853
0,                                              /*nb_rshift*/
 
854
0,                                              /*nb_and*/
 
855
0,                                              /*nb_xor*/
 
856
0,                                              /*nb_or*/
 
857
0,                                              /*nb_coerce*/
 
858
0,                                              /*nb_int*/
 
859
0,                                              /*nb_long*/
 
860
0,                                              /*nb_float*/
 
861
0,                                              /*nb_oct*/
 
862
0,                                              /*nb_hex*/
 
863
(binaryfunc)TrigRand_inplace_add,                 /*inplace_add*/
 
864
(binaryfunc)TrigRand_inplace_sub,                 /*inplace_subtract*/
 
865
(binaryfunc)TrigRand_inplace_multiply,            /*inplace_multiply*/
 
866
(binaryfunc)TrigRand_inplace_div,                                              /*inplace_divide*/
 
867
0,                                              /*inplace_remainder*/
 
868
0,                                              /*inplace_power*/
 
869
0,                                              /*inplace_lshift*/
 
870
0,                                              /*inplace_rshift*/
 
871
0,                                              /*inplace_and*/
 
872
0,                                              /*inplace_xor*/
 
873
0,                                              /*inplace_or*/
 
874
0,                                              /*nb_floor_divide*/
 
875
0,                                              /*nb_true_divide*/
 
876
0,                                              /*nb_inplace_floor_divide*/
 
877
0,                                              /*nb_inplace_true_divide*/
 
878
0,                                              /* nb_index */
 
879
};
 
880
 
 
881
PyTypeObject TrigRandType = {
 
882
PyObject_HEAD_INIT(NULL)
 
883
0,                                              /*ob_size*/
 
884
"_pyo.TrigRand_base",                                   /*tp_name*/
 
885
sizeof(TrigRand),                                 /*tp_basicsize*/
 
886
0,                                              /*tp_itemsize*/
 
887
(destructor)TrigRand_dealloc,                     /*tp_dealloc*/
 
888
0,                                              /*tp_print*/
 
889
0,                                              /*tp_getattr*/
 
890
0,                                              /*tp_setattr*/
 
891
0,                                              /*tp_compare*/
 
892
0,                                              /*tp_repr*/
 
893
&TrigRand_as_number,                              /*tp_as_number*/
 
894
0,                                              /*tp_as_sequence*/
 
895
0,                                              /*tp_as_mapping*/
 
896
0,                                              /*tp_hash */
 
897
0,                                              /*tp_call*/
 
898
0,                                              /*tp_str*/
 
899
0,                                              /*tp_getattro*/
 
900
0,                                              /*tp_setattro*/
 
901
0,                                              /*tp_as_buffer*/
 
902
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
903
"TrigRand objects. Generates a new random value on a trigger signal.",           /* tp_doc */
 
904
(traverseproc)TrigRand_traverse,                  /* tp_traverse */
 
905
(inquiry)TrigRand_clear,                          /* tp_clear */
 
906
0,                                              /* tp_richcompare */
 
907
0,                                              /* tp_weaklistoffset */
 
908
0,                                              /* tp_iter */
 
909
0,                                              /* tp_iternext */
 
910
TrigRand_methods,                                 /* tp_methods */
 
911
TrigRand_members,                                 /* tp_members */
 
912
0,                                              /* tp_getset */
 
913
0,                                              /* tp_base */
 
914
0,                                              /* tp_dict */
 
915
0,                                              /* tp_descr_get */
 
916
0,                                              /* tp_descr_set */
 
917
0,                                              /* tp_dictoffset */
 
918
(initproc)TrigRand_init,                          /* tp_init */
 
919
0,                                              /* tp_alloc */
 
920
TrigRand_new,                                     /* tp_new */
 
921
};
 
922
 
 
923
/*********************************************************************************************/
 
924
/* TrigChoice ********************************************************************************/
 
925
/*********************************************************************************************/
 
926
typedef struct {
 
927
    pyo_audio_HEAD
 
928
    PyObject *input;
 
929
    Stream *input_stream;
 
930
    int chSize;
 
931
    MYFLT *choice;
 
932
    MYFLT value;
 
933
    MYFLT currentValue;
 
934
    MYFLT time;
 
935
    int timeStep;
 
936
    MYFLT stepVal;
 
937
    int timeCount;
 
938
    int modebuffer[2]; // need at least 2 slots for mul & add 
 
939
} TrigChoice;
 
940
 
 
941
static void
 
942
TrigChoice_generate(TrigChoice *self) {
 
943
    int i;
 
944
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
945
    
 
946
    for (i=0; i<self->bufsize; i++) {
 
947
        if (in[i] == 1) {
 
948
            self->timeCount = 0;
 
949
            self->value = self->choice[(int)((rand()/((MYFLT)(RAND_MAX))) * self->chSize)];
 
950
            if (self->time <= 0.0)
 
951
                self->currentValue = self->value;
 
952
            else
 
953
                self->stepVal = (self->value - self->currentValue) / self->timeStep;
 
954
        }
 
955
        
 
956
        if (self->timeCount == (self->timeStep - 1)) {
 
957
            self->currentValue = self->value;
 
958
            self->timeCount++;
 
959
        }
 
960
        else if (self->timeCount < self->timeStep) {
 
961
            self->currentValue += self->stepVal;
 
962
            self->timeCount++;
 
963
        }
 
964
        
 
965
        self->data[i] = self->currentValue;
 
966
    }
 
967
}
 
968
 
 
969
static void TrigChoice_postprocessing_ii(TrigChoice *self) { POST_PROCESSING_II };
 
970
static void TrigChoice_postprocessing_ai(TrigChoice *self) { POST_PROCESSING_AI };
 
971
static void TrigChoice_postprocessing_ia(TrigChoice *self) { POST_PROCESSING_IA };
 
972
static void TrigChoice_postprocessing_aa(TrigChoice *self) { POST_PROCESSING_AA };
 
973
static void TrigChoice_postprocessing_ireva(TrigChoice *self) { POST_PROCESSING_IREVA };
 
974
static void TrigChoice_postprocessing_areva(TrigChoice *self) { POST_PROCESSING_AREVA };
 
975
static void TrigChoice_postprocessing_revai(TrigChoice *self) { POST_PROCESSING_REVAI };
 
976
static void TrigChoice_postprocessing_revaa(TrigChoice *self) { POST_PROCESSING_REVAA };
 
977
static void TrigChoice_postprocessing_revareva(TrigChoice *self) { POST_PROCESSING_REVAREVA };
 
978
 
 
979
static void
 
980
TrigChoice_setProcMode(TrigChoice *self)
 
981
{
 
982
    int muladdmode;
 
983
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
984
    
 
985
    self->proc_func_ptr = TrigChoice_generate;
 
986
    
 
987
        switch (muladdmode) {
 
988
        case 0:        
 
989
            self->muladd_func_ptr = TrigChoice_postprocessing_ii;
 
990
            break;
 
991
        case 1:    
 
992
            self->muladd_func_ptr = TrigChoice_postprocessing_ai;
 
993
            break;
 
994
        case 2:    
 
995
            self->muladd_func_ptr = TrigChoice_postprocessing_revai;
 
996
            break;
 
997
        case 10:        
 
998
            self->muladd_func_ptr = TrigChoice_postprocessing_ia;
 
999
            break;
 
1000
        case 11:    
 
1001
            self->muladd_func_ptr = TrigChoice_postprocessing_aa;
 
1002
            break;
 
1003
        case 12:    
 
1004
            self->muladd_func_ptr = TrigChoice_postprocessing_revaa;
 
1005
            break;
 
1006
        case 20:        
 
1007
            self->muladd_func_ptr = TrigChoice_postprocessing_ireva;
 
1008
            break;
 
1009
        case 21:    
 
1010
            self->muladd_func_ptr = TrigChoice_postprocessing_areva;
 
1011
            break;
 
1012
        case 22:    
 
1013
            self->muladd_func_ptr = TrigChoice_postprocessing_revareva;
 
1014
            break;
 
1015
    }  
 
1016
}
 
1017
 
 
1018
static void
 
1019
TrigChoice_compute_next_data_frame(TrigChoice *self)
 
1020
{
 
1021
    (*self->proc_func_ptr)(self); 
 
1022
    (*self->muladd_func_ptr)(self);
 
1023
}
 
1024
 
 
1025
static int
 
1026
TrigChoice_traverse(TrigChoice *self, visitproc visit, void *arg)
 
1027
{
 
1028
    pyo_VISIT
 
1029
    Py_VISIT(self->input);
 
1030
    Py_VISIT(self->input_stream);
 
1031
    return 0;
 
1032
}
 
1033
 
 
1034
static int 
 
1035
TrigChoice_clear(TrigChoice *self)
 
1036
{
 
1037
    pyo_CLEAR
 
1038
    Py_CLEAR(self->input);
 
1039
    Py_CLEAR(self->input_stream);
 
1040
    return 0;
 
1041
}
 
1042
 
 
1043
static void
 
1044
TrigChoice_dealloc(TrigChoice* self)
 
1045
{
 
1046
    free(self->data);
 
1047
    free(self->choice);
 
1048
    TrigChoice_clear(self);
 
1049
    self->ob_type->tp_free((PyObject*)self);
 
1050
}
 
1051
 
 
1052
static PyObject * TrigChoice_deleteStream(TrigChoice *self) { DELETE_STREAM };
 
1053
 
 
1054
static PyObject *
 
1055
TrigChoice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
1056
{
 
1057
    int i;
 
1058
    TrigChoice *self;
 
1059
    self = (TrigChoice *)type->tp_alloc(type, 0);
 
1060
    
 
1061
    self->value = self->currentValue = 0.;
 
1062
    self->time = 0.0;
 
1063
    self->timeCount = 0;
 
1064
    self->stepVal = 0.0;
 
1065
        self->modebuffer[0] = 0;
 
1066
        self->modebuffer[1] = 0;
 
1067
    
 
1068
    INIT_OBJECT_COMMON
 
1069
    Stream_setFunctionPtr(self->stream, TrigChoice_compute_next_data_frame);
 
1070
    self->mode_func_ptr = TrigChoice_setProcMode;
 
1071
    return (PyObject *)self;
 
1072
}
 
1073
 
 
1074
static int
 
1075
TrigChoice_init(TrigChoice *self, PyObject *args, PyObject *kwds)
 
1076
{
 
1077
    MYFLT inittmp = 0.0;
 
1078
    PyObject *inputtmp, *input_streamtmp, *choicetmp=NULL, *multmp=NULL, *addtmp=NULL;
 
1079
    
 
1080
    static char *kwlist[] = {"input", "choice", "port", "init", "mul", "add", NULL};
 
1081
    
 
1082
    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_OO_FFOO, kwlist, &inputtmp, &choicetmp, &self->time, &inittmp, &multmp, &addtmp))
 
1083
        return -1; 
 
1084
    
 
1085
    INIT_INPUT_STREAM
 
1086
    
 
1087
    if (choicetmp) {
 
1088
        PyObject_CallMethod((PyObject *)self, "setChoice", "O", choicetmp);
 
1089
    }
 
1090
 
 
1091
    if (multmp) {
 
1092
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
1093
    }
 
1094
    
 
1095
    if (addtmp) {
 
1096
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
1097
    }
 
1098
    
 
1099
    Py_INCREF(self->stream);
 
1100
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
1101
    
 
1102
    Server_generateSeed((Server *)self->server, TRIGCHOICE_ID);
 
1103
 
 
1104
    self->value = self->currentValue = inittmp;
 
1105
    self->timeStep = (int)(self->time * self->sr);
 
1106
    
 
1107
    (*self->mode_func_ptr)(self);
 
1108
        
 
1109
    Py_INCREF(self);
 
1110
    return 0;
 
1111
}
 
1112
 
 
1113
static PyObject * TrigChoice_getServer(TrigChoice* self) { GET_SERVER };
 
1114
static PyObject * TrigChoice_getStream(TrigChoice* self) { GET_STREAM };
 
1115
static PyObject * TrigChoice_setMul(TrigChoice *self, PyObject *arg) { SET_MUL };       
 
1116
static PyObject * TrigChoice_setAdd(TrigChoice *self, PyObject *arg) { SET_ADD };       
 
1117
static PyObject * TrigChoice_setSub(TrigChoice *self, PyObject *arg) { SET_SUB };       
 
1118
static PyObject * TrigChoice_setDiv(TrigChoice *self, PyObject *arg) { SET_DIV };       
 
1119
 
 
1120
static PyObject * TrigChoice_play(TrigChoice *self, PyObject *args, PyObject *kwds) { PLAY };
 
1121
static PyObject * TrigChoice_out(TrigChoice *self, PyObject *args, PyObject *kwds) { OUT };
 
1122
static PyObject * TrigChoice_stop(TrigChoice *self) { STOP };
 
1123
 
 
1124
static PyObject * TrigChoice_multiply(TrigChoice *self, PyObject *arg) { MULTIPLY };
 
1125
static PyObject * TrigChoice_inplace_multiply(TrigChoice *self, PyObject *arg) { INPLACE_MULTIPLY };
 
1126
static PyObject * TrigChoice_add(TrigChoice *self, PyObject *arg) { ADD };
 
1127
static PyObject * TrigChoice_inplace_add(TrigChoice *self, PyObject *arg) { INPLACE_ADD };
 
1128
static PyObject * TrigChoice_sub(TrigChoice *self, PyObject *arg) { SUB };
 
1129
static PyObject * TrigChoice_inplace_sub(TrigChoice *self, PyObject *arg) { INPLACE_SUB };
 
1130
static PyObject * TrigChoice_div(TrigChoice *self, PyObject *arg) { DIV };
 
1131
static PyObject * TrigChoice_inplace_div(TrigChoice *self, PyObject *arg) { INPLACE_DIV };
 
1132
 
 
1133
static PyObject *
 
1134
TrigChoice_setChoice(TrigChoice *self, PyObject *arg)
 
1135
{
 
1136
    int i;
 
1137
        PyObject *tmp;
 
1138
        
 
1139
        if (! PyList_Check(arg)) {
 
1140
        PyErr_SetString(PyExc_TypeError, "The choice attribute must be a list.");
 
1141
                Py_INCREF(Py_None);
 
1142
                return Py_None;
 
1143
        }
 
1144
 
 
1145
    tmp = arg;
 
1146
    self->chSize = PyList_Size(tmp);
 
1147
    self->choice = (MYFLT *)realloc(self->choice, self->chSize * sizeof(MYFLT));
 
1148
    for (i=0; i<self->chSize; i++) {
 
1149
        self->choice[i] = PyFloat_AS_DOUBLE(PyNumber_Float(PyList_GET_ITEM(tmp, i)));
 
1150
    }
 
1151
    
 
1152
    (*self->mode_func_ptr)(self);
 
1153
    
 
1154
        Py_INCREF(Py_None);
 
1155
        return Py_None;
 
1156
}       
 
1157
 
 
1158
static PyObject *
 
1159
TrigChoice_setPort(TrigChoice *self, PyObject *arg)
 
1160
{
 
1161
        PyObject *tmp;
 
1162
        
 
1163
        if (arg == NULL) {
 
1164
                Py_INCREF(Py_None);
 
1165
                return Py_None;
 
1166
        }
 
1167
    
 
1168
        int isNumber = PyNumber_Check(arg);
 
1169
        
 
1170
        tmp = arg;
 
1171
        Py_INCREF(tmp);
 
1172
        if (isNumber == 1) {
 
1173
                self->time = PyFloat_AS_DOUBLE(PyNumber_Float(tmp));
 
1174
        self->timeStep = (int)(self->time * self->sr);
 
1175
        }
 
1176
    
 
1177
        Py_INCREF(Py_None);
 
1178
        return Py_None;
 
1179
}       
 
1180
 
 
1181
static PyMemberDef TrigChoice_members[] = {
 
1182
{"server", T_OBJECT_EX, offsetof(TrigChoice, server), 0, "Pyo server."},
 
1183
{"stream", T_OBJECT_EX, offsetof(TrigChoice, stream), 0, "Stream object."},
 
1184
{"input", T_OBJECT_EX, offsetof(TrigChoice, input), 0, "Input sound object."},
 
1185
{"mul", T_OBJECT_EX, offsetof(TrigChoice, mul), 0, "Mul factor."},
 
1186
{"add", T_OBJECT_EX, offsetof(TrigChoice, add), 0, "Add factor."},
 
1187
{NULL}  /* Sentinel */
 
1188
};
 
1189
 
 
1190
static PyMethodDef TrigChoice_methods[] = {
 
1191
{"getServer", (PyCFunction)TrigChoice_getServer, METH_NOARGS, "Returns server object."},
 
1192
{"_getStream", (PyCFunction)TrigChoice_getStream, METH_NOARGS, "Returns stream object."},
 
1193
{"deleteStream", (PyCFunction)TrigChoice_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
1194
{"play", (PyCFunction)TrigChoice_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
1195
{"out", (PyCFunction)TrigChoice_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
 
1196
{"stop", (PyCFunction)TrigChoice_stop, METH_NOARGS, "Stops computing."},
 
1197
{"setChoice", (PyCFunction)TrigChoice_setChoice, METH_O, "Sets possible values."},
 
1198
{"setPort", (PyCFunction)TrigChoice_setPort, METH_O, "Sets new portamento time."},
 
1199
{"setMul", (PyCFunction)TrigChoice_setMul, METH_O, "Sets oscillator mul factor."},
 
1200
{"setAdd", (PyCFunction)TrigChoice_setAdd, METH_O, "Sets oscillator add factor."},
 
1201
{"setSub", (PyCFunction)TrigChoice_setSub, METH_O, "Sets inverse add factor."},
 
1202
{"setDiv", (PyCFunction)TrigChoice_setDiv, METH_O, "Sets inverse mul factor."},
 
1203
{NULL}  /* Sentinel */
 
1204
};
 
1205
 
 
1206
static PyNumberMethods TrigChoice_as_number = {
 
1207
(binaryfunc)TrigChoice_add,                         /*nb_add*/
 
1208
(binaryfunc)TrigChoice_sub,                         /*nb_subtract*/
 
1209
(binaryfunc)TrigChoice_multiply,                    /*nb_multiply*/
 
1210
(binaryfunc)TrigChoice_div,                                              /*nb_divide*/
 
1211
0,                                              /*nb_remainder*/
 
1212
0,                                              /*nb_divmod*/
 
1213
0,                                              /*nb_power*/
 
1214
0,                                              /*nb_neg*/
 
1215
0,                                              /*nb_pos*/
 
1216
0,                                              /*(unaryfunc)array_abs,*/
 
1217
0,                                              /*nb_nonzero*/
 
1218
0,                                              /*nb_invert*/
 
1219
0,                                              /*nb_lshift*/
 
1220
0,                                              /*nb_rshift*/
 
1221
0,                                              /*nb_and*/
 
1222
0,                                              /*nb_xor*/
 
1223
0,                                              /*nb_or*/
 
1224
0,                                              /*nb_coerce*/
 
1225
0,                                              /*nb_int*/
 
1226
0,                                              /*nb_long*/
 
1227
0,                                              /*nb_float*/
 
1228
0,                                              /*nb_oct*/
 
1229
0,                                              /*nb_hex*/
 
1230
(binaryfunc)TrigChoice_inplace_add,                 /*inplace_add*/
 
1231
(binaryfunc)TrigChoice_inplace_sub,                 /*inplace_subtract*/
 
1232
(binaryfunc)TrigChoice_inplace_multiply,            /*inplace_multiply*/
 
1233
(binaryfunc)TrigChoice_inplace_div,                                              /*inplace_divide*/
 
1234
0,                                              /*inplace_remainder*/
 
1235
0,                                              /*inplace_power*/
 
1236
0,                                              /*inplace_lshift*/
 
1237
0,                                              /*inplace_rshift*/
 
1238
0,                                              /*inplace_and*/
 
1239
0,                                              /*inplace_xor*/
 
1240
0,                                              /*inplace_or*/
 
1241
0,                                              /*nb_floor_divide*/
 
1242
0,                                              /*nb_true_divide*/
 
1243
0,                                              /*nb_inplace_floor_divide*/
 
1244
0,                                              /*nb_inplace_true_divide*/
 
1245
0,                                              /* nb_index */
 
1246
};
 
1247
 
 
1248
PyTypeObject TrigChoiceType = {
 
1249
PyObject_HEAD_INIT(NULL)
 
1250
0,                                              /*ob_size*/
 
1251
"_pyo.TrigChoice_base",                                   /*tp_name*/
 
1252
sizeof(TrigChoice),                                 /*tp_basicsize*/
 
1253
0,                                              /*tp_itemsize*/
 
1254
(destructor)TrigChoice_dealloc,                     /*tp_dealloc*/
 
1255
0,                                              /*tp_print*/
 
1256
0,                                              /*tp_getattr*/
 
1257
0,                                              /*tp_setattr*/
 
1258
0,                                              /*tp_compare*/
 
1259
0,                                              /*tp_repr*/
 
1260
&TrigChoice_as_number,                              /*tp_as_number*/
 
1261
0,                                              /*tp_as_sequence*/
 
1262
0,                                              /*tp_as_mapping*/
 
1263
0,                                              /*tp_hash */
 
1264
0,                                              /*tp_call*/
 
1265
0,                                              /*tp_str*/
 
1266
0,                                              /*tp_getattro*/
 
1267
0,                                              /*tp_setattro*/
 
1268
0,                                              /*tp_as_buffer*/
 
1269
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
1270
"TrigChoice objects. Generates a new random value pick in a user choice on a trigger signal.",           /* tp_doc */
 
1271
(traverseproc)TrigChoice_traverse,                  /* tp_traverse */
 
1272
(inquiry)TrigChoice_clear,                          /* tp_clear */
 
1273
0,                                              /* tp_richcompare */
 
1274
0,                                              /* tp_weaklistoffset */
 
1275
0,                                              /* tp_iter */
 
1276
0,                                              /* tp_iternext */
 
1277
TrigChoice_methods,                                 /* tp_methods */
 
1278
TrigChoice_members,                                 /* tp_members */
 
1279
0,                                              /* tp_getset */
 
1280
0,                                              /* tp_base */
 
1281
0,                                              /* tp_dict */
 
1282
0,                                              /* tp_descr_get */
 
1283
0,                                              /* tp_descr_set */
 
1284
0,                                              /* tp_dictoffset */
 
1285
(initproc)TrigChoice_init,                          /* tp_init */
 
1286
0,                                              /* tp_alloc */
 
1287
TrigChoice_new,                                     /* tp_new */
 
1288
};
 
1289
 
 
1290
/*********************************************************************************************/
 
1291
/* TrigFunc ********************************************************************************/
 
1292
/*********************************************************************************************/
 
1293
typedef struct {
 
1294
    pyo_audio_HEAD
 
1295
    PyObject *input;
 
1296
    PyObject *arg;
 
1297
    Stream *input_stream;
 
1298
    PyObject *func;
 
1299
} TrigFunc;
 
1300
 
 
1301
static void
 
1302
TrigFunc_generate(TrigFunc *self) {
 
1303
    int i;
 
1304
    PyObject *tuple, *result;
 
1305
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
1306
    
 
1307
    for (i=0; i<self->bufsize; i++) {
 
1308
        if (in[i] == 1) {
 
1309
            if (self->arg == Py_None) {
 
1310
                result = PyObject_Call(self->func, PyTuple_New(0), NULL);
 
1311
                if (result == NULL) {
 
1312
                    PyErr_Print();
 
1313
                    return;
 
1314
                }
 
1315
            }
 
1316
            else {
 
1317
                tuple = PyTuple_New(1);
 
1318
                PyTuple_SET_ITEM(tuple, 0, self->arg);
 
1319
                result = PyObject_Call(self->func, tuple, NULL);                
 
1320
                if (result == NULL) {
 
1321
                    PyErr_Print();
 
1322
                    return;
 
1323
                }
 
1324
            }
 
1325
        }    
 
1326
    }
 
1327
}
 
1328
 
 
1329
static void
 
1330
TrigFunc_compute_next_data_frame(TrigFunc *self)
 
1331
{
 
1332
    TrigFunc_generate(self); 
 
1333
}
 
1334
 
 
1335
static int
 
1336
TrigFunc_traverse(TrigFunc *self, visitproc visit, void *arg)
 
1337
{
 
1338
    pyo_VISIT
 
1339
    Py_VISIT(self->input);
 
1340
    Py_VISIT(self->input_stream);
 
1341
    Py_VISIT(self->func);
 
1342
    Py_VISIT(self->arg);
 
1343
    return 0;
 
1344
}
 
1345
 
 
1346
static int 
 
1347
TrigFunc_clear(TrigFunc *self)
 
1348
{
 
1349
    pyo_CLEAR
 
1350
    Py_CLEAR(self->input);
 
1351
    Py_CLEAR(self->input_stream);
 
1352
    Py_CLEAR(self->func);
 
1353
    Py_CLEAR(self->arg);
 
1354
    return 0;
 
1355
}
 
1356
 
 
1357
static void
 
1358
TrigFunc_dealloc(TrigFunc* self)
 
1359
{
 
1360
    free(self->data);
 
1361
    TrigFunc_clear(self);
 
1362
    self->ob_type->tp_free((PyObject*)self);
 
1363
}
 
1364
 
 
1365
static PyObject * TrigFunc_deleteStream(TrigFunc *self) { DELETE_STREAM };
 
1366
 
 
1367
static PyObject *
 
1368
TrigFunc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
1369
{
 
1370
    int i;
 
1371
    TrigFunc *self;
 
1372
    self = (TrigFunc *)type->tp_alloc(type, 0);
 
1373
 
 
1374
    self->arg = Py_None;
 
1375
 
 
1376
    INIT_OBJECT_COMMON
 
1377
    Stream_setFunctionPtr(self->stream, TrigFunc_compute_next_data_frame);
 
1378
    return (PyObject *)self;
 
1379
}
 
1380
 
 
1381
static int
 
1382
TrigFunc_init(TrigFunc *self, PyObject *args, PyObject *kwds)
 
1383
{
 
1384
    PyObject *inputtmp, *input_streamtmp, *functmp=NULL, *argtmp=NULL;
 
1385
    
 
1386
    static char *kwlist[] = {"input", "function", "arg", NULL};
 
1387
    
 
1388
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist, &inputtmp, &functmp, &argtmp))
 
1389
        return -1; 
 
1390
    
 
1391
    INIT_INPUT_STREAM
 
1392
    
 
1393
    if (functmp) {
 
1394
        PyObject_CallMethod((PyObject *)self, "setFunction", "O", functmp);
 
1395
    }
 
1396
 
 
1397
    if (argtmp) {
 
1398
        PyObject_CallMethod((PyObject *)self, "setArg", "O", argtmp);
 
1399
    }
 
1400
    
 
1401
    Py_INCREF(self->stream);
 
1402
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
1403
    
 
1404
    Py_INCREF(self);
 
1405
    return 0;
 
1406
}
 
1407
 
 
1408
static PyObject * TrigFunc_getServer(TrigFunc* self) { GET_SERVER };
 
1409
static PyObject * TrigFunc_getStream(TrigFunc* self) { GET_STREAM };
 
1410
 
 
1411
static PyObject * TrigFunc_play(TrigFunc *self, PyObject *args, PyObject *kwds) { PLAY };
 
1412
static PyObject * TrigFunc_stop(TrigFunc *self) { STOP };
 
1413
 
 
1414
static PyObject *
 
1415
TrigFunc_setFunction(TrigFunc *self, PyObject *arg)
 
1416
{
 
1417
        PyObject *tmp;
 
1418
        
 
1419
        if (! PyCallable_Check(arg)) {
 
1420
        PyErr_SetString(PyExc_TypeError, "The function attribute must be callable.");
 
1421
                Py_INCREF(Py_None);
 
1422
                return Py_None;
 
1423
        }
 
1424
    
 
1425
    tmp = arg;
 
1426
    Py_XDECREF(self->func);
 
1427
    Py_INCREF(tmp);
 
1428
    self->func = tmp;
 
1429
  
 
1430
        Py_INCREF(Py_None);
 
1431
        return Py_None;
 
1432
}       
 
1433
 
 
1434
static PyObject *
 
1435
TrigFunc_setArg(TrigFunc *self, PyObject *arg)
 
1436
{
 
1437
        PyObject *tmp;
 
1438
 
 
1439
    tmp = arg;
 
1440
    Py_DECREF(self->arg);
 
1441
    Py_INCREF(tmp);
 
1442
    self->arg = tmp;
 
1443
    
 
1444
        Py_INCREF(Py_None);
 
1445
        return Py_None;
 
1446
}       
 
1447
 
 
1448
static PyMemberDef TrigFunc_members[] = {
 
1449
{"server", T_OBJECT_EX, offsetof(TrigFunc, server), 0, "Pyo server."},
 
1450
{"stream", T_OBJECT_EX, offsetof(TrigFunc, stream), 0, "Stream object."},
 
1451
{"input", T_OBJECT_EX, offsetof(TrigFunc, input), 0, "Input sound object."},
 
1452
{NULL}  /* Sentinel */
 
1453
};
 
1454
 
 
1455
static PyMethodDef TrigFunc_methods[] = {
 
1456
{"getServer", (PyCFunction)TrigFunc_getServer, METH_NOARGS, "Returns server object."},
 
1457
{"_getStream", (PyCFunction)TrigFunc_getStream, METH_NOARGS, "Returns stream object."},
 
1458
{"deleteStream", (PyCFunction)TrigFunc_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
1459
{"play", (PyCFunction)TrigFunc_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
1460
{"stop", (PyCFunction)TrigFunc_stop, METH_NOARGS, "Stops computing."},
 
1461
{"setFunction", (PyCFunction)TrigFunc_setFunction, METH_O, "Sets function to be called."},
 
1462
{"setArg", (PyCFunction)TrigFunc_setArg, METH_O, "Sets function's argument."},
 
1463
{NULL}  /* Sentinel */
 
1464
};
 
1465
 
 
1466
PyTypeObject TrigFuncType = {
 
1467
PyObject_HEAD_INIT(NULL)
 
1468
0,                                              /*ob_size*/
 
1469
"_pyo.TrigFunc_base",                                   /*tp_name*/
 
1470
sizeof(TrigFunc),                                 /*tp_basicsize*/
 
1471
0,                                              /*tp_itemsize*/
 
1472
(destructor)TrigFunc_dealloc,                     /*tp_dealloc*/
 
1473
0,                                              /*tp_print*/
 
1474
0,                                              /*tp_getattr*/
 
1475
0,                                              /*tp_setattr*/
 
1476
0,                                              /*tp_compare*/
 
1477
0,                                              /*tp_repr*/
 
1478
0,                              /*tp_as_number*/
 
1479
0,                                              /*tp_as_sequence*/
 
1480
0,                                              /*tp_as_mapping*/
 
1481
0,                                              /*tp_hash */
 
1482
0,                                              /*tp_call*/
 
1483
0,                                              /*tp_str*/
 
1484
0,                                              /*tp_getattro*/
 
1485
0,                                              /*tp_setattro*/
 
1486
0,                                              /*tp_as_buffer*/
 
1487
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
1488
"TrigFunc objects. Called a function on a trigger signal.",           /* tp_doc */
 
1489
(traverseproc)TrigFunc_traverse,                  /* tp_traverse */
 
1490
(inquiry)TrigFunc_clear,                          /* tp_clear */
 
1491
0,                                              /* tp_richcompare */
 
1492
0,                                              /* tp_weaklistoffset */
 
1493
0,                                              /* tp_iter */
 
1494
0,                                              /* tp_iternext */
 
1495
TrigFunc_methods,                                 /* tp_methods */
 
1496
TrigFunc_members,                                 /* tp_members */
 
1497
0,                                              /* tp_getset */
 
1498
0,                                              /* tp_base */
 
1499
0,                                              /* tp_dict */
 
1500
0,                                              /* tp_descr_get */
 
1501
0,                                              /* tp_descr_set */
 
1502
0,                                              /* tp_dictoffset */
 
1503
(initproc)TrigFunc_init,                          /* tp_init */
 
1504
0,                                              /* tp_alloc */
 
1505
TrigFunc_new,                                     /* tp_new */
 
1506
};
 
1507
 
 
1508
/*********************************************************************************************/
 
1509
/* TrigEnv *********************************************************************************/
 
1510
/*********************************************************************************************/
 
1511
typedef struct {
 
1512
    pyo_audio_HEAD
 
1513
    PyObject *table;
 
1514
    PyObject *input;
 
1515
    Stream *input_stream;
 
1516
    PyObject *dur;
 
1517
    Stream *dur_stream;
 
1518
    int modebuffer[3];
 
1519
    int active;
 
1520
    MYFLT current_dur; // duration in samples
 
1521
    MYFLT inc; // table size / current_dur
 
1522
    double pointerPos; // reading position in sample
 
1523
    MYFLT *trigsBuffer;
 
1524
    TriggerStream *trig_stream;
 
1525
    int interp; /* 0 = default to 2, 1 = nointerp, 2 = linear, 3 = cos, 4 = cubic */
 
1526
    MYFLT (*interp_func_ptr)(MYFLT *, int, MYFLT, int);
 
1527
} TrigEnv;
 
1528
 
 
1529
static void
 
1530
TrigEnv_readframes_i(TrigEnv *self) {
 
1531
    MYFLT fpart;
 
1532
    int i, ipart;
 
1533
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
1534
    MYFLT *tablelist = TableStream_getData(self->table);
 
1535
    int size = TableStream_getSize(self->table);
 
1536
    
 
1537
    for (i=0; i<self->bufsize; i++) {
 
1538
        self->trigsBuffer[i] = 0.0;
 
1539
        if (in[i] == 1) {
 
1540
            MYFLT dur = PyFloat_AS_DOUBLE(self->dur);
 
1541
            self->current_dur = self->sr * dur;
 
1542
            if (self->current_dur <= 0.0) {
 
1543
                self->current_dur = 0.0;
 
1544
                self->inc = 0.0;
 
1545
                self->active = 0;
 
1546
            }
 
1547
            else {
 
1548
                self->inc = (MYFLT)size / self->current_dur;
 
1549
                self->active = 1;
 
1550
            }
 
1551
            self->pointerPos = 0.;
 
1552
        }
 
1553
        if (self->active == 1) {
 
1554
            ipart = (int)self->pointerPos;
 
1555
            fpart = self->pointerPos - ipart;
 
1556
            self->data[i] = (*self->interp_func_ptr)(tablelist, ipart, fpart, size);
 
1557
            self->pointerPos += self->inc;
 
1558
        }
 
1559
        else
 
1560
            self->data[i] = 0.;
 
1561
        
 
1562
        if (self->pointerPos > size && self->active == 1) {
 
1563
            self->trigsBuffer[i] = 1.0;
 
1564
            self->active = 0;
 
1565
        }    
 
1566
    }
 
1567
}
 
1568
 
 
1569
static void
 
1570
TrigEnv_readframes_a(TrigEnv *self) {
 
1571
    MYFLT fpart, dur;
 
1572
    int i, ipart;
 
1573
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
1574
    MYFLT *dur_st = Stream_getData((Stream *)self->dur_stream);
 
1575
    MYFLT *tablelist = TableStream_getData(self->table);
 
1576
    int size = TableStream_getSize(self->table);
 
1577
    
 
1578
    for (i=0; i<self->bufsize; i++) {
 
1579
        self->trigsBuffer[i] = 0.0;
 
1580
        if (in[i] == 1) {
 
1581
            dur = dur_st[i];
 
1582
            self->current_dur = self->sr * dur;
 
1583
            if (self->current_dur <= 0.0) {
 
1584
                self->current_dur = 0.0;
 
1585
                self->inc = 0.0;
 
1586
                self->active = 0;
 
1587
            }
 
1588
            else {
 
1589
                self->inc = (MYFLT)size / self->current_dur;
 
1590
                self->active = 1;
 
1591
            }
 
1592
            self->pointerPos = 0.;
 
1593
        }
 
1594
        if (self->active == 1) {
 
1595
            ipart = (int)self->pointerPos;
 
1596
            fpart = self->pointerPos - ipart;
 
1597
            self->data[i] = (*self->interp_func_ptr)(tablelist, ipart, fpart, size);
 
1598
            self->pointerPos += self->inc;
 
1599
        }
 
1600
        else
 
1601
            self->data[i] = 0.;
 
1602
        
 
1603
        if (self->pointerPos > size && self->active == 1) {
 
1604
            self->trigsBuffer[i] = 1.0;
 
1605
            self->active = 0;
 
1606
        }
 
1607
    }
 
1608
}
 
1609
 
 
1610
static void TrigEnv_postprocessing_ii(TrigEnv *self) { POST_PROCESSING_II };
 
1611
static void TrigEnv_postprocessing_ai(TrigEnv *self) { POST_PROCESSING_AI };
 
1612
static void TrigEnv_postprocessing_ia(TrigEnv *self) { POST_PROCESSING_IA };
 
1613
static void TrigEnv_postprocessing_aa(TrigEnv *self) { POST_PROCESSING_AA };
 
1614
static void TrigEnv_postprocessing_ireva(TrigEnv *self) { POST_PROCESSING_IREVA };
 
1615
static void TrigEnv_postprocessing_areva(TrigEnv *self) { POST_PROCESSING_AREVA };
 
1616
static void TrigEnv_postprocessing_revai(TrigEnv *self) { POST_PROCESSING_REVAI };
 
1617
static void TrigEnv_postprocessing_revaa(TrigEnv *self) { POST_PROCESSING_REVAA };
 
1618
static void TrigEnv_postprocessing_revareva(TrigEnv *self) { POST_PROCESSING_REVAREVA };
 
1619
 
 
1620
static void
 
1621
TrigEnv_setProcMode(TrigEnv *self)
 
1622
{
 
1623
    int procmode, muladdmode;
 
1624
    procmode = self->modebuffer[2];
 
1625
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
1626
    
 
1627
        switch (procmode) {
 
1628
        case 0:        
 
1629
            self->proc_func_ptr = TrigEnv_readframes_i;
 
1630
            break;
 
1631
        case 1:    
 
1632
            self->proc_func_ptr = TrigEnv_readframes_a;
 
1633
            break;
 
1634
    } 
 
1635
        switch (muladdmode) {
 
1636
        case 0:        
 
1637
            self->muladd_func_ptr = TrigEnv_postprocessing_ii;
 
1638
            break;
 
1639
        case 1:    
 
1640
            self->muladd_func_ptr = TrigEnv_postprocessing_ai;
 
1641
            break;
 
1642
        case 2:    
 
1643
            self->muladd_func_ptr = TrigEnv_postprocessing_revai;
 
1644
            break;
 
1645
        case 10:        
 
1646
            self->muladd_func_ptr = TrigEnv_postprocessing_ia;
 
1647
            break;
 
1648
        case 11:    
 
1649
            self->muladd_func_ptr = TrigEnv_postprocessing_aa;
 
1650
            break;
 
1651
        case 12:    
 
1652
            self->muladd_func_ptr = TrigEnv_postprocessing_revaa;
 
1653
            break;
 
1654
        case 20:        
 
1655
            self->muladd_func_ptr = TrigEnv_postprocessing_ireva;
 
1656
            break;
 
1657
        case 21:    
 
1658
            self->muladd_func_ptr = TrigEnv_postprocessing_areva;
 
1659
            break;
 
1660
        case 22:    
 
1661
            self->muladd_func_ptr = TrigEnv_postprocessing_revareva;
 
1662
            break;
 
1663
    } 
 
1664
}
 
1665
 
 
1666
static void
 
1667
TrigEnv_compute_next_data_frame(TrigEnv *self)
 
1668
{
 
1669
    (*self->proc_func_ptr)(self); 
 
1670
    (*self->muladd_func_ptr)(self);
 
1671
}
 
1672
 
 
1673
static int
 
1674
TrigEnv_traverse(TrigEnv *self, visitproc visit, void *arg)
 
1675
{
 
1676
    pyo_VISIT
 
1677
    Py_VISIT(self->table);
 
1678
    Py_VISIT(self->input);
 
1679
    Py_VISIT(self->input_stream);
 
1680
    Py_VISIT(self->dur);    
 
1681
    Py_VISIT(self->dur_stream);    
 
1682
    Py_VISIT(self->trig_stream);    
 
1683
    return 0;
 
1684
}
 
1685
 
 
1686
static int 
 
1687
TrigEnv_clear(TrigEnv *self)
 
1688
{
 
1689
    pyo_CLEAR
 
1690
    Py_CLEAR(self->table);
 
1691
    Py_CLEAR(self->input);
 
1692
    Py_CLEAR(self->input_stream);
 
1693
    Py_CLEAR(self->dur);    
 
1694
    Py_CLEAR(self->dur_stream);    
 
1695
    Py_CLEAR(self->trig_stream);    
 
1696
    return 0;
 
1697
}
 
1698
 
 
1699
static void
 
1700
TrigEnv_dealloc(TrigEnv* self)
 
1701
{
 
1702
    free(self->data);
 
1703
    free(self->trigsBuffer);
 
1704
    TrigEnv_clear(self);
 
1705
    self->ob_type->tp_free((PyObject*)self);
 
1706
}
 
1707
 
 
1708
static PyObject * TrigEnv_deleteStream(TrigEnv *self) { DELETE_STREAM };
 
1709
 
 
1710
static PyObject *
 
1711
TrigEnv_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
1712
{
 
1713
    int i;
 
1714
    TrigEnv *self;
 
1715
    self = (TrigEnv *)type->tp_alloc(type, 0);
 
1716
    
 
1717
        self->modebuffer[0] = 0;
 
1718
        self->modebuffer[1] = 0;
 
1719
        self->modebuffer[2] = 0;
 
1720
    
 
1721
    self->pointerPos = 0.;
 
1722
    self->active = 0;
 
1723
    self->interp = 2;
 
1724
    
 
1725
    INIT_OBJECT_COMMON
 
1726
    Stream_setFunctionPtr(self->stream, TrigEnv_compute_next_data_frame);
 
1727
    self->mode_func_ptr = TrigEnv_setProcMode;
 
1728
 
 
1729
    self->dur = PyFloat_FromDouble(1.);
 
1730
    self->current_dur = self->sr;
 
1731
 
 
1732
    return (PyObject *)self;
 
1733
}
 
1734
 
 
1735
static int
 
1736
TrigEnv_init(TrigEnv *self, PyObject *args, PyObject *kwds)
 
1737
{
 
1738
    int i;
 
1739
    PyObject *inputtmp, *input_streamtmp, *tabletmp, *durtmp=NULL, *multmp=NULL, *addtmp=NULL;
 
1740
    
 
1741
    static char *kwlist[] = {"input", "table", "dur", "interp", "mul", "add", NULL};
 
1742
    
 
1743
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OiOO", kwlist, &inputtmp, &tabletmp, &durtmp, &self->interp, &multmp, &addtmp))
 
1744
        return -1; 
 
1745
 
 
1746
    INIT_INPUT_STREAM
 
1747
    
 
1748
    Py_XDECREF(self->table);
 
1749
    self->table = PyObject_CallMethod((PyObject *)tabletmp, "getTableStream", "");
 
1750
    
 
1751
    if (durtmp) {
 
1752
        PyObject_CallMethod((PyObject *)self, "setDur", "O", durtmp);
 
1753
    }
 
1754
    
 
1755
    if (multmp) {
 
1756
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
1757
    }
 
1758
    
 
1759
    if (addtmp) {
 
1760
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
1761
    }
 
1762
    
 
1763
    Py_INCREF(self->stream);
 
1764
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
1765
 
 
1766
    self->trigsBuffer = (MYFLT *)realloc(self->trigsBuffer, self->bufsize * sizeof(MYFLT));
 
1767
    
 
1768
    for (i=0; i<self->bufsize; i++) {
 
1769
        self->trigsBuffer[i] = 0.0;
 
1770
    }    
 
1771
    
 
1772
    MAKE_NEW_TRIGGER_STREAM(self->trig_stream, &TriggerStreamType, NULL);
 
1773
    TriggerStream_setData(self->trig_stream, self->trigsBuffer);
 
1774
    
 
1775
    (*self->mode_func_ptr)(self);
 
1776
    
 
1777
    SET_INTERP_POINTER
 
1778
 
 
1779
    Py_INCREF(self);
 
1780
    return 0;
 
1781
}
 
1782
 
 
1783
static PyObject * TrigEnv_getServer(TrigEnv* self) { GET_SERVER };
 
1784
static PyObject * TrigEnv_getStream(TrigEnv* self) { GET_STREAM };
 
1785
static PyObject * TrigEnv_getTriggerStream(TrigEnv* self) { GET_TRIGGER_STREAM };
 
1786
static PyObject * TrigEnv_setMul(TrigEnv *self, PyObject *arg) { SET_MUL };     
 
1787
static PyObject * TrigEnv_setAdd(TrigEnv *self, PyObject *arg) { SET_ADD };     
 
1788
static PyObject * TrigEnv_setSub(TrigEnv *self, PyObject *arg) { SET_SUB };     
 
1789
static PyObject * TrigEnv_setDiv(TrigEnv *self, PyObject *arg) { SET_DIV };     
 
1790
 
 
1791
static PyObject * TrigEnv_play(TrigEnv *self, PyObject *args, PyObject *kwds) { PLAY };
 
1792
static PyObject * TrigEnv_out(TrigEnv *self, PyObject *args, PyObject *kwds) { OUT };
 
1793
static PyObject * TrigEnv_stop(TrigEnv *self) { STOP };
 
1794
 
 
1795
static PyObject * TrigEnv_multiply(TrigEnv *self, PyObject *arg) { MULTIPLY };
 
1796
static PyObject * TrigEnv_inplace_multiply(TrigEnv *self, PyObject *arg) { INPLACE_MULTIPLY };
 
1797
static PyObject * TrigEnv_add(TrigEnv *self, PyObject *arg) { ADD };
 
1798
static PyObject * TrigEnv_inplace_add(TrigEnv *self, PyObject *arg) { INPLACE_ADD };
 
1799
static PyObject * TrigEnv_sub(TrigEnv *self, PyObject *arg) { SUB };
 
1800
static PyObject * TrigEnv_inplace_sub(TrigEnv *self, PyObject *arg) { INPLACE_SUB };
 
1801
static PyObject * TrigEnv_div(TrigEnv *self, PyObject *arg) { DIV };
 
1802
static PyObject * TrigEnv_inplace_div(TrigEnv *self, PyObject *arg) { INPLACE_DIV };
 
1803
 
 
1804
static PyObject *
 
1805
TrigEnv_getTable(TrigEnv* self)
 
1806
{
 
1807
    Py_INCREF(self->table);
 
1808
    return self->table;
 
1809
};
 
1810
 
 
1811
static PyObject *
 
1812
TrigEnv_setTable(TrigEnv *self, PyObject *arg)
 
1813
{
 
1814
        PyObject *tmp;
 
1815
        
 
1816
        if (arg == NULL) {
 
1817
                Py_INCREF(Py_None);
 
1818
                return Py_None;
 
1819
        }
 
1820
    
 
1821
        tmp = arg;
 
1822
        Py_DECREF(self->table);
 
1823
    self->table = PyObject_CallMethod((PyObject *)tmp, "getTableStream", "");
 
1824
    
 
1825
        Py_INCREF(Py_None);
 
1826
        return Py_None;
 
1827
}       
 
1828
 
 
1829
static PyObject *
 
1830
TrigEnv_setDur(TrigEnv *self, PyObject *arg)
 
1831
{
 
1832
        PyObject *tmp, *streamtmp;
 
1833
        
 
1834
        if (arg == NULL) {
 
1835
                Py_INCREF(Py_None);
 
1836
                return Py_None;
 
1837
        }
 
1838
    
 
1839
        int isNumber = PyNumber_Check(arg);
 
1840
        
 
1841
        tmp = arg;
 
1842
        Py_INCREF(tmp);
 
1843
        Py_DECREF(self->dur);
 
1844
        if (isNumber == 1) {
 
1845
                self->dur = PyNumber_Float(tmp);
 
1846
        self->modebuffer[2] = 0;
 
1847
        }
 
1848
        else {
 
1849
                self->dur = tmp;
 
1850
        streamtmp = PyObject_CallMethod((PyObject *)self->dur, "_getStream", NULL);
 
1851
        Py_INCREF(streamtmp);
 
1852
        Py_XDECREF(self->dur_stream);
 
1853
        self->dur_stream = (Stream *)streamtmp;
 
1854
                self->modebuffer[2] = 1;
 
1855
        }
 
1856
    
 
1857
    (*self->mode_func_ptr)(self);
 
1858
    
 
1859
        Py_INCREF(Py_None);
 
1860
        return Py_None;
 
1861
}       
 
1862
 
 
1863
static PyObject *
 
1864
TrigEnv_setInterp(TrigEnv *self, PyObject *arg)
 
1865
{
 
1866
        if (arg == NULL) {
 
1867
                Py_INCREF(Py_None);
 
1868
                return Py_None;
 
1869
        }
 
1870
    
 
1871
    int isNumber = PyNumber_Check(arg);
 
1872
    
 
1873
        if (isNumber == 1) {
 
1874
                self->interp = PyInt_AsLong(PyNumber_Int(arg));
 
1875
    }  
 
1876
    
 
1877
    SET_INTERP_POINTER
 
1878
    
 
1879
    Py_INCREF(Py_None);
 
1880
    return Py_None;
 
1881
}
 
1882
 
 
1883
static PyMemberDef TrigEnv_members[] = {
 
1884
{"server", T_OBJECT_EX, offsetof(TrigEnv, server), 0, "Pyo server."},
 
1885
{"stream", T_OBJECT_EX, offsetof(TrigEnv, stream), 0, "Stream object."},
 
1886
{"trig_stream", T_OBJECT_EX, offsetof(TrigEnv, trig_stream), 0, "Trigger Stream object."},
 
1887
{"table", T_OBJECT_EX, offsetof(TrigEnv, table), 0, "Envelope table."},
 
1888
{"dur", T_OBJECT_EX, offsetof(TrigEnv, dur), 0, "Envelope duration in seconds."},
 
1889
{"mul", T_OBJECT_EX, offsetof(TrigEnv, mul), 0, "Mul factor."},
 
1890
{"add", T_OBJECT_EX, offsetof(TrigEnv, add), 0, "Add factor."},
 
1891
{NULL}  /* Sentinel */
 
1892
};
 
1893
 
 
1894
static PyMethodDef TrigEnv_methods[] = {
 
1895
{"getTable", (PyCFunction)TrigEnv_getTable, METH_NOARGS, "Returns waveform table object."},
 
1896
{"getServer", (PyCFunction)TrigEnv_getServer, METH_NOARGS, "Returns server object."},
 
1897
{"_getStream", (PyCFunction)TrigEnv_getStream, METH_NOARGS, "Returns stream object."},
 
1898
{"_getTriggerStream", (PyCFunction)TrigEnv_getTriggerStream, METH_NOARGS, "Returns trigger stream object."},
 
1899
{"deleteStream", (PyCFunction)TrigEnv_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
1900
{"play", (PyCFunction)TrigEnv_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
1901
{"out", (PyCFunction)TrigEnv_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
 
1902
{"stop", (PyCFunction)TrigEnv_stop, METH_NOARGS, "Stops computing."},
 
1903
{"setTable", (PyCFunction)TrigEnv_setTable, METH_O, "Sets envelope table."},
 
1904
{"setDur", (PyCFunction)TrigEnv_setDur, METH_O, "Sets envelope duration in second."},
 
1905
{"setInterp", (PyCFunction)TrigEnv_setInterp, METH_O, "Sets oscillator interpolation mode."},
 
1906
{"setMul", (PyCFunction)TrigEnv_setMul, METH_O, "Sets mul factor."},
 
1907
{"setAdd", (PyCFunction)TrigEnv_setAdd, METH_O, "Sets add factor."},
 
1908
{"setSub", (PyCFunction)TrigEnv_setSub, METH_O, "Sets inverse add factor."},
 
1909
{"setDiv", (PyCFunction)TrigEnv_setDiv, METH_O, "Sets inverse mul factor."},
 
1910
{NULL}  /* Sentinel */
 
1911
};
 
1912
 
 
1913
static PyNumberMethods TrigEnv_as_number = {
 
1914
(binaryfunc)TrigEnv_add,                      /*nb_add*/
 
1915
(binaryfunc)TrigEnv_sub,                 /*nb_subtract*/
 
1916
(binaryfunc)TrigEnv_multiply,                 /*nb_multiply*/
 
1917
(binaryfunc)TrigEnv_div,                   /*nb_divide*/
 
1918
0,                /*nb_remainder*/
 
1919
0,                   /*nb_divmod*/
 
1920
0,                   /*nb_power*/
 
1921
0,                  /*nb_neg*/
 
1922
0,                /*nb_pos*/
 
1923
0,                  /*(unaryfunc)array_abs,*/
 
1924
0,                    /*nb_nonzero*/
 
1925
0,                    /*nb_invert*/
 
1926
0,               /*nb_lshift*/
 
1927
0,              /*nb_rshift*/
 
1928
0,              /*nb_and*/
 
1929
0,              /*nb_xor*/
 
1930
0,               /*nb_or*/
 
1931
0,                                          /*nb_coerce*/
 
1932
0,                       /*nb_int*/
 
1933
0,                      /*nb_long*/
 
1934
0,                     /*nb_float*/
 
1935
0,                       /*nb_oct*/
 
1936
0,                       /*nb_hex*/
 
1937
(binaryfunc)TrigEnv_inplace_add,              /*inplace_add*/
 
1938
(binaryfunc)TrigEnv_inplace_sub,         /*inplace_subtract*/
 
1939
(binaryfunc)TrigEnv_inplace_multiply,         /*inplace_multiply*/
 
1940
(binaryfunc)TrigEnv_inplace_div,           /*inplace_divide*/
 
1941
0,        /*inplace_remainder*/
 
1942
0,           /*inplace_power*/
 
1943
0,       /*inplace_lshift*/
 
1944
0,      /*inplace_rshift*/
 
1945
0,      /*inplace_and*/
 
1946
0,      /*inplace_xor*/
 
1947
0,       /*inplace_or*/
 
1948
0,             /*nb_floor_divide*/
 
1949
0,              /*nb_true_divide*/
 
1950
0,     /*nb_inplace_floor_divide*/
 
1951
0,      /*nb_inplace_true_divide*/
 
1952
0,                     /* nb_index */
 
1953
};
 
1954
 
 
1955
PyTypeObject TrigEnvType = {
 
1956
PyObject_HEAD_INIT(NULL)
 
1957
0,                         /*ob_size*/
 
1958
"_pyo.TrigEnv_base",         /*tp_name*/
 
1959
sizeof(TrigEnv),         /*tp_basicsize*/
 
1960
0,                         /*tp_itemsize*/
 
1961
(destructor)TrigEnv_dealloc, /*tp_dealloc*/
 
1962
0,                         /*tp_print*/
 
1963
0,                         /*tp_getattr*/
 
1964
0,                         /*tp_setattr*/
 
1965
0,                         /*tp_compare*/
 
1966
0,                         /*tp_repr*/
 
1967
&TrigEnv_as_number,             /*tp_as_number*/
 
1968
0,                         /*tp_as_sequence*/
 
1969
0,                         /*tp_as_mapping*/
 
1970
0,                         /*tp_hash */
 
1971
0,                         /*tp_call*/
 
1972
0,                         /*tp_str*/
 
1973
0,                         /*tp_getattro*/
 
1974
0,                         /*tp_setattro*/
 
1975
0,                         /*tp_as_buffer*/
 
1976
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
1977
"TrigEnv objects. Starts an envelope on a trigger signal.",           /* tp_doc */
 
1978
(traverseproc)TrigEnv_traverse,   /* tp_traverse */
 
1979
(inquiry)TrigEnv_clear,           /* tp_clear */
 
1980
0,                             /* tp_richcompare */
 
1981
0,                             /* tp_weaklistoffset */
 
1982
0,                             /* tp_iter */
 
1983
0,                             /* tp_iternext */
 
1984
TrigEnv_methods,             /* tp_methods */
 
1985
TrigEnv_members,             /* tp_members */
 
1986
0,                      /* tp_getset */
 
1987
0,                         /* tp_base */
 
1988
0,                         /* tp_dict */
 
1989
0,                         /* tp_descr_get */
 
1990
0,                         /* tp_descr_set */
 
1991
0,                         /* tp_dictoffset */
 
1992
(initproc)TrigEnv_init,      /* tp_init */
 
1993
0,                         /* tp_alloc */
 
1994
TrigEnv_new,                 /* tp_new */
 
1995
};
 
1996
 
 
1997
/*********************************************************************************************/
 
1998
/* TrigLinseg *********************************************************************************/
 
1999
/*********************************************************************************************/
 
2000
typedef struct {
 
2001
    pyo_audio_HEAD
 
2002
    PyObject *pointslist;
 
2003
    PyObject *input;
 
2004
    Stream *input_stream;
 
2005
    int modebuffer[2];
 
2006
    double currentTime;
 
2007
    double currentValue;
 
2008
    MYFLT sampleToSec;
 
2009
    double increment;
 
2010
    MYFLT *targets;
 
2011
    MYFLT *times;
 
2012
    int which;
 
2013
    int flag;
 
2014
    int newlist;
 
2015
    int listsize;
 
2016
    MYFLT *trigsBuffer;
 
2017
    TriggerStream *trig_stream;
 
2018
} TrigLinseg;
 
2019
 
 
2020
static void
 
2021
TrigLinseg_convert_pointslist(TrigLinseg *self) {
 
2022
    int i;
 
2023
    PyObject *tup;
 
2024
    
 
2025
    self->listsize = PyList_Size(self->pointslist);
 
2026
    self->targets = (MYFLT *)realloc(self->targets, self->listsize * sizeof(MYFLT));
 
2027
    self->times = (MYFLT *)realloc(self->times, self->listsize * sizeof(MYFLT));
 
2028
    for (i=0; i<self->listsize; i++) {
 
2029
        tup = PyList_GET_ITEM(self->pointslist, i);
 
2030
        self->times[i] = PyFloat_AsDouble(PyNumber_Float(PyTuple_GET_ITEM(tup, 0)));
 
2031
        self->targets[i] = PyFloat_AsDouble(PyNumber_Float(PyTuple_GET_ITEM(tup, 1)));
 
2032
    }
 
2033
}
 
2034
 
 
2035
static void 
 
2036
TrigLinseg_reinit(TrigLinseg *self) {
 
2037
    if (self->newlist == 1) {
 
2038
        TrigLinseg_convert_pointslist((TrigLinseg *)self);
 
2039
        self->newlist = 0;
 
2040
    }    
 
2041
    self->currentTime = 0.0;
 
2042
    self->currentValue = self->targets[0];
 
2043
    self->which = 0;
 
2044
    self->flag = 1;
 
2045
}
 
2046
 
 
2047
static void
 
2048
TrigLinseg_generate(TrigLinseg *self) {
 
2049
    int i;
 
2050
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
2051
    
 
2052
    for (i=0; i<self->bufsize; i++) {
 
2053
        self->trigsBuffer[i] = 0.0;
 
2054
        if (in[i] == 1)
 
2055
            TrigLinseg_reinit((TrigLinseg *)self);
 
2056
 
 
2057
        if (self->flag == 1) {
 
2058
            if (self->currentTime >= self->times[self->which]) {
 
2059
                self->which++;
 
2060
                if (self->which == self->listsize) {
 
2061
                    self->trigsBuffer[i] = 1.0;
 
2062
                    self->flag = 0;
 
2063
                    self->currentValue = self->targets[self->which-1];
 
2064
                }    
 
2065
                else
 
2066
                    if ((self->times[self->which] - self->times[self->which-1]) <= 0)
 
2067
                        self->increment = self->targets[self->which] - self->currentValue;
 
2068
                    else
 
2069
                        self->increment = (self->targets[self->which] - self->targets[self->which-1]) / ((self->times[self->which] - self->times[self->which-1]) / self->sampleToSec);
 
2070
            }
 
2071
            if (self->currentTime <= self->times[self->listsize-1])
 
2072
                self->currentValue += self->increment;            
 
2073
            self->data[i] = (MYFLT)self->currentValue;
 
2074
            self->currentTime += self->sampleToSec;    
 
2075
        }
 
2076
        else
 
2077
            self->data[i] = (MYFLT)self->currentValue;
 
2078
    }
 
2079
}
 
2080
 
 
2081
static void TrigLinseg_postprocessing_ii(TrigLinseg *self) { POST_PROCESSING_II };
 
2082
static void TrigLinseg_postprocessing_ai(TrigLinseg *self) { POST_PROCESSING_AI };
 
2083
static void TrigLinseg_postprocessing_ia(TrigLinseg *self) { POST_PROCESSING_IA };
 
2084
static void TrigLinseg_postprocessing_aa(TrigLinseg *self) { POST_PROCESSING_AA };
 
2085
static void TrigLinseg_postprocessing_ireva(TrigLinseg *self) { POST_PROCESSING_IREVA };
 
2086
static void TrigLinseg_postprocessing_areva(TrigLinseg *self) { POST_PROCESSING_AREVA };
 
2087
static void TrigLinseg_postprocessing_revai(TrigLinseg *self) { POST_PROCESSING_REVAI };
 
2088
static void TrigLinseg_postprocessing_revaa(TrigLinseg *self) { POST_PROCESSING_REVAA };
 
2089
static void TrigLinseg_postprocessing_revareva(TrigLinseg *self) { POST_PROCESSING_REVAREVA };
 
2090
 
 
2091
static void
 
2092
TrigLinseg_setProcMode(TrigLinseg *self)
 
2093
{
 
2094
    int muladdmode;
 
2095
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
2096
    
 
2097
    self->proc_func_ptr = TrigLinseg_generate;
 
2098
    
 
2099
        switch (muladdmode) {
 
2100
        case 0:        
 
2101
            self->muladd_func_ptr = TrigLinseg_postprocessing_ii;
 
2102
            break;
 
2103
        case 1:    
 
2104
            self->muladd_func_ptr = TrigLinseg_postprocessing_ai;
 
2105
            break;
 
2106
        case 2:    
 
2107
            self->muladd_func_ptr = TrigLinseg_postprocessing_revai;
 
2108
            break;
 
2109
        case 10:        
 
2110
            self->muladd_func_ptr = TrigLinseg_postprocessing_ia;
 
2111
            break;
 
2112
        case 11:    
 
2113
            self->muladd_func_ptr = TrigLinseg_postprocessing_aa;
 
2114
            break;
 
2115
        case 12:    
 
2116
            self->muladd_func_ptr = TrigLinseg_postprocessing_revaa;
 
2117
            break;
 
2118
        case 20:        
 
2119
            self->muladd_func_ptr = TrigLinseg_postprocessing_ireva;
 
2120
            break;
 
2121
        case 21:    
 
2122
            self->muladd_func_ptr = TrigLinseg_postprocessing_areva;
 
2123
            break;
 
2124
        case 22:    
 
2125
            self->muladd_func_ptr = TrigLinseg_postprocessing_revareva;
 
2126
            break;
 
2127
    }   
 
2128
}
 
2129
 
 
2130
static void
 
2131
TrigLinseg_compute_next_data_frame(TrigLinseg *self)
 
2132
{
 
2133
    (*self->proc_func_ptr)(self); 
 
2134
    (*self->muladd_func_ptr)(self);
 
2135
}
 
2136
 
 
2137
static int
 
2138
TrigLinseg_traverse(TrigLinseg *self, visitproc visit, void *arg)
 
2139
{
 
2140
    pyo_VISIT
 
2141
    Py_VISIT(self->pointslist);
 
2142
    Py_VISIT(self->trig_stream);    
 
2143
    return 0;
 
2144
}
 
2145
 
 
2146
static int 
 
2147
TrigLinseg_clear(TrigLinseg *self)
 
2148
{
 
2149
    pyo_CLEAR
 
2150
    Py_CLEAR(self->pointslist);
 
2151
    Py_CLEAR(self->trig_stream);    
 
2152
    return 0;
 
2153
}
 
2154
 
 
2155
static void
 
2156
TrigLinseg_dealloc(TrigLinseg* self)
 
2157
{
 
2158
    free(self->data);
 
2159
    free(self->targets);
 
2160
    free(self->times);
 
2161
    free(self->trigsBuffer);
 
2162
    TrigLinseg_clear(self);
 
2163
    self->ob_type->tp_free((PyObject*)self);
 
2164
}
 
2165
 
 
2166
static PyObject * TrigLinseg_deleteStream(TrigLinseg *self) { DELETE_STREAM };
 
2167
 
 
2168
static PyObject *
 
2169
TrigLinseg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
2170
{
 
2171
    int i;
 
2172
    TrigLinseg *self;
 
2173
    self = (TrigLinseg *)type->tp_alloc(type, 0);
 
2174
    
 
2175
    self->newlist = 1;
 
2176
        self->modebuffer[0] = 0;
 
2177
        self->modebuffer[1] = 0;
 
2178
    
 
2179
    INIT_OBJECT_COMMON
 
2180
    Stream_setFunctionPtr(self->stream, TrigLinseg_compute_next_data_frame);
 
2181
    self->mode_func_ptr = TrigLinseg_setProcMode;
 
2182
 
 
2183
    self->sampleToSec = 1. / self->sr;
 
2184
    
 
2185
    return (PyObject *)self;
 
2186
}
 
2187
 
 
2188
static int
 
2189
TrigLinseg_init(TrigLinseg *self, PyObject *args, PyObject *kwds)
 
2190
{
 
2191
    PyObject *inputtmp, *input_streamtmp, *pointslist=NULL, *multmp=NULL, *addtmp=NULL;
 
2192
    int i;
 
2193
    
 
2194
    static char *kwlist[] = {"input", "list", "mul", "add", NULL};
 
2195
    
 
2196
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, &inputtmp, &pointslist, &multmp, &addtmp))
 
2197
        return -1; 
 
2198
 
 
2199
    INIT_INPUT_STREAM
 
2200
 
 
2201
    Py_INCREF(pointslist);
 
2202
    Py_XDECREF(self->pointslist);
 
2203
    self->pointslist = pointslist;
 
2204
    TrigLinseg_convert_pointslist((TrigLinseg *)self);
 
2205
    
 
2206
    if (multmp) {
 
2207
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
2208
    }
 
2209
    
 
2210
    if (addtmp) {
 
2211
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
2212
    }
 
2213
    
 
2214
    Py_INCREF(self->stream);
 
2215
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
2216
 
 
2217
    self->trigsBuffer = (MYFLT *)realloc(self->trigsBuffer, self->bufsize * sizeof(MYFLT));
 
2218
    
 
2219
    for (i=0; i<self->bufsize; i++) {
 
2220
        self->trigsBuffer[i] = 0.0;
 
2221
    }    
 
2222
    
 
2223
    MAKE_NEW_TRIGGER_STREAM(self->trig_stream, &TriggerStreamType, NULL);
 
2224
    TriggerStream_setData(self->trig_stream, self->trigsBuffer);
 
2225
 
 
2226
    (*self->mode_func_ptr)(self);
 
2227
 
 
2228
    Py_INCREF(self);
 
2229
    return 0;
 
2230
}
 
2231
 
 
2232
static PyObject * TrigLinseg_getServer(TrigLinseg* self) { GET_SERVER };
 
2233
static PyObject * TrigLinseg_getStream(TrigLinseg* self) { GET_STREAM };
 
2234
static PyObject * TrigLinseg_getTriggerStream(TrigLinseg* self) { GET_TRIGGER_STREAM };
 
2235
static PyObject * TrigLinseg_setMul(TrigLinseg *self, PyObject *arg) { SET_MUL };       
 
2236
static PyObject * TrigLinseg_setAdd(TrigLinseg *self, PyObject *arg) { SET_ADD };       
 
2237
static PyObject * TrigLinseg_setSub(TrigLinseg *self, PyObject *arg) { SET_SUB };       
 
2238
static PyObject * TrigLinseg_setDiv(TrigLinseg *self, PyObject *arg) { SET_DIV };       
 
2239
 
 
2240
static PyObject * TrigLinseg_play(TrigLinseg *self, PyObject *args, PyObject *kwds) { PLAY };
 
2241
static PyObject * TrigLinseg_stop(TrigLinseg *self) { STOP };
 
2242
 
 
2243
static PyObject * TrigLinseg_multiply(TrigLinseg *self, PyObject *arg) { MULTIPLY };
 
2244
static PyObject * TrigLinseg_inplace_multiply(TrigLinseg *self, PyObject *arg) { INPLACE_MULTIPLY };
 
2245
static PyObject * TrigLinseg_add(TrigLinseg *self, PyObject *arg) { ADD };
 
2246
static PyObject * TrigLinseg_inplace_add(TrigLinseg *self, PyObject *arg) { INPLACE_ADD };
 
2247
static PyObject * TrigLinseg_sub(TrigLinseg *self, PyObject *arg) { SUB };
 
2248
static PyObject * TrigLinseg_inplace_sub(TrigLinseg *self, PyObject *arg) { INPLACE_SUB };
 
2249
static PyObject * TrigLinseg_div(TrigLinseg *self, PyObject *arg) { DIV };
 
2250
static PyObject * TrigLinseg_inplace_div(TrigLinseg *self, PyObject *arg) { INPLACE_DIV };
 
2251
 
 
2252
static PyObject *
 
2253
TrigLinseg_setList(TrigLinseg *self, PyObject *value)
 
2254
{
 
2255
    if (value == NULL) {
 
2256
        PyErr_SetString(PyExc_TypeError, "Cannot delete the list attribute.");
 
2257
        return PyInt_FromLong(-1);
 
2258
    }
 
2259
    
 
2260
    if (! PyList_Check(value)) {
 
2261
        PyErr_SetString(PyExc_TypeError, "The points list attribute value must be a list of tuples.");
 
2262
        return PyInt_FromLong(-1);
 
2263
    }
 
2264
    
 
2265
    Py_INCREF(value);
 
2266
    Py_DECREF(self->pointslist);
 
2267
    self->pointslist = value; 
 
2268
    
 
2269
    self->newlist = 1;
 
2270
    
 
2271
    Py_INCREF(Py_None);
 
2272
    return Py_None;
 
2273
}
 
2274
 
 
2275
static PyMemberDef TrigLinseg_members[] = {
 
2276
{"server", T_OBJECT_EX, offsetof(TrigLinseg, server), 0, "Pyo server."},
 
2277
{"stream", T_OBJECT_EX, offsetof(TrigLinseg, stream), 0, "Stream object."},
 
2278
{"trig_stream", T_OBJECT_EX, offsetof(TrigLinseg, trig_stream), 0, "Trigger Stream object."},
 
2279
{"pointslist", T_OBJECT_EX, offsetof(TrigLinseg, pointslist), 0, "List of target points."},
 
2280
{"mul", T_OBJECT_EX, offsetof(TrigLinseg, mul), 0, "Mul factor."},
 
2281
{"add", T_OBJECT_EX, offsetof(TrigLinseg, add), 0, "Add factor."},
 
2282
{NULL}  /* Sentinel */
 
2283
};
 
2284
 
 
2285
static PyMethodDef TrigLinseg_methods[] = {
 
2286
{"getServer", (PyCFunction)TrigLinseg_getServer, METH_NOARGS, "Returns server object."},
 
2287
{"_getStream", (PyCFunction)TrigLinseg_getStream, METH_NOARGS, "Returns stream object."},
 
2288
{"_getTriggerStream", (PyCFunction)TrigLinseg_getTriggerStream, METH_NOARGS, "Returns trigger stream object."},
 
2289
{"deleteStream", (PyCFunction)TrigLinseg_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
2290
{"play", (PyCFunction)TrigLinseg_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
2291
{"stop", (PyCFunction)TrigLinseg_stop, METH_NOARGS, "Starts fadeout and stops computing."},
 
2292
{"setList", (PyCFunction)TrigLinseg_setList, METH_O, "Sets target points list."},
 
2293
{"setMul", (PyCFunction)TrigLinseg_setMul, METH_O, "Sets TrigLinseg mul factor."},
 
2294
{"setAdd", (PyCFunction)TrigLinseg_setAdd, METH_O, "Sets TrigLinseg add factor."},
 
2295
{"setSub", (PyCFunction)TrigLinseg_setSub, METH_O, "Sets inverse add factor."},
 
2296
{"setDiv", (PyCFunction)TrigLinseg_setDiv, METH_O, "Sets inverse mul factor."},
 
2297
{NULL}  /* Sentinel */
 
2298
};
 
2299
 
 
2300
static PyNumberMethods TrigLinseg_as_number = {
 
2301
(binaryfunc)TrigLinseg_add,                      /*nb_add*/
 
2302
(binaryfunc)TrigLinseg_sub,                 /*nb_subtract*/
 
2303
(binaryfunc)TrigLinseg_multiply,                 /*nb_multiply*/
 
2304
(binaryfunc)TrigLinseg_div,                   /*nb_divide*/
 
2305
0,                /*nb_remainder*/
 
2306
0,                   /*nb_divmod*/
 
2307
0,                   /*nb_power*/
 
2308
0,                  /*nb_neg*/
 
2309
0,                /*nb_pos*/
 
2310
0,                  /*(unaryfunc)array_abs,*/
 
2311
0,                    /*nb_nonzero*/
 
2312
0,                    /*nb_invert*/
 
2313
0,               /*nb_lshift*/
 
2314
0,              /*nb_rshift*/
 
2315
0,              /*nb_and*/
 
2316
0,              /*nb_xor*/
 
2317
0,               /*nb_or*/
 
2318
0,                                          /*nb_coerce*/
 
2319
0,                       /*nb_int*/
 
2320
0,                      /*nb_long*/
 
2321
0,                     /*nb_float*/
 
2322
0,                       /*nb_oct*/
 
2323
0,                       /*nb_hex*/
 
2324
(binaryfunc)TrigLinseg_inplace_add,              /*inplace_add*/
 
2325
(binaryfunc)TrigLinseg_inplace_sub,         /*inplace_subtract*/
 
2326
(binaryfunc)TrigLinseg_inplace_multiply,         /*inplace_multiply*/
 
2327
(binaryfunc)TrigLinseg_inplace_div,           /*inplace_divide*/
 
2328
0,        /*inplace_remainder*/
 
2329
0,           /*inplace_power*/
 
2330
0,       /*inplace_lshift*/
 
2331
0,      /*inplace_rshift*/
 
2332
0,      /*inplace_and*/
 
2333
0,      /*inplace_xor*/
 
2334
0,       /*inplace_or*/
 
2335
0,             /*nb_floor_divide*/
 
2336
0,              /*nb_true_divide*/
 
2337
0,     /*nb_inplace_floor_divide*/
 
2338
0,      /*nb_inplace_true_divide*/
 
2339
0,                     /* nb_index */
 
2340
};
 
2341
 
 
2342
PyTypeObject TrigLinsegType = {
 
2343
PyObject_HEAD_INIT(NULL)
 
2344
0,                         /*ob_size*/
 
2345
"_pyo.TrigLinseg_base",         /*tp_name*/
 
2346
sizeof(TrigLinseg),         /*tp_basicsize*/
 
2347
0,                         /*tp_itemsize*/
 
2348
(destructor)TrigLinseg_dealloc, /*tp_dealloc*/
 
2349
0,                         /*tp_print*/
 
2350
0,                         /*tp_getattr*/
 
2351
0,                         /*tp_setattr*/
 
2352
0,                         /*tp_compare*/
 
2353
0,                         /*tp_repr*/
 
2354
&TrigLinseg_as_number,             /*tp_as_number*/
 
2355
0,                         /*tp_as_sequence*/
 
2356
0,                         /*tp_as_mapping*/
 
2357
0,                         /*tp_hash */
 
2358
0,                         /*tp_call*/
 
2359
0,                         /*tp_str*/
 
2360
0,                         /*tp_getattro*/
 
2361
0,                         /*tp_setattro*/
 
2362
0,                         /*tp_as_buffer*/
 
2363
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
2364
"TrigLinseg objects. Generates a linear segments break-points line.",           /* tp_doc */
 
2365
(traverseproc)TrigLinseg_traverse,   /* tp_traverse */
 
2366
(inquiry)TrigLinseg_clear,           /* tp_clear */
 
2367
0,                             /* tp_richcompare */
 
2368
0,                             /* tp_weaklistoffset */
 
2369
0,                             /* tp_iter */
 
2370
0,                             /* tp_iternext */
 
2371
TrigLinseg_methods,             /* tp_methods */
 
2372
TrigLinseg_members,             /* tp_members */
 
2373
0,                      /* tp_getset */
 
2374
0,                         /* tp_base */
 
2375
0,                         /* tp_dict */
 
2376
0,                         /* tp_descr_get */
 
2377
0,                         /* tp_descr_set */
 
2378
0,                         /* tp_dictoffset */
 
2379
(initproc)TrigLinseg_init,      /* tp_init */
 
2380
0,                         /* tp_alloc */
 
2381
TrigLinseg_new,                 /* tp_new */
 
2382
};
 
2383
 
 
2384
/*********************************************************************************************/
 
2385
/* TrigExpseg *********************************************************************************/
 
2386
/*********************************************************************************************/
 
2387
typedef struct {
 
2388
    pyo_audio_HEAD
 
2389
    PyObject *pointslist;
 
2390
    PyObject *input;
 
2391
    Stream *input_stream;
 
2392
    int modebuffer[2];
 
2393
    double currentTime;
 
2394
    double currentValue;
 
2395
    MYFLT sampleToSec;
 
2396
    double inc;
 
2397
    double pointer;
 
2398
    MYFLT range;
 
2399
    double steps;
 
2400
    MYFLT *targets;
 
2401
    MYFLT *times;
 
2402
    int which;
 
2403
    int flag;
 
2404
    int newlist;
 
2405
    int listsize;
 
2406
    double exp;
 
2407
    double exp_tmp;
 
2408
    int inverse;
 
2409
    int inverse_tmp;    
 
2410
    MYFLT *trigsBuffer;
 
2411
    TriggerStream *trig_stream;
 
2412
} TrigExpseg;
 
2413
 
 
2414
static void
 
2415
TrigExpseg_convert_pointslist(TrigExpseg *self) {
 
2416
    int i;
 
2417
    PyObject *tup;
 
2418
    
 
2419
    self->listsize = PyList_Size(self->pointslist);
 
2420
    self->targets = (MYFLT *)realloc(self->targets, self->listsize * sizeof(MYFLT));
 
2421
    self->times = (MYFLT *)realloc(self->times, self->listsize * sizeof(MYFLT));
 
2422
    for (i=0; i<self->listsize; i++) {
 
2423
        tup = PyList_GET_ITEM(self->pointslist, i);
 
2424
        self->times[i] = PyFloat_AsDouble(PyNumber_Float(PyTuple_GET_ITEM(tup, 0)));
 
2425
        self->targets[i] = PyFloat_AsDouble(PyNumber_Float(PyTuple_GET_ITEM(tup, 1)));
 
2426
    }
 
2427
}
 
2428
 
 
2429
static void 
 
2430
TrigExpseg_reinit(TrigExpseg *self) {
 
2431
    if (self->newlist == 1) {
 
2432
        TrigExpseg_convert_pointslist((TrigExpseg *)self);
 
2433
        self->newlist = 0;
 
2434
    }    
 
2435
    self->currentTime = 0.0;
 
2436
    self->currentValue = self->targets[0];
 
2437
    self->which = 0;
 
2438
    self->flag = 1;
 
2439
    self->exp = self->exp_tmp;
 
2440
    self->inverse = self->inverse_tmp;
 
2441
}
 
2442
 
 
2443
static void
 
2444
TrigExpseg_generate(TrigExpseg *self) {
 
2445
    int i;
 
2446
    MYFLT scl;
 
2447
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
2448
    
 
2449
    for (i=0; i<self->bufsize; i++) {
 
2450
        self->trigsBuffer[i] = 0.0;
 
2451
        if (in[i] == 1)
 
2452
            TrigExpseg_reinit((TrigExpseg *)self);
 
2453
        
 
2454
        if (self->flag == 1) {
 
2455
            if (self->currentTime >= self->times[self->which]) {
 
2456
                self->which++;
 
2457
                if (self->which == self->listsize) {
 
2458
                    self->trigsBuffer[i] = 1.0;
 
2459
                    self->flag = 0;
 
2460
                    self->currentValue = self->targets[self->which-1];
 
2461
                }    
 
2462
                else {
 
2463
                    self->range = self->targets[self->which] - self->targets[self->which-1];
 
2464
                    self->steps = (self->times[self->which] - self->times[self->which-1]) * self->sr;
 
2465
                    if (self->steps <= 0)
 
2466
                        self->inc = 1.0;
 
2467
                    else
 
2468
                        self->inc = 1.0 / self->steps;
 
2469
                    self->pointer = 0.0;                    
 
2470
                }
 
2471
            }    
 
2472
            if (self->currentTime <= self->times[self->listsize-1]) {
 
2473
                if (self->pointer >= 1.0)
 
2474
                    self->pointer = 1.0;
 
2475
                if (self->inverse == 1 && self->range < 0.0)
 
2476
                    scl = 1.0 - MYPOW(1.0 - self->pointer, self->exp);
 
2477
                else
 
2478
                    scl = MYPOW(self->pointer, self->exp);
 
2479
                
 
2480
                self->currentValue = scl * self->range + self->targets[self->which-1];
 
2481
                self->pointer += self->inc;
 
2482
            } 
 
2483
            self->data[i] = (MYFLT)self->currentValue;
 
2484
            self->currentTime += self->sampleToSec;    
 
2485
        }
 
2486
        else
 
2487
            self->data[i] = (MYFLT)self->currentValue;
 
2488
    }
 
2489
}
 
2490
 
 
2491
static void TrigExpseg_postprocessing_ii(TrigExpseg *self) { POST_PROCESSING_II };
 
2492
static void TrigExpseg_postprocessing_ai(TrigExpseg *self) { POST_PROCESSING_AI };
 
2493
static void TrigExpseg_postprocessing_ia(TrigExpseg *self) { POST_PROCESSING_IA };
 
2494
static void TrigExpseg_postprocessing_aa(TrigExpseg *self) { POST_PROCESSING_AA };
 
2495
static void TrigExpseg_postprocessing_ireva(TrigExpseg *self) { POST_PROCESSING_IREVA };
 
2496
static void TrigExpseg_postprocessing_areva(TrigExpseg *self) { POST_PROCESSING_AREVA };
 
2497
static void TrigExpseg_postprocessing_revai(TrigExpseg *self) { POST_PROCESSING_REVAI };
 
2498
static void TrigExpseg_postprocessing_revaa(TrigExpseg *self) { POST_PROCESSING_REVAA };
 
2499
static void TrigExpseg_postprocessing_revareva(TrigExpseg *self) { POST_PROCESSING_REVAREVA };
 
2500
 
 
2501
static void
 
2502
TrigExpseg_setProcMode(TrigExpseg *self)
 
2503
{
 
2504
    int muladdmode;
 
2505
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
2506
    
 
2507
    self->proc_func_ptr = TrigExpseg_generate;
 
2508
    
 
2509
        switch (muladdmode) {
 
2510
        case 0:        
 
2511
            self->muladd_func_ptr = TrigExpseg_postprocessing_ii;
 
2512
            break;
 
2513
        case 1:    
 
2514
            self->muladd_func_ptr = TrigExpseg_postprocessing_ai;
 
2515
            break;
 
2516
        case 2:    
 
2517
            self->muladd_func_ptr = TrigExpseg_postprocessing_revai;
 
2518
            break;
 
2519
        case 10:        
 
2520
            self->muladd_func_ptr = TrigExpseg_postprocessing_ia;
 
2521
            break;
 
2522
        case 11:    
 
2523
            self->muladd_func_ptr = TrigExpseg_postprocessing_aa;
 
2524
            break;
 
2525
        case 12:    
 
2526
            self->muladd_func_ptr = TrigExpseg_postprocessing_revaa;
 
2527
            break;
 
2528
        case 20:        
 
2529
            self->muladd_func_ptr = TrigExpseg_postprocessing_ireva;
 
2530
            break;
 
2531
        case 21:    
 
2532
            self->muladd_func_ptr = TrigExpseg_postprocessing_areva;
 
2533
            break;
 
2534
        case 22:    
 
2535
            self->muladd_func_ptr = TrigExpseg_postprocessing_revareva;
 
2536
            break;
 
2537
    }   
 
2538
}
 
2539
 
 
2540
static void
 
2541
TrigExpseg_compute_next_data_frame(TrigExpseg *self)
 
2542
{
 
2543
    (*self->proc_func_ptr)(self); 
 
2544
    (*self->muladd_func_ptr)(self);
 
2545
}
 
2546
 
 
2547
static int
 
2548
TrigExpseg_traverse(TrigExpseg *self, visitproc visit, void *arg)
 
2549
{
 
2550
    pyo_VISIT
 
2551
    Py_VISIT(self->pointslist);
 
2552
    Py_VISIT(self->trig_stream);    
 
2553
    return 0;
 
2554
}
 
2555
 
 
2556
static int 
 
2557
TrigExpseg_clear(TrigExpseg *self)
 
2558
{
 
2559
    pyo_CLEAR
 
2560
    Py_CLEAR(self->pointslist);
 
2561
    Py_CLEAR(self->trig_stream);    
 
2562
    return 0;
 
2563
}
 
2564
 
 
2565
static void
 
2566
TrigExpseg_dealloc(TrigExpseg* self)
 
2567
{
 
2568
    free(self->data);
 
2569
    free(self->targets);
 
2570
    free(self->times);
 
2571
    free(self->trigsBuffer);
 
2572
    TrigExpseg_clear(self);
 
2573
    self->ob_type->tp_free((PyObject*)self);
 
2574
}
 
2575
 
 
2576
static PyObject * TrigExpseg_deleteStream(TrigExpseg *self) { DELETE_STREAM };
 
2577
 
 
2578
static PyObject *
 
2579
TrigExpseg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
2580
{
 
2581
    int i;
 
2582
    TrigExpseg *self;
 
2583
    self = (TrigExpseg *)type->tp_alloc(type, 0);
 
2584
    
 
2585
    self->newlist = 1;
 
2586
    self->exp = self->exp_tmp = 10;
 
2587
    self->inverse = self->inverse_tmp = 1;
 
2588
        self->modebuffer[0] = 0;
 
2589
        self->modebuffer[1] = 0;
 
2590
    
 
2591
    INIT_OBJECT_COMMON
 
2592
    Stream_setFunctionPtr(self->stream, TrigExpseg_compute_next_data_frame);
 
2593
    self->mode_func_ptr = TrigExpseg_setProcMode;
 
2594
    
 
2595
    self->sampleToSec = 1. / self->sr;
 
2596
    
 
2597
    return (PyObject *)self;
 
2598
}
 
2599
 
 
2600
static int
 
2601
TrigExpseg_init(TrigExpseg *self, PyObject *args, PyObject *kwds)
 
2602
{
 
2603
    PyObject *inputtmp, *input_streamtmp, *pointslist=NULL, *multmp=NULL, *addtmp=NULL;
 
2604
    int i;
 
2605
    
 
2606
    static char *kwlist[] = {"input", "list", "exp", "inverse", "mul", "add", NULL};
 
2607
    
 
2608
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|diOO", kwlist, &inputtmp, &pointslist, &self->exp_tmp, &self->inverse_tmp, &multmp, &addtmp))
 
2609
        return -1; 
 
2610
    
 
2611
    INIT_INPUT_STREAM
 
2612
    
 
2613
    Py_INCREF(pointslist);
 
2614
    Py_XDECREF(self->pointslist);
 
2615
    self->pointslist = pointslist;
 
2616
    TrigExpseg_convert_pointslist((TrigExpseg *)self);
 
2617
    
 
2618
    if (multmp) {
 
2619
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
2620
    }
 
2621
    
 
2622
    if (addtmp) {
 
2623
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
2624
    }
 
2625
    
 
2626
    Py_INCREF(self->stream);
 
2627
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
2628
    
 
2629
    self->trigsBuffer = (MYFLT *)realloc(self->trigsBuffer, self->bufsize * sizeof(MYFLT));
 
2630
    
 
2631
    for (i=0; i<self->bufsize; i++) {
 
2632
        self->trigsBuffer[i] = 0.0;
 
2633
    }    
 
2634
 
 
2635
    MAKE_NEW_TRIGGER_STREAM(self->trig_stream, &TriggerStreamType, NULL);
 
2636
    TriggerStream_setData(self->trig_stream, self->trigsBuffer);
 
2637
    
 
2638
    (*self->mode_func_ptr)(self);
 
2639
 
 
2640
    Py_INCREF(self);
 
2641
    return 0;
 
2642
}
 
2643
 
 
2644
static PyObject * TrigExpseg_getServer(TrigExpseg* self) { GET_SERVER };
 
2645
static PyObject * TrigExpseg_getStream(TrigExpseg* self) { GET_STREAM };
 
2646
static PyObject * TrigExpseg_getTriggerStream(TrigExpseg* self) { GET_TRIGGER_STREAM };
 
2647
static PyObject * TrigExpseg_setMul(TrigExpseg *self, PyObject *arg) { SET_MUL };       
 
2648
static PyObject * TrigExpseg_setAdd(TrigExpseg *self, PyObject *arg) { SET_ADD };       
 
2649
static PyObject * TrigExpseg_setSub(TrigExpseg *self, PyObject *arg) { SET_SUB };       
 
2650
static PyObject * TrigExpseg_setDiv(TrigExpseg *self, PyObject *arg) { SET_DIV };       
 
2651
 
 
2652
static PyObject * TrigExpseg_play(TrigExpseg *self, PyObject *args, PyObject *kwds) { PLAY };
 
2653
static PyObject * TrigExpseg_stop(TrigExpseg *self) { STOP };
 
2654
 
 
2655
static PyObject * TrigExpseg_multiply(TrigExpseg *self, PyObject *arg) { MULTIPLY };
 
2656
static PyObject * TrigExpseg_inplace_multiply(TrigExpseg *self, PyObject *arg) { INPLACE_MULTIPLY };
 
2657
static PyObject * TrigExpseg_add(TrigExpseg *self, PyObject *arg) { ADD };
 
2658
static PyObject * TrigExpseg_inplace_add(TrigExpseg *self, PyObject *arg) { INPLACE_ADD };
 
2659
static PyObject * TrigExpseg_sub(TrigExpseg *self, PyObject *arg) { SUB };
 
2660
static PyObject * TrigExpseg_inplace_sub(TrigExpseg *self, PyObject *arg) { INPLACE_SUB };
 
2661
static PyObject * TrigExpseg_div(TrigExpseg *self, PyObject *arg) { DIV };
 
2662
static PyObject * TrigExpseg_inplace_div(TrigExpseg *self, PyObject *arg) { INPLACE_DIV };
 
2663
 
 
2664
static PyObject *
 
2665
TrigExpseg_setList(TrigExpseg *self, PyObject *value)
 
2666
{
 
2667
    if (value == NULL) {
 
2668
        PyErr_SetString(PyExc_TypeError, "Cannot delete the list attribute.");
 
2669
        return PyInt_FromLong(-1);
 
2670
    }
 
2671
    
 
2672
    if (! PyList_Check(value)) {
 
2673
        PyErr_SetString(PyExc_TypeError, "The points list attribute value must be a list of tuples.");
 
2674
        return PyInt_FromLong(-1);
 
2675
    }
 
2676
    
 
2677
    Py_INCREF(value);
 
2678
    Py_DECREF(self->pointslist);
 
2679
    self->pointslist = value; 
 
2680
    
 
2681
    self->newlist = 1;
 
2682
    
 
2683
    Py_INCREF(Py_None);
 
2684
    return Py_None;
 
2685
}
 
2686
 
 
2687
static PyObject *
 
2688
TrigExpseg_setExp(TrigExpseg *self, PyObject *arg)
 
2689
{
 
2690
        if (arg == NULL) {
 
2691
                Py_INCREF(Py_None);
 
2692
                return Py_None;
 
2693
        }
 
2694
    
 
2695
    self->exp_tmp = PyFloat_AsDouble(PyNumber_Float(arg));
 
2696
    
 
2697
    Py_INCREF(Py_None);
 
2698
    return Py_None;
 
2699
}
 
2700
 
 
2701
static PyObject *
 
2702
TrigExpseg_setInverse(TrigExpseg *self, PyObject *arg)
 
2703
{
 
2704
        if (arg == NULL) {
 
2705
                Py_INCREF(Py_None);
 
2706
                return Py_None;
 
2707
        }
 
2708
    
 
2709
    self->inverse_tmp = PyInt_AsLong(PyNumber_Int(arg));
 
2710
    
 
2711
    Py_INCREF(Py_None);
 
2712
    return Py_None;
 
2713
}
 
2714
 
 
2715
static PyMemberDef TrigExpseg_members[] = {
 
2716
{"server", T_OBJECT_EX, offsetof(TrigExpseg, server), 0, "Pyo server."},
 
2717
{"stream", T_OBJECT_EX, offsetof(TrigExpseg, stream), 0, "Stream object."},
 
2718
{"trig_stream", T_OBJECT_EX, offsetof(TrigExpseg, trig_stream), 0, "Trigger Stream object."},
 
2719
{"pointslist", T_OBJECT_EX, offsetof(TrigExpseg, pointslist), 0, "List of target points."},
 
2720
{"mul", T_OBJECT_EX, offsetof(TrigExpseg, mul), 0, "Mul factor."},
 
2721
{"add", T_OBJECT_EX, offsetof(TrigExpseg, add), 0, "Add factor."},
 
2722
{NULL}  /* Sentinel */
 
2723
};
 
2724
 
 
2725
static PyMethodDef TrigExpseg_methods[] = {
 
2726
{"getServer", (PyCFunction)TrigExpseg_getServer, METH_NOARGS, "Returns server object."},
 
2727
{"_getStream", (PyCFunction)TrigExpseg_getStream, METH_NOARGS, "Returns stream object."},
 
2728
{"_getTriggerStream", (PyCFunction)TrigExpseg_getTriggerStream, METH_NOARGS, "Returns trigger stream object."},
 
2729
{"deleteStream", (PyCFunction)TrigExpseg_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
2730
{"play", (PyCFunction)TrigExpseg_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
2731
{"stop", (PyCFunction)TrigExpseg_stop, METH_NOARGS, "Starts fadeout and stops computing."},
 
2732
{"setList", (PyCFunction)TrigExpseg_setList, METH_O, "Sets target points list."},
 
2733
{"setExp", (PyCFunction)TrigExpseg_setExp, METH_O, "Sets exponent factor."},
 
2734
{"setInverse", (PyCFunction)TrigExpseg_setInverse, METH_O, "Sets inverse factor."},
 
2735
{"setMul", (PyCFunction)TrigExpseg_setMul, METH_O, "Sets TrigExpseg mul factor."},
 
2736
{"setAdd", (PyCFunction)TrigExpseg_setAdd, METH_O, "Sets TrigExpseg add factor."},
 
2737
{"setSub", (PyCFunction)TrigExpseg_setSub, METH_O, "Sets inverse add factor."},
 
2738
{"setDiv", (PyCFunction)TrigExpseg_setDiv, METH_O, "Sets inverse mul factor."},
 
2739
{NULL}  /* Sentinel */
 
2740
};
 
2741
 
 
2742
static PyNumberMethods TrigExpseg_as_number = {
 
2743
(binaryfunc)TrigExpseg_add,                      /*nb_add*/
 
2744
(binaryfunc)TrigExpseg_sub,                 /*nb_subtract*/
 
2745
(binaryfunc)TrigExpseg_multiply,                 /*nb_multiply*/
 
2746
(binaryfunc)TrigExpseg_div,                   /*nb_divide*/
 
2747
0,                /*nb_remainder*/
 
2748
0,                   /*nb_divmod*/
 
2749
0,                   /*nb_power*/
 
2750
0,                  /*nb_neg*/
 
2751
0,                /*nb_pos*/
 
2752
0,                  /*(unaryfunc)array_abs,*/
 
2753
0,                    /*nb_nonzero*/
 
2754
0,                    /*nb_invert*/
 
2755
0,               /*nb_lshift*/
 
2756
0,              /*nb_rshift*/
 
2757
0,              /*nb_and*/
 
2758
0,              /*nb_xor*/
 
2759
0,               /*nb_or*/
 
2760
0,                                          /*nb_coerce*/
 
2761
0,                       /*nb_int*/
 
2762
0,                      /*nb_long*/
 
2763
0,                     /*nb_float*/
 
2764
0,                       /*nb_oct*/
 
2765
0,                       /*nb_hex*/
 
2766
(binaryfunc)TrigExpseg_inplace_add,              /*inplace_add*/
 
2767
(binaryfunc)TrigExpseg_inplace_sub,         /*inplace_subtract*/
 
2768
(binaryfunc)TrigExpseg_inplace_multiply,         /*inplace_multiply*/
 
2769
(binaryfunc)TrigExpseg_inplace_div,           /*inplace_divide*/
 
2770
0,        /*inplace_remainder*/
 
2771
0,           /*inplace_power*/
 
2772
0,       /*inplace_lshift*/
 
2773
0,      /*inplace_rshift*/
 
2774
0,      /*inplace_and*/
 
2775
0,      /*inplace_xor*/
 
2776
0,       /*inplace_or*/
 
2777
0,             /*nb_floor_divide*/
 
2778
0,              /*nb_true_divide*/
 
2779
0,     /*nb_inplace_floor_divide*/
 
2780
0,      /*nb_inplace_true_divide*/
 
2781
0,                     /* nb_index */
 
2782
};
 
2783
 
 
2784
PyTypeObject TrigExpsegType = {
 
2785
PyObject_HEAD_INIT(NULL)
 
2786
0,                         /*ob_size*/
 
2787
"_pyo.TrigExpseg_base",         /*tp_name*/
 
2788
sizeof(TrigExpseg),         /*tp_basicsize*/
 
2789
0,                         /*tp_itemsize*/
 
2790
(destructor)TrigExpseg_dealloc, /*tp_dealloc*/
 
2791
0,                         /*tp_print*/
 
2792
0,                         /*tp_getattr*/
 
2793
0,                         /*tp_setattr*/
 
2794
0,                         /*tp_compare*/
 
2795
0,                         /*tp_repr*/
 
2796
&TrigExpseg_as_number,             /*tp_as_number*/
 
2797
0,                         /*tp_as_sequence*/
 
2798
0,                         /*tp_as_mapping*/
 
2799
0,                         /*tp_hash */
 
2800
0,                         /*tp_call*/
 
2801
0,                         /*tp_str*/
 
2802
0,                         /*tp_getattro*/
 
2803
0,                         /*tp_setattro*/
 
2804
0,                         /*tp_as_buffer*/
 
2805
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
2806
"TrigExpseg objects. Generates a linear segments break-points line.",           /* tp_doc */
 
2807
(traverseproc)TrigExpseg_traverse,   /* tp_traverse */
 
2808
(inquiry)TrigExpseg_clear,           /* tp_clear */
 
2809
0,                             /* tp_richcompare */
 
2810
0,                             /* tp_weaklistoffset */
 
2811
0,                             /* tp_iter */
 
2812
0,                             /* tp_iternext */
 
2813
TrigExpseg_methods,             /* tp_methods */
 
2814
TrigExpseg_members,             /* tp_members */
 
2815
0,                      /* tp_getset */
 
2816
0,                         /* tp_base */
 
2817
0,                         /* tp_dict */
 
2818
0,                         /* tp_descr_get */
 
2819
0,                         /* tp_descr_set */
 
2820
0,                         /* tp_dictoffset */
 
2821
(initproc)TrigExpseg_init,      /* tp_init */
 
2822
0,                         /* tp_alloc */
 
2823
TrigExpseg_new,                 /* tp_new */
 
2824
};
 
2825
 
 
2826
/****************/
 
2827
/**** TrigXnoise *****/
 
2828
/****************/
 
2829
typedef struct {
 
2830
    pyo_audio_HEAD
 
2831
    PyObject *input;
 
2832
    Stream *input_stream;
 
2833
    PyObject *x1;
 
2834
    PyObject *x2;
 
2835
    Stream *x1_stream;
 
2836
    Stream *x2_stream;
 
2837
    MYFLT (*type_func_ptr)();
 
2838
    MYFLT xx1;
 
2839
    MYFLT xx2;
 
2840
    int type;
 
2841
    MYFLT value;
 
2842
    MYFLT lastPoissonX1;
 
2843
    int poisson_tab;
 
2844
    MYFLT poisson_buffer[2000];
 
2845
    MYFLT walkerValue;
 
2846
    MYFLT loop_buffer[15];
 
2847
    int loopChoice;
 
2848
    int loopCountPlay;
 
2849
    int loopTime;
 
2850
    int loopCountRec;
 
2851
    int loopLen;
 
2852
    int loopStop;
 
2853
    int modebuffer[4]; // need at least 2 slots for mul & add 
 
2854
} TrigXnoise;
 
2855
 
 
2856
// no parameter
 
2857
static MYFLT
 
2858
TrigXnoise_uniform(TrigXnoise *self) {
 
2859
    return RANDOM_UNIFORM;    
 
2860
}
 
2861
 
 
2862
static MYFLT
 
2863
TrigXnoise_linear_min(TrigXnoise *self) {
 
2864
    MYFLT a = RANDOM_UNIFORM;    
 
2865
    MYFLT b = RANDOM_UNIFORM;
 
2866
    if (a < b) return a;
 
2867
    else return b;
 
2868
}
 
2869
 
 
2870
static MYFLT
 
2871
TrigXnoise_linear_max(TrigXnoise *self) {
 
2872
    MYFLT a = RANDOM_UNIFORM;    
 
2873
    MYFLT b = RANDOM_UNIFORM;
 
2874
    if (a > b) return a;
 
2875
    else return b;
 
2876
}
 
2877
 
 
2878
static MYFLT
 
2879
TrigXnoise_triangle(TrigXnoise *self) {
 
2880
    MYFLT a = RANDOM_UNIFORM;    
 
2881
    MYFLT b = RANDOM_UNIFORM;
 
2882
    return ((a + b) * 0.5);
 
2883
}
 
2884
 
 
2885
// x1 = slope
 
2886
static MYFLT
 
2887
TrigXnoise_expon_min(TrigXnoise *self) {
 
2888
    if (self->xx1 <= 0.0) self->xx1 = 0.00001;
 
2889
    MYFLT val = -MYLOG(RANDOM_UNIFORM) / self->xx1;    
 
2890
    if (val < 0.0) return 0.0;
 
2891
    else if (val > 1.0) return 1.0;
 
2892
    else return val;
 
2893
}
 
2894
 
 
2895
static MYFLT
 
2896
TrigXnoise_expon_max(TrigXnoise *self) {
 
2897
    if (self->xx1 <= 0.0) self->xx1 = 0.00001;
 
2898
    MYFLT val = 1.0 - (-MYLOG(RANDOM_UNIFORM) / self->xx1);    
 
2899
    if (val < 0.0) return 0.0;
 
2900
    else if (val > 1.0) return 1.0;
 
2901
    else return val;
 
2902
}
 
2903
 
 
2904
// x1 = bandwidth
 
2905
static MYFLT
 
2906
TrigXnoise_biexpon(TrigXnoise *self) {
 
2907
    MYFLT polar, val;
 
2908
    if (self->xx1 <= 0.0) self->xx1 = 0.00001;
 
2909
    MYFLT sum = RANDOM_UNIFORM * 2.0;
 
2910
    
 
2911
    if (sum > 1.0) {
 
2912
        polar = -1;
 
2913
        sum = 2.0 - sum;
 
2914
    }
 
2915
    else
 
2916
        polar = 1;
 
2917
    
 
2918
    val = 0.5 * (polar * MYLOG(sum) / self->xx1) + 0.5;
 
2919
    
 
2920
    if (val < 0.0) return 0.0;
 
2921
    else if (val > 1.0) return 1.0;
 
2922
    else return val;
 
2923
}
 
2924
 
 
2925
static MYFLT
 
2926
TrigXnoise_cauchy(TrigXnoise *self) {
 
2927
    MYFLT rnd, val, dir;
 
2928
    do {
 
2929
        rnd = RANDOM_UNIFORM;
 
2930
    }
 
2931
    while (rnd == 0.5);
 
2932
    
 
2933
    if (rand() < (RAND_MAX / 2))
 
2934
        dir = -1;
 
2935
    else
 
2936
        dir = 1;
 
2937
    
 
2938
    val = 0.5 * (MYTAN(rnd) * self->xx1 * dir) + 0.5;
 
2939
    
 
2940
    if (val < 0.0) return 0.0;
 
2941
    else if (val > 1.0) return 1.0;
 
2942
    else return val;
 
2943
}
 
2944
 
 
2945
// x1 = locator, x2 = shape
 
2946
static MYFLT
 
2947
TrigXnoise_weibull(TrigXnoise *self) {
 
2948
    MYFLT rnd, val;
 
2949
    if (self->xx2 <= 0.0) self->xx2 = 0.00001;
 
2950
    
 
2951
    rnd = 1.0 / (1.0 - RANDOM_UNIFORM);
 
2952
    val = self->xx1 * MYPOW(MYLOG(rnd), (1.0 / self->xx2));
 
2953
    
 
2954
    if (val < 0.0) return 0.0;
 
2955
    else if (val > 1.0) return 1.0;
 
2956
    else return val;
 
2957
}
 
2958
 
 
2959
// x1 = locator, x2 = bandwidth
 
2960
static MYFLT
 
2961
TrigXnoise_gaussian(TrigXnoise *self) {
 
2962
    MYFLT rnd, val;
 
2963
    
 
2964
    rnd = (RANDOM_UNIFORM + RANDOM_UNIFORM + RANDOM_UNIFORM + RANDOM_UNIFORM + RANDOM_UNIFORM + RANDOM_UNIFORM);
 
2965
    val = (self->xx2 * (rnd - 3.0) * 0.33 + self->xx1);
 
2966
    
 
2967
    if (val < 0.0) return 0.0;
 
2968
    else if (val > 1.0) return 1.0;
 
2969
    else return val;
 
2970
}
 
2971
 
 
2972
// x1 = gravity center, x2 = compress/expand
 
2973
static MYFLT
 
2974
TrigXnoise_poisson(TrigXnoise *self) {
 
2975
    int i, j, factorial;
 
2976
    long tot;
 
2977
    MYFLT val;
 
2978
    if (self->xx1 < 0.1) self->xx1 = 0.1;
 
2979
    if (self->xx2 < 0.1) self->xx2 = 0.1;
 
2980
    
 
2981
    if (self->xx1 != self->lastPoissonX1) {
 
2982
        self->lastPoissonX1 = self->xx1;
 
2983
        self->poisson_tab = 0;
 
2984
        factorial = 1;
 
2985
        for (i=1; i<12; i++) {
 
2986
            factorial *= i;
 
2987
            tot = (long)(1000.0 * (MYPOW(2.7182818, -self->xx1) * MYPOW(self->xx1, i) / factorial));
 
2988
            for (j=0; j<tot; j++) {
 
2989
                self->poisson_buffer[self->poisson_tab] = i;
 
2990
                self->poisson_tab++;
 
2991
            }
 
2992
        }
 
2993
    }
 
2994
    val = self->poisson_buffer[rand() % self->poisson_tab] / 12.0 * self->xx2;
 
2995
    
 
2996
    if (val < 0.0) return 0.0;
 
2997
    else if (val > 1.0) return 1.0;
 
2998
    else return val;
 
2999
}
 
3000
 
 
3001
// x1 = max value, x2 = max step
 
3002
static MYFLT
 
3003
TrigXnoise_walker(TrigXnoise *self) {
 
3004
    int modulo, dir;
 
3005
    
 
3006
    if (self->xx2 < 0.002) self->xx2 = 0.002;
 
3007
    
 
3008
    modulo = (int)(self->xx2 * 1000.0);
 
3009
    dir = rand() % 2;
 
3010
    
 
3011
    if (dir == 0)
 
3012
        self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
 
3013
    else
 
3014
        self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
 
3015
    
 
3016
    if (self->walkerValue > self->xx1)
 
3017
        self->walkerValue = self->xx1;
 
3018
    if (self->walkerValue < 0.0)
 
3019
        self->walkerValue = 0.0;
 
3020
    
 
3021
    return self->walkerValue;
 
3022
}
 
3023
 
 
3024
// x1 = max value, x2 = max step
 
3025
static MYFLT
 
3026
TrigXnoise_loopseg(TrigXnoise *self) {
 
3027
    int modulo, dir;
 
3028
    
 
3029
    if (self->loopChoice == 0) {
 
3030
        
 
3031
        self->loopCountPlay = self->loopTime = 0;
 
3032
        
 
3033
        if (self->xx2 < 0.002) self->xx2 = 0.002;
 
3034
        
 
3035
        modulo = (int)(self->xx2 * 1000.0);
 
3036
        dir = rand() % 2;
 
3037
        
 
3038
        if (dir == 0)
 
3039
            self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
 
3040
        else
 
3041
            self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
 
3042
        
 
3043
        if (self->walkerValue > self->xx1)
 
3044
            self->walkerValue = self->xx1;
 
3045
        if (self->walkerValue < 0.0)
 
3046
            self->walkerValue = 0.0;
 
3047
        
 
3048
        self->loop_buffer[self->loopCountRec++] = self->walkerValue;
 
3049
        
 
3050
        if (self->loopCountRec < self->loopLen)
 
3051
            self->loopChoice = 0;
 
3052
        else {
 
3053
            self->loopChoice = 1;
 
3054
            self->loopStop = (rand() % 4) + 1;
 
3055
        }
 
3056
    }
 
3057
    else {
 
3058
        self->loopCountRec = 0;
 
3059
        
 
3060
        self->walkerValue = self->loop_buffer[self->loopCountPlay++];
 
3061
        
 
3062
        if (self->loopCountPlay < self->loopLen)
 
3063
            self->loopChoice = 1;
 
3064
        else {
 
3065
            self->loopCountPlay = 0;
 
3066
            self->loopTime++;
 
3067
        }
 
3068
        
 
3069
        if (self->loopTime == self->loopStop) {
 
3070
            self->loopChoice = 0;
 
3071
            self->loopLen = (rand() % 10) + 3;
 
3072
        }
 
3073
    }
 
3074
    
 
3075
    return self->walkerValue;
 
3076
}
 
3077
 
 
3078
static void
 
3079
TrigXnoise_generate_ii(TrigXnoise *self) {
 
3080
    int i;
 
3081
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
3082
    self->xx1 = PyFloat_AS_DOUBLE(self->x1);
 
3083
    self->xx2 = PyFloat_AS_DOUBLE(self->x2);
 
3084
    
 
3085
    for (i=0; i<self->bufsize; i++) {
 
3086
        if (in[i] == 1)
 
3087
            self->value = (*self->type_func_ptr)(self);
 
3088
        self->data[i] = self->value;
 
3089
    }
 
3090
}
 
3091
 
 
3092
static void
 
3093
TrigXnoise_generate_ai(TrigXnoise *self) {
 
3094
    int i;
 
3095
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
3096
    MYFLT *x1 = Stream_getData((Stream *)self->x1_stream);
 
3097
    self->xx2 = PyFloat_AS_DOUBLE(self->x2);
 
3098
    
 
3099
    for (i=0; i<self->bufsize; i++) {
 
3100
        if (in[i] == 1) {
 
3101
            self->xx1 = x1[i];
 
3102
            self->value = (*self->type_func_ptr)(self);
 
3103
        }
 
3104
        self->data[i] = self->value;
 
3105
    }
 
3106
}
 
3107
 
 
3108
static void
 
3109
TrigXnoise_generate_ia(TrigXnoise *self) {
 
3110
    int i;
 
3111
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
3112
    self->xx1 = PyFloat_AS_DOUBLE(self->x1);
 
3113
    MYFLT *x2 = Stream_getData((Stream *)self->x2_stream);
 
3114
    
 
3115
    for (i=0; i<self->bufsize; i++) {
 
3116
        if (in[i] == 1) {
 
3117
            self->xx2 = x2[i];
 
3118
            self->value = (*self->type_func_ptr)(self);
 
3119
        }
 
3120
        self->data[i] = self->value;
 
3121
    }
 
3122
}
 
3123
 
 
3124
static void
 
3125
TrigXnoise_generate_aa(TrigXnoise *self) {
 
3126
    int i;
 
3127
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
3128
    MYFLT *x1 = Stream_getData((Stream *)self->x1_stream);
 
3129
    MYFLT *x2 = Stream_getData((Stream *)self->x2_stream);
 
3130
    
 
3131
    for (i=0; i<self->bufsize; i++) {
 
3132
        if (in[i] == 1) {
 
3133
            self->xx1 = x1[i];
 
3134
            self->xx2 = x2[i];
 
3135
            self->value = (*self->type_func_ptr)(self);
 
3136
        }
 
3137
        self->data[i] = self->value;
 
3138
    }
 
3139
}
 
3140
 
 
3141
static void TrigXnoise_postprocessing_ii(TrigXnoise *self) { POST_PROCESSING_II };
 
3142
static void TrigXnoise_postprocessing_ai(TrigXnoise *self) { POST_PROCESSING_AI };
 
3143
static void TrigXnoise_postprocessing_ia(TrigXnoise *self) { POST_PROCESSING_IA };
 
3144
static void TrigXnoise_postprocessing_aa(TrigXnoise *self) { POST_PROCESSING_AA };
 
3145
static void TrigXnoise_postprocessing_ireva(TrigXnoise *self) { POST_PROCESSING_IREVA };
 
3146
static void TrigXnoise_postprocessing_areva(TrigXnoise *self) { POST_PROCESSING_AREVA };
 
3147
static void TrigXnoise_postprocessing_revai(TrigXnoise *self) { POST_PROCESSING_REVAI };
 
3148
static void TrigXnoise_postprocessing_revaa(TrigXnoise *self) { POST_PROCESSING_REVAA };
 
3149
static void TrigXnoise_postprocessing_revareva(TrigXnoise *self) { POST_PROCESSING_REVAREVA };
 
3150
 
 
3151
static void
 
3152
TrigXnoise_setRandomType(TrigXnoise *self)
 
3153
{
 
3154
    
 
3155
    switch (self->type) {            
 
3156
        case 0:
 
3157
            self->type_func_ptr = TrigXnoise_uniform;
 
3158
            break;
 
3159
        case 1:
 
3160
            self->type_func_ptr = TrigXnoise_linear_min;
 
3161
            break;
 
3162
        case 2:
 
3163
            self->type_func_ptr = TrigXnoise_linear_max;
 
3164
            break;
 
3165
        case 3:
 
3166
            self->type_func_ptr = TrigXnoise_triangle;
 
3167
            break;
 
3168
        case 4:
 
3169
            self->type_func_ptr = TrigXnoise_expon_min;
 
3170
            break;
 
3171
        case 5:
 
3172
            self->type_func_ptr = TrigXnoise_expon_max;
 
3173
            break;
 
3174
        case 6:
 
3175
            self->type_func_ptr = TrigXnoise_biexpon;
 
3176
            break;
 
3177
        case 7:
 
3178
            self->type_func_ptr = TrigXnoise_cauchy;
 
3179
            break;
 
3180
        case 8:
 
3181
            self->type_func_ptr = TrigXnoise_weibull;
 
3182
            break;
 
3183
        case 9:
 
3184
            self->type_func_ptr = TrigXnoise_gaussian;
 
3185
            break;
 
3186
        case 10:
 
3187
            self->type_func_ptr = TrigXnoise_poisson;
 
3188
            break;
 
3189
        case 11:
 
3190
            self->type_func_ptr = TrigXnoise_walker;
 
3191
            break;
 
3192
        case 12:
 
3193
            self->type_func_ptr = TrigXnoise_loopseg;
 
3194
            break;
 
3195
    }        
 
3196
}
 
3197
 
 
3198
static void
 
3199
TrigXnoise_setProcMode(TrigXnoise *self)
 
3200
{
 
3201
    int procmode, muladdmode;
 
3202
    procmode = self->modebuffer[2] + self->modebuffer[3] * 10;
 
3203
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
3204
    
 
3205
        switch (procmode) {
 
3206
        case 0:    
 
3207
            self->proc_func_ptr = TrigXnoise_generate_ii;
 
3208
            break;
 
3209
        case 1:    
 
3210
            self->proc_func_ptr = TrigXnoise_generate_ai;
 
3211
            break;
 
3212
        case 10:    
 
3213
            self->proc_func_ptr = TrigXnoise_generate_ia;
 
3214
            break;
 
3215
        case 11:    
 
3216
            self->proc_func_ptr = TrigXnoise_generate_aa;
 
3217
            break;
 
3218
    } 
 
3219
        switch (muladdmode) {
 
3220
        case 0:        
 
3221
            self->muladd_func_ptr = TrigXnoise_postprocessing_ii;
 
3222
            break;
 
3223
        case 1:    
 
3224
            self->muladd_func_ptr = TrigXnoise_postprocessing_ai;
 
3225
            break;
 
3226
        case 2:    
 
3227
            self->muladd_func_ptr = TrigXnoise_postprocessing_revai;
 
3228
            break;
 
3229
        case 10:        
 
3230
            self->muladd_func_ptr = TrigXnoise_postprocessing_ia;
 
3231
            break;
 
3232
        case 11:    
 
3233
            self->muladd_func_ptr = TrigXnoise_postprocessing_aa;
 
3234
            break;
 
3235
        case 12:    
 
3236
            self->muladd_func_ptr = TrigXnoise_postprocessing_revaa;
 
3237
            break;
 
3238
        case 20:        
 
3239
            self->muladd_func_ptr = TrigXnoise_postprocessing_ireva;
 
3240
            break;
 
3241
        case 21:    
 
3242
            self->muladd_func_ptr = TrigXnoise_postprocessing_areva;
 
3243
            break;
 
3244
        case 22:    
 
3245
            self->muladd_func_ptr = TrigXnoise_postprocessing_revareva;
 
3246
            break;
 
3247
    }  
 
3248
}
 
3249
 
 
3250
static void
 
3251
TrigXnoise_compute_next_data_frame(TrigXnoise *self)
 
3252
{
 
3253
    (*self->proc_func_ptr)(self); 
 
3254
    (*self->muladd_func_ptr)(self);
 
3255
}
 
3256
 
 
3257
static int
 
3258
TrigXnoise_traverse(TrigXnoise *self, visitproc visit, void *arg)
 
3259
{
 
3260
    pyo_VISIT
 
3261
    Py_VISIT(self->input);
 
3262
    Py_VISIT(self->input_stream);
 
3263
    Py_VISIT(self->x1);    
 
3264
    Py_VISIT(self->x1_stream);    
 
3265
    Py_VISIT(self->x2);    
 
3266
    Py_VISIT(self->x2_stream);    
 
3267
    return 0;
 
3268
}
 
3269
 
 
3270
static int 
 
3271
TrigXnoise_clear(TrigXnoise *self)
 
3272
{
 
3273
    pyo_CLEAR
 
3274
    Py_CLEAR(self->input);
 
3275
    Py_CLEAR(self->input_stream);
 
3276
    Py_CLEAR(self->x1);    
 
3277
    Py_CLEAR(self->x1_stream);    
 
3278
    Py_CLEAR(self->x2);    
 
3279
    Py_CLEAR(self->x2_stream);    
 
3280
    return 0;
 
3281
}
 
3282
 
 
3283
static void
 
3284
TrigXnoise_dealloc(TrigXnoise* self)
 
3285
{
 
3286
    free(self->data);
 
3287
    TrigXnoise_clear(self);
 
3288
    self->ob_type->tp_free((PyObject*)self);
 
3289
}
 
3290
 
 
3291
static PyObject * TrigXnoise_deleteStream(TrigXnoise *self) { DELETE_STREAM };
 
3292
 
 
3293
static PyObject *
 
3294
TrigXnoise_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
3295
{
 
3296
    int i;
 
3297
    TrigXnoise *self;
 
3298
    self = (TrigXnoise *)type->tp_alloc(type, 0);
 
3299
        
 
3300
    self->x1 = PyFloat_FromDouble(0.5);
 
3301
    self->x2 = PyFloat_FromDouble(0.5);
 
3302
    self->xx1 = self->xx2 = self->walkerValue = 0.5;
 
3303
    self->value = 0.0;
 
3304
        self->modebuffer[0] = 0;
 
3305
        self->modebuffer[1] = 0;
 
3306
        self->modebuffer[2] = 0;
 
3307
        self->modebuffer[3] = 0;
 
3308
 
 
3309
    INIT_OBJECT_COMMON
 
3310
    
 
3311
    Server_generateSeed((Server *)self->server, TRIGXNOISE_ID);
 
3312
 
 
3313
    self->poisson_tab = 0;
 
3314
    self->lastPoissonX1 = -99.0;
 
3315
    for (i=0; i<2000; i++) {
 
3316
        self->poisson_buffer[i] = 0.0;
 
3317
    }
 
3318
    for (i=0; i<15; i++) {
 
3319
        self->loop_buffer[i] = 0.0;
 
3320
    }
 
3321
    self->loopChoice = self->loopCountPlay = self->loopTime = self->loopCountRec = self->loopStop = 0;    
 
3322
    self->loopLen = (rand() % 10) + 3;
 
3323
    
 
3324
    Stream_setFunctionPtr(self->stream, TrigXnoise_compute_next_data_frame);
 
3325
    self->mode_func_ptr = TrigXnoise_setProcMode;
 
3326
    return (PyObject *)self;
 
3327
}
 
3328
 
 
3329
static int
 
3330
TrigXnoise_init(TrigXnoise *self, PyObject *args, PyObject *kwds)
 
3331
{
 
3332
    PyObject *inputtmp, *input_streamtmp, *x1tmp=NULL, *x2tmp=NULL, *multmp=NULL, *addtmp=NULL;
 
3333
    
 
3334
    static char *kwlist[] = {"input", "type", "x1", "x2", "mul", "add", NULL};
 
3335
    
 
3336
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|iOOOO", kwlist, &inputtmp, &self->type, &x1tmp, &x2tmp, &multmp, &addtmp))
 
3337
        return -1; 
 
3338
 
 
3339
    INIT_INPUT_STREAM
 
3340
    
 
3341
    if (x1tmp) {
 
3342
        PyObject_CallMethod((PyObject *)self, "setX1", "O", x1tmp);
 
3343
    }
 
3344
    
 
3345
    if (x2tmp) {
 
3346
        PyObject_CallMethod((PyObject *)self, "setX2", "O", x2tmp);
 
3347
    }
 
3348
 
 
3349
    if (multmp) {
 
3350
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
3351
    }
 
3352
    
 
3353
    if (addtmp) {
 
3354
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
3355
    }
 
3356
    
 
3357
    Py_INCREF(self->stream);
 
3358
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
3359
    
 
3360
    TrigXnoise_setRandomType(self);
 
3361
    
 
3362
    (*self->mode_func_ptr)(self);
 
3363
        
 
3364
    Py_INCREF(self);
 
3365
    return 0;
 
3366
}
 
3367
 
 
3368
static PyObject * TrigXnoise_getServer(TrigXnoise* self) { GET_SERVER };
 
3369
static PyObject * TrigXnoise_getStream(TrigXnoise* self) { GET_STREAM };
 
3370
static PyObject * TrigXnoise_setMul(TrigXnoise *self, PyObject *arg) { SET_MUL };       
 
3371
static PyObject * TrigXnoise_setAdd(TrigXnoise *self, PyObject *arg) { SET_ADD };       
 
3372
static PyObject * TrigXnoise_setSub(TrigXnoise *self, PyObject *arg) { SET_SUB };       
 
3373
static PyObject * TrigXnoise_setDiv(TrigXnoise *self, PyObject *arg) { SET_DIV };       
 
3374
 
 
3375
static PyObject * TrigXnoise_play(TrigXnoise *self, PyObject *args, PyObject *kwds) { PLAY };
 
3376
static PyObject * TrigXnoise_out(TrigXnoise *self, PyObject *args, PyObject *kwds) { OUT };
 
3377
static PyObject * TrigXnoise_stop(TrigXnoise *self) { STOP };
 
3378
 
 
3379
static PyObject * TrigXnoise_multiply(TrigXnoise *self, PyObject *arg) { MULTIPLY };
 
3380
static PyObject * TrigXnoise_inplace_multiply(TrigXnoise *self, PyObject *arg) { INPLACE_MULTIPLY };
 
3381
static PyObject * TrigXnoise_add(TrigXnoise *self, PyObject *arg) { ADD };
 
3382
static PyObject * TrigXnoise_inplace_add(TrigXnoise *self, PyObject *arg) { INPLACE_ADD };
 
3383
static PyObject * TrigXnoise_sub(TrigXnoise *self, PyObject *arg) { SUB };
 
3384
static PyObject * TrigXnoise_inplace_sub(TrigXnoise *self, PyObject *arg) { INPLACE_SUB };
 
3385
static PyObject * TrigXnoise_div(TrigXnoise *self, PyObject *arg) { DIV };
 
3386
static PyObject * TrigXnoise_inplace_div(TrigXnoise *self, PyObject *arg) { INPLACE_DIV };
 
3387
 
 
3388
static PyObject *
 
3389
TrigXnoise_setType(TrigXnoise *self, PyObject *arg)
 
3390
{       
 
3391
        if (arg == NULL) {
 
3392
                Py_INCREF(Py_None);
 
3393
                return Py_None;
 
3394
        }
 
3395
    
 
3396
        int isNumber = PyInt_Check(arg);
 
3397
        
 
3398
        if (isNumber == 1) {
 
3399
                self->type = PyInt_AsLong(arg);
 
3400
        TrigXnoise_setRandomType(self);
 
3401
        }
 
3402
    
 
3403
        Py_INCREF(Py_None);
 
3404
        return Py_None;
 
3405
}       
 
3406
 
 
3407
static PyObject *
 
3408
TrigXnoise_setX1(TrigXnoise *self, PyObject *arg)
 
3409
{
 
3410
        PyObject *tmp, *streamtmp;
 
3411
        
 
3412
        if (arg == NULL) {
 
3413
                Py_INCREF(Py_None);
 
3414
                return Py_None;
 
3415
        }
 
3416
    
 
3417
        int isNumber = PyNumber_Check(arg);
 
3418
        
 
3419
        tmp = arg;
 
3420
        Py_INCREF(tmp);
 
3421
        Py_DECREF(self->x1);
 
3422
        if (isNumber == 1) {
 
3423
                self->x1 = PyNumber_Float(tmp);
 
3424
        self->modebuffer[2] = 0;
 
3425
        }
 
3426
        else {
 
3427
                self->x1 = tmp;
 
3428
        streamtmp = PyObject_CallMethod((PyObject *)self->x1, "_getStream", NULL);
 
3429
        Py_INCREF(streamtmp);
 
3430
        Py_XDECREF(self->x1_stream);
 
3431
        self->x1_stream = (Stream *)streamtmp;
 
3432
                self->modebuffer[2] = 1;
 
3433
        }
 
3434
    
 
3435
    (*self->mode_func_ptr)(self);
 
3436
    
 
3437
        Py_INCREF(Py_None);
 
3438
        return Py_None;
 
3439
}       
 
3440
 
 
3441
static PyObject *
 
3442
TrigXnoise_setX2(TrigXnoise *self, PyObject *arg)
 
3443
{
 
3444
        PyObject *tmp, *streamtmp;
 
3445
        
 
3446
        if (arg == NULL) {
 
3447
                Py_INCREF(Py_None);
 
3448
                return Py_None;
 
3449
        }
 
3450
    
 
3451
        int isNumber = PyNumber_Check(arg);
 
3452
        
 
3453
        tmp = arg;
 
3454
        Py_INCREF(tmp);
 
3455
        Py_DECREF(self->x2);
 
3456
        if (isNumber == 1) {
 
3457
                self->x2 = PyNumber_Float(tmp);
 
3458
        self->modebuffer[3] = 0;
 
3459
        }
 
3460
        else {
 
3461
                self->x2 = tmp;
 
3462
        streamtmp = PyObject_CallMethod((PyObject *)self->x2, "_getStream", NULL);
 
3463
        Py_INCREF(streamtmp);
 
3464
        Py_XDECREF(self->x2_stream);
 
3465
        self->x2_stream = (Stream *)streamtmp;
 
3466
                self->modebuffer[3] = 1;
 
3467
        }
 
3468
    
 
3469
    (*self->mode_func_ptr)(self);
 
3470
    
 
3471
        Py_INCREF(Py_None);
 
3472
        return Py_None;
 
3473
}       
 
3474
 
 
3475
static PyMemberDef TrigXnoise_members[] = {
 
3476
    {"server", T_OBJECT_EX, offsetof(TrigXnoise, server), 0, "Pyo server."},
 
3477
    {"stream", T_OBJECT_EX, offsetof(TrigXnoise, stream), 0, "Stream object."},
 
3478
    {"input", T_OBJECT_EX, offsetof(TrigXnoise, input), 0, "Trigger input."},
 
3479
    {"x1", T_OBJECT_EX, offsetof(TrigXnoise, x1), 0, "first param."},
 
3480
    {"x2", T_OBJECT_EX, offsetof(TrigXnoise, x2), 0, "second param."},
 
3481
    {"mul", T_OBJECT_EX, offsetof(TrigXnoise, mul), 0, "Mul factor."},
 
3482
    {"add", T_OBJECT_EX, offsetof(TrigXnoise, add), 0, "Add factor."},
 
3483
    {NULL}  /* Sentinel */
 
3484
};
 
3485
 
 
3486
static PyMethodDef TrigXnoise_methods[] = {
 
3487
    {"getServer", (PyCFunction)TrigXnoise_getServer, METH_NOARGS, "Returns server object."},
 
3488
    {"_getStream", (PyCFunction)TrigXnoise_getStream, METH_NOARGS, "Returns stream object."},
 
3489
    {"deleteStream", (PyCFunction)TrigXnoise_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
3490
    {"play", (PyCFunction)TrigXnoise_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
3491
    {"out", (PyCFunction)TrigXnoise_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
 
3492
    {"stop", (PyCFunction)TrigXnoise_stop, METH_NOARGS, "Stops computing."},
 
3493
    {"setType", (PyCFunction)TrigXnoise_setType, METH_O, "Sets distribution type."},
 
3494
    {"setX1", (PyCFunction)TrigXnoise_setX1, METH_O, "Sets first param."},
 
3495
    {"setX2", (PyCFunction)TrigXnoise_setX2, METH_O, "Sets second param."},
 
3496
    {"setMul", (PyCFunction)TrigXnoise_setMul, METH_O, "Sets oscillator mul factor."},
 
3497
    {"setAdd", (PyCFunction)TrigXnoise_setAdd, METH_O, "Sets oscillator add factor."},
 
3498
    {"setSub", (PyCFunction)TrigXnoise_setSub, METH_O, "Sets inverse add factor."},
 
3499
    {"setDiv", (PyCFunction)TrigXnoise_setDiv, METH_O, "Sets inverse mul factor."},
 
3500
    {NULL}  /* Sentinel */
 
3501
};
 
3502
 
 
3503
static PyNumberMethods TrigXnoise_as_number = {
 
3504
    (binaryfunc)TrigXnoise_add,                         /*nb_add*/
 
3505
    (binaryfunc)TrigXnoise_sub,                         /*nb_subtract*/
 
3506
    (binaryfunc)TrigXnoise_multiply,                    /*nb_multiply*/
 
3507
    (binaryfunc)TrigXnoise_div,                                              /*nb_divide*/
 
3508
    0,                                              /*nb_remainder*/
 
3509
    0,                                              /*nb_divmod*/
 
3510
    0,                                              /*nb_power*/
 
3511
    0,                                              /*nb_neg*/
 
3512
    0,                                              /*nb_pos*/
 
3513
    0,                                              /*(unaryfunc)array_abs,*/
 
3514
    0,                                              /*nb_nonzero*/
 
3515
    0,                                              /*nb_invert*/
 
3516
    0,                                              /*nb_lshift*/
 
3517
    0,                                              /*nb_rshift*/
 
3518
    0,                                              /*nb_and*/
 
3519
    0,                                              /*nb_xor*/
 
3520
    0,                                              /*nb_or*/
 
3521
    0,                                              /*nb_coerce*/
 
3522
    0,                                              /*nb_int*/
 
3523
    0,                                              /*nb_long*/
 
3524
    0,                                              /*nb_float*/
 
3525
    0,                                              /*nb_oct*/
 
3526
    0,                                              /*nb_hex*/
 
3527
    (binaryfunc)TrigXnoise_inplace_add,                 /*inplace_add*/
 
3528
    (binaryfunc)TrigXnoise_inplace_sub,                 /*inplace_subtract*/
 
3529
    (binaryfunc)TrigXnoise_inplace_multiply,            /*inplace_multiply*/
 
3530
    (binaryfunc)TrigXnoise_inplace_div,                                              /*inplace_divide*/
 
3531
    0,                                              /*inplace_remainder*/
 
3532
    0,                                              /*inplace_power*/
 
3533
    0,                                              /*inplace_lshift*/
 
3534
    0,                                              /*inplace_rshift*/
 
3535
    0,                                              /*inplace_and*/
 
3536
    0,                                              /*inplace_xor*/
 
3537
    0,                                              /*inplace_or*/
 
3538
    0,                                              /*nb_floor_divide*/
 
3539
    0,                                              /*nb_true_divide*/
 
3540
    0,                                              /*nb_inplace_floor_divide*/
 
3541
    0,                                              /*nb_inplace_true_divide*/
 
3542
    0,                                              /* nb_index */
 
3543
};
 
3544
 
 
3545
PyTypeObject TrigXnoiseType = {
 
3546
    PyObject_HEAD_INIT(NULL)
 
3547
    0,                                              /*ob_size*/
 
3548
    "_pyo.TrigXnoise_base",                                   /*tp_name*/
 
3549
    sizeof(TrigXnoise),                                 /*tp_basicsize*/
 
3550
    0,                                              /*tp_itemsize*/
 
3551
    (destructor)TrigXnoise_dealloc,                     /*tp_dealloc*/
 
3552
    0,                                              /*tp_print*/
 
3553
    0,                                              /*tp_getattr*/
 
3554
    0,                                              /*tp_setattr*/
 
3555
    0,                                              /*tp_compare*/
 
3556
    0,                                              /*tp_repr*/
 
3557
    &TrigXnoise_as_number,                              /*tp_as_number*/
 
3558
    0,                                              /*tp_as_sequence*/
 
3559
    0,                                              /*tp_as_mapping*/
 
3560
    0,                                              /*tp_hash */
 
3561
    0,                                              /*tp_call*/
 
3562
    0,                                              /*tp_str*/
 
3563
    0,                                              /*tp_getattro*/
 
3564
    0,                                              /*tp_setattro*/
 
3565
    0,                                              /*tp_as_buffer*/
 
3566
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
3567
    "TrigXnoise objects. Periodically generates a new random value.",           /* tp_doc */
 
3568
    (traverseproc)TrigXnoise_traverse,                  /* tp_traverse */
 
3569
    (inquiry)TrigXnoise_clear,                          /* tp_clear */
 
3570
    0,                                              /* tp_richcompare */
 
3571
    0,                                              /* tp_weaklistoffset */
 
3572
    0,                                              /* tp_iter */
 
3573
    0,                                              /* tp_iternext */
 
3574
    TrigXnoise_methods,                                 /* tp_methods */
 
3575
    TrigXnoise_members,                                 /* tp_members */
 
3576
    0,                                              /* tp_getset */
 
3577
    0,                                              /* tp_base */
 
3578
    0,                                              /* tp_dict */
 
3579
    0,                                              /* tp_descr_get */
 
3580
    0,                                              /* tp_descr_set */
 
3581
    0,                                              /* tp_dictoffset */
 
3582
    (initproc)TrigXnoise_init,                          /* tp_init */
 
3583
    0,                                              /* tp_alloc */
 
3584
    TrigXnoise_new,                                     /* tp_new */
 
3585
};
 
3586
 
 
3587
/****************/
 
3588
/**** TrigXnoiseMidi *****/
 
3589
/****************/
 
3590
typedef struct {
 
3591
    pyo_audio_HEAD
 
3592
    PyObject *input;
 
3593
    Stream *input_stream;
 
3594
    PyObject *x1;
 
3595
    PyObject *x2;
 
3596
    Stream *x1_stream;
 
3597
    Stream *x2_stream;
 
3598
    MYFLT (*type_func_ptr)();
 
3599
    int scale; // 0 = Midi, 1 = frequency, 2 = transpo
 
3600
    int range_min;
 
3601
    int range_max;
 
3602
    int centralkey;
 
3603
    MYFLT xx1;
 
3604
    MYFLT xx2;
 
3605
    int type;
 
3606
    MYFLT value;
 
3607
    MYFLT lastPoissonX1;
 
3608
    int poisson_tab;
 
3609
    MYFLT poisson_buffer[2000];
 
3610
    MYFLT walkerValue;
 
3611
    MYFLT loop_buffer[15];
 
3612
    int loopChoice;
 
3613
    int loopCountPlay;
 
3614
    int loopTime;
 
3615
    int loopCountRec;
 
3616
    int loopLen;
 
3617
    int loopStop;
 
3618
    int modebuffer[4]; // need at least 2 slots for mul & add 
 
3619
} TrigXnoiseMidi;
 
3620
 
 
3621
static MYFLT
 
3622
TrigXnoiseMidi_convert(TrigXnoiseMidi *self) {
 
3623
    int midival;
 
3624
    MYFLT val;
 
3625
    
 
3626
    midival = (int)((self->value * (self->range_max-self->range_min)) + self->range_min);
 
3627
    
 
3628
    if (midival < 0)
 
3629
        midival = 0;
 
3630
    else if (midival > 127)
 
3631
        midival = 127;
 
3632
    
 
3633
    if (self->scale == 0)
 
3634
        val = (MYFLT)midival;
 
3635
    else if (self->scale == 1)
 
3636
        val = 8.1757989156437 * MYPOW(1.0594630943593, midival);
 
3637
    else if (self->scale == 2)
 
3638
        val = MYPOW(1.0594630943593, midival - self->centralkey);
 
3639
    else
 
3640
        val = midival;
 
3641
 
 
3642
    return val;
 
3643
}
 
3644
 
 
3645
 
 
3646
// no parameter
 
3647
static MYFLT
 
3648
TrigXnoiseMidi_uniform(TrigXnoiseMidi *self) {
 
3649
    return RANDOM_UNIFORM;    
 
3650
}
 
3651
 
 
3652
static MYFLT
 
3653
TrigXnoiseMidi_linear_min(TrigXnoiseMidi *self) {
 
3654
    MYFLT a = RANDOM_UNIFORM;    
 
3655
    MYFLT b = RANDOM_UNIFORM;
 
3656
    if (a < b) return a;
 
3657
    else return b;
 
3658
}
 
3659
 
 
3660
static MYFLT
 
3661
TrigXnoiseMidi_linear_max(TrigXnoiseMidi *self) {
 
3662
    MYFLT a = RANDOM_UNIFORM;    
 
3663
    MYFLT b = RANDOM_UNIFORM;
 
3664
    if (a > b) return a;
 
3665
    else return b;
 
3666
}
 
3667
 
 
3668
static MYFLT
 
3669
TrigXnoiseMidi_triangle(TrigXnoiseMidi *self) {
 
3670
    MYFLT a = RANDOM_UNIFORM;    
 
3671
    MYFLT b = RANDOM_UNIFORM;
 
3672
    return ((a + b) * 0.5);
 
3673
}
 
3674
 
 
3675
// x1 = slope
 
3676
static MYFLT
 
3677
TrigXnoiseMidi_expon_min(TrigXnoiseMidi *self) {
 
3678
    if (self->xx1 <= 0.0) self->xx1 = 0.00001;
 
3679
    MYFLT val = -MYLOG(RANDOM_UNIFORM) / self->xx1;    
 
3680
    if (val < 0.0) return 0.0;
 
3681
    else if (val > 1.0) return 1.0;
 
3682
    else return val;
 
3683
}
 
3684
 
 
3685
static MYFLT
 
3686
TrigXnoiseMidi_expon_max(TrigXnoiseMidi *self) {
 
3687
    if (self->xx1 <= 0.0) self->xx1 = 0.00001;
 
3688
    MYFLT val = 1.0 - (-MYLOG(RANDOM_UNIFORM) / self->xx1);    
 
3689
    if (val < 0.0) return 0.0;
 
3690
    else if (val > 1.0) return 1.0;
 
3691
    else return val;
 
3692
}
 
3693
 
 
3694
// x1 = bandwidth
 
3695
static MYFLT
 
3696
TrigXnoiseMidi_biexpon(TrigXnoiseMidi *self) {
 
3697
    MYFLT polar, val;
 
3698
    if (self->xx1 <= 0.0) self->xx1 = 0.00001;
 
3699
    MYFLT sum = RANDOM_UNIFORM * 2.0;
 
3700
    
 
3701
    if (sum > 1.0) {
 
3702
        polar = -1;
 
3703
        sum = 2.0 - sum;
 
3704
    }
 
3705
    else
 
3706
        polar = 1;
 
3707
    
 
3708
    val = 0.5 * (polar * MYLOG(sum) / self->xx1) + 0.5;
 
3709
    
 
3710
    if (val < 0.0) return 0.0;
 
3711
    else if (val > 1.0) return 1.0;
 
3712
    else return val;
 
3713
}
 
3714
 
 
3715
static MYFLT
 
3716
TrigXnoiseMidi_cauchy(TrigXnoiseMidi *self) {
 
3717
    MYFLT rnd, val, dir;
 
3718
    do {
 
3719
        rnd = RANDOM_UNIFORM;
 
3720
    }
 
3721
    while (rnd == 0.5);
 
3722
    
 
3723
    if (rand() < (RAND_MAX / 2))
 
3724
        dir = -1;
 
3725
    else
 
3726
        dir = 1;
 
3727
    
 
3728
    val = 0.5 * (MYTAN(rnd) * self->xx1 * dir) + 0.5;
 
3729
    
 
3730
    if (val < 0.0) return 0.0;
 
3731
    else if (val > 1.0) return 1.0;
 
3732
    else return val;
 
3733
}
 
3734
 
 
3735
// x1 = locator, x2 = shape
 
3736
static MYFLT
 
3737
TrigXnoiseMidi_weibull(TrigXnoiseMidi *self) {
 
3738
    MYFLT rnd, val;
 
3739
    if (self->xx2 <= 0.0) self->xx2 = 0.00001;
 
3740
    
 
3741
    rnd = 1.0 / (1.0 - RANDOM_UNIFORM);
 
3742
    val = self->xx1 * MYPOW(MYLOG(rnd), (1.0 / self->xx2));
 
3743
    
 
3744
    if (val < 0.0) return 0.0;
 
3745
    else if (val > 1.0) return 1.0;
 
3746
    else return val;
 
3747
}
 
3748
 
 
3749
// x1 = locator, x2 = bandwidth
 
3750
static MYFLT
 
3751
TrigXnoiseMidi_gaussian(TrigXnoiseMidi *self) {
 
3752
    MYFLT rnd, val;
 
3753
    
 
3754
    rnd = (RANDOM_UNIFORM + RANDOM_UNIFORM + RANDOM_UNIFORM + RANDOM_UNIFORM + RANDOM_UNIFORM + RANDOM_UNIFORM);
 
3755
    val = (self->xx2 * (rnd - 3.0) * 0.33 + self->xx1);
 
3756
    
 
3757
    if (val < 0.0) return 0.0;
 
3758
    else if (val > 1.0) return 1.0;
 
3759
    else return val;
 
3760
}
 
3761
 
 
3762
// x1 = gravity center, x2 = compress/expand
 
3763
static MYFLT
 
3764
TrigXnoiseMidi_poisson(TrigXnoiseMidi *self) {
 
3765
    int i, j, factorial;
 
3766
    long tot;
 
3767
    MYFLT val;
 
3768
    if (self->xx1 < 0.1) self->xx1 = 0.1;
 
3769
    if (self->xx2 < 0.1) self->xx2 = 0.1;
 
3770
    
 
3771
    if (self->xx1 != self->lastPoissonX1) {
 
3772
        self->lastPoissonX1 = self->xx1;
 
3773
        self->poisson_tab = 0;
 
3774
        factorial = 1;
 
3775
        for (i=1; i<12; i++) {
 
3776
            factorial *= i;
 
3777
            tot = (long)(1000.0 * (MYPOW(2.7182818, -self->xx1) * MYPOW(self->xx1, i) / factorial));
 
3778
            for (j=0; j<tot; j++) {
 
3779
                self->poisson_buffer[self->poisson_tab] = i;
 
3780
                self->poisson_tab++;
 
3781
            }
 
3782
        }
 
3783
    }
 
3784
    val = self->poisson_buffer[rand() % self->poisson_tab] / 12.0 * self->xx2;
 
3785
    
 
3786
    if (val < 0.0) return 0.0;
 
3787
    else if (val > 1.0) return 1.0;
 
3788
    else return val;
 
3789
}
 
3790
 
 
3791
// x1 = max value, x2 = max step
 
3792
static MYFLT
 
3793
TrigXnoiseMidi_walker(TrigXnoiseMidi *self) {
 
3794
    int modulo, dir;
 
3795
    
 
3796
    if (self->xx2 < 0.002) self->xx2 = 0.002;
 
3797
    
 
3798
    modulo = (int)(self->xx2 * 1000.0);
 
3799
    dir = rand() % 2;
 
3800
    
 
3801
    if (dir == 0)
 
3802
        self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
 
3803
    else
 
3804
        self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
 
3805
    
 
3806
    if (self->walkerValue > self->xx1)
 
3807
        self->walkerValue = self->xx1;
 
3808
    if (self->walkerValue < 0.0)
 
3809
        self->walkerValue = 0.0;
 
3810
    
 
3811
    return self->walkerValue;
 
3812
}
 
3813
 
 
3814
// x1 = max value, x2 = max step
 
3815
static MYFLT
 
3816
TrigXnoiseMidi_loopseg(TrigXnoiseMidi *self) {
 
3817
    int modulo, dir;
 
3818
    
 
3819
    if (self->loopChoice == 0) {
 
3820
        
 
3821
        self->loopCountPlay = self->loopTime = 0;
 
3822
        
 
3823
        if (self->xx2 < 0.002) self->xx2 = 0.002;
 
3824
        
 
3825
        modulo = (int)(self->xx2 * 1000.0);
 
3826
        dir = rand() % 2;
 
3827
        
 
3828
        if (dir == 0)
 
3829
            self->walkerValue = self->walkerValue + (((rand() % modulo) - (modulo / 2)) * 0.001);
 
3830
        else
 
3831
            self->walkerValue = self->walkerValue - (((rand() % modulo) - (modulo / 2)) * 0.001);
 
3832
        
 
3833
        if (self->walkerValue > self->xx1)
 
3834
            self->walkerValue = self->xx1;
 
3835
        if (self->walkerValue < 0.0)
 
3836
            self->walkerValue = 0.0;
 
3837
        
 
3838
        self->loop_buffer[self->loopCountRec++] = self->walkerValue;
 
3839
        
 
3840
        if (self->loopCountRec < self->loopLen)
 
3841
            self->loopChoice = 0;
 
3842
        else {
 
3843
            self->loopChoice = 1;
 
3844
            self->loopStop = (rand() % 4) + 1;
 
3845
        }
 
3846
    }
 
3847
    else {
 
3848
        self->loopCountRec = 0;
 
3849
        
 
3850
        self->walkerValue = self->loop_buffer[self->loopCountPlay++];
 
3851
        
 
3852
        if (self->loopCountPlay < self->loopLen)
 
3853
            self->loopChoice = 1;
 
3854
        else {
 
3855
            self->loopCountPlay = 0;
 
3856
            self->loopTime++;
 
3857
        }
 
3858
        
 
3859
        if (self->loopTime == self->loopStop) {
 
3860
            self->loopChoice = 0;
 
3861
            self->loopLen = (rand() % 10) + 3;
 
3862
        }
 
3863
    }
 
3864
    
 
3865
    return self->walkerValue;
 
3866
}
 
3867
 
 
3868
static void
 
3869
TrigXnoiseMidi_generate_ii(TrigXnoiseMidi *self) {
 
3870
    int i;
 
3871
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
3872
    self->xx1 = PyFloat_AS_DOUBLE(self->x1);
 
3873
    self->xx2 = PyFloat_AS_DOUBLE(self->x2);
 
3874
    
 
3875
    for (i=0; i<self->bufsize; i++) {
 
3876
        if (in[i] == 1) {
 
3877
            self->value = (*self->type_func_ptr)(self);
 
3878
            self->value = TrigXnoiseMidi_convert(self);
 
3879
        }    
 
3880
        self->data[i] = self->value;
 
3881
    }
 
3882
}
 
3883
 
 
3884
static void
 
3885
TrigXnoiseMidi_generate_ai(TrigXnoiseMidi *self) {
 
3886
    int i;
 
3887
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
3888
    MYFLT *x1 = Stream_getData((Stream *)self->x1_stream);
 
3889
    self->xx2 = PyFloat_AS_DOUBLE(self->x2);
 
3890
    
 
3891
    for (i=0; i<self->bufsize; i++) {
 
3892
        if (in[i] == 1) {
 
3893
            self->xx1 = x1[i];
 
3894
            self->value = (*self->type_func_ptr)(self);
 
3895
            self->value = TrigXnoiseMidi_convert(self);
 
3896
        }
 
3897
        self->data[i] = self->value;
 
3898
    }
 
3899
}
 
3900
 
 
3901
static void
 
3902
TrigXnoiseMidi_generate_ia(TrigXnoiseMidi *self) {
 
3903
    int i;
 
3904
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
3905
    self->xx1 = PyFloat_AS_DOUBLE(self->x1);
 
3906
    MYFLT *x2 = Stream_getData((Stream *)self->x2_stream);
 
3907
    
 
3908
    for (i=0; i<self->bufsize; i++) {
 
3909
        if (in[i] == 1) {
 
3910
            self->xx2 = x2[i];
 
3911
            self->value = (*self->type_func_ptr)(self);
 
3912
            self->value = TrigXnoiseMidi_convert(self);
 
3913
        }
 
3914
        self->data[i] = self->value;
 
3915
    }
 
3916
}
 
3917
 
 
3918
static void
 
3919
TrigXnoiseMidi_generate_aa(TrigXnoiseMidi *self) {
 
3920
    int i;
 
3921
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
3922
    MYFLT *x1 = Stream_getData((Stream *)self->x1_stream);
 
3923
    MYFLT *x2 = Stream_getData((Stream *)self->x2_stream);
 
3924
    
 
3925
    for (i=0; i<self->bufsize; i++) {
 
3926
        if (in[i] == 1) {
 
3927
            self->xx1 = x1[i];
 
3928
            self->xx2 = x2[i];
 
3929
            self->value = (*self->type_func_ptr)(self);
 
3930
            self->value = TrigXnoiseMidi_convert(self);
 
3931
        }
 
3932
        self->data[i] = self->value;
 
3933
    }
 
3934
}
 
3935
 
 
3936
static void TrigXnoiseMidi_postprocessing_ii(TrigXnoiseMidi *self) { POST_PROCESSING_II };
 
3937
static void TrigXnoiseMidi_postprocessing_ai(TrigXnoiseMidi *self) { POST_PROCESSING_AI };
 
3938
static void TrigXnoiseMidi_postprocessing_ia(TrigXnoiseMidi *self) { POST_PROCESSING_IA };
 
3939
static void TrigXnoiseMidi_postprocessing_aa(TrigXnoiseMidi *self) { POST_PROCESSING_AA };
 
3940
static void TrigXnoiseMidi_postprocessing_ireva(TrigXnoiseMidi *self) { POST_PROCESSING_IREVA };
 
3941
static void TrigXnoiseMidi_postprocessing_areva(TrigXnoiseMidi *self) { POST_PROCESSING_AREVA };
 
3942
static void TrigXnoiseMidi_postprocessing_revai(TrigXnoiseMidi *self) { POST_PROCESSING_REVAI };
 
3943
static void TrigXnoiseMidi_postprocessing_revaa(TrigXnoiseMidi *self) { POST_PROCESSING_REVAA };
 
3944
static void TrigXnoiseMidi_postprocessing_revareva(TrigXnoiseMidi *self) { POST_PROCESSING_REVAREVA };
 
3945
 
 
3946
static void
 
3947
TrigXnoiseMidi_setRandomType(TrigXnoiseMidi *self)
 
3948
{
 
3949
    
 
3950
    switch (self->type) {            
 
3951
        case 0:
 
3952
            self->type_func_ptr = TrigXnoiseMidi_uniform;
 
3953
            break;
 
3954
        case 1:
 
3955
            self->type_func_ptr = TrigXnoiseMidi_linear_min;
 
3956
            break;
 
3957
        case 2:
 
3958
            self->type_func_ptr = TrigXnoiseMidi_linear_max;
 
3959
            break;
 
3960
        case 3:
 
3961
            self->type_func_ptr = TrigXnoiseMidi_triangle;
 
3962
            break;
 
3963
        case 4:
 
3964
            self->type_func_ptr = TrigXnoiseMidi_expon_min;
 
3965
            break;
 
3966
        case 5:
 
3967
            self->type_func_ptr = TrigXnoiseMidi_expon_max;
 
3968
            break;
 
3969
        case 6:
 
3970
            self->type_func_ptr = TrigXnoiseMidi_biexpon;
 
3971
            break;
 
3972
        case 7:
 
3973
            self->type_func_ptr = TrigXnoiseMidi_cauchy;
 
3974
            break;
 
3975
        case 8:
 
3976
            self->type_func_ptr = TrigXnoiseMidi_weibull;
 
3977
            break;
 
3978
        case 9:
 
3979
            self->type_func_ptr = TrigXnoiseMidi_gaussian;
 
3980
            break;
 
3981
        case 10:
 
3982
            self->type_func_ptr = TrigXnoiseMidi_poisson;
 
3983
            break;
 
3984
        case 11:
 
3985
            self->type_func_ptr = TrigXnoiseMidi_walker;
 
3986
            break;
 
3987
        case 12:
 
3988
            self->type_func_ptr = TrigXnoiseMidi_loopseg;
 
3989
            break;
 
3990
    }        
 
3991
}
 
3992
 
 
3993
static void
 
3994
TrigXnoiseMidi_setProcMode(TrigXnoiseMidi *self)
 
3995
{
 
3996
    int procmode, muladdmode;
 
3997
    procmode = self->modebuffer[2] + self->modebuffer[3] * 10;
 
3998
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
3999
    
 
4000
        switch (procmode) {
 
4001
        case 0:    
 
4002
            self->proc_func_ptr = TrigXnoiseMidi_generate_ii;
 
4003
            break;
 
4004
        case 1:    
 
4005
            self->proc_func_ptr = TrigXnoiseMidi_generate_ai;
 
4006
            break;
 
4007
        case 10:    
 
4008
            self->proc_func_ptr = TrigXnoiseMidi_generate_ia;
 
4009
            break;
 
4010
        case 11:    
 
4011
            self->proc_func_ptr = TrigXnoiseMidi_generate_aa;
 
4012
            break;
 
4013
    } 
 
4014
        switch (muladdmode) {
 
4015
        case 0:        
 
4016
            self->muladd_func_ptr = TrigXnoiseMidi_postprocessing_ii;
 
4017
            break;
 
4018
        case 1:    
 
4019
            self->muladd_func_ptr = TrigXnoiseMidi_postprocessing_ai;
 
4020
            break;
 
4021
        case 2:    
 
4022
            self->muladd_func_ptr = TrigXnoiseMidi_postprocessing_revai;
 
4023
            break;
 
4024
        case 10:        
 
4025
            self->muladd_func_ptr = TrigXnoiseMidi_postprocessing_ia;
 
4026
            break;
 
4027
        case 11:    
 
4028
            self->muladd_func_ptr = TrigXnoiseMidi_postprocessing_aa;
 
4029
            break;
 
4030
        case 12:    
 
4031
            self->muladd_func_ptr = TrigXnoiseMidi_postprocessing_revaa;
 
4032
            break;
 
4033
        case 20:        
 
4034
            self->muladd_func_ptr = TrigXnoiseMidi_postprocessing_ireva;
 
4035
            break;
 
4036
        case 21:    
 
4037
            self->muladd_func_ptr = TrigXnoiseMidi_postprocessing_areva;
 
4038
            break;
 
4039
        case 22:    
 
4040
            self->muladd_func_ptr = TrigXnoiseMidi_postprocessing_revareva;
 
4041
            break;
 
4042
    }  
 
4043
}
 
4044
 
 
4045
static void
 
4046
TrigXnoiseMidi_compute_next_data_frame(TrigXnoiseMidi *self)
 
4047
{
 
4048
    (*self->proc_func_ptr)(self); 
 
4049
    (*self->muladd_func_ptr)(self);
 
4050
}
 
4051
 
 
4052
static int
 
4053
TrigXnoiseMidi_traverse(TrigXnoiseMidi *self, visitproc visit, void *arg)
 
4054
{
 
4055
    pyo_VISIT
 
4056
    Py_VISIT(self->input);
 
4057
    Py_VISIT(self->input_stream);
 
4058
    Py_VISIT(self->x1);    
 
4059
    Py_VISIT(self->x1_stream);    
 
4060
    Py_VISIT(self->x2);    
 
4061
    Py_VISIT(self->x2_stream);    
 
4062
    return 0;
 
4063
}
 
4064
 
 
4065
static int 
 
4066
TrigXnoiseMidi_clear(TrigXnoiseMidi *self)
 
4067
{
 
4068
    pyo_CLEAR
 
4069
    Py_CLEAR(self->input);
 
4070
    Py_CLEAR(self->input_stream);
 
4071
    Py_CLEAR(self->x1);    
 
4072
    Py_CLEAR(self->x1_stream);    
 
4073
    Py_CLEAR(self->x2);    
 
4074
    Py_CLEAR(self->x2_stream);    
 
4075
    return 0;
 
4076
}
 
4077
 
 
4078
static void
 
4079
TrigXnoiseMidi_dealloc(TrigXnoiseMidi* self)
 
4080
{
 
4081
    free(self->data);
 
4082
    TrigXnoiseMidi_clear(self);
 
4083
    self->ob_type->tp_free((PyObject*)self);
 
4084
}
 
4085
 
 
4086
static PyObject * TrigXnoiseMidi_deleteStream(TrigXnoiseMidi *self) { DELETE_STREAM };
 
4087
 
 
4088
static PyObject *
 
4089
TrigXnoiseMidi_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
4090
{
 
4091
    int i;
 
4092
    TrigXnoiseMidi *self;
 
4093
    self = (TrigXnoiseMidi *)type->tp_alloc(type, 0);
 
4094
        
 
4095
    self->x1 = PyFloat_FromDouble(0.5);
 
4096
    self->x2 = PyFloat_FromDouble(0.5);
 
4097
    self->xx1 = self->xx2 = self->walkerValue = 0.5;
 
4098
    self->value = 0.0;
 
4099
    self->scale = 0;
 
4100
    self->range_min = 0;
 
4101
    self->range_max = 127;
 
4102
    self->centralkey = 64;
 
4103
        self->modebuffer[0] = 0;
 
4104
        self->modebuffer[1] = 0;
 
4105
        self->modebuffer[2] = 0;
 
4106
        self->modebuffer[3] = 0;
 
4107
        
 
4108
    INIT_OBJECT_COMMON
 
4109
    
 
4110
    Server_generateSeed((Server *)self->server, TRIGXNOISEMIDI_ID);
 
4111
 
 
4112
    self->poisson_tab = 0;
 
4113
    self->lastPoissonX1 = -99.0;
 
4114
    for (i=0; i<2000; i++) {
 
4115
        self->poisson_buffer[i] = 0.0;
 
4116
    }
 
4117
    for (i=0; i<15; i++) {
 
4118
        self->loop_buffer[i] = 0.0;
 
4119
    }
 
4120
    self->loopChoice = self->loopCountPlay = self->loopTime = self->loopCountRec = self->loopStop = 0;    
 
4121
    self->loopLen = (rand() % 10) + 3;
 
4122
    
 
4123
    Stream_setFunctionPtr(self->stream, TrigXnoiseMidi_compute_next_data_frame);
 
4124
    self->mode_func_ptr = TrigXnoiseMidi_setProcMode;
 
4125
    return (PyObject *)self;
 
4126
}
 
4127
 
 
4128
static int
 
4129
TrigXnoiseMidi_init(TrigXnoiseMidi *self, PyObject *args, PyObject *kwds)
 
4130
{
 
4131
    PyObject *inputtmp, *input_streamtmp, *x1tmp=NULL, *x2tmp=NULL, *rangetmp=NULL, *multmp=NULL, *addtmp=NULL;
 
4132
    
 
4133
    static char *kwlist[] = {"input", "type", "x1", "x2", "scale", "range", "mul", "add", NULL};
 
4134
    
 
4135
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|iOOiOOO", kwlist, &inputtmp, &self->type, &x1tmp, &x2tmp, &self->scale, &rangetmp, &multmp, &addtmp))
 
4136
        return -1; 
 
4137
    
 
4138
    INIT_INPUT_STREAM
 
4139
    
 
4140
    if (x1tmp) {
 
4141
        PyObject_CallMethod((PyObject *)self, "setX1", "O", x1tmp);
 
4142
    }
 
4143
    
 
4144
    if (x2tmp) {
 
4145
        PyObject_CallMethod((PyObject *)self, "setX2", "O", x2tmp);
 
4146
    }
 
4147
 
 
4148
    if (rangetmp) {
 
4149
        PyObject_CallMethod((PyObject *)self, "setRange", "O", rangetmp);
 
4150
    }
 
4151
    
 
4152
    if (multmp) {
 
4153
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
4154
    }
 
4155
    
 
4156
    if (addtmp) {
 
4157
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
4158
    }
 
4159
    
 
4160
    Py_INCREF(self->stream);
 
4161
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
4162
    
 
4163
    TrigXnoiseMidi_setRandomType(self);
 
4164
    
 
4165
    (*self->mode_func_ptr)(self);
 
4166
        
 
4167
    Py_INCREF(self);
 
4168
    return 0;
 
4169
}
 
4170
 
 
4171
static PyObject * TrigXnoiseMidi_getServer(TrigXnoiseMidi* self) { GET_SERVER };
 
4172
static PyObject * TrigXnoiseMidi_getStream(TrigXnoiseMidi* self) { GET_STREAM };
 
4173
static PyObject * TrigXnoiseMidi_setMul(TrigXnoiseMidi *self, PyObject *arg) { SET_MUL };       
 
4174
static PyObject * TrigXnoiseMidi_setAdd(TrigXnoiseMidi *self, PyObject *arg) { SET_ADD };       
 
4175
static PyObject * TrigXnoiseMidi_setSub(TrigXnoiseMidi *self, PyObject *arg) { SET_SUB };       
 
4176
static PyObject * TrigXnoiseMidi_setDiv(TrigXnoiseMidi *self, PyObject *arg) { SET_DIV };       
 
4177
 
 
4178
static PyObject * TrigXnoiseMidi_play(TrigXnoiseMidi *self, PyObject *args, PyObject *kwds) { PLAY };
 
4179
static PyObject * TrigXnoiseMidi_out(TrigXnoiseMidi *self, PyObject *args, PyObject *kwds) { OUT };
 
4180
static PyObject * TrigXnoiseMidi_stop(TrigXnoiseMidi *self) { STOP };
 
4181
 
 
4182
static PyObject * TrigXnoiseMidi_multiply(TrigXnoiseMidi *self, PyObject *arg) { MULTIPLY };
 
4183
static PyObject * TrigXnoiseMidi_inplace_multiply(TrigXnoiseMidi *self, PyObject *arg) { INPLACE_MULTIPLY };
 
4184
static PyObject * TrigXnoiseMidi_add(TrigXnoiseMidi *self, PyObject *arg) { ADD };
 
4185
static PyObject * TrigXnoiseMidi_inplace_add(TrigXnoiseMidi *self, PyObject *arg) { INPLACE_ADD };
 
4186
static PyObject * TrigXnoiseMidi_sub(TrigXnoiseMidi *self, PyObject *arg) { SUB };
 
4187
static PyObject * TrigXnoiseMidi_inplace_sub(TrigXnoiseMidi *self, PyObject *arg) { INPLACE_SUB };
 
4188
static PyObject * TrigXnoiseMidi_div(TrigXnoiseMidi *self, PyObject *arg) { DIV };
 
4189
static PyObject * TrigXnoiseMidi_inplace_div(TrigXnoiseMidi *self, PyObject *arg) { INPLACE_DIV };
 
4190
 
 
4191
static PyObject *
 
4192
TrigXnoiseMidi_setType(TrigXnoiseMidi *self, PyObject *arg)
 
4193
{       
 
4194
        if (arg == NULL) {
 
4195
                Py_INCREF(Py_None);
 
4196
                return Py_None;
 
4197
        }
 
4198
    
 
4199
        int isNumber = PyInt_Check(arg);
 
4200
        
 
4201
        if (isNumber == 1) {
 
4202
                self->type = PyInt_AsLong(arg);
 
4203
        TrigXnoiseMidi_setRandomType(self);
 
4204
        }
 
4205
    
 
4206
        Py_INCREF(Py_None);
 
4207
        return Py_None;
 
4208
}       
 
4209
 
 
4210
static PyObject *
 
4211
TrigXnoiseMidi_setScale(TrigXnoiseMidi *self, PyObject *arg)
 
4212
{       
 
4213
    int tmp;
 
4214
        if (arg == NULL) {
 
4215
                Py_INCREF(Py_None);
 
4216
                return Py_None;
 
4217
        }
 
4218
    
 
4219
        int isNumber = PyInt_Check(arg);
 
4220
        
 
4221
        if (isNumber == 1) {
 
4222
                tmp = PyInt_AsLong(arg);
 
4223
        if (tmp >= 0 && tmp <= 2)
 
4224
            self->scale = tmp;
 
4225
        else
 
4226
            printf("scale attribute must be an integer {0, 1, 2}\n");
 
4227
        }
 
4228
    
 
4229
        Py_INCREF(Py_None);
 
4230
        return Py_None;
 
4231
}       
 
4232
 
 
4233
static PyObject *
 
4234
TrigXnoiseMidi_setRange(TrigXnoiseMidi *self, PyObject *args)
 
4235
{       
 
4236
        if (args == NULL) {
 
4237
                Py_INCREF(Py_None);
 
4238
                return Py_None;
 
4239
        }
 
4240
    
 
4241
        int isTuple = PyTuple_Check(args);
 
4242
    
 
4243
        if (isTuple == 1) {
 
4244
        self->range_min = PyInt_AsLong(PyTuple_GET_ITEM(args, 0));
 
4245
        self->range_max = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
 
4246
        self->centralkey = (int)((self->range_max + self->range_min) / 2);
 
4247
        }
 
4248
    
 
4249
    Py_INCREF(Py_None);
 
4250
        return Py_None;
 
4251
}       
 
4252
 
 
4253
static PyObject *
 
4254
TrigXnoiseMidi_setX1(TrigXnoiseMidi *self, PyObject *arg)
 
4255
{
 
4256
        PyObject *tmp, *streamtmp;
 
4257
        
 
4258
        if (arg == NULL) {
 
4259
                Py_INCREF(Py_None);
 
4260
                return Py_None;
 
4261
        }
 
4262
    
 
4263
        int isNumber = PyNumber_Check(arg);
 
4264
        
 
4265
        tmp = arg;
 
4266
        Py_INCREF(tmp);
 
4267
        Py_DECREF(self->x1);
 
4268
        if (isNumber == 1) {
 
4269
                self->x1 = PyNumber_Float(tmp);
 
4270
        self->modebuffer[2] = 0;
 
4271
        }
 
4272
        else {
 
4273
                self->x1 = tmp;
 
4274
        streamtmp = PyObject_CallMethod((PyObject *)self->x1, "_getStream", NULL);
 
4275
        Py_INCREF(streamtmp);
 
4276
        Py_XDECREF(self->x1_stream);
 
4277
        self->x1_stream = (Stream *)streamtmp;
 
4278
                self->modebuffer[2] = 1;
 
4279
        }
 
4280
    
 
4281
    (*self->mode_func_ptr)(self);
 
4282
    
 
4283
        Py_INCREF(Py_None);
 
4284
        return Py_None;
 
4285
}       
 
4286
 
 
4287
static PyObject *
 
4288
TrigXnoiseMidi_setX2(TrigXnoiseMidi *self, PyObject *arg)
 
4289
{
 
4290
        PyObject *tmp, *streamtmp;
 
4291
        
 
4292
        if (arg == NULL) {
 
4293
                Py_INCREF(Py_None);
 
4294
                return Py_None;
 
4295
        }
 
4296
    
 
4297
        int isNumber = PyNumber_Check(arg);
 
4298
        
 
4299
        tmp = arg;
 
4300
        Py_INCREF(tmp);
 
4301
        Py_DECREF(self->x2);
 
4302
        if (isNumber == 1) {
 
4303
                self->x2 = PyNumber_Float(tmp);
 
4304
        self->modebuffer[3] = 0;
 
4305
        }
 
4306
        else {
 
4307
                self->x2 = tmp;
 
4308
        streamtmp = PyObject_CallMethod((PyObject *)self->x2, "_getStream", NULL);
 
4309
        Py_INCREF(streamtmp);
 
4310
        Py_XDECREF(self->x2_stream);
 
4311
        self->x2_stream = (Stream *)streamtmp;
 
4312
                self->modebuffer[3] = 1;
 
4313
        }
 
4314
    
 
4315
    (*self->mode_func_ptr)(self);
 
4316
    
 
4317
        Py_INCREF(Py_None);
 
4318
        return Py_None;
 
4319
}       
 
4320
 
 
4321
static PyMemberDef TrigXnoiseMidi_members[] = {
 
4322
    {"server", T_OBJECT_EX, offsetof(TrigXnoiseMidi, server), 0, "Pyo server."},
 
4323
    {"stream", T_OBJECT_EX, offsetof(TrigXnoiseMidi, stream), 0, "Stream object."},
 
4324
    {"input", T_OBJECT_EX, offsetof(TrigXnoiseMidi, input), 0, "Trigger input."},
 
4325
    {"x1", T_OBJECT_EX, offsetof(TrigXnoiseMidi, x1), 0, "first param."},
 
4326
    {"x2", T_OBJECT_EX, offsetof(TrigXnoiseMidi, x2), 0, "second param."},
 
4327
    {"mul", T_OBJECT_EX, offsetof(TrigXnoiseMidi, mul), 0, "Mul factor."},
 
4328
    {"add", T_OBJECT_EX, offsetof(TrigXnoiseMidi, add), 0, "Add factor."},
 
4329
    {NULL}  /* Sentinel */
 
4330
};
 
4331
 
 
4332
static PyMethodDef TrigXnoiseMidi_methods[] = {
 
4333
    {"getServer", (PyCFunction)TrigXnoiseMidi_getServer, METH_NOARGS, "Returns server object."},
 
4334
    {"_getStream", (PyCFunction)TrigXnoiseMidi_getStream, METH_NOARGS, "Returns stream object."},
 
4335
    {"deleteStream", (PyCFunction)TrigXnoiseMidi_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
4336
    {"play", (PyCFunction)TrigXnoiseMidi_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
4337
    {"out", (PyCFunction)TrigXnoiseMidi_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
 
4338
    {"stop", (PyCFunction)TrigXnoiseMidi_stop, METH_NOARGS, "Stops computing."},
 
4339
    {"setType", (PyCFunction)TrigXnoiseMidi_setType, METH_O, "Sets distribution type."},
 
4340
    {"setScale", (PyCFunction)TrigXnoiseMidi_setScale, METH_O, "Sets output scale."},
 
4341
    {"setRange", (PyCFunction)TrigXnoiseMidi_setRange, METH_VARARGS, "Sets range in midi notes (min, max)."},
 
4342
    {"setX1", (PyCFunction)TrigXnoiseMidi_setX1, METH_O, "Sets first param."},
 
4343
    {"setX2", (PyCFunction)TrigXnoiseMidi_setX2, METH_O, "Sets second param."},
 
4344
    {"setMul", (PyCFunction)TrigXnoiseMidi_setMul, METH_O, "Sets oscillator mul factor."},
 
4345
    {"setAdd", (PyCFunction)TrigXnoiseMidi_setAdd, METH_O, "Sets oscillator add factor."},
 
4346
    {"setSub", (PyCFunction)TrigXnoiseMidi_setSub, METH_O, "Sets inverse add factor."},
 
4347
    {"setDiv", (PyCFunction)TrigXnoiseMidi_setDiv, METH_O, "Sets inverse mul factor."},
 
4348
    {NULL}  /* Sentinel */
 
4349
};
 
4350
 
 
4351
static PyNumberMethods TrigXnoiseMidi_as_number = {
 
4352
    (binaryfunc)TrigXnoiseMidi_add,                         /*nb_add*/
 
4353
    (binaryfunc)TrigXnoiseMidi_sub,                         /*nb_subtract*/
 
4354
    (binaryfunc)TrigXnoiseMidi_multiply,                    /*nb_multiply*/
 
4355
    (binaryfunc)TrigXnoiseMidi_div,                                              /*nb_divide*/
 
4356
    0,                                              /*nb_remainder*/
 
4357
    0,                                              /*nb_divmod*/
 
4358
    0,                                              /*nb_power*/
 
4359
    0,                                              /*nb_neg*/
 
4360
    0,                                              /*nb_pos*/
 
4361
    0,                                              /*(unaryfunc)array_abs,*/
 
4362
    0,                                              /*nb_nonzero*/
 
4363
    0,                                              /*nb_invert*/
 
4364
    0,                                              /*nb_lshift*/
 
4365
    0,                                              /*nb_rshift*/
 
4366
    0,                                              /*nb_and*/
 
4367
    0,                                              /*nb_xor*/
 
4368
    0,                                              /*nb_or*/
 
4369
    0,                                              /*nb_coerce*/
 
4370
    0,                                              /*nb_int*/
 
4371
    0,                                              /*nb_long*/
 
4372
    0,                                              /*nb_float*/
 
4373
    0,                                              /*nb_oct*/
 
4374
    0,                                              /*nb_hex*/
 
4375
    (binaryfunc)TrigXnoiseMidi_inplace_add,                 /*inplace_add*/
 
4376
    (binaryfunc)TrigXnoiseMidi_inplace_sub,                 /*inplace_subtract*/
 
4377
    (binaryfunc)TrigXnoiseMidi_inplace_multiply,            /*inplace_multiply*/
 
4378
    (binaryfunc)TrigXnoiseMidi_inplace_div,                                              /*inplace_divide*/
 
4379
    0,                                              /*inplace_remainder*/
 
4380
    0,                                              /*inplace_power*/
 
4381
    0,                                              /*inplace_lshift*/
 
4382
    0,                                              /*inplace_rshift*/
 
4383
    0,                                              /*inplace_and*/
 
4384
    0,                                              /*inplace_xor*/
 
4385
    0,                                              /*inplace_or*/
 
4386
    0,                                              /*nb_floor_divide*/
 
4387
    0,                                              /*nb_true_divide*/
 
4388
    0,                                              /*nb_inplace_floor_divide*/
 
4389
    0,                                              /*nb_inplace_true_divide*/
 
4390
    0,                                              /* nb_index */
 
4391
};
 
4392
 
 
4393
PyTypeObject TrigXnoiseMidiType = {
 
4394
    PyObject_HEAD_INIT(NULL)
 
4395
    0,                                              /*ob_size*/
 
4396
    "_pyo.TrigXnoiseMidi_base",                                   /*tp_name*/
 
4397
    sizeof(TrigXnoiseMidi),                                 /*tp_basicsize*/
 
4398
    0,                                              /*tp_itemsize*/
 
4399
    (destructor)TrigXnoiseMidi_dealloc,                     /*tp_dealloc*/
 
4400
    0,                                              /*tp_print*/
 
4401
    0,                                              /*tp_getattr*/
 
4402
    0,                                              /*tp_setattr*/
 
4403
    0,                                              /*tp_compare*/
 
4404
    0,                                              /*tp_repr*/
 
4405
    &TrigXnoiseMidi_as_number,                              /*tp_as_number*/
 
4406
    0,                                              /*tp_as_sequence*/
 
4407
    0,                                              /*tp_as_mapping*/
 
4408
    0,                                              /*tp_hash */
 
4409
    0,                                              /*tp_call*/
 
4410
    0,                                              /*tp_str*/
 
4411
    0,                                              /*tp_getattro*/
 
4412
    0,                                              /*tp_setattro*/
 
4413
    0,                                              /*tp_as_buffer*/
 
4414
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
4415
    "TrigXnoiseMidi objects. Periodically generates a new random value.",           /* tp_doc */
 
4416
    (traverseproc)TrigXnoiseMidi_traverse,                  /* tp_traverse */
 
4417
    (inquiry)TrigXnoiseMidi_clear,                          /* tp_clear */
 
4418
    0,                                              /* tp_richcompare */
 
4419
    0,                                              /* tp_weaklistoffset */
 
4420
    0,                                              /* tp_iter */
 
4421
    0,                                              /* tp_iternext */
 
4422
    TrigXnoiseMidi_methods,                                 /* tp_methods */
 
4423
    TrigXnoiseMidi_members,                                 /* tp_members */
 
4424
    0,                                              /* tp_getset */
 
4425
    0,                                              /* tp_base */
 
4426
    0,                                              /* tp_dict */
 
4427
    0,                                              /* tp_descr_get */
 
4428
    0,                                              /* tp_descr_set */
 
4429
    0,                                              /* tp_dictoffset */
 
4430
    (initproc)TrigXnoiseMidi_init,                          /* tp_init */
 
4431
    0,                                              /* tp_alloc */
 
4432
    TrigXnoiseMidi_new,                                     /* tp_new */
 
4433
};
 
4434
 
 
4435
/***************************************************/
 
4436
/******* Counter ***********/
 
4437
/***************************************************/
 
4438
typedef struct {
 
4439
    pyo_audio_HEAD
 
4440
    PyObject *input;
 
4441
    Stream *input_stream;
 
4442
    long tmp;
 
4443
    long min;
 
4444
    long max;
 
4445
    int dir;
 
4446
    int direction;
 
4447
    MYFLT value;
 
4448
    int modebuffer[2]; // need at least 2 slots for mul & add 
 
4449
} Counter;
 
4450
 
 
4451
static void
 
4452
Counter_generates(Counter *self) {
 
4453
    int i;
 
4454
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
4455
    
 
4456
    for (i=0; i<self->bufsize; i++) {
 
4457
        if (in[i] == 1) {
 
4458
            if (self->dir == 0) {
 
4459
                self->value = (MYFLT)self->tmp;
 
4460
                self->tmp++;
 
4461
                if (self->tmp >= self->max)
 
4462
                    self->tmp = self->min;
 
4463
            }    
 
4464
            else if (self->dir == 1) {
 
4465
                self->value = (MYFLT)self->tmp;
 
4466
                self->tmp--;
 
4467
                if (self->tmp < self->min)
 
4468
                    self->tmp = self->max - 1;
 
4469
            }    
 
4470
            else if (self->dir == 2) {
 
4471
                self->value = (MYFLT)self->tmp;
 
4472
                self->tmp = self->tmp + self->direction;
 
4473
                if (self->tmp >= self->max) {
 
4474
                    self->direction = -1;
 
4475
                    self->tmp -= 2;
 
4476
                }    
 
4477
                else if (self->tmp <= self->min) {
 
4478
                    self->direction = 1;
 
4479
                }    
 
4480
            }
 
4481
        }
 
4482
        self->data[i] = self->value;
 
4483
    }
 
4484
}
 
4485
 
 
4486
static void Counter_postprocessing_ii(Counter *self) { POST_PROCESSING_II };
 
4487
static void Counter_postprocessing_ai(Counter *self) { POST_PROCESSING_AI };
 
4488
static void Counter_postprocessing_ia(Counter *self) { POST_PROCESSING_IA };
 
4489
static void Counter_postprocessing_aa(Counter *self) { POST_PROCESSING_AA };
 
4490
static void Counter_postprocessing_ireva(Counter *self) { POST_PROCESSING_IREVA };
 
4491
static void Counter_postprocessing_areva(Counter *self) { POST_PROCESSING_AREVA };
 
4492
static void Counter_postprocessing_revai(Counter *self) { POST_PROCESSING_REVAI };
 
4493
static void Counter_postprocessing_revaa(Counter *self) { POST_PROCESSING_REVAA };
 
4494
static void Counter_postprocessing_revareva(Counter *self) { POST_PROCESSING_REVAREVA };
 
4495
 
 
4496
static void
 
4497
Counter_setProcMode(Counter *self)
 
4498
{
 
4499
    int muladdmode;
 
4500
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
4501
    
 
4502
    self->proc_func_ptr = Counter_generates;
 
4503
 
 
4504
        switch (muladdmode) {
 
4505
        case 0:        
 
4506
            self->muladd_func_ptr = Counter_postprocessing_ii;
 
4507
            break;
 
4508
        case 1:    
 
4509
            self->muladd_func_ptr = Counter_postprocessing_ai;
 
4510
            break;
 
4511
        case 2:    
 
4512
            self->muladd_func_ptr = Counter_postprocessing_revai;
 
4513
            break;
 
4514
        case 10:        
 
4515
            self->muladd_func_ptr = Counter_postprocessing_ia;
 
4516
            break;
 
4517
        case 11:    
 
4518
            self->muladd_func_ptr = Counter_postprocessing_aa;
 
4519
            break;
 
4520
        case 12:    
 
4521
            self->muladd_func_ptr = Counter_postprocessing_revaa;
 
4522
            break;
 
4523
        case 20:        
 
4524
            self->muladd_func_ptr = Counter_postprocessing_ireva;
 
4525
            break;
 
4526
        case 21:    
 
4527
            self->muladd_func_ptr = Counter_postprocessing_areva;
 
4528
            break;
 
4529
        case 22:    
 
4530
            self->muladd_func_ptr = Counter_postprocessing_revareva;
 
4531
            break;
 
4532
    }  
 
4533
}
 
4534
 
 
4535
static void
 
4536
Counter_compute_next_data_frame(Counter *self)
 
4537
{
 
4538
    (*self->proc_func_ptr)(self); 
 
4539
    (*self->muladd_func_ptr)(self);
 
4540
}
 
4541
 
 
4542
static int
 
4543
Counter_traverse(Counter *self, visitproc visit, void *arg)
 
4544
{
 
4545
    pyo_VISIT
 
4546
    Py_VISIT(self->input);
 
4547
    Py_VISIT(self->input_stream);
 
4548
    return 0;
 
4549
}
 
4550
 
 
4551
static int 
 
4552
Counter_clear(Counter *self)
 
4553
{
 
4554
    pyo_CLEAR
 
4555
    Py_CLEAR(self->input);
 
4556
    Py_CLEAR(self->input_stream);
 
4557
    return 0;
 
4558
}
 
4559
 
 
4560
static void
 
4561
Counter_dealloc(Counter* self)
 
4562
{
 
4563
    free(self->data);
 
4564
    Counter_clear(self);
 
4565
    self->ob_type->tp_free((PyObject*)self);
 
4566
}
 
4567
 
 
4568
static PyObject * Counter_deleteStream(Counter *self) { DELETE_STREAM };
 
4569
 
 
4570
static PyObject *
 
4571
Counter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
4572
{
 
4573
    int i;
 
4574
    Counter *self;
 
4575
    self = (Counter *)type->tp_alloc(type, 0);
 
4576
    
 
4577
    self->min = 0;
 
4578
    self->max = 100;
 
4579
    self->dir = 0;
 
4580
    self->direction = 1;
 
4581
        self->modebuffer[0] = 0;
 
4582
        self->modebuffer[1] = 0;
 
4583
    
 
4584
    INIT_OBJECT_COMMON
 
4585
    Stream_setFunctionPtr(self->stream, Counter_compute_next_data_frame);
 
4586
    self->mode_func_ptr = Counter_setProcMode;
 
4587
    return (PyObject *)self;
 
4588
}
 
4589
 
 
4590
static int
 
4591
Counter_init(Counter *self, PyObject *args, PyObject *kwds)
 
4592
{
 
4593
    PyObject *inputtmp, *input_streamtmp, *multmp=NULL, *addtmp=NULL;
 
4594
    
 
4595
    static char *kwlist[] = {"input", "min", "max", "dir", "mul", "add", NULL};
 
4596
    
 
4597
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|lliOO", kwlist, &inputtmp, &self->min, &self->max, &self->dir, &multmp, &addtmp))
 
4598
        return -1; 
 
4599
    
 
4600
    INIT_INPUT_STREAM
 
4601
 
 
4602
    if (multmp) {
 
4603
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
4604
    }
 
4605
    
 
4606
    if (addtmp) {
 
4607
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
4608
    }
 
4609
    
 
4610
    Py_INCREF(self->stream);
 
4611
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
4612
 
 
4613
    if (self->dir == 0 || self->dir == 2)
 
4614
        self->tmp = self->min;
 
4615
    else
 
4616
        self->tmp = self->max - 1;
 
4617
    
 
4618
    (*self->mode_func_ptr)(self);
 
4619
        
 
4620
    Py_INCREF(self);
 
4621
    return 0;
 
4622
}
 
4623
 
 
4624
static PyObject * Counter_getServer(Counter* self) { GET_SERVER };
 
4625
static PyObject * Counter_getStream(Counter* self) { GET_STREAM };
 
4626
static PyObject * Counter_setMul(Counter *self, PyObject *arg) { SET_MUL };     
 
4627
static PyObject * Counter_setAdd(Counter *self, PyObject *arg) { SET_ADD };     
 
4628
static PyObject * Counter_setSub(Counter *self, PyObject *arg) { SET_SUB };     
 
4629
static PyObject * Counter_setDiv(Counter *self, PyObject *arg) { SET_DIV };     
 
4630
 
 
4631
static PyObject * Counter_play(Counter *self, PyObject *args, PyObject *kwds) { PLAY };
 
4632
static PyObject * Counter_stop(Counter *self) { STOP };
 
4633
 
 
4634
static PyObject * Counter_multiply(Counter *self, PyObject *arg) { MULTIPLY };
 
4635
static PyObject * Counter_inplace_multiply(Counter *self, PyObject *arg) { INPLACE_MULTIPLY };
 
4636
static PyObject * Counter_add(Counter *self, PyObject *arg) { ADD };
 
4637
static PyObject * Counter_inplace_add(Counter *self, PyObject *arg) { INPLACE_ADD };
 
4638
static PyObject * Counter_sub(Counter *self, PyObject *arg) { SUB };
 
4639
static PyObject * Counter_inplace_sub(Counter *self, PyObject *arg) { INPLACE_SUB };
 
4640
static PyObject * Counter_div(Counter *self, PyObject *arg) { DIV };
 
4641
static PyObject * Counter_inplace_div(Counter *self, PyObject *arg) { INPLACE_DIV };
 
4642
 
 
4643
static PyObject *
 
4644
Counter_setMin(Counter *self, PyObject *arg)
 
4645
{       
 
4646
        if (arg == NULL) {
 
4647
                Py_INCREF(Py_None);
 
4648
                return Py_None;
 
4649
        }
 
4650
    
 
4651
        if (PyLong_Check(arg) || PyInt_Check(arg)) {    
 
4652
                self->min = PyLong_AsLong(arg);
 
4653
        }
 
4654
 
 
4655
        Py_INCREF(Py_None);
 
4656
        return Py_None;
 
4657
}       
 
4658
 
 
4659
static PyObject *
 
4660
Counter_setMax(Counter *self, PyObject *arg)
 
4661
{       
 
4662
        if (arg == NULL) {
 
4663
                Py_INCREF(Py_None);
 
4664
                return Py_None;
 
4665
        }
 
4666
    
 
4667
        if (PyLong_Check(arg) || PyInt_Check(arg)) {    
 
4668
                self->max = PyLong_AsLong(arg);
 
4669
        }
 
4670
    
 
4671
        Py_INCREF(Py_None);
 
4672
        return Py_None;
 
4673
}       
 
4674
 
 
4675
static PyObject *
 
4676
Counter_setDir(Counter *self, PyObject *arg)
 
4677
{       
 
4678
        if (arg == NULL) {
 
4679
                Py_INCREF(Py_None);
 
4680
                return Py_None;
 
4681
        }
 
4682
    
 
4683
        if (PyInt_Check(arg)) { 
 
4684
                self->dir = PyInt_AsLong(arg);
 
4685
        }
 
4686
    
 
4687
        Py_INCREF(Py_None);
 
4688
        return Py_None;
 
4689
}       
 
4690
 
 
4691
static PyObject *
 
4692
Counter_reset(Counter *self, PyObject *arg)
 
4693
{
 
4694
    int val;
 
4695
    
 
4696
    if (arg == Py_None) {
 
4697
        if (self->dir == 0 || self->dir == 2)
 
4698
            val = self->min;
 
4699
        else
 
4700
            val = self->max - 1;
 
4701
        self->tmp = val;
 
4702
    }
 
4703
    
 
4704
    else if (PyInt_Check(arg)) {
 
4705
        val = PyInt_AsLong(arg);
 
4706
        self->tmp = val;
 
4707
    }
 
4708
    
 
4709
        Py_INCREF(Py_None);
 
4710
        return Py_None;
 
4711
}
 
4712
 
 
4713
static PyMemberDef Counter_members[] = {
 
4714
{"server", T_OBJECT_EX, offsetof(Counter, server), 0, "Pyo server."},
 
4715
{"stream", T_OBJECT_EX, offsetof(Counter, stream), 0, "Stream object."},
 
4716
{"input", T_OBJECT_EX, offsetof(Counter, input), 0, "Input sound object."},
 
4717
{"mul", T_OBJECT_EX, offsetof(Counter, mul), 0, "Mul factor."},
 
4718
{"add", T_OBJECT_EX, offsetof(Counter, add), 0, "Add factor."},
 
4719
{NULL}  /* Sentinel */
 
4720
};
 
4721
 
 
4722
static PyMethodDef Counter_methods[] = {
 
4723
{"getServer", (PyCFunction)Counter_getServer, METH_NOARGS, "Returns server object."},
 
4724
{"_getStream", (PyCFunction)Counter_getStream, METH_NOARGS, "Returns stream object."},
 
4725
{"deleteStream", (PyCFunction)Counter_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
4726
{"play", (PyCFunction)Counter_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
4727
{"stop", (PyCFunction)Counter_stop, METH_NOARGS, "Stops computing."},
 
4728
{"setMin", (PyCFunction)Counter_setMin, METH_O, "Sets minimum value."},
 
4729
{"setMax", (PyCFunction)Counter_setMax, METH_O, "Sets maximum value."},
 
4730
{"setDir", (PyCFunction)Counter_setDir, METH_O, "Sets direction. 0 = forward, 1 = backward, 2 = back and forth"},
 
4731
{"reset", (PyCFunction)Counter_reset, METH_O, "Resets the current count of the counter."},
 
4732
{"setMul", (PyCFunction)Counter_setMul, METH_O, "Sets oscillator mul factor."},
 
4733
{"setAdd", (PyCFunction)Counter_setAdd, METH_O, "Sets oscillator add factor."},
 
4734
{"setSub", (PyCFunction)Counter_setSub, METH_O, "Sets inverse add factor."},
 
4735
{"setDiv", (PyCFunction)Counter_setDiv, METH_O, "Sets inverse mul factor."},
 
4736
{NULL}  /* Sentinel */
 
4737
};
 
4738
 
 
4739
static PyNumberMethods Counter_as_number = {
 
4740
(binaryfunc)Counter_add,                         /*nb_add*/
 
4741
(binaryfunc)Counter_sub,                         /*nb_subtract*/
 
4742
(binaryfunc)Counter_multiply,                    /*nb_multiply*/
 
4743
(binaryfunc)Counter_div,                                              /*nb_divide*/
 
4744
0,                                              /*nb_remainder*/
 
4745
0,                                              /*nb_divmod*/
 
4746
0,                                              /*nb_power*/
 
4747
0,                                              /*nb_neg*/
 
4748
0,                                              /*nb_pos*/
 
4749
0,                                              /*(unaryfunc)array_abs,*/
 
4750
0,                                              /*nb_nonzero*/
 
4751
0,                                              /*nb_invert*/
 
4752
0,                                              /*nb_lshift*/
 
4753
0,                                              /*nb_rshift*/
 
4754
0,                                              /*nb_and*/
 
4755
0,                                              /*nb_xor*/
 
4756
0,                                              /*nb_or*/
 
4757
0,                                              /*nb_coerce*/
 
4758
0,                                              /*nb_int*/
 
4759
0,                                              /*nb_long*/
 
4760
0,                                              /*nb_float*/
 
4761
0,                                              /*nb_oct*/
 
4762
0,                                              /*nb_hex*/
 
4763
(binaryfunc)Counter_inplace_add,                 /*inplace_add*/
 
4764
(binaryfunc)Counter_inplace_sub,                 /*inplace_subtract*/
 
4765
(binaryfunc)Counter_inplace_multiply,            /*inplace_multiply*/
 
4766
(binaryfunc)Counter_inplace_div,                                              /*inplace_divide*/
 
4767
0,                                              /*inplace_remainder*/
 
4768
0,                                              /*inplace_power*/
 
4769
0,                                              /*inplace_lshift*/
 
4770
0,                                              /*inplace_rshift*/
 
4771
0,                                              /*inplace_and*/
 
4772
0,                                              /*inplace_xor*/
 
4773
0,                                              /*inplace_or*/
 
4774
0,                                              /*nb_floor_divide*/
 
4775
0,                                              /*nb_true_divide*/
 
4776
0,                                              /*nb_inplace_floor_divide*/
 
4777
0,                                              /*nb_inplace_true_divide*/
 
4778
0,                                              /* nb_index */
 
4779
};
 
4780
 
 
4781
PyTypeObject CounterType = {
 
4782
PyObject_HEAD_INIT(NULL)
 
4783
0,                                              /*ob_size*/
 
4784
"_pyo.Counter_base",                                   /*tp_name*/
 
4785
sizeof(Counter),                                 /*tp_basicsize*/
 
4786
0,                                              /*tp_itemsize*/
 
4787
(destructor)Counter_dealloc,                     /*tp_dealloc*/
 
4788
0,                                              /*tp_print*/
 
4789
0,                                              /*tp_getattr*/
 
4790
0,                                              /*tp_setattr*/
 
4791
0,                                              /*tp_compare*/
 
4792
0,                                              /*tp_repr*/
 
4793
&Counter_as_number,                              /*tp_as_number*/
 
4794
0,                                              /*tp_as_sequence*/
 
4795
0,                                              /*tp_as_mapping*/
 
4796
0,                                              /*tp_hash */
 
4797
0,                                              /*tp_call*/
 
4798
0,                                              /*tp_str*/
 
4799
0,                                              /*tp_getattro*/
 
4800
0,                                              /*tp_setattro*/
 
4801
0,                                              /*tp_as_buffer*/
 
4802
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
4803
"Counter objects. Integer incrementor.",           /* tp_doc */
 
4804
(traverseproc)Counter_traverse,                  /* tp_traverse */
 
4805
(inquiry)Counter_clear,                          /* tp_clear */
 
4806
0,                                              /* tp_richcompare */
 
4807
0,                                              /* tp_weaklistoffset */
 
4808
0,                                              /* tp_iter */
 
4809
0,                                              /* tp_iternext */
 
4810
Counter_methods,                                 /* tp_methods */
 
4811
Counter_members,                                 /* tp_members */
 
4812
0,                                              /* tp_getset */
 
4813
0,                                              /* tp_base */
 
4814
0,                                              /* tp_dict */
 
4815
0,                                              /* tp_descr_get */
 
4816
0,                                              /* tp_descr_set */
 
4817
0,                                              /* tp_dictoffset */
 
4818
(initproc)Counter_init,                          /* tp_init */
 
4819
0,                                              /* tp_alloc */
 
4820
Counter_new,                                     /* tp_new */
 
4821
};
 
4822
 
 
4823
/***************************************************/
 
4824
/******* Thresh ***********/
 
4825
/***************************************************/
 
4826
typedef struct {
 
4827
    pyo_audio_HEAD
 
4828
    PyObject *input;
 
4829
    Stream *input_stream;
 
4830
    PyObject *threshold;
 
4831
    Stream *threshold_stream;
 
4832
    int dir;
 
4833
    int ready;
 
4834
    int modebuffer[3];
 
4835
} Thresh;
 
4836
 
 
4837
static void
 
4838
Thresh_generates_i(Thresh *self) {
 
4839
    int i;
 
4840
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
4841
    MYFLT thresh = PyFloat_AS_DOUBLE(self->threshold);
 
4842
 
 
4843
    switch (self->dir) {
 
4844
        case 0:
 
4845
            for (i=0; i<self->bufsize; i++) {
 
4846
                self->data[i] = 0.0;
 
4847
                if (in[i] > thresh && self->ready == 1) {
 
4848
                    self->data[i] = 1.0;
 
4849
                    self->ready = 0;
 
4850
                }
 
4851
                else if (in[i] <= thresh && self->ready == 0)
 
4852
                    self->ready = 1;
 
4853
            } 
 
4854
            break;
 
4855
        case 1:
 
4856
            for (i=0; i<self->bufsize; i++) {
 
4857
                self->data[i] = 0.0;
 
4858
                if (in[i] < thresh && self->ready == 1) {
 
4859
                    self->data[i] = 1.0;
 
4860
                    self->ready = 0;
 
4861
                }
 
4862
                else if (in[i] >= thresh && self->ready == 0)
 
4863
                    self->ready = 1;
 
4864
            } 
 
4865
            break;
 
4866
        case 2:
 
4867
            for (i=0; i<self->bufsize; i++) {
 
4868
                self->data[i] = 0.0;
 
4869
                if (in[i] > thresh && self->ready == 1) {
 
4870
                    self->data[i] = 1.0;
 
4871
                    self->ready = 0;
 
4872
                }
 
4873
                else if (in[i] <= thresh && self->ready == 0) {
 
4874
                    self->data[i] = 1.0;
 
4875
                    self->ready = 1;
 
4876
                }    
 
4877
            } 
 
4878
            break;
 
4879
    }
 
4880
}
 
4881
 
 
4882
static void
 
4883
Thresh_generates_a(Thresh *self) {
 
4884
    int i;
 
4885
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
4886
    MYFLT *thresh = Stream_getData((Stream *)self->threshold_stream);
 
4887
    
 
4888
    switch (self->dir) {
 
4889
        case 0:
 
4890
            for (i=0; i<self->bufsize; i++) {
 
4891
                self->data[i] = 0.0;
 
4892
                if (in[i] > thresh[i] && self->ready == 1) {
 
4893
                    self->data[i] = 1.0;
 
4894
                    self->ready = 0;
 
4895
                }
 
4896
                else if (in[i] <= thresh[i] && self->ready == 0)
 
4897
                    self->ready = 1;
 
4898
            } 
 
4899
            break;
 
4900
        case 1:
 
4901
            for (i=0; i<self->bufsize; i++) {
 
4902
                self->data[i] = 0.0;
 
4903
                if (in[i] < thresh[i] && self->ready == 1) {
 
4904
                    self->data[i] = 1.0;
 
4905
                    self->ready = 0;
 
4906
                }
 
4907
                else if (in[i] >= thresh[i] && self->ready == 0)
 
4908
                    self->ready = 1;
 
4909
            } 
 
4910
            break;
 
4911
        case 2:
 
4912
            for (i=0; i<self->bufsize; i++) {
 
4913
                self->data[i] = 0.0;
 
4914
                if (in[i] > thresh[i] && self->ready == 1) {
 
4915
                    self->data[i] = 1.0;
 
4916
                    self->ready = 0;
 
4917
                }
 
4918
                else if (in[i] <= thresh[i] && self->ready == 0)
 
4919
                    self->data[i] = 1.0;
 
4920
                self->ready = 1;
 
4921
            } 
 
4922
            break;
 
4923
    }
 
4924
}
 
4925
 
 
4926
static void Thresh_postprocessing_ii(Thresh *self) { POST_PROCESSING_II };
 
4927
static void Thresh_postprocessing_ai(Thresh *self) { POST_PROCESSING_AI };
 
4928
static void Thresh_postprocessing_ia(Thresh *self) { POST_PROCESSING_IA };
 
4929
static void Thresh_postprocessing_aa(Thresh *self) { POST_PROCESSING_AA };
 
4930
static void Thresh_postprocessing_ireva(Thresh *self) { POST_PROCESSING_IREVA };
 
4931
static void Thresh_postprocessing_areva(Thresh *self) { POST_PROCESSING_AREVA };
 
4932
static void Thresh_postprocessing_revai(Thresh *self) { POST_PROCESSING_REVAI };
 
4933
static void Thresh_postprocessing_revaa(Thresh *self) { POST_PROCESSING_REVAA };
 
4934
static void Thresh_postprocessing_revareva(Thresh *self) { POST_PROCESSING_REVAREVA };
 
4935
 
 
4936
static void
 
4937
Thresh_setProcMode(Thresh *self)
 
4938
{    
 
4939
    int procmode = self->modebuffer[2];
 
4940
    int muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
4941
 
 
4942
    switch (procmode) {
 
4943
        case 0:        
 
4944
            self->proc_func_ptr = Thresh_generates_i;
 
4945
            break;
 
4946
        case 1:    
 
4947
            self->proc_func_ptr = Thresh_generates_a;
 
4948
            break;
 
4949
    }
 
4950
    switch (muladdmode) {
 
4951
        case 0:        
 
4952
            self->muladd_func_ptr = Thresh_postprocessing_ii;
 
4953
            break;
 
4954
        case 1:    
 
4955
            self->muladd_func_ptr = Thresh_postprocessing_ai;
 
4956
            break;
 
4957
        case 2:    
 
4958
            self->muladd_func_ptr = Thresh_postprocessing_revai;
 
4959
            break;
 
4960
        case 10:        
 
4961
            self->muladd_func_ptr = Thresh_postprocessing_ia;
 
4962
            break;
 
4963
        case 11:    
 
4964
            self->muladd_func_ptr = Thresh_postprocessing_aa;
 
4965
            break;
 
4966
        case 12:    
 
4967
            self->muladd_func_ptr = Thresh_postprocessing_revaa;
 
4968
            break;
 
4969
        case 20:        
 
4970
            self->muladd_func_ptr = Thresh_postprocessing_ireva;
 
4971
            break;
 
4972
        case 21:    
 
4973
            self->muladd_func_ptr = Thresh_postprocessing_areva;
 
4974
            break;
 
4975
        case 22:    
 
4976
            self->muladd_func_ptr = Thresh_postprocessing_revareva;
 
4977
            break;
 
4978
    }  
 
4979
}
 
4980
 
 
4981
static void
 
4982
Thresh_compute_next_data_frame(Thresh *self)
 
4983
{
 
4984
    (*self->proc_func_ptr)(self); 
 
4985
    (*self->muladd_func_ptr)(self);
 
4986
}
 
4987
 
 
4988
static int
 
4989
Thresh_traverse(Thresh *self, visitproc visit, void *arg)
 
4990
{
 
4991
    pyo_VISIT
 
4992
    Py_VISIT(self->input);
 
4993
    Py_VISIT(self->input_stream);
 
4994
    Py_VISIT(self->threshold);
 
4995
    Py_VISIT(self->threshold_stream);
 
4996
    return 0;
 
4997
}
 
4998
 
 
4999
static int 
 
5000
Thresh_clear(Thresh *self)
 
5001
{
 
5002
    pyo_CLEAR
 
5003
    Py_CLEAR(self->input);
 
5004
    Py_CLEAR(self->input_stream);
 
5005
    Py_CLEAR(self->threshold);
 
5006
    Py_CLEAR(self->threshold_stream);
 
5007
    return 0;
 
5008
}
 
5009
 
 
5010
static void
 
5011
Thresh_dealloc(Thresh* self)
 
5012
{
 
5013
    free(self->data);
 
5014
    Thresh_clear(self);
 
5015
    self->ob_type->tp_free((PyObject*)self);
 
5016
}
 
5017
 
 
5018
static PyObject * Thresh_deleteStream(Thresh *self) { DELETE_STREAM };
 
5019
 
 
5020
static PyObject *
 
5021
Thresh_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
5022
{
 
5023
    int i;
 
5024
    Thresh *self;
 
5025
    self = (Thresh *)type->tp_alloc(type, 0);
 
5026
    
 
5027
    self->threshold = PyFloat_FromDouble(0.);
 
5028
    self->dir = 0;
 
5029
    self->ready = 0;
 
5030
        self->modebuffer[0] = 0;
 
5031
        self->modebuffer[1] = 0;
 
5032
    self->modebuffer[2] = 0;
 
5033
    
 
5034
    INIT_OBJECT_COMMON
 
5035
    Stream_setFunctionPtr(self->stream, Thresh_compute_next_data_frame);
 
5036
    self->mode_func_ptr = Thresh_setProcMode;
 
5037
    return (PyObject *)self;
 
5038
}
 
5039
 
 
5040
static int
 
5041
Thresh_init(Thresh *self, PyObject *args, PyObject *kwds)
 
5042
{
 
5043
    PyObject *inputtmp, *input_streamtmp, *thresholdtmp, *multmp=NULL, *addtmp=NULL;
 
5044
    
 
5045
    static char *kwlist[] = {"input", "threshold", "dir", "mul", "add", NULL};
 
5046
    
 
5047
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OiOO", kwlist, &inputtmp, &thresholdtmp, &self->dir, &multmp, &addtmp))
 
5048
        return -1; 
 
5049
    
 
5050
    INIT_INPUT_STREAM
 
5051
    
 
5052
    if (thresholdtmp) {
 
5053
        PyObject_CallMethod((PyObject *)self, "setThreshold", "O", thresholdtmp);
 
5054
    }
 
5055
    if (multmp) {
 
5056
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
5057
    }
 
5058
    
 
5059
    if (addtmp) {
 
5060
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
5061
    }
 
5062
    
 
5063
    Py_INCREF(self->stream);
 
5064
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
5065
 
 
5066
    (*self->mode_func_ptr)(self);
 
5067
        
 
5068
    Py_INCREF(self);
 
5069
    return 0;
 
5070
}
 
5071
 
 
5072
static PyObject * Thresh_getServer(Thresh* self) { GET_SERVER };
 
5073
static PyObject * Thresh_getStream(Thresh* self) { GET_STREAM };
 
5074
static PyObject * Thresh_setMul(Thresh *self, PyObject *arg) { SET_MUL };       
 
5075
static PyObject * Thresh_setAdd(Thresh *self, PyObject *arg) { SET_ADD };       
 
5076
static PyObject * Thresh_setSub(Thresh *self, PyObject *arg) { SET_SUB };       
 
5077
static PyObject * Thresh_setDiv(Thresh *self, PyObject *arg) { SET_DIV };       
 
5078
 
 
5079
static PyObject * Thresh_play(Thresh *self, PyObject *args, PyObject *kwds) { PLAY };
 
5080
static PyObject * Thresh_stop(Thresh *self) { STOP };
 
5081
 
 
5082
static PyObject * Thresh_multiply(Thresh *self, PyObject *arg) { MULTIPLY };
 
5083
static PyObject * Thresh_inplace_multiply(Thresh *self, PyObject *arg) { INPLACE_MULTIPLY };
 
5084
static PyObject * Thresh_add(Thresh *self, PyObject *arg) { ADD };
 
5085
static PyObject * Thresh_inplace_add(Thresh *self, PyObject *arg) { INPLACE_ADD };
 
5086
static PyObject * Thresh_sub(Thresh *self, PyObject *arg) { SUB };
 
5087
static PyObject * Thresh_inplace_sub(Thresh *self, PyObject *arg) { INPLACE_SUB };
 
5088
static PyObject * Thresh_div(Thresh *self, PyObject *arg) { DIV };
 
5089
static PyObject * Thresh_inplace_div(Thresh *self, PyObject *arg) { INPLACE_DIV };
 
5090
 
 
5091
static PyObject *
 
5092
Thresh_setThreshold(Thresh *self, PyObject *arg)
 
5093
{
 
5094
        PyObject *tmp, *streamtmp;
 
5095
        
 
5096
        if (arg == NULL) {
 
5097
                Py_INCREF(Py_None);
 
5098
                return Py_None;
 
5099
        }
 
5100
    
 
5101
        int isNumber = PyNumber_Check(arg);
 
5102
        
 
5103
        tmp = arg;
 
5104
        Py_INCREF(tmp);
 
5105
        Py_DECREF(self->threshold);
 
5106
        if (isNumber == 1) {
 
5107
                self->threshold = PyNumber_Float(tmp);
 
5108
        self->modebuffer[2] = 0;
 
5109
        }
 
5110
        else {
 
5111
                self->threshold = tmp;
 
5112
        streamtmp = PyObject_CallMethod((PyObject *)self->threshold, "_getStream", NULL);
 
5113
        Py_INCREF(streamtmp);
 
5114
        Py_XDECREF(self->threshold_stream);
 
5115
        self->threshold_stream = (Stream *)streamtmp;
 
5116
                self->modebuffer[2] = 1;
 
5117
        }
 
5118
    
 
5119
    (*self->mode_func_ptr)(self);
 
5120
    
 
5121
        Py_INCREF(Py_None);
 
5122
        return Py_None;
 
5123
}       
 
5124
 
 
5125
static PyObject *
 
5126
Thresh_setDir(Thresh *self, PyObject *arg)
 
5127
{       
 
5128
        if (arg == NULL) {
 
5129
                Py_INCREF(Py_None);
 
5130
                return Py_None;
 
5131
        }
 
5132
    
 
5133
        if (PyInt_Check(arg)) { 
 
5134
                self->dir = PyInt_AsLong(arg);
 
5135
        }
 
5136
    
 
5137
        Py_INCREF(Py_None);
 
5138
        return Py_None;
 
5139
}       
 
5140
 
 
5141
static PyMemberDef Thresh_members[] = {
 
5142
{"server", T_OBJECT_EX, offsetof(Thresh, server), 0, "Pyo server."},
 
5143
{"stream", T_OBJECT_EX, offsetof(Thresh, stream), 0, "Stream object."},
 
5144
{"input", T_OBJECT_EX, offsetof(Thresh, input), 0, "Input sound object."},
 
5145
{"threshold", T_OBJECT_EX, offsetof(Thresh, threshold), 0, "Threshold object."},
 
5146
{"mul", T_OBJECT_EX, offsetof(Thresh, mul), 0, "Mul factor."},
 
5147
{"add", T_OBJECT_EX, offsetof(Thresh, add), 0, "Add factor."},
 
5148
{NULL}  /* Sentinel */
 
5149
};
 
5150
 
 
5151
static PyMethodDef Thresh_methods[] = {
 
5152
{"getServer", (PyCFunction)Thresh_getServer, METH_NOARGS, "Returns server object."},
 
5153
{"_getStream", (PyCFunction)Thresh_getStream, METH_NOARGS, "Returns stream object."},
 
5154
{"deleteStream", (PyCFunction)Thresh_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
5155
{"play", (PyCFunction)Thresh_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
5156
{"stop", (PyCFunction)Thresh_stop, METH_NOARGS, "Stops computing."},
 
5157
{"setThreshold", (PyCFunction)Thresh_setThreshold, METH_O, "Sets threshold value."},
 
5158
{"setDir", (PyCFunction)Thresh_setDir, METH_O, "Sets direction. 0 = upward, 1 = downward, 2 = up and down"},
 
5159
{"setMul", (PyCFunction)Thresh_setMul, METH_O, "Sets mul factor."},
 
5160
{"setAdd", (PyCFunction)Thresh_setAdd, METH_O, "Sets add factor."},
 
5161
{"setSub", (PyCFunction)Thresh_setSub, METH_O, "Sets inverse add factor."},
 
5162
{"setDiv", (PyCFunction)Thresh_setDiv, METH_O, "Sets inverse mul factor."},
 
5163
{NULL}  /* Sentinel */
 
5164
};
 
5165
 
 
5166
static PyNumberMethods Thresh_as_number = {
 
5167
    (binaryfunc)Thresh_add,                         /*nb_add*/
 
5168
    (binaryfunc)Thresh_sub,                         /*nb_subtract*/
 
5169
    (binaryfunc)Thresh_multiply,                    /*nb_multiply*/
 
5170
    (binaryfunc)Thresh_div,                                              /*nb_divide*/
 
5171
    0,                                              /*nb_remainder*/
 
5172
    0,                                              /*nb_divmod*/
 
5173
    0,                                              /*nb_power*/
 
5174
    0,                                              /*nb_neg*/
 
5175
    0,                                              /*nb_pos*/
 
5176
    0,                                              /*(unaryfunc)array_abs,*/
 
5177
    0,                                              /*nb_nonzero*/
 
5178
    0,                                              /*nb_invert*/
 
5179
    0,                                              /*nb_lshift*/
 
5180
    0,                                              /*nb_rshift*/
 
5181
    0,                                              /*nb_and*/
 
5182
    0,                                              /*nb_xor*/
 
5183
    0,                                              /*nb_or*/
 
5184
    0,                                              /*nb_coerce*/
 
5185
    0,                                              /*nb_int*/
 
5186
    0,                                              /*nb_long*/
 
5187
    0,                                              /*nb_float*/
 
5188
    0,                                              /*nb_oct*/
 
5189
    0,                                              /*nb_hex*/
 
5190
    (binaryfunc)Thresh_inplace_add,                 /*inplace_add*/
 
5191
    (binaryfunc)Thresh_inplace_sub,                 /*inplace_subtract*/
 
5192
    (binaryfunc)Thresh_inplace_multiply,            /*inplace_multiply*/
 
5193
    (binaryfunc)Thresh_inplace_div,                                              /*inplace_divide*/
 
5194
    0,                                              /*inplace_remainder*/
 
5195
    0,                                              /*inplace_power*/
 
5196
    0,                                              /*inplace_lshift*/
 
5197
    0,                                              /*inplace_rshift*/
 
5198
    0,                                              /*inplace_and*/
 
5199
    0,                                              /*inplace_xor*/
 
5200
    0,                                              /*inplace_or*/
 
5201
    0,                                              /*nb_floor_divide*/
 
5202
    0,                                              /*nb_true_divide*/
 
5203
    0,                                              /*nb_inplace_floor_divide*/
 
5204
    0,                                              /*nb_inplace_true_divide*/
 
5205
    0,                                              /* nb_index */
 
5206
};
 
5207
 
 
5208
PyTypeObject ThreshType = {
 
5209
PyObject_HEAD_INIT(NULL)
 
5210
0,                                              /*ob_size*/
 
5211
"_pyo.Thresh_base",                                   /*tp_name*/
 
5212
sizeof(Thresh),                                 /*tp_basicsize*/
 
5213
0,                                              /*tp_itemsize*/
 
5214
(destructor)Thresh_dealloc,                     /*tp_dealloc*/
 
5215
0,                                              /*tp_print*/
 
5216
0,                                              /*tp_getattr*/
 
5217
0,                                              /*tp_setattr*/
 
5218
0,                                              /*tp_compare*/
 
5219
0,                                              /*tp_repr*/
 
5220
&Thresh_as_number,                              /*tp_as_number*/
 
5221
0,                                              /*tp_as_sequence*/
 
5222
0,                                              /*tp_as_mapping*/
 
5223
0,                                              /*tp_hash */
 
5224
0,                                              /*tp_call*/
 
5225
0,                                              /*tp_str*/
 
5226
0,                                              /*tp_getattro*/
 
5227
0,                                              /*tp_setattro*/
 
5228
0,                                              /*tp_as_buffer*/
 
5229
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
5230
"Thresh objects. Threshold detector.",           /* tp_doc */
 
5231
(traverseproc)Thresh_traverse,                  /* tp_traverse */
 
5232
(inquiry)Thresh_clear,                          /* tp_clear */
 
5233
0,                                              /* tp_richcompare */
 
5234
0,                                              /* tp_weaklistoffset */
 
5235
0,                                              /* tp_iter */
 
5236
0,                                              /* tp_iternext */
 
5237
Thresh_methods,                                 /* tp_methods */
 
5238
Thresh_members,                                 /* tp_members */
 
5239
0,                                              /* tp_getset */
 
5240
0,                                              /* tp_base */
 
5241
0,                                              /* tp_dict */
 
5242
0,                                              /* tp_descr_get */
 
5243
0,                                              /* tp_descr_set */
 
5244
0,                                              /* tp_dictoffset */
 
5245
(initproc)Thresh_init,                          /* tp_init */
 
5246
0,                                              /* tp_alloc */
 
5247
Thresh_new,                                     /* tp_new */
 
5248
};
 
5249
 
 
5250
/***************************************************/
 
5251
/******* Percent ***********/
 
5252
/***************************************************/
 
5253
typedef struct {
 
5254
    pyo_audio_HEAD
 
5255
    PyObject *input;
 
5256
    Stream *input_stream;
 
5257
    PyObject *percent;
 
5258
    Stream *percent_stream;
 
5259
    int modebuffer[3];
 
5260
} Percent;
 
5261
 
 
5262
static void
 
5263
Percent_generates_i(Percent *self) {
 
5264
    int i;
 
5265
    MYFLT guess;
 
5266
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
5267
    MYFLT perc = PyFloat_AS_DOUBLE(self->percent);
 
5268
    for (i=0; i<self->bufsize; i++) {
 
5269
        self->data[i] = 0.0;
 
5270
        if (in[i] == 1.0) {
 
5271
            guess = (rand()/((MYFLT)(RAND_MAX)+1)) * 100.0;
 
5272
            if (guess <= perc)
 
5273
                self->data[i] = 1.0;
 
5274
        }    
 
5275
    }
 
5276
}
 
5277
 
 
5278
static void
 
5279
Percent_generates_a(Percent *self) {
 
5280
    int i;
 
5281
    MYFLT guess;
 
5282
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
5283
    MYFLT *perc = Stream_getData((Stream *)self->percent_stream);
 
5284
    
 
5285
    for (i=0; i<self->bufsize; i++) {
 
5286
        self->data[i] = 0.0;
 
5287
        if (in[i] == 1.0) {
 
5288
            guess = (rand()/((MYFLT)(RAND_MAX)+1)) * 100.0;
 
5289
            if (guess <= perc[i])
 
5290
                self->data[i] = 1.0;
 
5291
        }    
 
5292
    }
 
5293
}
 
5294
 
 
5295
static void Percent_postprocessing_ii(Percent *self) { POST_PROCESSING_II };
 
5296
static void Percent_postprocessing_ai(Percent *self) { POST_PROCESSING_AI };
 
5297
static void Percent_postprocessing_ia(Percent *self) { POST_PROCESSING_IA };
 
5298
static void Percent_postprocessing_aa(Percent *self) { POST_PROCESSING_AA };
 
5299
static void Percent_postprocessing_ireva(Percent *self) { POST_PROCESSING_IREVA };
 
5300
static void Percent_postprocessing_areva(Percent *self) { POST_PROCESSING_AREVA };
 
5301
static void Percent_postprocessing_revai(Percent *self) { POST_PROCESSING_REVAI };
 
5302
static void Percent_postprocessing_revaa(Percent *self) { POST_PROCESSING_REVAA };
 
5303
static void Percent_postprocessing_revareva(Percent *self) { POST_PROCESSING_REVAREVA };
 
5304
 
 
5305
static void
 
5306
Percent_setProcMode(Percent *self)
 
5307
{    
 
5308
    int muladdmode, procmode
 
5309
    ;
 
5310
    procmode = self->modebuffer[2];
 
5311
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
5312
    switch (procmode) {
 
5313
        case 0:        
 
5314
            self->proc_func_ptr = Percent_generates_i;
 
5315
            break;
 
5316
        case 1:    
 
5317
            self->proc_func_ptr = Percent_generates_a;
 
5318
            break;
 
5319
    }
 
5320
    switch (muladdmode) {
 
5321
        case 0:        
 
5322
            self->muladd_func_ptr = Percent_postprocessing_ii;
 
5323
            break;
 
5324
        case 1:    
 
5325
            self->muladd_func_ptr = Percent_postprocessing_ai;
 
5326
            break;
 
5327
        case 2:    
 
5328
            self->muladd_func_ptr = Percent_postprocessing_revai;
 
5329
            break;
 
5330
        case 10:        
 
5331
            self->muladd_func_ptr = Percent_postprocessing_ia;
 
5332
            break;
 
5333
        case 11:    
 
5334
            self->muladd_func_ptr = Percent_postprocessing_aa;
 
5335
            break;
 
5336
        case 12:    
 
5337
            self->muladd_func_ptr = Percent_postprocessing_revaa;
 
5338
            break;
 
5339
        case 20:        
 
5340
            self->muladd_func_ptr = Percent_postprocessing_ireva;
 
5341
            break;
 
5342
        case 21:    
 
5343
            self->muladd_func_ptr = Percent_postprocessing_areva;
 
5344
            break;
 
5345
        case 22:    
 
5346
            self->muladd_func_ptr = Percent_postprocessing_revareva;
 
5347
            break;
 
5348
    }  
 
5349
}
 
5350
 
 
5351
static void
 
5352
Percent_compute_next_data_frame(Percent *self)
 
5353
{
 
5354
    (*self->proc_func_ptr)(self); 
 
5355
    (*self->muladd_func_ptr)(self);
 
5356
}
 
5357
 
 
5358
static int
 
5359
Percent_traverse(Percent *self, visitproc visit, void *arg)
 
5360
{
 
5361
    pyo_VISIT
 
5362
    Py_VISIT(self->input);
 
5363
    Py_VISIT(self->input_stream);
 
5364
    Py_VISIT(self->percent);
 
5365
    Py_VISIT(self->percent_stream);
 
5366
    return 0;
 
5367
}
 
5368
 
 
5369
static int 
 
5370
Percent_clear(Percent *self)
 
5371
{
 
5372
    pyo_CLEAR
 
5373
    Py_CLEAR(self->input);
 
5374
    Py_CLEAR(self->input_stream);
 
5375
    Py_CLEAR(self->percent);
 
5376
    Py_CLEAR(self->percent_stream);
 
5377
    return 0;
 
5378
}
 
5379
 
 
5380
static void
 
5381
Percent_dealloc(Percent* self)
 
5382
{
 
5383
    free(self->data);
 
5384
    Percent_clear(self);
 
5385
    self->ob_type->tp_free((PyObject*)self);
 
5386
}
 
5387
 
 
5388
static PyObject * Percent_deleteStream(Percent *self) { DELETE_STREAM };
 
5389
 
 
5390
static PyObject *
 
5391
Percent_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
5392
{
 
5393
    int i;
 
5394
    Percent *self;
 
5395
    self = (Percent *)type->tp_alloc(type, 0);
 
5396
    
 
5397
    self->percent = PyFloat_FromDouble(50.);
 
5398
        self->modebuffer[0] = 0;
 
5399
        self->modebuffer[1] = 0;
 
5400
    self->modebuffer[2] = 0;
 
5401
    
 
5402
    INIT_OBJECT_COMMON
 
5403
    Stream_setFunctionPtr(self->stream, Percent_compute_next_data_frame);
 
5404
    self->mode_func_ptr = Percent_setProcMode;
 
5405
    return (PyObject *)self;
 
5406
}
 
5407
 
 
5408
static int
 
5409
Percent_init(Percent *self, PyObject *args, PyObject *kwds)
 
5410
{
 
5411
    PyObject *inputtmp, *input_streamtmp, *percenttmp, *multmp=NULL, *addtmp=NULL;
 
5412
    
 
5413
    static char *kwlist[] = {"input", "percent", "mul", "add", NULL};
 
5414
    
 
5415
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|OOO", kwlist, &inputtmp, &percenttmp, &multmp, &addtmp))
 
5416
        return -1; 
 
5417
    
 
5418
    INIT_INPUT_STREAM
 
5419
    
 
5420
    if (percenttmp) {
 
5421
        PyObject_CallMethod((PyObject *)self, "setPercent", "O", percenttmp);
 
5422
    }
 
5423
    if (multmp) {
 
5424
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
5425
    }
 
5426
    
 
5427
    if (addtmp) {
 
5428
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
5429
    }
 
5430
    
 
5431
    Py_INCREF(self->stream);
 
5432
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
5433
    
 
5434
    Server_generateSeed((Server *)self->server, PERCENT_ID);
 
5435
 
 
5436
    (*self->mode_func_ptr)(self);
 
5437
    
 
5438
    Py_INCREF(self);
 
5439
    return 0;
 
5440
}
 
5441
 
 
5442
static PyObject * Percent_getServer(Percent* self) { GET_SERVER };
 
5443
static PyObject * Percent_getStream(Percent* self) { GET_STREAM };
 
5444
static PyObject * Percent_setMul(Percent *self, PyObject *arg) { SET_MUL };     
 
5445
static PyObject * Percent_setAdd(Percent *self, PyObject *arg) { SET_ADD };     
 
5446
static PyObject * Percent_setSub(Percent *self, PyObject *arg) { SET_SUB };     
 
5447
static PyObject * Percent_setDiv(Percent *self, PyObject *arg) { SET_DIV };     
 
5448
 
 
5449
static PyObject * Percent_play(Percent *self, PyObject *args, PyObject *kwds) { PLAY };
 
5450
static PyObject * Percent_stop(Percent *self) { STOP };
 
5451
 
 
5452
static PyObject * Percent_multiply(Percent *self, PyObject *arg) { MULTIPLY };
 
5453
static PyObject * Percent_inplace_multiply(Percent *self, PyObject *arg) { INPLACE_MULTIPLY };
 
5454
static PyObject * Percent_add(Percent *self, PyObject *arg) { ADD };
 
5455
static PyObject * Percent_inplace_add(Percent *self, PyObject *arg) { INPLACE_ADD };
 
5456
static PyObject * Percent_sub(Percent *self, PyObject *arg) { SUB };
 
5457
static PyObject * Percent_inplace_sub(Percent *self, PyObject *arg) { INPLACE_SUB };
 
5458
static PyObject * Percent_div(Percent *self, PyObject *arg) { DIV };
 
5459
static PyObject * Percent_inplace_div(Percent *self, PyObject *arg) { INPLACE_DIV };
 
5460
 
 
5461
static PyObject *
 
5462
Percent_setPercent(Percent *self, PyObject *arg)
 
5463
{
 
5464
        PyObject *tmp, *streamtmp;
 
5465
        
 
5466
        if (arg == NULL) {
 
5467
                Py_INCREF(Py_None);
 
5468
                return Py_None;
 
5469
        }
 
5470
    
 
5471
        int isNumber = PyNumber_Check(arg);
 
5472
        
 
5473
        tmp = arg;
 
5474
        Py_INCREF(tmp);
 
5475
        Py_DECREF(self->percent);
 
5476
        if (isNumber == 1) {
 
5477
                self->percent = PyNumber_Float(tmp);
 
5478
        self->modebuffer[2] = 0;
 
5479
        }
 
5480
        else {
 
5481
                self->percent = tmp;
 
5482
        streamtmp = PyObject_CallMethod((PyObject *)self->percent, "_getStream", NULL);
 
5483
        Py_INCREF(streamtmp);
 
5484
        Py_XDECREF(self->percent_stream);
 
5485
        self->percent_stream = (Stream *)streamtmp;
 
5486
                self->modebuffer[2] = 1;
 
5487
        }
 
5488
    
 
5489
    (*self->mode_func_ptr)(self);
 
5490
    
 
5491
        Py_INCREF(Py_None);
 
5492
        return Py_None;
 
5493
}       
 
5494
 
 
5495
static PyMemberDef Percent_members[] = {
 
5496
    {"server", T_OBJECT_EX, offsetof(Percent, server), 0, "Pyo server."},
 
5497
    {"stream", T_OBJECT_EX, offsetof(Percent, stream), 0, "Stream object."},
 
5498
    {"input", T_OBJECT_EX, offsetof(Percent, input), 0, "Input sound object."},
 
5499
    {"percent", T_OBJECT_EX, offsetof(Percent, percent), 0, "percent attribute."},
 
5500
    {"mul", T_OBJECT_EX, offsetof(Percent, mul), 0, "Mul factor."},
 
5501
    {"add", T_OBJECT_EX, offsetof(Percent, add), 0, "Add factor."},
 
5502
    {NULL}  /* Sentinel */
 
5503
};
 
5504
 
 
5505
static PyMethodDef Percent_methods[] = {
 
5506
    {"getServer", (PyCFunction)Percent_getServer, METH_NOARGS, "Returns server object."},
 
5507
    {"_getStream", (PyCFunction)Percent_getStream, METH_NOARGS, "Returns stream object."},
 
5508
    {"deleteStream", (PyCFunction)Percent_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
5509
    {"play", (PyCFunction)Percent_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
5510
    {"stop", (PyCFunction)Percent_stop, METH_NOARGS, "Stops computing."},
 
5511
    {"setPercent", (PyCFunction)Percent_setPercent, METH_O, "Sets percentange value."},
 
5512
    {"setMul", (PyCFunction)Percent_setMul, METH_O, "Sets mul factor."},
 
5513
    {"setAdd", (PyCFunction)Percent_setAdd, METH_O, "Sets add factor."},
 
5514
    {"setSub", (PyCFunction)Percent_setSub, METH_O, "Sets inverse add factor."},
 
5515
    {"setDiv", (PyCFunction)Percent_setDiv, METH_O, "Sets inverse mul factor."},
 
5516
    {NULL}  /* Sentinel */
 
5517
};
 
5518
 
 
5519
static PyNumberMethods Percent_as_number = {
 
5520
    (binaryfunc)Percent_add,                         /*nb_add*/
 
5521
    (binaryfunc)Percent_sub,                         /*nb_subtract*/
 
5522
    (binaryfunc)Percent_multiply,                    /*nb_multiply*/
 
5523
    (binaryfunc)Percent_div,                                              /*nb_divide*/
 
5524
    0,                                              /*nb_remainder*/
 
5525
    0,                                              /*nb_divmod*/
 
5526
    0,                                              /*nb_power*/
 
5527
    0,                                              /*nb_neg*/
 
5528
    0,                                              /*nb_pos*/
 
5529
    0,                                              /*(unaryfunc)array_abs,*/
 
5530
    0,                                              /*nb_nonzero*/
 
5531
    0,                                              /*nb_invert*/
 
5532
    0,                                              /*nb_lshift*/
 
5533
    0,                                              /*nb_rshift*/
 
5534
    0,                                              /*nb_and*/
 
5535
    0,                                              /*nb_xor*/
 
5536
    0,                                              /*nb_or*/
 
5537
    0,                                              /*nb_coerce*/
 
5538
    0,                                              /*nb_int*/
 
5539
    0,                                              /*nb_long*/
 
5540
    0,                                              /*nb_float*/
 
5541
    0,                                              /*nb_oct*/
 
5542
    0,                                              /*nb_hex*/
 
5543
    (binaryfunc)Percent_inplace_add,                 /*inplace_add*/
 
5544
    (binaryfunc)Percent_inplace_sub,                 /*inplace_subtract*/
 
5545
    (binaryfunc)Percent_inplace_multiply,            /*inplace_multiply*/
 
5546
    (binaryfunc)Percent_inplace_div,                                              /*inplace_divide*/
 
5547
    0,                                              /*inplace_remainder*/
 
5548
    0,                                              /*inplace_power*/
 
5549
    0,                                              /*inplace_lshift*/
 
5550
    0,                                              /*inplace_rshift*/
 
5551
    0,                                              /*inplace_and*/
 
5552
    0,                                              /*inplace_xor*/
 
5553
    0,                                              /*inplace_or*/
 
5554
    0,                                              /*nb_floor_divide*/
 
5555
    0,                                              /*nb_true_divide*/
 
5556
    0,                                              /*nb_inplace_floor_divide*/
 
5557
    0,                                              /*nb_inplace_true_divide*/
 
5558
    0,                                              /* nb_index */
 
5559
};
 
5560
 
 
5561
PyTypeObject PercentType = {
 
5562
    PyObject_HEAD_INIT(NULL)
 
5563
    0,                                              /*ob_size*/
 
5564
    "_pyo.Percent_base",                                   /*tp_name*/
 
5565
    sizeof(Percent),                                 /*tp_basicsize*/
 
5566
    0,                                              /*tp_itemsize*/
 
5567
    (destructor)Percent_dealloc,                     /*tp_dealloc*/
 
5568
    0,                                              /*tp_print*/
 
5569
    0,                                              /*tp_getattr*/
 
5570
    0,                                              /*tp_setattr*/
 
5571
    0,                                              /*tp_compare*/
 
5572
    0,                                              /*tp_repr*/
 
5573
    &Percent_as_number,                              /*tp_as_number*/
 
5574
    0,                                              /*tp_as_sequence*/
 
5575
    0,                                              /*tp_as_mapping*/
 
5576
    0,                                              /*tp_hash */
 
5577
    0,                                              /*tp_call*/
 
5578
    0,                                              /*tp_str*/
 
5579
    0,                                              /*tp_getattro*/
 
5580
    0,                                              /*tp_setattro*/
 
5581
    0,                                              /*tp_as_buffer*/
 
5582
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
5583
    "Percent objects. Looks for input triggers and sets how much percentage of it to let pass.",           /* tp_doc */
 
5584
    (traverseproc)Percent_traverse,                  /* tp_traverse */
 
5585
    (inquiry)Percent_clear,                          /* tp_clear */
 
5586
    0,                                              /* tp_richcompare */
 
5587
    0,                                              /* tp_weaklistoffset */
 
5588
    0,                                              /* tp_iter */
 
5589
    0,                                              /* tp_iternext */
 
5590
    Percent_methods,                                 /* tp_methods */
 
5591
    Percent_members,                                 /* tp_members */
 
5592
    0,                                              /* tp_getset */
 
5593
    0,                                              /* tp_base */
 
5594
    0,                                              /* tp_dict */
 
5595
    0,                                              /* tp_descr_get */
 
5596
    0,                                              /* tp_descr_set */
 
5597
    0,                                              /* tp_dictoffset */
 
5598
    (initproc)Percent_init,                          /* tp_init */
 
5599
    0,                                              /* tp_alloc */
 
5600
    Percent_new,                                     /* tp_new */
 
5601
};
 
5602
 
 
5603
/*************************/
 
5604
/******* Timer ***********/
 
5605
/*************************/
 
5606
typedef struct {
 
5607
    pyo_audio_HEAD
 
5608
    PyObject *input;
 
5609
    Stream *input_stream;
 
5610
    PyObject *input2;
 
5611
    Stream *input2_stream;
 
5612
    unsigned long count;
 
5613
    MYFLT lasttime;
 
5614
    int started;
 
5615
    int modebuffer[2];
 
5616
} Timer;
 
5617
 
 
5618
static void
 
5619
Timer_generates(Timer *self) {
 
5620
    int i;
 
5621
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
5622
    MYFLT *in2 = Stream_getData((Stream *)self->input2_stream);
 
5623
    
 
5624
    for (i=0; i<self->bufsize; i++) {
 
5625
        if (self->started == 1) {
 
5626
            self->count++;
 
5627
            if (in[i] == 1.0) {
 
5628
                self->lasttime = self->count / self->sr;
 
5629
                self->started = 0;
 
5630
            }
 
5631
        }
 
5632
        
 
5633
        if (in2[i] == 1 && self->started == 0) {
 
5634
            self->count = 0;
 
5635
            self->started = 1;
 
5636
        }
 
5637
        
 
5638
        self->data[i] = self->lasttime;
 
5639
    } 
 
5640
}
 
5641
 
 
5642
static void Timer_postprocessing_ii(Timer *self) { POST_PROCESSING_II };
 
5643
static void Timer_postprocessing_ai(Timer *self) { POST_PROCESSING_AI };
 
5644
static void Timer_postprocessing_ia(Timer *self) { POST_PROCESSING_IA };
 
5645
static void Timer_postprocessing_aa(Timer *self) { POST_PROCESSING_AA };
 
5646
static void Timer_postprocessing_ireva(Timer *self) { POST_PROCESSING_IREVA };
 
5647
static void Timer_postprocessing_areva(Timer *self) { POST_PROCESSING_AREVA };
 
5648
static void Timer_postprocessing_revai(Timer *self) { POST_PROCESSING_REVAI };
 
5649
static void Timer_postprocessing_revaa(Timer *self) { POST_PROCESSING_REVAA };
 
5650
static void Timer_postprocessing_revareva(Timer *self) { POST_PROCESSING_REVAREVA };
 
5651
 
 
5652
static void
 
5653
Timer_setProcMode(Timer *self)
 
5654
{    
 
5655
    int muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
5656
    
 
5657
    self->proc_func_ptr = Timer_generates;
 
5658
    
 
5659
    switch (muladdmode) {
 
5660
        case 0:        
 
5661
            self->muladd_func_ptr = Timer_postprocessing_ii;
 
5662
            break;
 
5663
        case 1:    
 
5664
            self->muladd_func_ptr = Timer_postprocessing_ai;
 
5665
            break;
 
5666
        case 2:    
 
5667
            self->muladd_func_ptr = Timer_postprocessing_revai;
 
5668
            break;
 
5669
        case 10:        
 
5670
            self->muladd_func_ptr = Timer_postprocessing_ia;
 
5671
            break;
 
5672
        case 11:    
 
5673
            self->muladd_func_ptr = Timer_postprocessing_aa;
 
5674
            break;
 
5675
        case 12:    
 
5676
            self->muladd_func_ptr = Timer_postprocessing_revaa;
 
5677
            break;
 
5678
        case 20:        
 
5679
            self->muladd_func_ptr = Timer_postprocessing_ireva;
 
5680
            break;
 
5681
        case 21:    
 
5682
            self->muladd_func_ptr = Timer_postprocessing_areva;
 
5683
            break;
 
5684
        case 22:    
 
5685
            self->muladd_func_ptr = Timer_postprocessing_revareva;
 
5686
            break;
 
5687
    }  
 
5688
}
 
5689
 
 
5690
static void
 
5691
Timer_compute_next_data_frame(Timer *self)
 
5692
{
 
5693
    (*self->proc_func_ptr)(self); 
 
5694
    (*self->muladd_func_ptr)(self);
 
5695
}
 
5696
 
 
5697
static int
 
5698
Timer_traverse(Timer *self, visitproc visit, void *arg)
 
5699
{
 
5700
    pyo_VISIT
 
5701
    Py_VISIT(self->input);
 
5702
    Py_VISIT(self->input_stream);
 
5703
    Py_VISIT(self->input2);
 
5704
    Py_VISIT(self->input2_stream);
 
5705
    return 0;
 
5706
}
 
5707
 
 
5708
static int 
 
5709
Timer_clear(Timer *self)
 
5710
{
 
5711
    pyo_CLEAR
 
5712
    Py_CLEAR(self->input);
 
5713
    Py_CLEAR(self->input_stream);
 
5714
    Py_CLEAR(self->input2);
 
5715
    Py_CLEAR(self->input2_stream);
 
5716
    return 0;
 
5717
}
 
5718
 
 
5719
static void
 
5720
Timer_dealloc(Timer* self)
 
5721
{
 
5722
    free(self->data);
 
5723
    Timer_clear(self);
 
5724
    self->ob_type->tp_free((PyObject*)self);
 
5725
}
 
5726
 
 
5727
static PyObject * Timer_deleteStream(Timer *self) { DELETE_STREAM };
 
5728
 
 
5729
static PyObject *
 
5730
Timer_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
5731
{
 
5732
    int i;
 
5733
    Timer *self;
 
5734
    self = (Timer *)type->tp_alloc(type, 0);
 
5735
    
 
5736
    self->count = 0;
 
5737
    self->started = 0;
 
5738
    self->lasttime = 0.0;
 
5739
        self->modebuffer[0] = 0;
 
5740
        self->modebuffer[1] = 0;
 
5741
    
 
5742
    INIT_OBJECT_COMMON
 
5743
    Stream_setFunctionPtr(self->stream, Timer_compute_next_data_frame);
 
5744
    self->mode_func_ptr = Timer_setProcMode;
 
5745
    return (PyObject *)self;
 
5746
}
 
5747
 
 
5748
static int
 
5749
Timer_init(Timer *self, PyObject *args, PyObject *kwds)
 
5750
{
 
5751
    PyObject *inputtmp, *input_streamtmp, *input2tmp, *input2_streamtmp, *multmp=NULL, *addtmp=NULL;
 
5752
    
 
5753
    static char *kwlist[] = {"input", "input2", "mul", "add", NULL};
 
5754
    
 
5755
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, &inputtmp, &input2tmp, &multmp, &addtmp))
 
5756
        return -1; 
 
5757
    
 
5758
    INIT_INPUT_STREAM
 
5759
    
 
5760
    Py_XDECREF(self->input2);
 
5761
    self->input2 = input2tmp;
 
5762
    input2_streamtmp = PyObject_CallMethod((PyObject *)self->input2, "_getStream", NULL);
 
5763
    Py_INCREF(input2_streamtmp);
 
5764
    Py_XDECREF(self->input2_stream);
 
5765
    self->input2_stream = (Stream *)input2_streamtmp;
 
5766
    
 
5767
    if (multmp) {
 
5768
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
5769
    }
 
5770
    
 
5771
    if (addtmp) {
 
5772
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
5773
    }
 
5774
    
 
5775
    Py_INCREF(self->stream);
 
5776
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
5777
    
 
5778
    (*self->mode_func_ptr)(self);
 
5779
    
 
5780
    Py_INCREF(self);
 
5781
    return 0;
 
5782
}
 
5783
 
 
5784
static PyObject * Timer_getServer(Timer* self) { GET_SERVER };
 
5785
static PyObject * Timer_getStream(Timer* self) { GET_STREAM };
 
5786
static PyObject * Timer_setMul(Timer *self, PyObject *arg) { SET_MUL }; 
 
5787
static PyObject * Timer_setAdd(Timer *self, PyObject *arg) { SET_ADD }; 
 
5788
static PyObject * Timer_setSub(Timer *self, PyObject *arg) { SET_SUB }; 
 
5789
static PyObject * Timer_setDiv(Timer *self, PyObject *arg) { SET_DIV }; 
 
5790
 
 
5791
static PyObject * Timer_play(Timer *self, PyObject *args, PyObject *kwds) { PLAY };
 
5792
static PyObject * Timer_stop(Timer *self) { STOP };
 
5793
 
 
5794
static PyObject * Timer_multiply(Timer *self, PyObject *arg) { MULTIPLY };
 
5795
static PyObject * Timer_inplace_multiply(Timer *self, PyObject *arg) { INPLACE_MULTIPLY };
 
5796
static PyObject * Timer_add(Timer *self, PyObject *arg) { ADD };
 
5797
static PyObject * Timer_inplace_add(Timer *self, PyObject *arg) { INPLACE_ADD };
 
5798
static PyObject * Timer_sub(Timer *self, PyObject *arg) { SUB };
 
5799
static PyObject * Timer_inplace_sub(Timer *self, PyObject *arg) { INPLACE_SUB };
 
5800
static PyObject * Timer_div(Timer *self, PyObject *arg) { DIV };
 
5801
static PyObject * Timer_inplace_div(Timer *self, PyObject *arg) { INPLACE_DIV };
 
5802
 
 
5803
static PyMemberDef Timer_members[] = {
 
5804
    {"server", T_OBJECT_EX, offsetof(Timer, server), 0, "Pyo server."},
 
5805
    {"stream", T_OBJECT_EX, offsetof(Timer, stream), 0, "Stream object."},
 
5806
    {"input", T_OBJECT_EX, offsetof(Timer, input), 0, "Stops timer and output time elapsed."},
 
5807
    {"input2", T_OBJECT_EX, offsetof(Timer, input2), 0, "Starts timer."},
 
5808
    {"mul", T_OBJECT_EX, offsetof(Timer, mul), 0, "Mul factor."},
 
5809
    {"add", T_OBJECT_EX, offsetof(Timer, add), 0, "Add factor."},
 
5810
    {NULL}  /* Sentinel */
 
5811
};
 
5812
 
 
5813
static PyMethodDef Timer_methods[] = {
 
5814
    {"getServer", (PyCFunction)Timer_getServer, METH_NOARGS, "Returns server object."},
 
5815
    {"_getStream", (PyCFunction)Timer_getStream, METH_NOARGS, "Returns stream object."},
 
5816
    {"deleteStream", (PyCFunction)Timer_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
5817
    {"play", (PyCFunction)Timer_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
5818
    {"stop", (PyCFunction)Timer_stop, METH_NOARGS, "Stops computing."},
 
5819
    {"setMul", (PyCFunction)Timer_setMul, METH_O, "Sets mul factor."},
 
5820
    {"setAdd", (PyCFunction)Timer_setAdd, METH_O, "Sets add factor."},
 
5821
    {"setSub", (PyCFunction)Timer_setSub, METH_O, "Sets inverse add factor."},
 
5822
    {"setDiv", (PyCFunction)Timer_setDiv, METH_O, "Sets inverse mul factor."},
 
5823
    {NULL}  /* Sentinel */
 
5824
};
 
5825
 
 
5826
static PyNumberMethods Timer_as_number = {
 
5827
    (binaryfunc)Timer_add,                         /*nb_add*/
 
5828
    (binaryfunc)Timer_sub,                         /*nb_subtract*/
 
5829
    (binaryfunc)Timer_multiply,                    /*nb_multiply*/
 
5830
    (binaryfunc)Timer_div,                                              /*nb_divide*/
 
5831
    0,                                              /*nb_remainder*/
 
5832
    0,                                              /*nb_divmod*/
 
5833
    0,                                              /*nb_power*/
 
5834
    0,                                              /*nb_neg*/
 
5835
    0,                                              /*nb_pos*/
 
5836
    0,                                              /*(unaryfunc)array_abs,*/
 
5837
    0,                                              /*nb_nonzero*/
 
5838
    0,                                              /*nb_invert*/
 
5839
    0,                                              /*nb_lshift*/
 
5840
    0,                                              /*nb_rshift*/
 
5841
    0,                                              /*nb_and*/
 
5842
    0,                                              /*nb_xor*/
 
5843
    0,                                              /*nb_or*/
 
5844
    0,                                              /*nb_coerce*/
 
5845
    0,                                              /*nb_int*/
 
5846
    0,                                              /*nb_long*/
 
5847
    0,                                              /*nb_float*/
 
5848
    0,                                              /*nb_oct*/
 
5849
    0,                                              /*nb_hex*/
 
5850
    (binaryfunc)Timer_inplace_add,                 /*inplace_add*/
 
5851
    (binaryfunc)Timer_inplace_sub,                 /*inplace_subtract*/
 
5852
    (binaryfunc)Timer_inplace_multiply,            /*inplace_multiply*/
 
5853
    (binaryfunc)Timer_inplace_div,                                              /*inplace_divide*/
 
5854
    0,                                              /*inplace_remainder*/
 
5855
    0,                                              /*inplace_power*/
 
5856
    0,                                              /*inplace_lshift*/
 
5857
    0,                                              /*inplace_rshift*/
 
5858
    0,                                              /*inplace_and*/
 
5859
    0,                                              /*inplace_xor*/
 
5860
    0,                                              /*inplace_or*/
 
5861
    0,                                              /*nb_floor_divide*/
 
5862
    0,                                              /*nb_true_divide*/
 
5863
    0,                                              /*nb_inplace_floor_divide*/
 
5864
    0,                                              /*nb_inplace_true_divide*/
 
5865
    0,                                              /* nb_index */
 
5866
};
 
5867
 
 
5868
PyTypeObject TimerType = {
 
5869
    PyObject_HEAD_INIT(NULL)
 
5870
    0,                                              /*ob_size*/
 
5871
    "_pyo.Timer_base",                                   /*tp_name*/
 
5872
    sizeof(Timer),                                 /*tp_basicsize*/
 
5873
    0,                                              /*tp_itemsize*/
 
5874
    (destructor)Timer_dealloc,                     /*tp_dealloc*/
 
5875
    0,                                              /*tp_print*/
 
5876
    0,                                              /*tp_getattr*/
 
5877
    0,                                              /*tp_setattr*/
 
5878
    0,                                              /*tp_compare*/
 
5879
    0,                                              /*tp_repr*/
 
5880
    &Timer_as_number,                              /*tp_as_number*/
 
5881
    0,                                              /*tp_as_sequence*/
 
5882
    0,                                              /*tp_as_mapping*/
 
5883
    0,                                              /*tp_hash */
 
5884
    0,                                              /*tp_call*/
 
5885
    0,                                              /*tp_str*/
 
5886
    0,                                              /*tp_getattro*/
 
5887
    0,                                              /*tp_setattro*/
 
5888
    0,                                              /*tp_as_buffer*/
 
5889
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
5890
    "Timer objects. Returns elapsed time between two triggers.",           /* tp_doc */
 
5891
    (traverseproc)Timer_traverse,                  /* tp_traverse */
 
5892
    (inquiry)Timer_clear,                          /* tp_clear */
 
5893
    0,                                              /* tp_richcompare */
 
5894
    0,                                              /* tp_weaklistoffset */
 
5895
    0,                                              /* tp_iter */
 
5896
    0,                                              /* tp_iternext */
 
5897
    Timer_methods,                                 /* tp_methods */
 
5898
    Timer_members,                                 /* tp_members */
 
5899
    0,                                              /* tp_getset */
 
5900
    0,                                              /* tp_base */
 
5901
    0,                                              /* tp_dict */
 
5902
    0,                                              /* tp_descr_get */
 
5903
    0,                                              /* tp_descr_set */
 
5904
    0,                                              /* tp_dictoffset */
 
5905
    (initproc)Timer_init,                          /* tp_init */
 
5906
    0,                                              /* tp_alloc */
 
5907
    Timer_new,                                     /* tp_new */
 
5908
};
 
5909
 
 
5910
/*********************************************************************************************/
 
5911
/* Iter ********************************************************************************/
 
5912
/*********************************************************************************************/
 
5913
typedef struct {
 
5914
    pyo_audio_HEAD
 
5915
    PyObject *input;
 
5916
    Stream *input_stream;
 
5917
    int chSize;
 
5918
    int chCount;
 
5919
    MYFLT *choice;
 
5920
    MYFLT value;
 
5921
    int modebuffer[2]; // need at least 2 slots for mul & add 
 
5922
} Iter;
 
5923
 
 
5924
static void
 
5925
Iter_generate(Iter *self) {
 
5926
    int i;
 
5927
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
5928
    
 
5929
    for (i=0; i<self->bufsize; i++) {
 
5930
        if (in[i] == 1) {
 
5931
            if (self->chCount >= self->chSize)
 
5932
                self->chCount = 0;
 
5933
            self->value = self->choice[self->chCount];
 
5934
            self->chCount++;
 
5935
        }
 
5936
        self->data[i] = self->value;
 
5937
    }
 
5938
}
 
5939
 
 
5940
static void Iter_postprocessing_ii(Iter *self) { POST_PROCESSING_II };
 
5941
static void Iter_postprocessing_ai(Iter *self) { POST_PROCESSING_AI };
 
5942
static void Iter_postprocessing_ia(Iter *self) { POST_PROCESSING_IA };
 
5943
static void Iter_postprocessing_aa(Iter *self) { POST_PROCESSING_AA };
 
5944
static void Iter_postprocessing_ireva(Iter *self) { POST_PROCESSING_IREVA };
 
5945
static void Iter_postprocessing_areva(Iter *self) { POST_PROCESSING_AREVA };
 
5946
static void Iter_postprocessing_revai(Iter *self) { POST_PROCESSING_REVAI };
 
5947
static void Iter_postprocessing_revaa(Iter *self) { POST_PROCESSING_REVAA };
 
5948
static void Iter_postprocessing_revareva(Iter *self) { POST_PROCESSING_REVAREVA };
 
5949
 
 
5950
static void
 
5951
Iter_setProcMode(Iter *self)
 
5952
{
 
5953
    int muladdmode;
 
5954
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
5955
    
 
5956
    self->proc_func_ptr = Iter_generate;
 
5957
    
 
5958
        switch (muladdmode) {
 
5959
        case 0:        
 
5960
            self->muladd_func_ptr = Iter_postprocessing_ii;
 
5961
            break;
 
5962
        case 1:    
 
5963
            self->muladd_func_ptr = Iter_postprocessing_ai;
 
5964
            break;
 
5965
        case 2:    
 
5966
            self->muladd_func_ptr = Iter_postprocessing_revai;
 
5967
            break;
 
5968
        case 10:        
 
5969
            self->muladd_func_ptr = Iter_postprocessing_ia;
 
5970
            break;
 
5971
        case 11:    
 
5972
            self->muladd_func_ptr = Iter_postprocessing_aa;
 
5973
            break;
 
5974
        case 12:    
 
5975
            self->muladd_func_ptr = Iter_postprocessing_revaa;
 
5976
            break;
 
5977
        case 20:        
 
5978
            self->muladd_func_ptr = Iter_postprocessing_ireva;
 
5979
            break;
 
5980
        case 21:    
 
5981
            self->muladd_func_ptr = Iter_postprocessing_areva;
 
5982
            break;
 
5983
        case 22:    
 
5984
            self->muladd_func_ptr = Iter_postprocessing_revareva;
 
5985
            break;
 
5986
    }  
 
5987
}
 
5988
 
 
5989
static void
 
5990
Iter_compute_next_data_frame(Iter *self)
 
5991
{
 
5992
    (*self->proc_func_ptr)(self); 
 
5993
    (*self->muladd_func_ptr)(self);
 
5994
}
 
5995
 
 
5996
static int
 
5997
Iter_traverse(Iter *self, visitproc visit, void *arg)
 
5998
{
 
5999
    pyo_VISIT
 
6000
    Py_VISIT(self->input);
 
6001
    Py_VISIT(self->input_stream);
 
6002
    return 0;
 
6003
}
 
6004
 
 
6005
static int 
 
6006
Iter_clear(Iter *self)
 
6007
{
 
6008
    pyo_CLEAR
 
6009
    Py_CLEAR(self->input);
 
6010
    Py_CLEAR(self->input_stream);
 
6011
    return 0;
 
6012
}
 
6013
 
 
6014
static void
 
6015
Iter_dealloc(Iter* self)
 
6016
{
 
6017
    free(self->data);
 
6018
    free(self->choice);
 
6019
    Iter_clear(self);
 
6020
    self->ob_type->tp_free((PyObject*)self);
 
6021
}
 
6022
 
 
6023
static PyObject * Iter_deleteStream(Iter *self) { DELETE_STREAM };
 
6024
 
 
6025
static PyObject *
 
6026
Iter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
6027
{
 
6028
    int i;
 
6029
    Iter *self;
 
6030
    self = (Iter *)type->tp_alloc(type, 0);
 
6031
    
 
6032
    self->value = 0.;
 
6033
    self->chCount = 0;
 
6034
        self->modebuffer[0] = 0;
 
6035
        self->modebuffer[1] = 0;
 
6036
    
 
6037
    INIT_OBJECT_COMMON
 
6038
    Stream_setFunctionPtr(self->stream, Iter_compute_next_data_frame);
 
6039
    self->mode_func_ptr = Iter_setProcMode;
 
6040
    return (PyObject *)self;
 
6041
}
 
6042
 
 
6043
static int
 
6044
Iter_init(Iter *self, PyObject *args, PyObject *kwds)
 
6045
{
 
6046
    MYFLT inittmp = 0.0;
 
6047
    PyObject *inputtmp, *input_streamtmp, *choicetmp=NULL, *multmp=NULL, *addtmp=NULL;
 
6048
    
 
6049
    static char *kwlist[] = {"input", "choice", "init", "mul", "add", NULL};
 
6050
    
 
6051
    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE_OO_FOO, kwlist, &inputtmp, &choicetmp, &inittmp, &multmp, &addtmp))
 
6052
        return -1; 
 
6053
    
 
6054
    INIT_INPUT_STREAM
 
6055
    
 
6056
    if (choicetmp) {
 
6057
        PyObject_CallMethod((PyObject *)self, "setChoice", "O", choicetmp);
 
6058
    }
 
6059
    
 
6060
    if (multmp) {
 
6061
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
6062
    }
 
6063
    
 
6064
    if (addtmp) {
 
6065
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
6066
    }
 
6067
    
 
6068
    Py_INCREF(self->stream);
 
6069
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
6070
 
 
6071
    self->value = inittmp;
 
6072
    
 
6073
    (*self->mode_func_ptr)(self);
 
6074
    
 
6075
    Py_INCREF(self);
 
6076
    return 0;
 
6077
}
 
6078
 
 
6079
static PyObject * Iter_getServer(Iter* self) { GET_SERVER };
 
6080
static PyObject * Iter_getStream(Iter* self) { GET_STREAM };
 
6081
static PyObject * Iter_setMul(Iter *self, PyObject *arg) { SET_MUL };   
 
6082
static PyObject * Iter_setAdd(Iter *self, PyObject *arg) { SET_ADD };   
 
6083
static PyObject * Iter_setSub(Iter *self, PyObject *arg) { SET_SUB };   
 
6084
static PyObject * Iter_setDiv(Iter *self, PyObject *arg) { SET_DIV };   
 
6085
 
 
6086
static PyObject * Iter_play(Iter *self, PyObject *args, PyObject *kwds) { PLAY };
 
6087
static PyObject * Iter_out(Iter *self, PyObject *args, PyObject *kwds) { OUT };
 
6088
static PyObject * Iter_stop(Iter *self) { STOP };
 
6089
 
 
6090
static PyObject * Iter_multiply(Iter *self, PyObject *arg) { MULTIPLY };
 
6091
static PyObject * Iter_inplace_multiply(Iter *self, PyObject *arg) { INPLACE_MULTIPLY };
 
6092
static PyObject * Iter_add(Iter *self, PyObject *arg) { ADD };
 
6093
static PyObject * Iter_inplace_add(Iter *self, PyObject *arg) { INPLACE_ADD };
 
6094
static PyObject * Iter_sub(Iter *self, PyObject *arg) { SUB };
 
6095
static PyObject * Iter_inplace_sub(Iter *self, PyObject *arg) { INPLACE_SUB };
 
6096
static PyObject * Iter_div(Iter *self, PyObject *arg) { DIV };
 
6097
static PyObject * Iter_inplace_div(Iter *self, PyObject *arg) { INPLACE_DIV };
 
6098
 
 
6099
static PyObject *
 
6100
Iter_setChoice(Iter *self, PyObject *arg)
 
6101
{
 
6102
    int i;
 
6103
        PyObject *tmp;
 
6104
        
 
6105
        if (! PyList_Check(arg)) {
 
6106
        PyErr_SetString(PyExc_TypeError, "The choice attribute must be a list.");
 
6107
                Py_INCREF(Py_None);
 
6108
                return Py_None;
 
6109
        }
 
6110
    
 
6111
    tmp = arg;
 
6112
    self->chSize = PyList_Size(tmp);
 
6113
    self->choice = (MYFLT *)realloc(self->choice, self->chSize * sizeof(MYFLT));
 
6114
    for (i=0; i<self->chSize; i++) {
 
6115
        self->choice[i] = PyFloat_AS_DOUBLE(PyNumber_Float(PyList_GET_ITEM(tmp, i)));
 
6116
    }
 
6117
    
 
6118
    (*self->mode_func_ptr)(self);
 
6119
    
 
6120
        Py_INCREF(Py_None);
 
6121
        return Py_None;
 
6122
}       
 
6123
 
 
6124
static PyObject * 
 
6125
Iter_reset(Iter *self, PyObject *arg)
 
6126
{
 
6127
    int tmp;
 
6128
    if (PyInt_Check(arg)) {
 
6129
        tmp = PyInt_AsLong(arg);
 
6130
        if (tmp < self->chSize)
 
6131
            self->chCount = tmp;
 
6132
        else
 
6133
            self->chCount = 0;
 
6134
    }
 
6135
        Py_INCREF(Py_None);
 
6136
        return Py_None;
 
6137
}
 
6138
 
 
6139
static PyMemberDef Iter_members[] = {
 
6140
    {"server", T_OBJECT_EX, offsetof(Iter, server), 0, "Pyo server."},
 
6141
    {"stream", T_OBJECT_EX, offsetof(Iter, stream), 0, "Stream object."},
 
6142
    {"input", T_OBJECT_EX, offsetof(Iter, input), 0, "Input sound object."},
 
6143
    {"mul", T_OBJECT_EX, offsetof(Iter, mul), 0, "Mul factor."},
 
6144
    {"add", T_OBJECT_EX, offsetof(Iter, add), 0, "Add factor."},
 
6145
    {NULL}  /* Sentinel */
 
6146
};
 
6147
 
 
6148
static PyMethodDef Iter_methods[] = {
 
6149
    {"getServer", (PyCFunction)Iter_getServer, METH_NOARGS, "Returns server object."},
 
6150
    {"_getStream", (PyCFunction)Iter_getStream, METH_NOARGS, "Returns stream object."},
 
6151
    {"deleteStream", (PyCFunction)Iter_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
6152
    {"play", (PyCFunction)Iter_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
6153
    {"out", (PyCFunction)Iter_out, METH_VARARGS|METH_KEYWORDS, "Starts computing and sends sound to soundcard channel speficied by argument."},
 
6154
    {"stop", (PyCFunction)Iter_stop, METH_NOARGS, "Stops computing."},
 
6155
    {"setChoice", (PyCFunction)Iter_setChoice, METH_O, "Sets possible values."},
 
6156
    {"reset", (PyCFunction)Iter_reset, METH_O, "Resets count to 0."},
 
6157
    {"setMul", (PyCFunction)Iter_setMul, METH_O, "Sets oscillator mul factor."},
 
6158
    {"setAdd", (PyCFunction)Iter_setAdd, METH_O, "Sets oscillator add factor."},
 
6159
    {"setSub", (PyCFunction)Iter_setSub, METH_O, "Sets inverse add factor."},
 
6160
    {"setDiv", (PyCFunction)Iter_setDiv, METH_O, "Sets inverse mul factor."},
 
6161
    {NULL}  /* Sentinel */
 
6162
};
 
6163
 
 
6164
static PyNumberMethods Iter_as_number = {
 
6165
    (binaryfunc)Iter_add,                         /*nb_add*/
 
6166
    (binaryfunc)Iter_sub,                         /*nb_subtract*/
 
6167
    (binaryfunc)Iter_multiply,                    /*nb_multiply*/
 
6168
    (binaryfunc)Iter_div,                                              /*nb_divide*/
 
6169
    0,                                              /*nb_remainder*/
 
6170
    0,                                              /*nb_divmod*/
 
6171
    0,                                              /*nb_power*/
 
6172
    0,                                              /*nb_neg*/
 
6173
    0,                                              /*nb_pos*/
 
6174
    0,                                              /*(unaryfunc)array_abs,*/
 
6175
    0,                                              /*nb_nonzero*/
 
6176
    0,                                              /*nb_invert*/
 
6177
    0,                                              /*nb_lshift*/
 
6178
    0,                                              /*nb_rshift*/
 
6179
    0,                                              /*nb_and*/
 
6180
    0,                                              /*nb_xor*/
 
6181
    0,                                              /*nb_or*/
 
6182
    0,                                              /*nb_coerce*/
 
6183
    0,                                              /*nb_int*/
 
6184
    0,                                              /*nb_long*/
 
6185
    0,                                              /*nb_float*/
 
6186
    0,                                              /*nb_oct*/
 
6187
    0,                                              /*nb_hex*/
 
6188
    (binaryfunc)Iter_inplace_add,                 /*inplace_add*/
 
6189
    (binaryfunc)Iter_inplace_sub,                 /*inplace_subtract*/
 
6190
    (binaryfunc)Iter_inplace_multiply,            /*inplace_multiply*/
 
6191
    (binaryfunc)Iter_inplace_div,                                              /*inplace_divide*/
 
6192
    0,                                              /*inplace_remainder*/
 
6193
    0,                                              /*inplace_power*/
 
6194
    0,                                              /*inplace_lshift*/
 
6195
    0,                                              /*inplace_rshift*/
 
6196
    0,                                              /*inplace_and*/
 
6197
    0,                                              /*inplace_xor*/
 
6198
    0,                                              /*inplace_or*/
 
6199
    0,                                              /*nb_floor_divide*/
 
6200
    0,                                              /*nb_true_divide*/
 
6201
    0,                                              /*nb_inplace_floor_divide*/
 
6202
    0,                                              /*nb_inplace_true_divide*/
 
6203
    0,                                              /* nb_index */
 
6204
};
 
6205
 
 
6206
PyTypeObject IterType = {
 
6207
    PyObject_HEAD_INIT(NULL)
 
6208
    0,                                              /*ob_size*/
 
6209
    "_pyo.Iter_base",                                   /*tp_name*/
 
6210
    sizeof(Iter),                                 /*tp_basicsize*/
 
6211
    0,                                              /*tp_itemsize*/
 
6212
    (destructor)Iter_dealloc,                     /*tp_dealloc*/
 
6213
    0,                                              /*tp_print*/
 
6214
    0,                                              /*tp_getattr*/
 
6215
    0,                                              /*tp_setattr*/
 
6216
    0,                                              /*tp_compare*/
 
6217
    0,                                              /*tp_repr*/
 
6218
    &Iter_as_number,                              /*tp_as_number*/
 
6219
    0,                                              /*tp_as_sequence*/
 
6220
    0,                                              /*tp_as_mapping*/
 
6221
    0,                                              /*tp_hash */
 
6222
    0,                                              /*tp_call*/
 
6223
    0,                                              /*tp_str*/
 
6224
    0,                                              /*tp_getattro*/
 
6225
    0,                                              /*tp_setattro*/
 
6226
    0,                                              /*tp_as_buffer*/
 
6227
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
6228
    "Iter objects. Triggers iterate over a list of values.",           /* tp_doc */
 
6229
    (traverseproc)Iter_traverse,                  /* tp_traverse */
 
6230
    (inquiry)Iter_clear,                          /* tp_clear */
 
6231
    0,                                              /* tp_richcompare */
 
6232
    0,                                              /* tp_weaklistoffset */
 
6233
    0,                                              /* tp_iter */
 
6234
    0,                                              /* tp_iternext */
 
6235
    Iter_methods,                                 /* tp_methods */
 
6236
    Iter_members,                                 /* tp_members */
 
6237
    0,                                              /* tp_getset */
 
6238
    0,                                              /* tp_base */
 
6239
    0,                                              /* tp_dict */
 
6240
    0,                                              /* tp_descr_get */
 
6241
    0,                                              /* tp_descr_set */
 
6242
    0,                                              /* tp_dictoffset */
 
6243
    (initproc)Iter_init,                          /* tp_init */
 
6244
    0,                                              /* tp_alloc */
 
6245
    Iter_new,                                     /* tp_new */
 
6246
};
 
6247
 
 
6248
/*************************/
 
6249
/******* Count ***********/
 
6250
/*************************/
 
6251
typedef struct {
 
6252
    pyo_audio_HEAD
 
6253
    PyObject *input;
 
6254
    Stream *input_stream;
 
6255
    unsigned long count;
 
6256
    unsigned long min;
 
6257
    unsigned long max;
 
6258
    int started;
 
6259
    int modebuffer[2];
 
6260
} Count;
 
6261
 
 
6262
static void
 
6263
Count_generates(Count *self) {
 
6264
    int i;
 
6265
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
6266
    
 
6267
    for (i=0; i<self->bufsize; i++) {        
 
6268
        if (in[i] == 1) {
 
6269
            self->count = self->min;
 
6270
            self->started = 1;
 
6271
        }
 
6272
        if (self->started == 1) {
 
6273
            self->data[i] = (MYFLT)self->count;
 
6274
            if (self->count++ >= self->max && self->max != 0)
 
6275
                self->count = self->min;
 
6276
        }
 
6277
        else {
 
6278
            self->data[i] = self->min;
 
6279
        }
 
6280
    } 
 
6281
}
 
6282
 
 
6283
static void Count_postprocessing_ii(Count *self) { POST_PROCESSING_II };
 
6284
static void Count_postprocessing_ai(Count *self) { POST_PROCESSING_AI };
 
6285
static void Count_postprocessing_ia(Count *self) { POST_PROCESSING_IA };
 
6286
static void Count_postprocessing_aa(Count *self) { POST_PROCESSING_AA };
 
6287
static void Count_postprocessing_ireva(Count *self) { POST_PROCESSING_IREVA };
 
6288
static void Count_postprocessing_areva(Count *self) { POST_PROCESSING_AREVA };
 
6289
static void Count_postprocessing_revai(Count *self) { POST_PROCESSING_REVAI };
 
6290
static void Count_postprocessing_revaa(Count *self) { POST_PROCESSING_REVAA };
 
6291
static void Count_postprocessing_revareva(Count *self) { POST_PROCESSING_REVAREVA };
 
6292
 
 
6293
static void
 
6294
Count_setProcMode(Count *self)
 
6295
{    
 
6296
    int muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
6297
    
 
6298
    self->proc_func_ptr = Count_generates;
 
6299
    
 
6300
    switch (muladdmode) {
 
6301
        case 0:        
 
6302
            self->muladd_func_ptr = Count_postprocessing_ii;
 
6303
            break;
 
6304
        case 1:    
 
6305
            self->muladd_func_ptr = Count_postprocessing_ai;
 
6306
            break;
 
6307
        case 2:    
 
6308
            self->muladd_func_ptr = Count_postprocessing_revai;
 
6309
            break;
 
6310
        case 10:        
 
6311
            self->muladd_func_ptr = Count_postprocessing_ia;
 
6312
            break;
 
6313
        case 11:    
 
6314
            self->muladd_func_ptr = Count_postprocessing_aa;
 
6315
            break;
 
6316
        case 12:    
 
6317
            self->muladd_func_ptr = Count_postprocessing_revaa;
 
6318
            break;
 
6319
        case 20:        
 
6320
            self->muladd_func_ptr = Count_postprocessing_ireva;
 
6321
            break;
 
6322
        case 21:    
 
6323
            self->muladd_func_ptr = Count_postprocessing_areva;
 
6324
            break;
 
6325
        case 22:    
 
6326
            self->muladd_func_ptr = Count_postprocessing_revareva;
 
6327
            break;
 
6328
    }  
 
6329
}
 
6330
 
 
6331
static void
 
6332
Count_compute_next_data_frame(Count *self)
 
6333
{
 
6334
    (*self->proc_func_ptr)(self); 
 
6335
    (*self->muladd_func_ptr)(self);
 
6336
}
 
6337
 
 
6338
static int
 
6339
Count_traverse(Count *self, visitproc visit, void *arg)
 
6340
{
 
6341
    pyo_VISIT
 
6342
    Py_VISIT(self->input);
 
6343
    Py_VISIT(self->input_stream);
 
6344
    return 0;
 
6345
}
 
6346
 
 
6347
static int 
 
6348
Count_clear(Count *self)
 
6349
{
 
6350
    pyo_CLEAR
 
6351
    Py_CLEAR(self->input);
 
6352
    Py_CLEAR(self->input_stream);
 
6353
    return 0;
 
6354
}
 
6355
 
 
6356
static void
 
6357
Count_dealloc(Count* self)
 
6358
{
 
6359
    free(self->data);
 
6360
    Count_clear(self);
 
6361
    self->ob_type->tp_free((PyObject*)self);
 
6362
}
 
6363
 
 
6364
static PyObject * Count_deleteStream(Count *self) { DELETE_STREAM };
 
6365
 
 
6366
static PyObject *
 
6367
Count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
6368
{
 
6369
    int i;
 
6370
    Count *self;
 
6371
    self = (Count *)type->tp_alloc(type, 0);
 
6372
    
 
6373
    self->started = 0;
 
6374
    self->count = 0;
 
6375
    self->min = 0;
 
6376
    self->max = 0;
 
6377
        self->modebuffer[0] = 0;
 
6378
        self->modebuffer[1] = 0;
 
6379
    
 
6380
    INIT_OBJECT_COMMON
 
6381
    Stream_setFunctionPtr(self->stream, Count_compute_next_data_frame);
 
6382
    self->mode_func_ptr = Count_setProcMode;
 
6383
    return (PyObject *)self;
 
6384
}
 
6385
 
 
6386
static int
 
6387
Count_init(Count *self, PyObject *args, PyObject *kwds)
 
6388
{
 
6389
    PyObject *inputtmp, *input_streamtmp, *multmp=NULL, *addtmp=NULL;
 
6390
    
 
6391
    static char *kwlist[] = {"input", "min", "max", "mul", "add", NULL};
 
6392
    
 
6393
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|kkOO", kwlist, &inputtmp, &self->min, &self->max, &multmp, &addtmp))
 
6394
        return -1; 
 
6395
    
 
6396
    INIT_INPUT_STREAM
 
6397
 
 
6398
    if (multmp) {
 
6399
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
6400
    }
 
6401
    
 
6402
    if (addtmp) {
 
6403
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
6404
    }
 
6405
    
 
6406
    Py_INCREF(self->stream);
 
6407
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
6408
    
 
6409
    (*self->mode_func_ptr)(self);
 
6410
    
 
6411
    Py_INCREF(self);
 
6412
    return 0;
 
6413
}
 
6414
 
 
6415
static PyObject * Count_getServer(Count* self) { GET_SERVER };
 
6416
static PyObject * Count_getStream(Count* self) { GET_STREAM };
 
6417
static PyObject * Count_setMul(Count *self, PyObject *arg) { SET_MUL }; 
 
6418
static PyObject * Count_setAdd(Count *self, PyObject *arg) { SET_ADD }; 
 
6419
static PyObject * Count_setSub(Count *self, PyObject *arg) { SET_SUB }; 
 
6420
static PyObject * Count_setDiv(Count *self, PyObject *arg) { SET_DIV }; 
 
6421
 
 
6422
static PyObject * Count_play(Count *self, PyObject *args, PyObject *kwds) { PLAY };
 
6423
static PyObject * Count_stop(Count *self) { STOP };
 
6424
 
 
6425
static PyObject * Count_multiply(Count *self, PyObject *arg) { MULTIPLY };
 
6426
static PyObject * Count_inplace_multiply(Count *self, PyObject *arg) { INPLACE_MULTIPLY };
 
6427
static PyObject * Count_add(Count *self, PyObject *arg) { ADD };
 
6428
static PyObject * Count_inplace_add(Count *self, PyObject *arg) { INPLACE_ADD };
 
6429
static PyObject * Count_sub(Count *self, PyObject *arg) { SUB };
 
6430
static PyObject * Count_inplace_sub(Count *self, PyObject *arg) { INPLACE_SUB };
 
6431
static PyObject * Count_div(Count *self, PyObject *arg) { DIV };
 
6432
static PyObject * Count_inplace_div(Count *self, PyObject *arg) { INPLACE_DIV };
 
6433
 
 
6434
static PyObject *
 
6435
Count_setMin(Count *self, PyObject *arg)
 
6436
{           
 
6437
        if (PyLong_Check(arg) || PyInt_Check(arg))      
 
6438
                self->min = PyLong_AsLong(arg);
 
6439
    
 
6440
        Py_INCREF(Py_None);
 
6441
        return Py_None;
 
6442
}       
 
6443
 
 
6444
static PyObject *
 
6445
Count_setMax(Count *self, PyObject *arg)
 
6446
{         
 
6447
    if (arg == Py_None)
 
6448
        self->max = 0;
 
6449
        else if (PyLong_Check(arg) || PyInt_Check(arg)) 
 
6450
                self->max = PyLong_AsLong(arg);
 
6451
    
 
6452
        Py_INCREF(Py_None);
 
6453
        return Py_None;
 
6454
}       
 
6455
 
 
6456
static PyMemberDef Count_members[] = {
 
6457
    {"server", T_OBJECT_EX, offsetof(Count, server), 0, "Pyo server."},
 
6458
    {"stream", T_OBJECT_EX, offsetof(Count, stream), 0, "Stream object."},
 
6459
    {"input", T_OBJECT_EX, offsetof(Count, input), 0, "Starts the count."},
 
6460
    {"mul", T_OBJECT_EX, offsetof(Count, mul), 0, "Mul factor."},
 
6461
    {"add", T_OBJECT_EX, offsetof(Count, add), 0, "Add factor."},
 
6462
    {NULL}  /* Sentinel */
 
6463
};
 
6464
 
 
6465
static PyMethodDef Count_methods[] = {
 
6466
    {"getServer", (PyCFunction)Count_getServer, METH_NOARGS, "Returns server object."},
 
6467
    {"_getStream", (PyCFunction)Count_getStream, METH_NOARGS, "Returns stream object."},
 
6468
    {"deleteStream", (PyCFunction)Count_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
6469
    {"play", (PyCFunction)Count_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
6470
    {"stop", (PyCFunction)Count_stop, METH_NOARGS, "Stops computing."},
 
6471
    {"setMin", (PyCFunction)Count_setMin, METH_O, "Sets the minimum value."},
 
6472
    {"setMax", (PyCFunction)Count_setMax, METH_O, "Sets the maximum value."},
 
6473
    {"setMul", (PyCFunction)Count_setMul, METH_O, "Sets mul factor."},
 
6474
    {"setAdd", (PyCFunction)Count_setAdd, METH_O, "Sets add factor."},
 
6475
    {"setSub", (PyCFunction)Count_setSub, METH_O, "Sets inverse add factor."},
 
6476
    {"setDiv", (PyCFunction)Count_setDiv, METH_O, "Sets inverse mul factor."},
 
6477
    {NULL}  /* Sentinel */
 
6478
};
 
6479
 
 
6480
static PyNumberMethods Count_as_number = {
 
6481
    (binaryfunc)Count_add,                         /*nb_add*/
 
6482
    (binaryfunc)Count_sub,                         /*nb_subtract*/
 
6483
    (binaryfunc)Count_multiply,                    /*nb_multiply*/
 
6484
    (binaryfunc)Count_div,                                              /*nb_divide*/
 
6485
    0,                                              /*nb_remainder*/
 
6486
    0,                                              /*nb_divmod*/
 
6487
    0,                                              /*nb_power*/
 
6488
    0,                                              /*nb_neg*/
 
6489
    0,                                              /*nb_pos*/
 
6490
    0,                                              /*(unaryfunc)array_abs,*/
 
6491
    0,                                              /*nb_nonzero*/
 
6492
    0,                                              /*nb_invert*/
 
6493
    0,                                              /*nb_lshift*/
 
6494
    0,                                              /*nb_rshift*/
 
6495
    0,                                              /*nb_and*/
 
6496
    0,                                              /*nb_xor*/
 
6497
    0,                                              /*nb_or*/
 
6498
    0,                                              /*nb_coerce*/
 
6499
    0,                                              /*nb_int*/
 
6500
    0,                                              /*nb_long*/
 
6501
    0,                                              /*nb_float*/
 
6502
    0,                                              /*nb_oct*/
 
6503
    0,                                              /*nb_hex*/
 
6504
    (binaryfunc)Count_inplace_add,                 /*inplace_add*/
 
6505
    (binaryfunc)Count_inplace_sub,                 /*inplace_subtract*/
 
6506
    (binaryfunc)Count_inplace_multiply,            /*inplace_multiply*/
 
6507
    (binaryfunc)Count_inplace_div,                                              /*inplace_divide*/
 
6508
    0,                                              /*inplace_remainder*/
 
6509
    0,                                              /*inplace_power*/
 
6510
    0,                                              /*inplace_lshift*/
 
6511
    0,                                              /*inplace_rshift*/
 
6512
    0,                                              /*inplace_and*/
 
6513
    0,                                              /*inplace_xor*/
 
6514
    0,                                              /*inplace_or*/
 
6515
    0,                                              /*nb_floor_divide*/
 
6516
    0,                                              /*nb_true_divide*/
 
6517
    0,                                              /*nb_inplace_floor_divide*/
 
6518
    0,                                              /*nb_inplace_true_divide*/
 
6519
    0,                                              /* nb_index */
 
6520
};
 
6521
 
 
6522
PyTypeObject CountType = {
 
6523
    PyObject_HEAD_INIT(NULL)
 
6524
    0,                                              /*ob_size*/
 
6525
    "_pyo.Count_base",                                   /*tp_name*/
 
6526
    sizeof(Count),                                 /*tp_basicsize*/
 
6527
    0,                                              /*tp_itemsize*/
 
6528
    (destructor)Count_dealloc,                     /*tp_dealloc*/
 
6529
    0,                                              /*tp_print*/
 
6530
    0,                                              /*tp_getattr*/
 
6531
    0,                                              /*tp_setattr*/
 
6532
    0,                                              /*tp_compare*/
 
6533
    0,                                              /*tp_repr*/
 
6534
    &Count_as_number,                              /*tp_as_number*/
 
6535
    0,                                              /*tp_as_sequence*/
 
6536
    0,                                              /*tp_as_mapping*/
 
6537
    0,                                              /*tp_hash */
 
6538
    0,                                              /*tp_call*/
 
6539
    0,                                              /*tp_str*/
 
6540
    0,                                              /*tp_getattro*/
 
6541
    0,                                              /*tp_setattro*/
 
6542
    0,                                              /*tp_as_buffer*/
 
6543
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
6544
    "Count objects. Counts integer at audio rate.",           /* tp_doc */
 
6545
    (traverseproc)Count_traverse,                  /* tp_traverse */
 
6546
    (inquiry)Count_clear,                          /* tp_clear */
 
6547
    0,                                              /* tp_richcompare */
 
6548
    0,                                              /* tp_weaklistoffset */
 
6549
    0,                                              /* tp_iter */
 
6550
    0,                                              /* tp_iternext */
 
6551
    Count_methods,                                 /* tp_methods */
 
6552
    Count_members,                                 /* tp_members */
 
6553
    0,                                              /* tp_getset */
 
6554
    0,                                              /* tp_base */
 
6555
    0,                                              /* tp_dict */
 
6556
    0,                                              /* tp_descr_get */
 
6557
    0,                                              /* tp_descr_set */
 
6558
    0,                                              /* tp_dictoffset */
 
6559
    (initproc)Count_init,                          /* tp_init */
 
6560
    0,                                              /* tp_alloc */
 
6561
    Count_new,                                     /* tp_new */
 
6562
};
 
6563
 
 
6564
/*************************/
 
6565
/******* NextTrig ********/
 
6566
/*************************/
 
6567
typedef struct {
 
6568
    pyo_audio_HEAD
 
6569
    PyObject *input;
 
6570
    Stream *input_stream;
 
6571
    PyObject *input2;
 
6572
    Stream *input2_stream;
 
6573
    int gate;
 
6574
    int modebuffer[2];
 
6575
} NextTrig;
 
6576
 
 
6577
static void
 
6578
NextTrig_generates(NextTrig *self) {
 
6579
    int i;
 
6580
    MYFLT *in = Stream_getData((Stream *)self->input_stream);
 
6581
    MYFLT *in2 = Stream_getData((Stream *)self->input2_stream);
 
6582
    
 
6583
    for (i=0; i<self->bufsize; i++) {
 
6584
        self->data[i] = 0.0;
 
6585
        if (self->gate == 1 && in[i] == 1.0) {
 
6586
                self->data[i] = 1.0;
 
6587
                self->gate = 0;
 
6588
        }
 
6589
        
 
6590
        if (in2[i] == 1 && self->gate == 0)
 
6591
            self->gate = 1;
 
6592
    } 
 
6593
}
 
6594
 
 
6595
static void NextTrig_postprocessing_ii(NextTrig *self) { POST_PROCESSING_II };
 
6596
static void NextTrig_postprocessing_ai(NextTrig *self) { POST_PROCESSING_AI };
 
6597
static void NextTrig_postprocessing_ia(NextTrig *self) { POST_PROCESSING_IA };
 
6598
static void NextTrig_postprocessing_aa(NextTrig *self) { POST_PROCESSING_AA };
 
6599
static void NextTrig_postprocessing_ireva(NextTrig *self) { POST_PROCESSING_IREVA };
 
6600
static void NextTrig_postprocessing_areva(NextTrig *self) { POST_PROCESSING_AREVA };
 
6601
static void NextTrig_postprocessing_revai(NextTrig *self) { POST_PROCESSING_REVAI };
 
6602
static void NextTrig_postprocessing_revaa(NextTrig *self) { POST_PROCESSING_REVAA };
 
6603
static void NextTrig_postprocessing_revareva(NextTrig *self) { POST_PROCESSING_REVAREVA };
 
6604
 
 
6605
static void
 
6606
NextTrig_setProcMode(NextTrig *self)
 
6607
{    
 
6608
    int muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
6609
    
 
6610
    self->proc_func_ptr = NextTrig_generates;
 
6611
    
 
6612
    switch (muladdmode) {
 
6613
        case 0:        
 
6614
            self->muladd_func_ptr = NextTrig_postprocessing_ii;
 
6615
            break;
 
6616
        case 1:    
 
6617
            self->muladd_func_ptr = NextTrig_postprocessing_ai;
 
6618
            break;
 
6619
        case 2:    
 
6620
            self->muladd_func_ptr = NextTrig_postprocessing_revai;
 
6621
            break;
 
6622
        case 10:        
 
6623
            self->muladd_func_ptr = NextTrig_postprocessing_ia;
 
6624
            break;
 
6625
        case 11:    
 
6626
            self->muladd_func_ptr = NextTrig_postprocessing_aa;
 
6627
            break;
 
6628
        case 12:    
 
6629
            self->muladd_func_ptr = NextTrig_postprocessing_revaa;
 
6630
            break;
 
6631
        case 20:        
 
6632
            self->muladd_func_ptr = NextTrig_postprocessing_ireva;
 
6633
            break;
 
6634
        case 21:    
 
6635
            self->muladd_func_ptr = NextTrig_postprocessing_areva;
 
6636
            break;
 
6637
        case 22:    
 
6638
            self->muladd_func_ptr = NextTrig_postprocessing_revareva;
 
6639
            break;
 
6640
    }  
 
6641
}
 
6642
 
 
6643
static void
 
6644
NextTrig_compute_next_data_frame(NextTrig *self)
 
6645
{
 
6646
    (*self->proc_func_ptr)(self); 
 
6647
    (*self->muladd_func_ptr)(self);
 
6648
}
 
6649
 
 
6650
static int
 
6651
NextTrig_traverse(NextTrig *self, visitproc visit, void *arg)
 
6652
{
 
6653
    pyo_VISIT
 
6654
    Py_VISIT(self->input);
 
6655
    Py_VISIT(self->input_stream);
 
6656
    Py_VISIT(self->input2);
 
6657
    Py_VISIT(self->input2_stream);
 
6658
    return 0;
 
6659
}
 
6660
 
 
6661
static int 
 
6662
NextTrig_clear(NextTrig *self)
 
6663
{
 
6664
    pyo_CLEAR
 
6665
    Py_CLEAR(self->input);
 
6666
    Py_CLEAR(self->input_stream);
 
6667
    Py_CLEAR(self->input2);
 
6668
    Py_CLEAR(self->input2_stream);
 
6669
    return 0;
 
6670
}
 
6671
 
 
6672
static void
 
6673
NextTrig_dealloc(NextTrig* self)
 
6674
{
 
6675
    free(self->data);
 
6676
    NextTrig_clear(self);
 
6677
    self->ob_type->tp_free((PyObject*)self);
 
6678
}
 
6679
 
 
6680
static PyObject * NextTrig_deleteStream(NextTrig *self) { DELETE_STREAM };
 
6681
 
 
6682
static PyObject *
 
6683
NextTrig_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
6684
{
 
6685
    int i;
 
6686
    NextTrig *self;
 
6687
    self = (NextTrig *)type->tp_alloc(type, 0);
 
6688
    
 
6689
    self->gate = 0;
 
6690
        self->modebuffer[0] = 0;
 
6691
        self->modebuffer[1] = 0;
 
6692
    
 
6693
    INIT_OBJECT_COMMON
 
6694
    Stream_setFunctionPtr(self->stream, NextTrig_compute_next_data_frame);
 
6695
    self->mode_func_ptr = NextTrig_setProcMode;
 
6696
    return (PyObject *)self;
 
6697
}
 
6698
 
 
6699
static int
 
6700
NextTrig_init(NextTrig *self, PyObject *args, PyObject *kwds)
 
6701
{
 
6702
    PyObject *inputtmp, *input_streamtmp, *input2tmp, *input2_streamtmp, *multmp=NULL, *addtmp=NULL;
 
6703
    
 
6704
    static char *kwlist[] = {"input", "input2", "mul", "add", NULL};
 
6705
    
 
6706
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO", kwlist, &inputtmp, &input2tmp, &multmp, &addtmp))
 
6707
        return -1; 
 
6708
    
 
6709
    INIT_INPUT_STREAM
 
6710
    
 
6711
    Py_XDECREF(self->input2);
 
6712
    self->input2 = input2tmp;
 
6713
    input2_streamtmp = PyObject_CallMethod((PyObject *)self->input2, "_getStream", NULL);
 
6714
    Py_INCREF(input2_streamtmp);
 
6715
    Py_XDECREF(self->input2_stream);
 
6716
    self->input2_stream = (Stream *)input2_streamtmp;
 
6717
    
 
6718
    if (multmp) {
 
6719
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
6720
    }
 
6721
    
 
6722
    if (addtmp) {
 
6723
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
6724
    }
 
6725
    
 
6726
    Py_INCREF(self->stream);
 
6727
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
6728
    
 
6729
    (*self->mode_func_ptr)(self);
 
6730
    
 
6731
    Py_INCREF(self);
 
6732
    return 0;
 
6733
}
 
6734
 
 
6735
static PyObject * NextTrig_getServer(NextTrig* self) { GET_SERVER };
 
6736
static PyObject * NextTrig_getStream(NextTrig* self) { GET_STREAM };
 
6737
static PyObject * NextTrig_setMul(NextTrig *self, PyObject *arg) { SET_MUL };   
 
6738
static PyObject * NextTrig_setAdd(NextTrig *self, PyObject *arg) { SET_ADD };   
 
6739
static PyObject * NextTrig_setSub(NextTrig *self, PyObject *arg) { SET_SUB };   
 
6740
static PyObject * NextTrig_setDiv(NextTrig *self, PyObject *arg) { SET_DIV };   
 
6741
 
 
6742
static PyObject * NextTrig_play(NextTrig *self, PyObject *args, PyObject *kwds) { PLAY };
 
6743
static PyObject * NextTrig_stop(NextTrig *self) { STOP };
 
6744
 
 
6745
static PyObject * NextTrig_multiply(NextTrig *self, PyObject *arg) { MULTIPLY };
 
6746
static PyObject * NextTrig_inplace_multiply(NextTrig *self, PyObject *arg) { INPLACE_MULTIPLY };
 
6747
static PyObject * NextTrig_add(NextTrig *self, PyObject *arg) { ADD };
 
6748
static PyObject * NextTrig_inplace_add(NextTrig *self, PyObject *arg) { INPLACE_ADD };
 
6749
static PyObject * NextTrig_sub(NextTrig *self, PyObject *arg) { SUB };
 
6750
static PyObject * NextTrig_inplace_sub(NextTrig *self, PyObject *arg) { INPLACE_SUB };
 
6751
static PyObject * NextTrig_div(NextTrig *self, PyObject *arg) { DIV };
 
6752
static PyObject * NextTrig_inplace_div(NextTrig *self, PyObject *arg) { INPLACE_DIV };
 
6753
 
 
6754
static PyMemberDef NextTrig_members[] = {
 
6755
    {"server", T_OBJECT_EX, offsetof(NextTrig, server), 0, "Pyo server."},
 
6756
    {"stream", T_OBJECT_EX, offsetof(NextTrig, stream), 0, "Stream object."},
 
6757
    {"input", T_OBJECT_EX, offsetof(NextTrig, input), 0, "Stops NextTrig and output time elapsed."},
 
6758
    {"input2", T_OBJECT_EX, offsetof(NextTrig, input2), 0, "Starts NextTrig."},
 
6759
    {"mul", T_OBJECT_EX, offsetof(NextTrig, mul), 0, "Mul factor."},
 
6760
    {"add", T_OBJECT_EX, offsetof(NextTrig, add), 0, "Add factor."},
 
6761
    {NULL}  /* Sentinel */
 
6762
};
 
6763
 
 
6764
static PyMethodDef NextTrig_methods[] = {
 
6765
    {"getServer", (PyCFunction)NextTrig_getServer, METH_NOARGS, "Returns server object."},
 
6766
    {"_getStream", (PyCFunction)NextTrig_getStream, METH_NOARGS, "Returns stream object."},
 
6767
    {"deleteStream", (PyCFunction)NextTrig_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
6768
    {"play", (PyCFunction)NextTrig_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
6769
    {"stop", (PyCFunction)NextTrig_stop, METH_NOARGS, "Stops computing."},
 
6770
    {"setMul", (PyCFunction)NextTrig_setMul, METH_O, "Sets mul factor."},
 
6771
    {"setAdd", (PyCFunction)NextTrig_setAdd, METH_O, "Sets add factor."},
 
6772
    {"setSub", (PyCFunction)NextTrig_setSub, METH_O, "Sets inverse add factor."},
 
6773
    {"setDiv", (PyCFunction)NextTrig_setDiv, METH_O, "Sets inverse mul factor."},
 
6774
    {NULL}  /* Sentinel */
 
6775
};
 
6776
 
 
6777
static PyNumberMethods NextTrig_as_number = {
 
6778
    (binaryfunc)NextTrig_add,                         /*nb_add*/
 
6779
    (binaryfunc)NextTrig_sub,                         /*nb_subtract*/
 
6780
    (binaryfunc)NextTrig_multiply,                    /*nb_multiply*/
 
6781
    (binaryfunc)NextTrig_div,                                              /*nb_divide*/
 
6782
    0,                                              /*nb_remainder*/
 
6783
    0,                                              /*nb_divmod*/
 
6784
    0,                                              /*nb_power*/
 
6785
    0,                                              /*nb_neg*/
 
6786
    0,                                              /*nb_pos*/
 
6787
    0,                                              /*(unaryfunc)array_abs,*/
 
6788
    0,                                              /*nb_nonzero*/
 
6789
    0,                                              /*nb_invert*/
 
6790
    0,                                              /*nb_lshift*/
 
6791
    0,                                              /*nb_rshift*/
 
6792
    0,                                              /*nb_and*/
 
6793
    0,                                              /*nb_xor*/
 
6794
    0,                                              /*nb_or*/
 
6795
    0,                                              /*nb_coerce*/
 
6796
    0,                                              /*nb_int*/
 
6797
    0,                                              /*nb_long*/
 
6798
    0,                                              /*nb_float*/
 
6799
    0,                                              /*nb_oct*/
 
6800
    0,                                              /*nb_hex*/
 
6801
    (binaryfunc)NextTrig_inplace_add,                 /*inplace_add*/
 
6802
    (binaryfunc)NextTrig_inplace_sub,                 /*inplace_subtract*/
 
6803
    (binaryfunc)NextTrig_inplace_multiply,            /*inplace_multiply*/
 
6804
    (binaryfunc)NextTrig_inplace_div,                                              /*inplace_divide*/
 
6805
    0,                                              /*inplace_remainder*/
 
6806
    0,                                              /*inplace_power*/
 
6807
    0,                                              /*inplace_lshift*/
 
6808
    0,                                              /*inplace_rshift*/
 
6809
    0,                                              /*inplace_and*/
 
6810
    0,                                              /*inplace_xor*/
 
6811
    0,                                              /*inplace_or*/
 
6812
    0,                                              /*nb_floor_divide*/
 
6813
    0,                                              /*nb_true_divide*/
 
6814
    0,                                              /*nb_inplace_floor_divide*/
 
6815
    0,                                              /*nb_inplace_true_divide*/
 
6816
    0,                                              /* nb_index */
 
6817
};
 
6818
 
 
6819
PyTypeObject NextTrigType = {
 
6820
    PyObject_HEAD_INIT(NULL)
 
6821
    0,                                              /*ob_size*/
 
6822
    "_pyo.NextTrig_base",                                   /*tp_name*/
 
6823
    sizeof(NextTrig),                                 /*tp_basicsize*/
 
6824
    0,                                              /*tp_itemsize*/
 
6825
    (destructor)NextTrig_dealloc,                     /*tp_dealloc*/
 
6826
    0,                                              /*tp_print*/
 
6827
    0,                                              /*tp_getattr*/
 
6828
    0,                                              /*tp_setattr*/
 
6829
    0,                                              /*tp_compare*/
 
6830
    0,                                              /*tp_repr*/
 
6831
    &NextTrig_as_number,                              /*tp_as_number*/
 
6832
    0,                                              /*tp_as_sequence*/
 
6833
    0,                                              /*tp_as_mapping*/
 
6834
    0,                                              /*tp_hash */
 
6835
    0,                                              /*tp_call*/
 
6836
    0,                                              /*tp_str*/
 
6837
    0,                                              /*tp_getattro*/
 
6838
    0,                                              /*tp_setattro*/
 
6839
    0,                                              /*tp_as_buffer*/
 
6840
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
6841
    "NextTrig objects. A trig opens a gate only for the next one.",           /* tp_doc */
 
6842
    (traverseproc)NextTrig_traverse,                  /* tp_traverse */
 
6843
    (inquiry)NextTrig_clear,                          /* tp_clear */
 
6844
    0,                                              /* tp_richcompare */
 
6845
    0,                                              /* tp_weaklistoffset */
 
6846
    0,                                              /* tp_iter */
 
6847
    0,                                              /* tp_iternext */
 
6848
    NextTrig_methods,                                 /* tp_methods */
 
6849
    NextTrig_members,                                 /* tp_members */
 
6850
    0,                                              /* tp_getset */
 
6851
    0,                                              /* tp_base */
 
6852
    0,                                              /* tp_dict */
 
6853
    0,                                              /* tp_descr_get */
 
6854
    0,                                              /* tp_descr_set */
 
6855
    0,                                              /* tp_dictoffset */
 
6856
    (initproc)NextTrig_init,                          /* tp_init */
 
6857
    0,                                              /* tp_alloc */
 
6858
    NextTrig_new,                                     /* tp_new */
 
6859
};