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

« back to all changes in this revision

Viewing changes to src/objects/fadermodule.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
 
 
28
typedef struct {
 
29
    pyo_audio_HEAD
 
30
    int modebuffer[2];
 
31
    int fademode;
 
32
    MYFLT topValue;
 
33
    MYFLT attack;
 
34
    MYFLT release;
 
35
    MYFLT duration;
 
36
    double currentTime;
 
37
    MYFLT sampleToSec;
 
38
} Fader;
 
39
 
 
40
static void Fader_internal_stop(Fader *self) { 
 
41
    int i;
 
42
    Stream_setStreamActive(self->stream, 0);
 
43
    Stream_setStreamChnl(self->stream, 0);
 
44
    Stream_setStreamToDac(self->stream, 0);
 
45
    for (i=0; i<self->bufsize; i++) {
 
46
        self->data[i] = 0;
 
47
    }
 
48
}
 
49
 
 
50
static void
 
51
Fader_generate_auto(Fader *self) {
 
52
    MYFLT val;
 
53
    int i;
 
54
 
 
55
    for (i=0; i<self->bufsize; i++) {
 
56
        if (self->currentTime <= self->attack)
 
57
            val = self->currentTime / self->attack;
 
58
        else if (self->currentTime > self->duration)
 
59
            val = 0.;
 
60
        else if (self->currentTime >= (self->duration - self->release))
 
61
            val = (self->duration - self->currentTime) / self->release;
 
62
        else
 
63
            val = 1.;
 
64
        
 
65
        self->data[i] = val;
 
66
        self->currentTime += self->sampleToSec;
 
67
    }
 
68
}
 
69
 
 
70
static void
 
71
Fader_generate_wait(Fader *self) {
 
72
    MYFLT val;
 
73
    int i;
 
74
    
 
75
    for (i=0; i<self->bufsize; i++) {
 
76
        if (self->fademode == 0) {
 
77
            
 
78
            if (self->currentTime <= self->attack)
 
79
                val = self->currentTime / self->attack;
 
80
            else
 
81
                val = 1.;
 
82
            self->topValue = val;    
 
83
        }    
 
84
        else {  
 
85
            if (self->currentTime <= self->release)
 
86
                val = (1. - self->currentTime / self->release) * self->topValue;
 
87
            else 
 
88
                val = 0.;
 
89
        }    
 
90
        self->data[i] = val;
 
91
        self->currentTime += self->sampleToSec;    
 
92
    }
 
93
    if (self->fademode == 1 && self->currentTime > self->release)
 
94
        Fader_internal_stop((Fader *)self);
 
95
}
 
96
 
 
97
static void Fader_postprocessing_ii(Fader *self) { POST_PROCESSING_II };
 
98
static void Fader_postprocessing_ai(Fader *self) { POST_PROCESSING_AI };
 
99
static void Fader_postprocessing_ia(Fader *self) { POST_PROCESSING_IA };
 
100
static void Fader_postprocessing_aa(Fader *self) { POST_PROCESSING_AA };
 
101
static void Fader_postprocessing_ireva(Fader *self) { POST_PROCESSING_IREVA };
 
102
static void Fader_postprocessing_areva(Fader *self) { POST_PROCESSING_AREVA };
 
103
static void Fader_postprocessing_revai(Fader *self) { POST_PROCESSING_REVAI };
 
104
static void Fader_postprocessing_revaa(Fader *self) { POST_PROCESSING_REVAA };
 
105
static void Fader_postprocessing_revareva(Fader *self) { POST_PROCESSING_REVAREVA };
 
106
 
 
107
static void
 
108
Fader_setProcMode(Fader *self)
 
109
{
 
110
    int muladdmode;
 
111
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
112
    
 
113
    if (self->duration == 0.0)
 
114
        self->proc_func_ptr = Fader_generate_wait;
 
115
    else
 
116
        self->proc_func_ptr = Fader_generate_auto;        
 
117
        
 
118
        switch (muladdmode) {
 
119
        case 0:        
 
120
            self->muladd_func_ptr = Fader_postprocessing_ii;
 
121
            break;
 
122
        case 1:    
 
123
            self->muladd_func_ptr = Fader_postprocessing_ai;
 
124
            break;
 
125
        case 2:    
 
126
            self->muladd_func_ptr = Fader_postprocessing_revai;
 
127
            break;
 
128
        case 10:        
 
129
            self->muladd_func_ptr = Fader_postprocessing_ia;
 
130
            break;
 
131
        case 11:    
 
132
            self->muladd_func_ptr = Fader_postprocessing_aa;
 
133
            break;
 
134
        case 12:    
 
135
            self->muladd_func_ptr = Fader_postprocessing_revaa;
 
136
            break;
 
137
        case 20:        
 
138
            self->muladd_func_ptr = Fader_postprocessing_ireva;
 
139
            break;
 
140
        case 21:    
 
141
            self->muladd_func_ptr = Fader_postprocessing_areva;
 
142
            break;
 
143
        case 22:    
 
144
            self->muladd_func_ptr = Fader_postprocessing_revareva;
 
145
            break;
 
146
    }   
 
147
}
 
148
 
 
149
static void
 
150
Fader_compute_next_data_frame(Fader *self)
 
151
{
 
152
    (*self->proc_func_ptr)(self); 
 
153
    (*self->muladd_func_ptr)(self);
 
154
}
 
155
 
 
156
static int
 
157
Fader_traverse(Fader *self, visitproc visit, void *arg)
 
158
{
 
159
    pyo_VISIT
 
160
    return 0;
 
161
}
 
162
 
 
163
static int 
 
164
Fader_clear(Fader *self)
 
165
{
 
166
    pyo_CLEAR
 
167
    return 0;
 
168
}
 
169
 
 
170
static void
 
171
Fader_dealloc(Fader* self)
 
172
{
 
173
    free(self->data);
 
174
    Fader_clear(self);
 
175
    self->ob_type->tp_free((PyObject*)self);
 
176
}
 
177
 
 
178
static PyObject * Fader_deleteStream(Fader *self) { DELETE_STREAM };
 
179
 
 
180
static PyObject *
 
181
Fader_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
182
{
 
183
    int i;
 
184
    Fader *self;
 
185
    self = (Fader *)type->tp_alloc(type, 0);
 
186
    
 
187
        self->modebuffer[0] = 0;
 
188
        self->modebuffer[1] = 0;
 
189
    self->topValue = 0.0;
 
190
    self->fademode = 0;
 
191
    self->attack = 0.01;
 
192
    self->release = 0.1;
 
193
    self->duration = 0.0;
 
194
    self->currentTime = 0.0;
 
195
 
 
196
    INIT_OBJECT_COMMON
 
197
    Stream_setFunctionPtr(self->stream, Fader_compute_next_data_frame);
 
198
    self->mode_func_ptr = Fader_setProcMode;
 
199
    
 
200
    Stream_setStreamActive(self->stream, 0);
 
201
    
 
202
    self->sampleToSec = 1. / self->sr;
 
203
    
 
204
    return (PyObject *)self;
 
205
}
 
206
 
 
207
static int
 
208
Fader_init(Fader *self, PyObject *args, PyObject *kwds)
 
209
{
 
210
    PyObject *multmp=NULL, *addtmp=NULL;
 
211
    
 
212
    static char *kwlist[] = {"fadein", "fadeout", "dur", "mul", "add", NULL};
 
213
    
 
214
    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE__FFFOO, kwlist, &self->attack, &self->release, &self->duration, &multmp, &addtmp))
 
215
        return -1; 
 
216
 
 
217
    if (multmp) {
 
218
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
219
    }
 
220
    
 
221
    if (addtmp) {
 
222
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
223
    }
 
224
    
 
225
    Py_INCREF(self->stream);
 
226
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
227
    
 
228
    (*self->mode_func_ptr)(self);
 
229
        
 
230
    Py_INCREF(self);
 
231
    return 0;
 
232
}
 
233
 
 
234
static PyObject * Fader_getServer(Fader* self) { GET_SERVER };
 
235
static PyObject * Fader_getStream(Fader* self) { GET_STREAM };
 
236
static PyObject * Fader_setMul(Fader *self, PyObject *arg) { SET_MUL }; 
 
237
static PyObject * Fader_setAdd(Fader *self, PyObject *arg) { SET_ADD }; 
 
238
static PyObject * Fader_setSub(Fader *self, PyObject *arg) { SET_SUB }; 
 
239
static PyObject * Fader_setDiv(Fader *self, PyObject *arg) { SET_DIV }; 
 
240
 
 
241
static PyObject * Fader_play(Fader *self, PyObject *args, PyObject *kwds) 
 
242
{
 
243
    self->fademode = 0;
 
244
    self->currentTime = 0.0;
 
245
    (*self->mode_func_ptr)(self);
 
246
    PLAY
 
247
};
 
248
 
 
249
static PyObject *
 
250
Fader_stop(Fader *self)
 
251
{
 
252
    if (self->duration == 0.0) {
 
253
        self->fademode = 1;
 
254
        self->currentTime = 0.0;
 
255
    }
 
256
    else
 
257
        Fader_internal_stop((Fader *)self);
 
258
 
 
259
    Py_INCREF(Py_None);
 
260
    return Py_None;
 
261
}
 
262
 
 
263
static PyObject * Fader_multiply(Fader *self, PyObject *arg) { MULTIPLY };
 
264
static PyObject * Fader_inplace_multiply(Fader *self, PyObject *arg) { INPLACE_MULTIPLY };
 
265
static PyObject * Fader_add(Fader *self, PyObject *arg) { ADD };
 
266
static PyObject * Fader_inplace_add(Fader *self, PyObject *arg) { INPLACE_ADD };
 
