1
/*************************************************************************
2
* Copyright 2010 Olivier Belanger *
4
* This file is part of pyo, a python module to help digital signal *
5
* processing script creation. *
7
* pyo is free software: you can redistribute it and/or modify *
8
* it under the terms of the GNU General Public License as published by *
9
* the Free Software Foundation, either version 3 of the License, or *
10
* (at your option) any later version. *
12
* pyo is distributed in the hope that it will be useful, *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
* GNU General Public License for more details. *
17
* You should have received a copy of the GNU General Public License *
18
* along with pyo. If not, see <http://www.gnu.org/licenses/>. *
19
*************************************************************************/
22
#include "structmember.h"
23
#include "pyomodule.h"
24
#include "streammodule.h"
25
#include "servermodule.h"
26
#include "dummymodule.h"
40
static void Fader_internal_stop(Fader *self) {
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++) {
51
Fader_generate_auto(Fader *self) {
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)
60
else if (self->currentTime >= (self->duration - self->release))
61
val = (self->duration - self->currentTime) / self->release;
66
self->currentTime += self->sampleToSec;
71
Fader_generate_wait(Fader *self) {
75
for (i=0; i<self->bufsize; i++) {
76
if (self->fademode == 0) {
78
if (self->currentTime <= self->attack)
79
val = self->currentTime / self->attack;
85
if (self->currentTime <= self->release)
86
val = (1. - self->currentTime / self->release) * self->topValue;
91
self->currentTime += self->sampleToSec;
93
if (self->fademode == 1 && self->currentTime > self->release)
94
Fader_internal_stop((Fader *)self);
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 };
108
Fader_setProcMode(Fader *self)
111
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
113
if (self->duration == 0.0)
114
self->proc_func_ptr = Fader_generate_wait;
116
self->proc_func_ptr = Fader_generate_auto;
118
switch (muladdmode) {
120
self->muladd_func_ptr = Fader_postprocessing_ii;
123
self->muladd_func_ptr = Fader_postprocessing_ai;
126
self->muladd_func_ptr = Fader_postprocessing_revai;
129
self->muladd_func_ptr = Fader_postprocessing_ia;
132
self->muladd_func_ptr = Fader_postprocessing_aa;
135
self->muladd_func_ptr = Fader_postprocessing_revaa;
138
self->muladd_func_ptr = Fader_postprocessing_ireva;
141
self->muladd_func_ptr = Fader_postprocessing_areva;
144
self->muladd_func_ptr = Fader_postprocessing_revareva;
150
Fader_compute_next_data_frame(Fader *self)
152
(*self->proc_func_ptr)(self);
153
(*self->muladd_func_ptr)(self);
157
Fader_traverse(Fader *self, visitproc visit, void *arg)
164
Fader_clear(Fader *self)
171
Fader_dealloc(Fader* self)
175
self->ob_type->tp_free((PyObject*)self);
178
static PyObject * Fader_deleteStream(Fader *self) { DELETE_STREAM };
181
Fader_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
185
self = (Fader *)type->tp_alloc(type, 0);
187
self->modebuffer[0] = 0;
188
self->modebuffer[1] = 0;
189
self->topValue = 0.0;
193
self->duration = 0.0;
194
self->currentTime = 0.0;
197
Stream_setFunctionPtr(self->stream, Fader_compute_next_data_frame);
198
self->mode_func_ptr = Fader_setProcMode;
200
Stream_setStreamActive(self->stream, 0);
202
self->sampleToSec = 1. / self->sr;
204
return (PyObject *)self;
208
Fader_init(Fader *self, PyObject *args, PyObject *kwds)
210
PyObject *multmp=NULL, *addtmp=NULL;
212
static char *kwlist[] = {"fadein", "fadeout", "dur", "mul", "add", NULL};
214
if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE__FFFOO, kwlist, &self->attack, &self->release, &self->duration, &multmp, &addtmp))
218
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
222
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
225
Py_INCREF(self->stream);
226
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
228
(*self->mode_func_ptr)(self);
234
static PyObject * 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 };
241
static PyObject * Fader_play(Fader *self, PyObject *args, PyObject *kwds)
244
self->currentTime = 0.0;
245
(*self->mode_func_ptr)(self);
250
Fader_stop(Fader *self)
252
if (self->duration == 0.0) {
254
self->currentTime = 0.0;
257
Fader_internal_stop((Fader *)self);
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 };
273
Fader_setFadein(Fader *self, PyObject *arg)
275
self->attack = PyFloat_AsDouble(arg);
281
Fader_setFadeout(Fader *self, PyObject *arg)
283
self->release = PyFloat_AsDouble(arg);
289
Fader_setDur(Fader *self, PyObject *arg)
291
self->duration = PyFloat_AsDouble(arg);
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 */
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 */
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*/
330
0, /*(unaryfunc)array_abs,*/
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*/
350
0, /*inplace_lshift*/
351
0, /*inplace_rshift*/
355
0, /*nb_floor_divide*/
356
0, /*nb_true_divide*/
357
0, /*nb_inplace_floor_divide*/
358
0, /*nb_inplace_true_divide*/
362
PyTypeObject FaderType = {
363
PyObject_HEAD_INIT(NULL)
365
"_pyo.Fader_base", /*tp_name*/
366
sizeof(Fader), /*tp_basicsize*/
368
(destructor)Fader_dealloc, /*tp_dealloc*/
374
&Fader_as_number, /*tp_as_number*/
375
0, /*tp_as_sequence*/
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 */
391
Fader_methods, /* tp_methods */
392
Fader_members, /* tp_members */
396
0, /* tp_descr_get */
397
0, /* tp_descr_set */
398
0, /* tp_dictoffset */
399
(initproc)Fader_init, /* tp_init */
401
Fader_new, /* tp_new */
418
static void Adsr_internal_stop(Adsr *self) {
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++) {
429
Adsr_generate_auto(Adsr *self) {
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)
440
else if (self->currentTime >= (self->duration - self->release))
441
val = (self->duration - self->currentTime) / self->release * self->sustain;
446
self->currentTime += self->sampleToSec;
451
Adsr_generate_wait(Adsr *self) {
455
for (i=0; i<self->bufsize; i++) {
456
if (self->fademode == 0) {
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;
464
self->topValue = val;
467
if (self->currentTime <= self->release)
468
val = self->topValue * (1. - self->currentTime / self->release);
473
self->currentTime += self->sampleToSec;
475
if (self->fademode == 1 && self->currentTime > self->release)
476
Adsr_internal_stop((Adsr *)self);
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 };
490
Adsr_setProcMode(Adsr *self)
493
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
495
if (self->duration == 0.0)
496
self->proc_func_ptr = Adsr_generate_wait;
498
self->proc_func_ptr = Adsr_generate_auto;
500
switch (muladdmode) {
502
self->muladd_func_ptr = Adsr_postprocessing_ii;
505
self->muladd_func_ptr = Adsr_postprocessing_ai;
508
self->muladd_func_ptr = Adsr_postprocessing_revai;
511
self->muladd_func_ptr = Adsr_postprocessing_ia;
514
self->muladd_func_ptr = Adsr_postprocessing_aa;
517
self->muladd_func_ptr = Adsr_postprocessing_revaa;
520
self->muladd_func_ptr = Adsr_postprocessing_ireva;
523
self->muladd_func_ptr = Adsr_postprocessing_areva;
526
self->muladd_func_ptr = Adsr_postprocessing_revareva;
532
Adsr_compute_next_data_frame(Adsr *self)
534
(*self->proc_func_ptr)(self);
535
(*self->muladd_func_ptr)(self);
539
Adsr_traverse(Adsr *self, visitproc visit, void *arg)
546
Adsr_clear(Adsr *self)
553
Adsr_dealloc(Adsr* self)
557
self->ob_type->tp_free((PyObject*)self);
560
static PyObject * Adsr_deleteStream(Adsr *self) { DELETE_STREAM };
563
Adsr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
567
self = (Adsr *)type->tp_alloc(type, 0);
569
self->modebuffer[0] = 0;
570
self->modebuffer[1] = 0;
571
self->topValue = 0.0;
575
self->sustain = 0.707;
577
self->duration = 0.0;
578
self->currentTime = 0.0;
581
Stream_setFunctionPtr(self->stream, Adsr_compute_next_data_frame);
582
self->mode_func_ptr = Adsr_setProcMode;
584
Stream_setStreamActive(self->stream, 0);
586
self->sampleToSec = 1. / self->sr;
588
return (PyObject *)self;
592
Adsr_init(Adsr *self, PyObject *args, PyObject *kwds)
594
PyObject *multmp=NULL, *addtmp=NULL;
596
static char *kwlist[] = {"attack", "decay", "sustain", "release", "dur", "mul", "add", NULL};
598
if (! PyArg_ParseTupleAndKeywords(args, kwds, TYPE__FFFFFOO, kwlist, &self->attack, &self->decay, &self->sustain, &self->release, &self->duration, &multmp, &addtmp))
602
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
606
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
609
Py_INCREF(self->stream);
610
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
612
(*self->mode_func_ptr)(self);
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 };
625
static PyObject * Adsr_play(Adsr *self, PyObject *args, PyObject *kwds)
628
self->currentTime = 0.0;
629
(*self->mode_func_ptr)(self);
634
Adsr_stop(Adsr *self)
636
if (self->duration == 0.0) {
638
self->currentTime = 0.0;
641
Adsr_internal_stop((Adsr *)self);
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 };
657
Adsr_setAttack(Adsr *self, PyObject *arg)
659
self->attack = PyFloat_AsDouble(PyNumber_Float(arg));
665
Adsr_setDecay(Adsr *self, PyObject *arg)
667
self->decay = PyFloat_AsDouble(PyNumber_Float(arg));
673
Adsr_setSustain(Adsr *self, PyObject *arg)
675
self->sustain = PyFloat_AsDouble(PyNumber_Float(arg));
681
Adsr_setRelease(Adsr *self, PyObject *arg)
683
self->release = PyFloat_AsDouble(PyNumber_Float(arg));
689
Adsr_setDur(Adsr *self, PyObject *arg)
691
self->duration = PyFloat_AsDouble(PyNumber_Float(arg));
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 */
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 */
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*/
732
0, /*(unaryfunc)array_abs,*/
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*/
752
0, /*inplace_lshift*/
753
0, /*inplace_rshift*/
757
0, /*nb_floor_divide*/
758
0, /*nb_true_divide*/
759
0, /*nb_inplace_floor_divide*/
760
0, /*nb_inplace_true_divide*/
764
PyTypeObject AdsrType = {
765
PyObject_HEAD_INIT(NULL)
767
"_pyo.Adsr_base", /*tp_name*/
768
sizeof(Adsr), /*tp_basicsize*/
770
(destructor)Adsr_dealloc, /*tp_dealloc*/
776
&Adsr_as_number, /*tp_as_number*/
777
0, /*tp_as_sequence*/
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 */
793
Adsr_methods, /* tp_methods */
794
Adsr_members, /* tp_members */
798
0, /* tp_descr_get */
799
0, /* tp_descr_set */
800
0, /* tp_dictoffset */
801
(initproc)Adsr_init, /* tp_init */
803
Adsr_new, /* tp_new */
808
PyObject *pointslist;
824
Linseg_convert_pointslist(Linseg *self) {
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)));
839
Linseg_reinit(Linseg *self) {
840
if (self->newlist == 1) {
841
Linseg_convert_pointslist((Linseg *)self);
844
self->currentTime = 0.0;
845
self->currentValue = self->targets[0];
851
Linseg_generate(Linseg *self) {
854
for (i=0; i<self->bufsize; i++) {
855
if (self->flag == 1) {
856
if (self->currentTime >= self->times[self->which]) {
858
if (self->which == self->listsize) {
860
Linseg_reinit((Linseg *)self);
863
self->currentValue = self->targets[self->which-1];
867
if ((self->times[self->which] - self->times[self->which-1]) <= 0)
868
self->increment = self->targets[self->which] - self->currentValue;
870
self->increment = (self->targets[self->which] - self->targets[self->which-1]) / ((self->times[self->which] - self->times[self->which-1]) / self->sampleToSec);
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;
879
self->data[i] = (MYFLT)self->currentValue;
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 };
894
Linseg_setProcMode(Linseg *self)
897
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
899
self->proc_func_ptr = Linseg_generate;
901
switch (muladdmode) {
903
self->muladd_func_ptr = Linseg_postprocessing_ii;
906
self->muladd_func_ptr = Linseg_postprocessing_ai;
909
self->muladd_func_ptr = Linseg_postprocessing_revai;
912
self->muladd_func_ptr = Linseg_postprocessing_ia;
915
self->muladd_func_ptr = Linseg_postprocessing_aa;
918
self->muladd_func_ptr = Linseg_postprocessing_revaa;
921
self->muladd_func_ptr = Linseg_postprocessing_ireva;
924
self->muladd_func_ptr = Linseg_postprocessing_areva;
927
self->muladd_func_ptr = Linseg_postprocessing_revareva;
933
Linseg_compute_next_data_frame(Linseg *self)
935
(*self->proc_func_ptr)(self);
936
(*self->muladd_func_ptr)(self);
940
Linseg_traverse(Linseg *self, visitproc visit, void *arg)
943
Py_VISIT(self->pointslist);
948
Linseg_clear(Linseg *self)
951
Py_CLEAR(self->pointslist);
956
Linseg_dealloc(Linseg* self)
962
self->ob_type->tp_free((PyObject*)self);
965
static PyObject * Linseg_deleteStream(Linseg *self) { DELETE_STREAM };
968
Linseg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
972
self = (Linseg *)type->tp_alloc(type, 0);
976
self->modebuffer[0] = 0;
977
self->modebuffer[1] = 0;
980
Stream_setFunctionPtr(self->stream, Linseg_compute_next_data_frame);
981
self->mode_func_ptr = Linseg_setProcMode;
983
Stream_setStreamActive(self->stream, 0);
985
self->sampleToSec = 1. / self->sr;
987
return (PyObject *)self;
991
Linseg_init(Linseg *self, PyObject *args, PyObject *kwds)
993
PyObject *pointslist=NULL, *multmp=NULL, *addtmp=NULL;
994
int i, initToFirstVal = 0;
996
static char *kwlist[] = {"list", "loop", "initToFirstVal", "mul", "add", NULL};
998
if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|iiOO", kwlist, &pointslist, &self->loop, &initToFirstVal, &multmp, &addtmp))
1001
Py_INCREF(pointslist);
1002
Py_XDECREF(self->pointslist);
1003
self->pointslist = pointslist;
1004
Linseg_convert_pointslist((Linseg *)self);
1007
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
1011
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
1014
Py_INCREF(self->stream);
1015
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
1017
if (initToFirstVal) {
1018
for (i=0; i<self->bufsize; i++) {
1019
self->data[i] = self->targets[0];
1023
(*self->mode_func_ptr)(self);
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 };
1036
static PyObject * Linseg_play(Linseg *self, PyObject *args, PyObject *kwds)
1038
Linseg_reinit((Linseg *)self);
1042
static PyObject * Linseg_stop(Linseg *self) { STOP };
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 };
1054
Linseg_setList(Linseg *self, PyObject *value)
1056
if (value == NULL) {
1057
PyErr_SetString(PyExc_TypeError, "Cannot delete the list attribute.");
1058
return PyInt_FromLong(-1);
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);
1067
Py_DECREF(self->pointslist);
1068
self->pointslist = value;
1077
Linseg_setLoop(Linseg *self, PyObject *arg)
1084
self->loop = PyInt_AsLong(arg);
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 */
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 */
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*/
1124
0, /*(unaryfunc)array_abs,*/
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*/
1149
0, /*nb_floor_divide*/
1150
0, /*nb_true_divide*/
1151
0, /*nb_inplace_floor_divide*/
1152
0, /*nb_inplace_true_divide*/
1156
PyTypeObject LinsegType = {
1157
PyObject_HEAD_INIT(NULL)
1159
"_pyo.Linseg_base", /*tp_name*/
1160
sizeof(Linseg), /*tp_basicsize*/
1162
(destructor)Linseg_dealloc, /*tp_dealloc*/
1168
&Linseg_as_number, /*tp_as_number*/
1169
0, /*tp_as_sequence*/
1170
0, /*tp_as_mapping*/
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 */
1184
0, /* tp_iternext */
1185
Linseg_methods, /* tp_methods */
1186
Linseg_members, /* tp_members */
1190
0, /* tp_descr_get */
1191
0, /* tp_descr_set */
1192
0, /* tp_dictoffset */
1193
(initproc)Linseg_init, /* tp_init */
1195
Linseg_new, /* tp_new */
1200
PyObject *pointslist;
1203
double currentValue;
1223
Expseg_convert_pointslist(Expseg *self) {
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)));
1238
Expseg_reinit(Expseg *self) {
1239
if (self->newlist == 1) {
1240
Expseg_convert_pointslist((Expseg *)self);
1243
self->currentTime = 0.0;
1244
self->currentValue = self->targets[0];
1247
self->exp = self->exp_tmp;
1248
self->inverse = self->inverse_tmp;
1252
Expseg_generate(Expseg *self) {
1256
for (i=0; i<self->bufsize; i++) {
1257
if (self->flag == 1) {
1258
if (self->currentTime >= self->times[self->which]) {
1260
if (self->which == self->listsize) {
1261
if (self->loop == 1)
1262
Expseg_reinit((Expseg *)self);
1265
self->currentValue = self->targets[self->which-1];
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)
1274
self->inc = 1.0 / self->steps;
1276
self->pointer = 0.0;
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);
1284
scl = pow(self->pointer, self->exp);
1286
self->currentValue = scl * self->range + self->targets[self->which-1];
1287
self->pointer += self->inc;
1289
self->data[i] = (MYFLT)self->currentValue;
1290
self->currentTime += self->sampleToSec;
1293
self->data[i] = (MYFLT)self->currentValue;
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 };
1308
Expseg_setProcMode(Expseg *self)
1311
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
1313
self->proc_func_ptr = Expseg_generate;
1315
switch (muladdmode) {
1317
self->muladd_func_ptr = Expseg_postprocessing_ii;
1320
self->muladd_func_ptr = Expseg_postprocessing_ai;
1323
self->muladd_func_ptr = Expseg_postprocessing_revai;
1326
self->muladd_func_ptr = Expseg_postprocessing_ia;
1329
self->muladd_func_ptr = Expseg_postprocessing_aa;
1332
self->muladd_func_ptr = Expseg_postprocessing_revaa;
1335
self->muladd_func_ptr = Expseg_postprocessing_ireva;
1338
self->muladd_func_ptr = Expseg_postprocessing_areva;
1341
self->muladd_func_ptr = Expseg_postprocessing_revareva;
1347
Expseg_compute_next_data_frame(Expseg *self)
1349
(*self->proc_func_ptr)(self);
1350
(*self->muladd_func_ptr)(self);
1354
Expseg_traverse(Expseg *self, visitproc visit, void *arg)
1357
Py_VISIT(self->pointslist);
1362
Expseg_clear(Expseg *self)
1365
Py_CLEAR(self->pointslist);
1370
Expseg_dealloc(Expseg* self)
1373
free(self->targets);
1376
self->ob_type->tp_free((PyObject*)self);
1379
static PyObject * Expseg_deleteStream(Expseg *self) { DELETE_STREAM };
1382
Expseg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1386
self = (Expseg *)type->tp_alloc(type, 0);
1390
self->exp = self->exp_tmp = 10;
1391
self->inverse = self->inverse_tmp = 1;
1392
self->modebuffer[0] = 0;
1393
self->modebuffer[1] = 0;
1396
Stream_setFunctionPtr(self->stream, Expseg_compute_next_data_frame);
1397
self->mode_func_ptr = Expseg_setProcMode;
1399
Stream_setStreamActive(self->stream, 0);
1401
self->sampleToSec = 1. / self->sr;
1403
return (PyObject *)self;
1407
Expseg_init(Expseg *self, PyObject *args, PyObject *kwds)
1409
PyObject *pointslist=NULL, *multmp=NULL, *addtmp=NULL;
1410
int i, initToFirstVal = 0;
1412
static char *kwlist[] = {"list", "loop", "exp", "inverse", "initToFirstVal", "mul", "add", NULL};
1414
if (! PyArg_ParseTupleAndKeywords(args, kwds, "O|idiiOO", kwlist, &pointslist, &self->loop, &self->exp_tmp, &self->inverse_tmp, &initToFirstVal, &multmp, &addtmp))
1417
Py_INCREF(pointslist);
1418
Py_XDECREF(self->pointslist);
1419
self->pointslist = pointslist;
1420
Expseg_convert_pointslist((Expseg *)self);
1423
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
1427
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
1430
Py_INCREF(self->stream);
1431
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
1433
if (initToFirstVal) {
1434
for (i=0; i<self->bufsize; i++) {
1435
self->data[i] = self->targets[0];
1439
(*self->mode_func_ptr)(self);
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 };
1452
static PyObject * Expseg_play(Expseg *self, PyObject *args, PyObject *kwds)
1454
Expseg_reinit((Expseg *)self);
1458
static PyObject * Expseg_stop(Expseg *self) { STOP };
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 };
1470
Expseg_setList(Expseg *self, PyObject *value)
1472
if (value == NULL) {
1473
PyErr_SetString(PyExc_TypeError, "Cannot delete the list attribute.");
1474
return PyInt_FromLong(-1);
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);
1483
Py_DECREF(self->pointslist);
1484
self->pointslist = value;
1493
Expseg_setLoop(Expseg *self, PyObject *arg)
1500
self->loop = PyInt_AsLong(arg);
1507
Expseg_setExp(Expseg *self, PyObject *arg)
1514
self->exp_tmp = PyFloat_AsDouble(PyNumber_Float(arg));
1521
Expseg_setInverse(Expseg *self, PyObject *arg)
1528
self->inverse_tmp = PyInt_AsLong(PyNumber_Int(arg));
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 */
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 */
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*/
1570
0, /*(unaryfunc)array_abs,*/
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*/
1595
0, /*nb_floor_divide*/
1596
0, /*nb_true_divide*/
1597
0, /*nb_inplace_floor_divide*/
1598
0, /*nb_inplace_true_divide*/
1602
PyTypeObject ExpsegType = {
1603
PyObject_HEAD_INIT(NULL)
1605
"_pyo.Expseg_base", /*tp_name*/
1606
sizeof(Expseg), /*tp_basicsize*/
1608
(destructor)Expseg_dealloc, /*tp_dealloc*/
1614
&Expseg_as_number, /*tp_as_number*/
1615
0, /*tp_as_sequence*/
1616
0, /*tp_as_mapping*/
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 */
1630
0, /* tp_iternext */
1631
Expseg_methods, /* tp_methods */
1632
Expseg_members, /* tp_members */
1636
0, /* tp_descr_get */
1637
0, /* tp_descr_set */
1638
0, /* tp_dictoffset */
1639
(initproc)Expseg_init, /* tp_init */
1641
Expseg_new, /* tp_new */