267
static PyObject * Fader_sub(Fader *self, PyObject *arg) { SUB };
 
268
static PyObject * Fader_inplace_sub(Fader *self, PyObject *arg) { INPLACE_SUB };
 
269
static PyObject * Fader_div(Fader *self, PyObject *arg) { DIV };
 
270
static PyObject * Fader_inplace_div(Fader *self, PyObject *arg) { INPLACE_DIV };
 
271
 
 
272
static PyObject *
 
273
Fader_setFadein(Fader *self, PyObject *arg)
 
274
{
 
275
    self->attack = PyFloat_AsDouble(arg);
 
276
    Py_INCREF(Py_None);
 
277
    return Py_None;
 
278
}
 
279
 
 
280
static PyObject *
 
281
Fader_setFadeout(Fader *self, PyObject *arg)
 
282
{
 
283
    self->release = PyFloat_AsDouble(arg);
 
284
    Py_INCREF(Py_None);
 
285
    return Py_None;
 
286
}
 
287
 
 
288
static PyObject *
 
289
Fader_setDur(Fader *self, PyObject *arg)
 
290
{
 
291
    self->duration = PyFloat_AsDouble(arg);
 
292
    Py_INCREF(Py_None);
 
293
    return Py_None;
 
294
}
 
295
 
 
296
static PyMemberDef Fader_members[] = {
 
297
{"server", T_OBJECT_EX, offsetof(Fader, server), 0, "Pyo server."},
 
298
{"stream", T_OBJECT_EX, offsetof(Fader, stream), 0, "Stream object."},
 
299
{"mul", T_OBJECT_EX, offsetof(Fader, mul), 0, "Mul factor."},
 
300
{"add", T_OBJECT_EX, offsetof(Fader, add), 0, "Add factor."},
 
301
{NULL}  /* Sentinel */
 
302
};
 
303
 
 
304
static PyMethodDef Fader_methods[] = {
 
305
{"getServer", (PyCFunction)Fader_getServer, METH_NOARGS, "Returns server object."},
 
306
{"_getStream", (PyCFunction)Fader_getStream, METH_NOARGS, "Returns stream object."},
 
307
{"deleteStream", (PyCFunction)Fader_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
308
{"play", (PyCFunction)Fader_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
309
{"stop", (PyCFunction)Fader_stop, METH_NOARGS, "Starts fadeout and stops computing."},
 
310
{"setMul", (PyCFunction)Fader_setMul, METH_O, "Sets Fader mul factor."},
 
311
{"setAdd", (PyCFunction)Fader_setAdd, METH_O, "Sets Fader add factor."},
 
312
{"setSub", (PyCFunction)Fader_setSub, METH_O, "Sets inverse add factor."},
 
313
{"setFadein", (PyCFunction)Fader_setFadein, METH_O, "Sets fadein time in seconds."},
 
314
{"setFadeout", (PyCFunction)Fader_setFadeout, METH_O, "Sets fadeout time in seconds."},
 
315
{"setDur", (PyCFunction)Fader_setDur, METH_O, "Sets duration in seconds (0 means wait for stop method to start fadeout)."},
 
316
{"setDiv", (PyCFunction)Fader_setDiv, METH_O, "Sets inverse mul factor."},
 
317
{NULL}  /* Sentinel */
 
318
};
 
319
 
 
320
static PyNumberMethods Fader_as_number = {
 
321
(binaryfunc)Fader_add,                      /*nb_add*/
 
322
(binaryfunc)Fader_sub,                 /*nb_subtract*/
 
323
(binaryfunc)Fader_multiply,                 /*nb_multiply*/
 
324
(binaryfunc)Fader_div,                   /*nb_divide*/
 
325
0,                /*nb_remainder*/
 
326
0,                   /*nb_divmod*/
 
327
0,                   /*nb_power*/
 
328
0,                  /*nb_neg*/
 
329
0,                /*nb_pos*/
 
330
0,                  /*(unaryfunc)array_abs,*/
 
331
0,                    /*nb_nonzero*/
 
332
0,                    /*nb_invert*/
 
333
0,               /*nb_lshift*/
 
334
0,              /*nb_rshift*/
 
335
0,              /*nb_and*/
 
336
0,              /*nb_xor*/
 
337
0,               /*nb_or*/
 
338
0,                                          /*nb_coerce*/
 
339
0,                       /*nb_int*/
 
340
0,                      /*nb_long*/
 
341
0,                     /*nb_float*/
 
342
0,                       /*nb_oct*/
 
343
0,                       /*nb_hex*/
 
344
(binaryfunc)Fader_inplace_add,              /*inplace_add*/
 
345
(binaryfunc)Fader_inplace_sub,         /*inplace_subtract*/
 
346
(binaryfunc)Fader_inplace_multiply,         /*inplace_multiply*/
 
347
(binaryfunc)Fader_inplace_div,           /*inplace_divide*/
 
348
0,        /*inplace_remainder*/
 
349
0,           /*inplace_power*/
 
350
0,       /*inplace_lshift*/
 
351
0,      /*inplace_rshift*/
 
352
0,      /*inplace_and*/
 
353
0,      /*inplace_xor*/
 
354
0,       /*inplace_or*/
 
355
0,             /*nb_floor_divide*/
 
356
0,              /*nb_true_divide*/
 
357
0,     /*nb_inplace_floor_divide*/
 
358
0,      /*nb_inplace_true_divide*/
 
359
0,                     /* nb_index */
 
360
};
 
361
 
 
362
PyTypeObject FaderType = {
 
363
PyObject_HEAD_INIT(NULL)
 
364
0,                         /*ob_size*/
 
365
"_pyo.Fader_base",         /*tp_name*/
 
366
sizeof(Fader),         /*tp_basicsize*/
 
367
0,                         /*tp_itemsize*/
 
368
(destructor)Fader_dealloc, /*tp_dealloc*/
 
369
0,                         /*tp_print*/
 
370
0,                         /*tp_getattr*/
 
371
0,                         /*tp_setattr*/
 
372
0,                         /*tp_compare*/
 
373
0,                         /*tp_repr*/
 
374
&Fader_as_number,             /*tp_as_number*/
 
375
0,                         /*tp_as_sequence*/
 
376
0,                         /*tp_as_mapping*/
 
377
0,                         /*tp_hash */
 
378
0,                         /*tp_call*/
 
379
0,                         /*tp_str*/
 
380
0,                         /*tp_getattro*/
 
381
0,                         /*tp_setattro*/
 
382
0,                         /*tp_as_buffer*/
 
383
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
384
"Fader objects. Generates fadin and fadeout signal.",           /* tp_doc */
 
385
(traverseproc)Fader_traverse,   /* tp_traverse */
 
386
(inquiry)Fader_clear,           /* tp_clear */
 
387
0,                             /* tp_richcompare */
 
388
0,                             /* tp_weaklistoffset */
 
389
0,                             /* tp_iter */
 
390
0,                             /* tp_iternext */
 
391
Fader_methods,             /* tp_methods */
 
392
Fader_members,             /* tp_members */
 
393
0,                      /* tp_getset */
 
394
0,                         /* tp_base */
 
395
0,                         /* tp_dict */
 
396
0,                         /* tp_descr_get */
 
397
0,                         /* tp_descr_set */
 
398
0,                         /* tp_dictoffset */
 
399
(initproc)Fader_init,      /* tp_init */
 
400
0,                         /* tp_alloc */
 
401
Fader_new,                 /* tp_new */
 
402
};
 
403
 
 
404
typedef struct {
 
405
    pyo_audio_HEAD
 
406
    int modebuffer[2];
 
407
    int fademode;
 
408
    MYFLT topValue;
 
409
    MYFLT attack;
 
410
    MYFLT decay;
 
411
    MYFLT sustain;
 
412
    MYFLT release;
 
413
    MYFLT duration;
 
414
    double currentTime;
 
415
    MYFLT sampleToSec;
 
416
} Adsr;
 
417
 
 
418
static void Adsr_internal_stop(Adsr *self) { 
 
419
    int i;
 
420
    Stream_setStreamActive(self->stream, 0);
 
421
    Stream_setStreamChnl(self->stream, 0);
 
422
    Stream_setStreamToDac(self->stream, 0);
 
423
    for (i=0; i<self->bufsize; i++) {
 
424
        self->data[i] = 0;
 
425
    }
 
426
}
 
427
 
 
428
static void
 
429
Adsr_generate_auto(Adsr *self) {
 
430
    MYFLT val;
 
431
    int i;
 
432
    
 
433
    for (i=0; i<self->bufsize; i++) {
 
434
        if (self->currentTime <= self->attack)
 
435
            val = self->currentTime / self->attack;
 
436
        else if (self->currentTime <= (self->attack + self->decay))
 
437
            val = (self->decay - (self->currentTime - self->attack)) / self->decay * (1. - self->sustain) + self->sustain;
 
438
        else if (self->currentTime > self->duration)
 
439
            val = 0.;
 
440
        else if (self->currentTime >= (self->duration - self->release))
 
441
            val = (self->duration - self->currentTime) / self->release * self->sustain;
 
442
        else
 
443
            val = self->sustain;
 
444
        
 
445
        self->data[i] = val;
 
446
        self->currentTime += self->sampleToSec;
 
447
    }
 
448
}
 
449
 
 
450
static void
 
451
Adsr_generate_wait(Adsr *self) {
 
452
    MYFLT val;
 
453
    int i;
 
454
    
 
455
    for (i=0; i<self->bufsize; i++) {
 
456
        if (self->fademode == 0) {
 
457
            
 
458
            if (self->currentTime <= self->attack)
 
459
                val = self->currentTime / self->attack;
 
460
            else if (self->currentTime <= (self->attack + self->decay))
 
461
                val = (self->decay - (self->currentTime - self->attack)) / self->decay * (1. - self->sustain) + self->sustain;
 
462
            else
 
463
                val = self->sustain;
 
464
            self->topValue = val;
 
465
        }    
 
466
        else {  
 
467
            if (self->currentTime <= self->release)
 
468
                val = self->topValue * (1. - self->currentTime / self->release);
 
469
            else 
 
470
                val = 0.;
 
471
        }    
 
472
        self->data[i] = val;
 
473
        self->currentTime += self->sampleToSec;    
 
474
    }
 
475
    if (self->fademode == 1 && self->currentTime > self->release)
 
476
        Adsr_internal_stop((Adsr *)self);
 
477
}
 
478
 
 
479
static void Adsr_postprocessing_ii(Adsr *self) { POST_PROCESSING_II };
 
480
static void Adsr_postprocessing_ai(Adsr *self) { POST_PROCESSING_AI };
 
481
static void Adsr_postprocessing_ia(Adsr *self) { POST_PROCESSING_IA };
 
482
static void Adsr_postprocessing_aa(Adsr *self) { POST_PROCESSING_AA };
 
483
static void Adsr_postprocessing_ireva(Adsr *self) { POST_PROCESSING_IREVA };
 
484
static void Adsr_postprocessing_areva(Adsr *self) { POST_PROCESSING_AREVA };
 
485
static void Adsr_postprocessing_revai(Adsr *self) { POST_PROCESSING_REVAI };
 
486
static void Adsr_postprocessing_revaa(Adsr *self) { POST_PROCESSING_REVAA };
 
487
static void Adsr_postprocessing_revareva(Adsr *self) { POST_PROCESSING_REVAREVA };
 
488
 
 
489
static void
 
490
Adsr_setProcMode(Adsr *self)
 
491
{
 
492
    int muladdmode;
 
493
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
494
    
 
495
    if (self->duration == 0.0)
 
496
        self->proc_func_ptr = Adsr_generate_wait;
 
497
    else
 
498
        self->proc_func_ptr = Adsr_generate_auto;        
 
499
    
 
500
        switch (muladdmode) {
 
501
        case 0:        
 
502
            self->muladd_func_ptr = Adsr_postprocessing_ii;
 
503
            break;
 
504
        case 1:    
 
505
            self->muladd_func_ptr = Adsr_postprocessing_ai;
 
506
            break;
 
507
        case 2:    
 
508
            self->muladd_func_ptr = Adsr_postprocessing_revai;
 
509
            break;
 
510
        case 10:        
 
511
            self->muladd_func_ptr = Adsr_postprocessing_ia;
 
512
            break;
 
513
        case 11:    
 
514
            self->muladd_func_ptr = Adsr_postprocessing_aa;
 
515
            break;
 
516
        case 12:    
 
517
            self->muladd_func_ptr = Adsr_postprocessing_revaa;
 
518
            break;
 
519
        case 20:        
 
520
            self->muladd_func_ptr = Adsr_postprocessing_ireva;
 
521
            break;
 
522
        case 21:    
 
523
            self->muladd_func_ptr = Adsr_postprocessing_areva;
 
524
            break;
 
525
        case 22:    
 
526
            self->muladd_func_ptr = Adsr_postprocessing_revareva;
 
527
            break;
 
528
    }   
 
529
}
 
530
 
 
531
static void
 
532
Adsr_compute_next_data_frame(Adsr *self)
 
533
{
 
534
    (*self->proc_func_ptr)(self); 
 
535
    (*self->muladd_func_ptr)(self);
 
536
}
 
537
 
 
538
static int
 
539
Adsr_traverse(Adsr *self, visitproc visit, void *arg)
 
540
{
 
541
    pyo_VISIT
 
542
    return 0;
 
543
}
 
544
 
 
545
static int 
 
546
Adsr_clear(Adsr *self)
 
547
{
 
548
    pyo_CLEAR
 
549
    return 0;
 
550
}
 
551
 
 
552
static void
 
553
Adsr_dealloc(Adsr* self)
 
554
{
 
555
    free(self->data);
 
556
    Adsr_clear(self);
 
557
    self->ob_type->tp_free((PyObject*)self);
 
558
}
 
559
 
 
560
static PyObject * Adsr_deleteStream(Adsr *self) { DELETE_STREAM };
 
561
 
 
562
static PyObject *
 
563
Adsr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
564
{
 
565
    int i;
 
566
    Adsr *self;
 
567
    self = (Adsr *)type->tp_alloc(type, 0);
 
568
    
 
569
        self->modebuffer[0] = 0;
 
570
        self->modebuffer[1] = 0;
 
571
    self->topValue = 0.0;
 
572
    self->fademode = 0;
 
573
    self->attack = 0.01;
 
574
    self->decay = 0.05;
 
575
    self->sustain = 0.707;
 
576
    self->release = 0.1;
 
577
    self->duration = 0.0;
 
578
    self->currentTime = 0.0;
 
579
    
 
580
    INIT_OBJECT_COMMON
 
581
    Stream_setFunctionPtr(self->stream, Adsr_compute_next_data_frame);
 
582
    self->mode_func_ptr = Adsr_setProcMode;
 
583
    
 
584
    Stream_setStreamActive(self->stream, 0);
 
585
    
 
586
    self->sampleToSec = 1. / self->sr;
 
587
    
 
588
    return (PyObject *)self;
 
589
}
 
590
 
 
591
static int
 
592
Adsr_init(Adsr *self, PyObject *args, PyObject *kwds)
 
593
{
 
594
    PyObject *multmp=NULL, *addtmp=NULL;
 
595
 
 
596
    static char *kwlist[] = {"attack", "decay", "sustain", "release", "dur", "mul", "add", NULL};
 
597
    
 
598
    if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE__FFFFFOO, kwlist, &self->attack, &self->decay, &self->sustain, &self->release, &self->duration, &multmp, &addtmp))
 
599
        return -1; 
 
600
    
 
601
    if (multmp) {
 
602
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
603
    }
 
604
    
 
605
    if (addtmp) {
 
606
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
607
    }
 
608
    
 
609
    Py_INCREF(self->stream);
 
610
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
611
    
 
612
    (*self->mode_func_ptr)(self);
 
613
        
 
614
    Py_INCREF(self);
 
615
    return 0;
 
616
}
 
617
 
 
618
static PyObject * Adsr_getServer(Adsr* self) { GET_SERVER };
 
619
static PyObject * Adsr_getStream(Adsr* self) { GET_STREAM };
 
620
static PyObject * Adsr_setMul(Adsr *self, PyObject *arg) { SET_MUL };   
 
621
static PyObject * Adsr_setAdd(Adsr *self, PyObject *arg) { SET_ADD };   
 
622
static PyObject * Adsr_setSub(Adsr *self, PyObject *arg) { SET_SUB };   
 
623
static PyObject * Adsr_setDiv(Adsr *self, PyObject *arg) { SET_DIV };   
 
624
 
 
625
static PyObject * Adsr_play(Adsr *self, PyObject *args, PyObject *kwds) 
 
626
{
 
627
    self->fademode = 0;
 
628
    self->currentTime = 0.0;
 
629
    (*self->mode_func_ptr)(self);
 
630
    PLAY
 
631
};
 
632
 
 
633
static PyObject *
 
634
Adsr_stop(Adsr *self)
 
635
{
 
636
    if (self->duration == 0.0) {
 
637
        self->fademode = 1;
 
638
        self->currentTime = 0.0;
 
639
    }
 
640
    else
 
641
        Adsr_internal_stop((Adsr *)self);
 
642
    
 
643
    Py_INCREF(Py_None);
 
644
    return Py_None;
 
645
}
 
646
 
 
647
static PyObject * Adsr_multiply(Adsr *self, PyObject *arg) { MULTIPLY };
 
648
static PyObject * Adsr_inplace_multiply(Adsr *self, PyObject *arg) { INPLACE_MULTIPLY };
 
649
static PyObject * Adsr_add(Adsr *self, PyObject *arg) { ADD };
 
650
static PyObject * Adsr_inplace_add(Adsr *self, PyObject *arg) { INPLACE_ADD };
 
651
static PyObject * Adsr_sub(Adsr *self, PyObject *arg) { SUB };
 
652
static PyObject * Adsr_inplace_sub(Adsr *self, PyObject *arg) { INPLACE_SUB };
 
653
static PyObject * Adsr_div(Adsr *self, PyObject *arg) { DIV };
 
654
static PyObject * Adsr_inplace_div(Adsr *self, PyObject *arg) { INPLACE_DIV };
 
655
 
 
656
static PyObject *
 
657
Adsr_setAttack(Adsr *self, PyObject *arg)
 
658
{
 
659
    self->attack = PyFloat_AsDouble(PyNumber_Float(arg));
 
660
    Py_INCREF(Py_None);
 
661
    return Py_None;
 
662
}
 
663
 
 
664
static PyObject *
 
665
Adsr_setDecay(Adsr *self, PyObject *arg)
 
666
{
 
667
    self->decay = PyFloat_AsDouble(PyNumber_Float(arg));
 
668
    Py_INCREF(Py_None);
 
669
    return Py_None;
 
670
}
 
671
 
 
672
static PyObject *
 
673
Adsr_setSustain(Adsr *self, PyObject *arg)
 
674
{
 
675
    self->sustain = PyFloat_AsDouble(PyNumber_Float(arg));
 
676
    Py_INCREF(Py_None);
 
677
    return Py_None;
 
678
}
 
679
 
 
680
static PyObject *
 
681
Adsr_setRelease(Adsr *self, PyObject *arg)
 
682
{
 
683
    self->release = PyFloat_AsDouble(PyNumber_Float(arg));
 
684
    Py_INCREF(Py_None);
 
685
    return Py_None;
 
686
}
 
687
 
 
688
static PyObject *
 
689
Adsr_setDur(Adsr *self, PyObject *arg)
 
690
{
 
691
    self->duration = PyFloat_AsDouble(PyNumber_Float(arg));
 
692
    Py_INCREF(Py_None);
 
693
    return Py_None;
 
694
}
 
695
 
 
696
static PyMemberDef Adsr_members[] = {
 
697
{"server", T_OBJECT_EX, offsetof(Adsr, server), 0, "Pyo server."},
 
698
{"stream", T_OBJECT_EX, offsetof(Adsr, stream), 0, "Stream object."},
 
699
{"mul", T_OBJECT_EX, offsetof(Adsr, mul), 0, "Mul factor."},
 
700
{"add", T_OBJECT_EX, offsetof(Adsr, add), 0, "Add factor."},
 
701
{NULL}  /* Sentinel */
 
702
};
 
703
 
 
704
static PyMethodDef Adsr_methods[] = {
 
705
{"getServer", (PyCFunction)Adsr_getServer, METH_NOARGS, "Returns server object."},
 
706
{"_getStream", (PyCFunction)Adsr_getStream, METH_NOARGS, "Returns stream object."},
 
707
{"deleteStream", (PyCFunction)Adsr_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
708
{"play", (PyCFunction)Adsr_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
709
{"stop", (PyCFunction)Adsr_stop, METH_NOARGS, "Starts fadeout and stops computing."},
 
710
{"setMul", (PyCFunction)Adsr_setMul, METH_O, "Sets Adsr mul factor."},
 
711
{"setAdd", (PyCFunction)Adsr_setAdd, METH_O, "Sets Adsr add factor."},
 
712
{"setSub", (PyCFunction)Adsr_setSub, METH_O, "Sets inverse add factor."},
 
713
{"setAttack", (PyCFunction)Adsr_setAttack, METH_O, "Sets attack time in seconds."},
 
714
{"setDecay", (PyCFunction)Adsr_setDecay, METH_O, "Sets attack time in seconds."},
 
715
{"setSustain", (PyCFunction)Adsr_setSustain, METH_O, "Sets attack time in seconds."},
 
716
{"setRelease", (PyCFunction)Adsr_setRelease, METH_O, "Sets release time in seconds."},
 
717
{"setDur", (PyCFunction)Adsr_setDur, METH_O, "Sets duration in seconds (0 means wait for stop method to start fadeout)."},
 
718
{"setDiv", (PyCFunction)Adsr_setDiv, METH_O, "Sets inverse mul factor."},
 
719
{NULL}  /* Sentinel */
 
720
};
 
721
 
 
722
static PyNumberMethods Adsr_as_number = {
 
723
(binaryfunc)Adsr_add,                      /*nb_add*/
 
724
(binaryfunc)Adsr_sub,                 /*nb_subtract*/
 
725
(binaryfunc)Adsr_multiply,                 /*nb_multiply*/
 
726
(binaryfunc)Adsr_div,                   /*nb_divide*/
 
727
0,                /*nb_remainder*/
 
728
0,                   /*nb_divmod*/
 
729
0,                   /*nb_power*/
 
730
0,                  /*nb_neg*/
 
731
0,                /*nb_pos*/
 
732
0,                  /*(unaryfunc)array_abs,*/
 
733
0,                    /*nb_nonzero*/
 
734
0,                    /*nb_invert*/
 
735
0,               /*nb_lshift*/
 
736
0,              /*nb_rshift*/
 
737
0,              /*nb_and*/
 
738
0,              /*nb_xor*/
 
739
0,               /*nb_or*/
 
740
0,                                          /*nb_coerce*/
 
741
0,                       /*nb_int*/
 
742
0,                      /*nb_long*/
 
743
0,                     /*nb_float*/
 
744
0,                       /*nb_oct*/
 
745
0,                       /*nb_hex*/
 
746
(binaryfunc)Adsr_inplace_add,              /*inplace_add*/
 
747
(binaryfunc)Adsr_inplace_sub,         /*inplace_subtract*/
 
748
(binaryfunc)Adsr_inplace_multiply,         /*inplace_multiply*/
 
749
(binaryfunc)Adsr_inplace_div,           /*inplace_divide*/
 
750
0,        /*inplace_remainder*/
 
751
0,           /*inplace_power*/
 
752
0,       /*inplace_lshift*/
 
753
0,      /*inplace_rshift*/
 
754
0,      /*inplace_and*/
 
755
0,      /*inplace_xor*/
 
756
0,       /*inplace_or*/
 
757
0,             /*nb_floor_divide*/
 
758
0,              /*nb_true_divide*/
 
759
0,     /*nb_inplace_floor_divide*/
 
760
0,      /*nb_inplace_true_divide*/
 
761
0,                     /* nb_index */
 
762
};
 
763
 
 
764
PyTypeObject AdsrType = {
 
765
PyObject_HEAD_INIT(NULL)
 
766
0,                         /*ob_size*/
 
767
"_pyo.Adsr_base",         /*tp_name*/
 
768
sizeof(Adsr),         /*tp_basicsize*/
 
769
0,                         /*tp_itemsize*/
 
770
(destructor)Adsr_dealloc, /*tp_dealloc*/
 
771
0,                         /*tp_print*/
 
772
0,                         /*tp_getattr*/
 
773
0,                         /*tp_setattr*/
 
774
0,                         /*tp_compare*/
 
775
0,                         /*tp_repr*/
 
776
&Adsr_as_number,             /*tp_as_number*/
 
777
0,                         /*tp_as_sequence*/
 
778
0,                         /*tp_as_mapping*/
 
779
0,                         /*tp_hash */
 
780
0,                         /*tp_call*/
 
781
0,                         /*tp_str*/
 
782
0,                         /*tp_getattro*/
 
783
0,                         /*tp_setattro*/
 
784
0,                         /*tp_as_buffer*/
 
785
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
786
"Adsr objects. Generates Adsr envelope signal.",           /* tp_doc */
 
787
(traverseproc)Adsr_traverse,   /* tp_traverse */
 
788
(inquiry)Adsr_clear,           /* tp_clear */
 
789
0,                             /* tp_richcompare */
 
790
0,                             /* tp_weaklistoffset */
 
791
0,                             /* tp_iter */
 
792
0,                             /* tp_iternext */
 
793
Adsr_methods,             /* tp_methods */
 
794
Adsr_members,             /* tp_members */
 
795
0,                      /* tp_getset */
 
796
0,                         /* tp_base */
 
797
0,                         /* tp_dict */
 
798
0,                         /* tp_descr_get */
 
799
0,                         /* tp_descr_set */
 
800
0,                         /* tp_dictoffset */
 
801
(initproc)Adsr_init,      /* tp_init */
 
802
0,                         /* tp_alloc */
 
803
Adsr_new,                 /* tp_new */
 
804
};
 
805
 
 
806
typedef struct {
 
807
    pyo_audio_HEAD
 
808
    PyObject *pointslist;
 
809
    int modebuffer[2];
 
810
    double currentTime;
 
811
    double currentValue;
 
812
    MYFLT sampleToSec;
 
813
    double increment;
 
814
    MYFLT *targets;
 
815
    MYFLT *times;
 
816
    int which;
 
817
    int flag;
 
818
    int newlist;
 
819
    int loop;
 
820
    int listsize;
 
821
} Linseg;
 
822
 
 
823
static void
 
824
Linseg_convert_pointslist(Linseg *self) {
 
825
    int i;
 
826
    PyObject *tup;
 
827
 
 
828
    self->listsize = PyList_Size(self->pointslist);
 
829
    self->targets = (MYFLT *)realloc(self->targets, self->listsize * sizeof(MYFLT));
 
830
    self->times = (MYFLT *)realloc(self->times, self->listsize * sizeof(MYFLT));
 
831
    for (i=0; i<self->listsize; i++) {
 
832
        tup = PyList_GET_ITEM(self->pointslist, i);
 
833
        self->times[i] = PyFloat_AsDouble(PyNumber_Float(PyTuple_GET_ITEM(tup, 0)));
 
834
        self->targets[i] = PyFloat_AsDouble(PyNumber_Float(PyTuple_GET_ITEM(tup, 1)));
 
835
    }
 
836
}
 
837
 
 
838
static void 
 
839
Linseg_reinit(Linseg *self) {
 
840
    if (self->newlist == 1) {
 
841
        Linseg_convert_pointslist((Linseg *)self);
 
842
        self->newlist = 0;
 
843
    }    
 
844
    self->currentTime = 0.0;
 
845
    self->currentValue = self->targets[0];
 
846
    self->which = 0;
 
847
    self->flag = 1;
 
848
}
 
849
 
 
850
static void
 
851
Linseg_generate(Linseg *self) {
 
852
    int i;
 
853
    
 
854
    for (i=0; i<self->bufsize; i++) {
 
855
        if (self->flag == 1) {
 
856
            if (self->currentTime >= self->times[self->which]) {
 
857
                self->which++;
 
858
                if (self->which == self->listsize) {
 
859
                    if (self->loop == 1)
 
860
                        Linseg_reinit((Linseg *)self);
 
861
                    else {
 
862
                        self->flag = 0;
 
863
                        self->currentValue = self->targets[self->which-1];
 
864
                    }    
 
865
                }    
 
866
                else {
 
867
                    if ((self->times[self->which] - self->times[self->which-1]) <= 0)
 
868
                        self->increment = self->targets[self->which] - self->currentValue;
 
869
                    else
 
870
                        self->increment = (self->targets[self->which] - self->targets[self->which-1]) / ((self->times[self->which] - self->times[self->which-1]) / self->sampleToSec);
 
871
                }
 
872
            }
 
873
            if (self->currentTime <= self->times[self->listsize-1])
 
874
                self->currentValue += self->increment;            
 
875
            self->data[i] = (MYFLT)self->currentValue;
 
876
            self->currentTime += self->sampleToSec;    
 
877
        }
 
878
        else
 
879
            self->data[i] = (MYFLT)self->currentValue;
 
880
    }
 
881
}
 
882
 
 
883
static void Linseg_postprocessing_ii(Linseg *self) { POST_PROCESSING_II };
 
884
static void Linseg_postprocessing_ai(Linseg *self) { POST_PROCESSING_AI };
 
885
static void Linseg_postprocessing_ia(Linseg *self) { POST_PROCESSING_IA };
 
886
static void Linseg_postprocessing_aa(Linseg *self) { POST_PROCESSING_AA };
 
887
static void Linseg_postprocessing_ireva(Linseg *self) { POST_PROCESSING_IREVA };
 
888
static void Linseg_postprocessing_areva(Linseg *self) { POST_PROCESSING_AREVA };
 
889
static void Linseg_postprocessing_revai(Linseg *self) { POST_PROCESSING_REVAI };
 
890
static void Linseg_postprocessing_revaa(Linseg *self) { POST_PROCESSING_REVAA };
 
891
static void Linseg_postprocessing_revareva(Linseg *self) { POST_PROCESSING_REVAREVA };
 
892
 
 
893
static void
 
894
Linseg_setProcMode(Linseg *self)
 
895
{
 
896
    int muladdmode;
 
897
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
898
    
 
899
    self->proc_func_ptr = Linseg_generate;
 
900
    
 
901
        switch (muladdmode) {
 
902
        case 0:        
 
903
            self->muladd_func_ptr = Linseg_postprocessing_ii;
 
904
            break;
 
905
        case 1:    
 
906
            self->muladd_func_ptr = Linseg_postprocessing_ai;
 
907
            break;
 
908
        case 2:    
 
909
            self->muladd_func_ptr = Linseg_postprocessing_revai;
 
910
            break;
 
911
        case 10:        
 
912
            self->muladd_func_ptr = Linseg_postprocessing_ia;
 
913
            break;
 
914
        case 11:    
 
915
            self->muladd_func_ptr = Linseg_postprocessing_aa;
 
916
            break;
 
917
        case 12:    
 
918
            self->muladd_func_ptr = Linseg_postprocessing_revaa;
 
919
            break;
 
920
        case 20:        
 
921
            self->muladd_func_ptr = Linseg_postprocessing_ireva;
 
922
            break;
 
923
        case 21:    
 
924
            self->muladd_func_ptr = Linseg_postprocessing_areva;
 
925
            break;
 
926
        case 22:    
 
927
            self->muladd_func_ptr = Linseg_postprocessing_revareva;
 
928
            break;
 
929
    }   
 
930
}
 
931
 
 
932
static void
 
933
Linseg_compute_next_data_frame(Linseg *self)
 
934
{
 
935
    (*self->proc_func_ptr)(self); 
 
936
    (*self->muladd_func_ptr)(self);
 
937
}
 
938
 
 
939
static int
 
940
Linseg_traverse(Linseg *self, visitproc visit, void *arg)
 
941
{
 
942
    pyo_VISIT
 
943
    Py_VISIT(self->pointslist);
 
944
    return 0;
 
945
}
 
946
 
 
947
static int 
 
948
Linseg_clear(Linseg *self)
 
949
{
 
950
    pyo_CLEAR
 
951
    Py_CLEAR(self->pointslist);
 
952
    return 0;
 
953
}
 
954
 
 
955
static void
 
956
Linseg_dealloc(Linseg* self)
 
957
{
 
958
    free(self->data);
 
959
    free(self->targets);
 
960
    free(self->times);
 
961
    Linseg_clear(self);
 
962
    self->ob_type->tp_free((PyObject*)self);
 
963
}
 
964
 
 
965
static PyObject * Linseg_deleteStream(Linseg *self) { DELETE_STREAM };
 
966
 
 
967
static PyObject *
 
968
Linseg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
969
{
 
970
    int i;
 
971
    Linseg *self;
 
972
    self = (Linseg *)type->tp_alloc(type, 0);
 
973
    
 
974
    self->loop = 0;
 
975
    self->newlist = 1;
 
976
        self->modebuffer[0] = 0;
 
977
        self->modebuffer[1] = 0;
 
978
    
 
979
    INIT_OBJECT_COMMON
 
980
    Stream_setFunctionPtr(self->stream, Linseg_compute_next_data_frame);
 
981
    self->mode_func_ptr = Linseg_setProcMode;
 
982
    
 
983
    Stream_setStreamActive(self->stream, 0);
 
984
    
 
985
    self->sampleToSec = 1. / self->sr;
 
986
    
 
987
    return (PyObject *)self;
 
988
}
 
989
 
 
990
static int
 
991
Linseg_init(Linseg *self, PyObject *args, PyObject *kwds)
 
992
{
 
993
    PyObject *pointslist=NULL, *multmp=NULL, *addtmp=NULL;
 
994
    int i, initToFirstVal = 0;
 
995
    
 
996
    static char *kwlist[] = {"list", "loop", "initToFirstVal", "mul", "add", NULL};
 
997
    
 
998
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|iiOO", kwlist, &pointslist, &self->loop, &initToFirstVal, &multmp, &addtmp))
 
999
        return -1; 
 
1000
 
 
1001
    Py_INCREF(pointslist);
 
1002
    Py_XDECREF(self->pointslist);
 
1003
    self->pointslist = pointslist;
 
1004
    Linseg_convert_pointslist((Linseg *)self);
 
1005
    
 
1006
    if (multmp) {
 
1007
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
1008
    }
 
1009
    
 
1010
    if (addtmp) {
 
1011
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
1012
    }
 
1013
    
 
1014
    Py_INCREF(self->stream);
 
1015
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
1016
    
 
1017
    if (initToFirstVal) {
 
1018
        for (i=0; i<self->bufsize; i++) {
 
1019
            self->data[i] = self->targets[0];
 
1020
        }
 
1021
    }
 
1022
    
 
1023
    (*self->mode_func_ptr)(self);
 
1024
        
 
1025
    Py_INCREF(self);
 
1026
    return 0;
 
1027
}
 
1028
 
 
1029
static PyObject * Linseg_getServer(Linseg* self) { GET_SERVER };
 
1030
static PyObject * Linseg_getStream(Linseg* self) { GET_STREAM };
 
1031
static PyObject * Linseg_setMul(Linseg *self, PyObject *arg) { SET_MUL };       
 
1032
static PyObject * Linseg_setAdd(Linseg *self, PyObject *arg) { SET_ADD };       
 
1033
static PyObject * Linseg_setSub(Linseg *self, PyObject *arg) { SET_SUB };       
 
1034
static PyObject * Linseg_setDiv(Linseg *self, PyObject *arg) { SET_DIV };       
 
1035
 
 
1036
static PyObject * Linseg_play(Linseg *self, PyObject *args, PyObject *kwds) 
 
1037
{
 
1038
    Linseg_reinit((Linseg *)self);
 
1039
    PLAY
 
1040
};
 
1041
 
 
1042
static PyObject * Linseg_stop(Linseg *self) { STOP };
 
1043
 
 
1044
static PyObject * Linseg_multiply(Linseg *self, PyObject *arg) { MULTIPLY };
 
1045
static PyObject * Linseg_inplace_multiply(Linseg *self, PyObject *arg) { INPLACE_MULTIPLY };
 
1046
static PyObject * Linseg_add(Linseg *self, PyObject *arg) { ADD };
 
1047
static PyObject * Linseg_inplace_add(Linseg *self, PyObject *arg) { INPLACE_ADD };
 
1048
static PyObject * Linseg_sub(Linseg *self, PyObject *arg) { SUB };
 
1049
static PyObject * Linseg_inplace_sub(Linseg *self, PyObject *arg) { INPLACE_SUB };
 
1050
static PyObject * Linseg_div(Linseg *self, PyObject *arg) { DIV };
 
1051
static PyObject * Linseg_inplace_div(Linseg *self, PyObject *arg) { INPLACE_DIV };
 
1052
 
 
1053
static PyObject *
 
1054
Linseg_setList(Linseg *self, PyObject *value)
 
1055
{
 
1056
    if (value == NULL) {
 
1057
        PyErr_SetString(PyExc_TypeError, "Cannot delete the list attribute.");
 
1058
        return PyInt_FromLong(-1);
 
1059
    }
 
1060
    
 
1061
    if (! PyList_Check(value)) {
 
1062
        PyErr_SetString(PyExc_TypeError, "The points list attribute value must be a list of tuples.");
 
1063
        return PyInt_FromLong(-1);
 
1064
    }
 
1065
    
 
1066
    Py_INCREF(value);
 
1067
    Py_DECREF(self->pointslist);
 
1068
    self->pointslist = value; 
 
1069
    
 
1070
    self->newlist = 1;
 
1071
    
 
1072
    Py_INCREF(Py_None);
 
1073
    return Py_None;
 
1074
}
 
1075
 
 
1076
static PyObject *
 
1077
Linseg_setLoop(Linseg *self, PyObject *arg)
 
1078
{
 
1079
        if (arg == NULL) {
 
1080
                Py_INCREF(Py_None);
 
1081
                return Py_None;
 
1082
        }
 
1083
    
 
1084
    self->loop = PyInt_AsLong(arg);
 
1085
    
 
1086
    Py_INCREF(Py_None);
 
1087
    return Py_None;
 
1088
}
 
1089
 
 
1090
static PyMemberDef Linseg_members[] = {
 
1091
{"server", T_OBJECT_EX, offsetof(Linseg, server), 0, "Pyo server."},
 
1092
{"stream", T_OBJECT_EX, offsetof(Linseg, stream), 0, "Stream object."},
 
1093
{"pointslist", T_OBJECT_EX, offsetof(Linseg, pointslist), 0, "List of target points."},
 
1094
{"mul", T_OBJECT_EX, offsetof(Linseg, mul), 0, "Mul factor."},
 
1095
{"add", T_OBJECT_EX, offsetof(Linseg, add), 0, "Add factor."},
 
1096
{NULL}  /* Sentinel */
 
1097
};
 
1098
 
 
1099
static PyMethodDef Linseg_methods[] = {
 
1100
{"getServer", (PyCFunction)Linseg_getServer, METH_NOARGS, "Returns server object."},
 
1101
{"_getStream", (PyCFunction)Linseg_getStream, METH_NOARGS, "Returns stream object."},
 
1102
{"deleteStream", (PyCFunction)Linseg_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
1103
{"play", (PyCFunction)Linseg_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
1104
{"stop", (PyCFunction)Linseg_stop, METH_NOARGS, "Starts fadeout and stops computing."},
 
1105
{"setList", (PyCFunction)Linseg_setList, METH_O, "Sets target points list."},
 
1106
{"setLoop", (PyCFunction)Linseg_setLoop, METH_O, "Sets looping mode."},
 
1107
{"setMul", (PyCFunction)Linseg_setMul, METH_O, "Sets Linseg mul factor."},
 
1108
{"setAdd", (PyCFunction)Linseg_setAdd, METH_O, "Sets Linseg add factor."},
 
1109
{"setSub", (PyCFunction)Linseg_setSub, METH_O, "Sets inverse add factor."},
 
1110
{"setDiv", (PyCFunction)Linseg_setDiv, METH_O, "Sets inverse mul factor."},
 
1111
{NULL}  /* Sentinel */
 
1112
};
 
1113
 
 
1114
static PyNumberMethods Linseg_as_number = {
 
1115
(binaryfunc)Linseg_add,                      /*nb_add*/
 
1116
(binaryfunc)Linseg_sub,                 /*nb_subtract*/
 
1117
(binaryfunc)Linseg_multiply,                 /*nb_multiply*/
 
1118
(binaryfunc)Linseg_div,                   /*nb_divide*/
 
1119
0,                /*nb_remainder*/
 
1120
0,                   /*nb_divmod*/
 
1121
0,                   /*nb_power*/
 
1122
0,                  /*nb_neg*/
 
1123
0,                /*nb_pos*/
 
1124
0,                  /*(unaryfunc)array_abs,*/
 
1125
0,                    /*nb_nonzero*/
 
1126
0,                    /*nb_invert*/
 
1127
0,               /*nb_lshift*/
 
1128
0,              /*nb_rshift*/
 
1129
0,              /*nb_and*/
 
1130
0,              /*nb_xor*/
 
1131
0,               /*nb_or*/
 
1132
0,                                          /*nb_coerce*/
 
1133
0,                       /*nb_int*/
 
1134
0,                      /*nb_long*/
 
1135
0,                     /*nb_float*/
 
1136
0,                       /*nb_oct*/
 
1137
0,                       /*nb_hex*/
 
1138
(binaryfunc)Linseg_inplace_add,              /*inplace_add*/
 
1139
(binaryfunc)Linseg_inplace_sub,         /*inplace_subtract*/
 
1140
(binaryfunc)Linseg_inplace_multiply,         /*inplace_multiply*/
 
1141
(binaryfunc)Linseg_inplace_div,           /*inplace_divide*/
 
1142
0,        /*inplace_remainder*/
 
1143
0,           /*inplace_power*/
 
1144
0,       /*inplace_lshift*/
 
1145
0,      /*inplace_rshift*/
 
1146
0,      /*inplace_and*/
 
1147
0,      /*inplace_xor*/
 
1148
0,       /*inplace_or*/
 
1149
0,             /*nb_floor_divide*/
 
1150
0,              /*nb_true_divide*/
 
1151
0,     /*nb_inplace_floor_divide*/
 
1152
0,      /*nb_inplace_true_divide*/
 
1153
0,                     /* nb_index */
 
1154
};
 
1155
 
 
1156
PyTypeObject LinsegType = {
 
1157
PyObject_HEAD_INIT(NULL)
 
1158
0,                         /*ob_size*/
 
1159
"_pyo.Linseg_base",         /*tp_name*/
 
1160
sizeof(Linseg),         /*tp_basicsize*/
 
1161
0,                         /*tp_itemsize*/
 
1162
(destructor)Linseg_dealloc, /*tp_dealloc*/
 
1163
0,                         /*tp_print*/
 
1164
0,                         /*tp_getattr*/
 
1165
0,                         /*tp_setattr*/
 
1166
0,                         /*tp_compare*/
 
1167
0,                         /*tp_repr*/
 
1168
&Linseg_as_number,             /*tp_as_number*/
 
1169
0,                         /*tp_as_sequence*/
 
1170
0,                         /*tp_as_mapping*/
 
1171
0,                         /*tp_hash */
 
1172
0,                         /*tp_call*/
 
1173
0,                         /*tp_str*/
 
1174
0,                         /*tp_getattro*/
 
1175
0,                         /*tp_setattro*/
 
1176
0,                         /*tp_as_buffer*/
 
1177
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
1178
"Linseg objects. Generates a linear segments break-points line.",           /* tp_doc */
 
1179
(traverseproc)Linseg_traverse,   /* tp_traverse */
 
1180
(inquiry)Linseg_clear,           /* tp_clear */
 
1181
0,                             /* tp_richcompare */
 
1182
0,                             /* tp_weaklistoffset */
 
1183
0,                             /* tp_iter */
 
1184
0,                             /* tp_iternext */
 
1185
Linseg_methods,             /* tp_methods */
 
1186
Linseg_members,             /* tp_members */
 
1187
0,                      /* tp_getset */
 
1188
0,                         /* tp_base */
 
1189
0,                         /* tp_dict */
 
1190
0,                         /* tp_descr_get */
 
1191
0,                         /* tp_descr_set */
 
1192
0,                         /* tp_dictoffset */
 
1193
(initproc)Linseg_init,      /* tp_init */
 
1194
0,                         /* tp_alloc */
 
1195
Linseg_new,                 /* tp_new */
 
1196
};
 
1197
 
 
1198
typedef struct {
 
1199
    pyo_audio_HEAD
 
1200
    PyObject *pointslist;
 
1201
    int modebuffer[2];
 
1202
    double currentTime;
 
1203
    double currentValue;
 
1204
    MYFLT sampleToSec;
 
1205
    double inc;
 
1206
    double pointer;
 
1207
    MYFLT range;
 
1208
    double steps;
 
1209
    MYFLT *targets;
 
1210
    MYFLT *times;
 
1211
    int which;
 
1212
    int flag;
 
1213
    int newlist;
 
1214
    int loop;
 
1215
    int listsize;
 
1216
    double exp;
 
1217
    double exp_tmp;
 
1218
    int inverse;
 
1219
    int inverse_tmp;
 
1220
} Expseg;
 
1221
 
 
1222
static void
 
1223
Expseg_convert_pointslist(Expseg *self) {
 
1224
    int i;
 
1225
    PyObject *tup;
 
1226
    
 
1227
    self->listsize = PyList_Size(self->pointslist);
 
1228
    self->targets = (MYFLT *)realloc(self->targets, self->listsize * sizeof(MYFLT));
 
1229
    self->times = (MYFLT *)realloc(self->times, self->listsize * sizeof(MYFLT));
 
1230
    for (i=0; i<self->listsize; i++) {
 
1231
        tup = PyList_GET_ITEM(self->pointslist, i);
 
1232
        self->times[i] = PyFloat_AsDouble(PyNumber_Float(PyTuple_GET_ITEM(tup, 0)));
 
1233
        self->targets[i] = PyFloat_AsDouble(PyNumber_Float(PyTuple_GET_ITEM(tup, 1)));
 
1234
    }
 
1235
}
 
1236
 
 
1237
static void 
 
1238
Expseg_reinit(Expseg *self) {
 
1239
    if (self->newlist == 1) {
 
1240
        Expseg_convert_pointslist((Expseg *)self);
 
1241
        self->newlist = 0;
 
1242
    }    
 
1243
    self->currentTime = 0.0;
 
1244
    self->currentValue = self->targets[0];
 
1245
    self->which = 0;
 
1246
    self->flag = 1;
 
1247
    self->exp = self->exp_tmp;
 
1248
    self->inverse = self->inverse_tmp;
 
1249
}
 
1250
 
 
1251
static void
 
1252
Expseg_generate(Expseg *self) {
 
1253
    int i;
 
1254
    double scl;
 
1255
    
 
1256
    for (i=0; i<self->bufsize; i++) {
 
1257
        if (self->flag == 1) {
 
1258
            if (self->currentTime >= self->times[self->which]) {
 
1259
                self->which++;
 
1260
                if (self->which == self->listsize) {
 
1261
                    if (self->loop == 1)
 
1262
                        Expseg_reinit((Expseg *)self);
 
1263
                    else {
 
1264
                        self->flag = 0;
 
1265
                        self->currentValue = self->targets[self->which-1];
 
1266
                    }    
 
1267
                }    
 
1268
                else {
 
1269
                    self->range = self->targets[self->which] - self->targets[self->which-1];
 
1270
                    self->steps = (self->times[self->which] - self->times[self->which-1]) * self->sr;
 
1271
                    if (self->steps <= 0)
 
1272
                        self->inc = 1.0;
 
1273
                    else
 
1274
                        self->inc = 1.0 / self->steps;
 
1275
                }    
 
1276
                self->pointer = 0.0;   
 
1277
            }
 
1278
            if (self->currentTime <= self->times[self->listsize-1]) {
 
1279
                if (self->pointer >= 1.0)
 
1280
                    self->pointer = 1.0;
 
1281
                if (self->inverse == 1 && self->range < 0.0)
 
1282
                    scl = 1.0 - pow(1.0 - self->pointer, self->exp);
 
1283
                else
 
1284
                    scl = pow(self->pointer, self->exp);
 
1285
 
 
1286
                self->currentValue = scl * self->range + self->targets[self->which-1];
 
1287
                self->pointer += self->inc;
 
1288
            }    
 
1289
            self->data[i] = (MYFLT)self->currentValue;
 
1290
            self->currentTime += self->sampleToSec;    
 
1291
        }
 
1292
        else
 
1293
            self->data[i] = (MYFLT)self->currentValue;
 
1294
    }
 
1295
}
 
1296
 
 
1297
static void Expseg_postprocessing_ii(Expseg *self) { POST_PROCESSING_II };
 
1298
static void Expseg_postprocessing_ai(Expseg *self) { POST_PROCESSING_AI };
 
1299
static void Expseg_postprocessing_ia(Expseg *self) { POST_PROCESSING_IA };
 
1300
static void Expseg_postprocessing_aa(Expseg *self) { POST_PROCESSING_AA };
 
1301
static void Expseg_postprocessing_ireva(Expseg *self) { POST_PROCESSING_IREVA };
 
1302
static void Expseg_postprocessing_areva(Expseg *self) { POST_PROCESSING_AREVA };
 
1303
static void Expseg_postprocessing_revai(Expseg *self) { POST_PROCESSING_REVAI };
 
1304
static void Expseg_postprocessing_revaa(Expseg *self) { POST_PROCESSING_REVAA };
 
1305
static void Expseg_postprocessing_revareva(Expseg *self) { POST_PROCESSING_REVAREVA };
 
1306
 
 
1307
static void
 
1308
Expseg_setProcMode(Expseg *self)
 
1309
{
 
1310
    int muladdmode;
 
1311
    muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
 
1312
    
 
1313
    self->proc_func_ptr = Expseg_generate;
 
1314
    
 
1315
        switch (muladdmode) {
 
1316
        case 0:        
 
1317
            self->muladd_func_ptr = Expseg_postprocessing_ii;
 
1318
            break;
 
1319
        case 1:    
 
1320
            self->muladd_func_ptr = Expseg_postprocessing_ai;
 
1321
            break;
 
1322
        case 2:    
 
1323
            self->muladd_func_ptr = Expseg_postprocessing_revai;
 
1324
            break;
 
1325
        case 10:        
 
1326
            self->muladd_func_ptr = Expseg_postprocessing_ia;
 
1327
            break;
 
1328
        case 11:    
 
1329
            self->muladd_func_ptr = Expseg_postprocessing_aa;
 
1330
            break;
 
1331
        case 12:    
 
1332
            self->muladd_func_ptr = Expseg_postprocessing_revaa;
 
1333
            break;
 
1334
        case 20:        
 
1335
            self->muladd_func_ptr = Expseg_postprocessing_ireva;
 
1336
            break;
 
1337
        case 21:    
 
1338
            self->muladd_func_ptr = Expseg_postprocessing_areva;
 
1339
            break;
 
1340
        case 22:    
 
1341
            self->muladd_func_ptr = Expseg_postprocessing_revareva;
 
1342
            break;
 
1343
    }   
 
1344
}
 
1345
 
 
1346
static void
 
1347
Expseg_compute_next_data_frame(Expseg *self)
 
1348
{
 
1349
    (*self->proc_func_ptr)(self); 
 
1350
    (*self->muladd_func_ptr)(self);
 
1351
}
 
1352
 
 
1353
static int
 
1354
Expseg_traverse(Expseg *self, visitproc visit, void *arg)
 
1355
{
 
1356
    pyo_VISIT
 
1357
    Py_VISIT(self->pointslist);
 
1358
    return 0;
 
1359
}
 
1360
 
 
1361
static int 
 
1362
Expseg_clear(Expseg *self)
 
1363
{
 
1364
    pyo_CLEAR
 
1365
    Py_CLEAR(self->pointslist);
 
1366
    return 0;
 
1367
}
 
1368
 
 
1369
static void
 
1370
Expseg_dealloc(Expseg* self)
 
1371
{
 
1372
    free(self->data);
 
1373
    free(self->targets);
 
1374
    free(self->times);
 
1375
    Expseg_clear(self);
 
1376
    self->ob_type->tp_free((PyObject*)self);
 
1377
}
 
1378
 
 
1379
static PyObject * Expseg_deleteStream(Expseg *self) { DELETE_STREAM };
 
1380
 
 
1381
static PyObject *
 
1382
Expseg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
1383
{
 
1384
    int i;
 
1385
    Expseg *self;
 
1386
    self = (Expseg *)type->tp_alloc(type, 0);
 
1387
    
 
1388
    self->loop = 0;
 
1389
    self->newlist = 1;
 
1390
    self->exp = self->exp_tmp = 10;
 
1391
    self->inverse = self->inverse_tmp = 1;
 
1392
        self->modebuffer[0] = 0;
 
1393
        self->modebuffer[1] = 0;
 
1394
    
 
1395
    INIT_OBJECT_COMMON
 
1396
    Stream_setFunctionPtr(self->stream, Expseg_compute_next_data_frame);
 
1397
    self->mode_func_ptr = Expseg_setProcMode;
 
1398
    
 
1399
    Stream_setStreamActive(self->stream, 0);
 
1400
    
 
1401
    self->sampleToSec = 1. / self->sr;
 
1402
    
 
1403
    return (PyObject *)self;
 
1404
}
 
1405
 
 
1406
static int
 
1407
Expseg_init(Expseg *self, PyObject *args, PyObject *kwds)
 
1408
{
 
1409
    PyObject *pointslist=NULL, *multmp=NULL, *addtmp=NULL;
 
1410
    int i, initToFirstVal = 0;
 
1411
    
 
1412
    static char *kwlist[] = {"list", "loop", "exp", "inverse", "initToFirstVal", "mul", "add", NULL};
 
1413
    
 
1414
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|idiiOO", kwlist, &pointslist, &self->loop, &self->exp_tmp, &self->inverse_tmp, &initToFirstVal, &multmp, &addtmp))
 
1415
        return -1; 
 
1416
    
 
1417
    Py_INCREF(pointslist);
 
1418
    Py_XDECREF(self->pointslist);
 
1419
    self->pointslist = pointslist;
 
1420
    Expseg_convert_pointslist((Expseg *)self);
 
1421
    
 
1422
    if (multmp) {
 
1423
        PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
 
1424
    }
 
1425
    
 
1426
    if (addtmp) {
 
1427
        PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
 
1428
    }
 
1429
    
 
1430
    Py_INCREF(self->stream);
 
1431
    PyObject_CallMethod(self->server, "addStream", "O", self->stream);
 
1432
 
 
1433
    if (initToFirstVal) {
 
1434
        for (i=0; i<self->bufsize; i++) {
 
1435
            self->data[i] = self->targets[0];
 
1436
        }
 
1437
    }
 
1438
 
 
1439
    (*self->mode_func_ptr)(self);
 
1440
        
 
1441
    Py_INCREF(self);
 
1442
    return 0;
 
1443
}
 
1444
 
 
1445
static PyObject * Expseg_getServer(Expseg* self) { GET_SERVER };
 
1446
static PyObject * Expseg_getStream(Expseg* self) { GET_STREAM };
 
1447
static PyObject * Expseg_setMul(Expseg *self, PyObject *arg) { SET_MUL };       
 
1448
static PyObject * Expseg_setAdd(Expseg *self, PyObject *arg) { SET_ADD };       
 
1449
static PyObject * Expseg_setSub(Expseg *self, PyObject *arg) { SET_SUB };       
 
1450
static PyObject * Expseg_setDiv(Expseg *self, PyObject *arg) { SET_DIV };       
 
1451
 
 
1452
static PyObject * Expseg_play(Expseg *self, PyObject *args, PyObject *kwds) 
 
1453
{
 
1454
    Expseg_reinit((Expseg *)self);
 
1455
    PLAY
 
1456
};
 
1457
 
 
1458
static PyObject * Expseg_stop(Expseg *self) { STOP };
 
1459
 
 
1460
static PyObject * Expseg_multiply(Expseg *self, PyObject *arg) { MULTIPLY };
 
1461
static PyObject * Expseg_inplace_multiply(Expseg *self, PyObject *arg) { INPLACE_MULTIPLY };
 
1462
static PyObject * Expseg_add(Expseg *self, PyObject *arg) { ADD };
 
1463
static PyObject * Expseg_inplace_add(Expseg *self, PyObject *arg) { INPLACE_ADD };
 
1464
static PyObject * Expseg_sub(Expseg *self, PyObject *arg) { SUB };
 
1465
static PyObject * Expseg_inplace_sub(Expseg *self, PyObject *arg) { INPLACE_SUB };
 
1466
static PyObject * Expseg_div(Expseg *self, PyObject *arg) { DIV };
 
1467
static PyObject * Expseg_inplace_div(Expseg *self, PyObject *arg) { INPLACE_DIV };
 
1468
 
 
1469
static PyObject *
 
1470
Expseg_setList(Expseg *self, PyObject *value)
 
1471
{
 
1472
    if (value == NULL) {
 
1473
        PyErr_SetString(PyExc_TypeError, "Cannot delete the list attribute.");
 
1474
        return PyInt_FromLong(-1);
 
1475
    }
 
1476
    
 
1477
    if (! PyList_Check(value)) {
 
1478
        PyErr_SetString(PyExc_TypeError, "The points list attribute value must be a list of tuples.");
 
1479
        return PyInt_FromLong(-1);
 
1480
    }
 
1481
    
 
1482
    Py_INCREF(value);
 
1483
    Py_DECREF(self->pointslist);
 
1484
    self->pointslist = value; 
 
1485
    
 
1486
    self->newlist = 1;
 
1487
    
 
1488
    Py_INCREF(Py_None);
 
1489
    return Py_None;
 
1490
}
 
1491
 
 
1492
static PyObject *
 
1493
Expseg_setLoop(Expseg *self, PyObject *arg)
 
1494
{
 
1495
        if (arg == NULL) {
 
1496
                Py_INCREF(Py_None);
 
1497
                return Py_None;
 
1498
        }
 
1499
    
 
1500
    self->loop = PyInt_AsLong(arg);
 
1501
    
 
1502
    Py_INCREF(Py_None);
 
1503
    return Py_None;
 
1504
}
 
1505
 
 
1506
static PyObject *
 
1507
Expseg_setExp(Expseg *self, PyObject *arg)
 
1508
{
 
1509
        if (arg == NULL) {
 
1510
                Py_INCREF(Py_None);
 
1511
                return Py_None;
 
1512
        }
 
1513
    
 
1514
    self->exp_tmp = PyFloat_AsDouble(PyNumber_Float(arg));
 
1515
    
 
1516
    Py_INCREF(Py_None);
 
1517
    return Py_None;
 
1518
}
 
1519
 
 
1520
static PyObject *
 
1521
Expseg_setInverse(Expseg *self, PyObject *arg)
 
1522
{
 
1523
        if (arg == NULL) {
 
1524
                Py_INCREF(Py_None);
 
1525
                return Py_None;
 
1526
        }
 
1527
    
 
1528
    self->inverse_tmp = PyInt_AsLong(PyNumber_Int(arg));
 
1529
    
 
1530
    Py_INCREF(Py_None);
 
1531
    return Py_None;
 
1532
}
 
1533
 
 
1534
static PyMemberDef Expseg_members[] = {
 
1535
    {"server", T_OBJECT_EX, offsetof(Expseg, server), 0, "Pyo server."},
 
1536
    {"stream", T_OBJECT_EX, offsetof(Expseg, stream), 0, "Stream object."},
 
1537
    {"pointslist", T_OBJECT_EX, offsetof(Expseg, pointslist), 0, "List of target points."},
 
1538
    {"mul", T_OBJECT_EX, offsetof(Expseg, mul), 0, "Mul factor."},
 
1539
    {"add", T_OBJECT_EX, offsetof(Expseg, add), 0, "Add factor."},
 
1540
    {NULL}  /* Sentinel */
 
1541
};
 
1542
 
 
1543
static PyMethodDef Expseg_methods[] = {
 
1544
    {"getServer", (PyCFunction)Expseg_getServer, METH_NOARGS, "Returns server object."},
 
1545
    {"_getStream", (PyCFunction)Expseg_getStream, METH_NOARGS, "Returns stream object."},
 
1546
    {"deleteStream", (PyCFunction)Expseg_deleteStream, METH_NOARGS, "Remove stream from server and delete the object."},
 
1547
    {"play", (PyCFunction)Expseg_play, METH_VARARGS|METH_KEYWORDS, "Starts computing without sending sound to soundcard."},
 
1548
    {"stop", (PyCFunction)Expseg_stop, METH_NOARGS, "Starts fadeout and stops computing."},
 
1549
    {"setList", (PyCFunction)Expseg_setList, METH_O, "Sets target points list."},
 
1550
    {"setLoop", (PyCFunction)Expseg_setLoop, METH_O, "Sets looping mode."},
 
1551
    {"setExp", (PyCFunction)Expseg_setExp, METH_O, "Sets exponent factor."},
 
1552
    {"setInverse", (PyCFunction)Expseg_setInverse, METH_O, "Sets inverse factor."},
 
1553
    {"setMul", (PyCFunction)Expseg_setMul, METH_O, "Sets Expseg mul factor."},
 
1554
    {"setAdd", (PyCFunction)Expseg_setAdd, METH_O, "Sets Expseg add factor."},
 
1555
    {"setSub", (PyCFunction)Expseg_setSub, METH_O, "Sets inverse add factor."},
 
1556
    {"setDiv", (PyCFunction)Expseg_setDiv, METH_O, "Sets inverse mul factor."},
 
1557
    {NULL}  /* Sentinel */
 
1558
};
 
1559
 
 
1560
static PyNumberMethods Expseg_as_number = {
 
1561
    (binaryfunc)Expseg_add,                      /*nb_add*/
 
1562
    (binaryfunc)Expseg_sub,                 /*nb_subtract*/
 
1563
    (binaryfunc)Expseg_multiply,                 /*nb_multiply*/
 
1564
    (binaryfunc)Expseg_div,                   /*nb_divide*/
 
1565
    0,                /*nb_remainder*/
 
1566
    0,                   /*nb_divmod*/
 
1567
    0,                   /*nb_power*/
 
1568
    0,                  /*nb_neg*/
 
1569
    0,                /*nb_pos*/
 
1570
    0,                  /*(unaryfunc)array_abs,*/
 
1571
    0,                    /*nb_nonzero*/
 
1572
    0,                    /*nb_invert*/
 
1573
    0,               /*nb_lshift*/
 
1574
    0,              /*nb_rshift*/
 
1575
    0,              /*nb_and*/
 
1576
    0,              /*nb_xor*/
 
1577
    0,               /*nb_or*/
 
1578
    0,                                          /*nb_coerce*/
 
1579
    0,                       /*nb_int*/
 
1580
    0,                      /*nb_long*/
 
1581
    0,                     /*nb_float*/
 
1582
    0,                       /*nb_oct*/
 
1583
    0,                       /*nb_hex*/
 
1584
    (binaryfunc)Expseg_inplace_add,              /*inplace_add*/
 
1585
    (binaryfunc)Expseg_inplace_sub,         /*inplace_subtract*/
 
1586
    (binaryfunc)Expseg_inplace_multiply,         /*inplace_multiply*/
 
1587
    (binaryfunc)Expseg_inplace_div,           /*inplace_divide*/
 
1588
    0,        /*inplace_remainder*/
 
1589
    0,           /*inplace_power*/
 
1590
    0,       /*inplace_lshift*/
 
1591
    0,      /*inplace_rshift*/
 
1592
    0,      /*inplace_and*/
 
1593
    0,      /*inplace_xor*/
 
1594
    0,       /*inplace_or*/
 
1595
    0,             /*nb_floor_divide*/
 
1596
    0,              /*nb_true_divide*/
 
1597
    0,     /*nb_inplace_floor_divide*/
 
1598
    0,      /*nb_inplace_true_divide*/
 
1599
    0,                     /* nb_index */
 
1600
};
 
1601
 
 
1602
PyTypeObject ExpsegType = {
 
1603
    PyObject_HEAD_INIT(NULL)
 
1604
    0,                         /*ob_size*/
 
1605
    "_pyo.Expseg_base",         /*tp_name*/
 
1606
    sizeof(Expseg),         /*tp_basicsize*/
 
1607
    0,                         /*tp_itemsize*/
 
1608
    (destructor)Expseg_dealloc, /*tp_dealloc*/
 
1609
    0,                         /*tp_print*/
 
1610
    0,                         /*tp_getattr*/
 
1611
    0,                         /*tp_setattr*/
 
1612
    0,                         /*tp_compare*/
 
1613
    0,                         /*tp_repr*/
 
1614
    &Expseg_as_number,             /*tp_as_number*/
 
1615
    0,                         /*tp_as_sequence*/
 
1616
    0,                         /*tp_as_mapping*/
 
1617
    0,                         /*tp_hash */
 
1618
    0,                         /*tp_call*/
 
1619
    0,                         /*tp_str*/
 
1620
    0,                         /*tp_getattro*/
 
1621
    0,                         /*tp_setattro*/
 
1622
    0,                         /*tp_as_buffer*/
 
1623
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
 
1624
    "Expseg objects. Generates a linear segments break-points line.",           /* tp_doc */
 
1625
    (traverseproc)Expseg_traverse,   /* tp_traverse */
 
1626
    (inquiry)Expseg_clear,           /* tp_clear */
 
1627
    0,                         /* tp_richcompare */
 
1628
    0,                         /* tp_weaklistoffset */
 
1629
    0,                         /* tp_iter */
 
1630
    0,                         /* tp_iternext */
 
1631
    Expseg_methods,             /* tp_methods */
 
1632
    Expseg_members,             /* tp_members */
 
1633
    0,                      /* tp_getset */
 
1634
    0,                         /* tp_base */
 
1635
    0,                         /* tp_dict */
 
1636
    0,                         /* tp_descr_get */
 
1637
    0,                         /* tp_descr_set */
 
1638
    0,                         /* tp_dictoffset */
 
1639
    (initproc)Expseg_init,      /* tp_init */
 
1640
    0,                         /* tp_alloc */
 
1641
    Expseg_new,                 /* tp_new */
 
1642
};