1
/*************************************************************************
2
* Copyright 2010 Olivier Belanger *
1
/**************************************************************************
2
* Copyright 2009-2015 Olivier Belanger *
4
4
* This file is part of pyo, a python module to help digital signal *
5
* processing script creation. *
5
* processing script creation. *
7
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. *
8
* it under the terms of the GNU Lesser General Public License as *
9
* published by the Free Software Foundation, either version 3 of the *
10
* License, or (at your option) any later version. *
12
12
* pyo is distributed in the hope that it will be useful, *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
* GNU General Public License for more details. *
15
* GNU Lesser 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/>. *
17
* You should have received a copy of the GNU Lesser General Public *
18
* License along with pyo. If not, see <http://www.gnu.org/licenses/>. *
19
19
*************************************************************************/
21
21
#include <Python.h>
66
66
maxHarms = (int)(self->srOverFour/freq);
67
67
numh = sharp * 46.0 + 4.0;
68
68
if (numh > maxHarms)
70
70
for (i=0; i<self->bufsize; i++) {
71
71
pointer = self->pointerPos * 2.0 - 1.0;
72
72
val = pointer - MYTANH(numh * pointer) / MYTANH(numh);
75
75
if (self->pointerPos < 0)
76
76
self->pointerPos += 1.0;
77
77
else if (self->pointerPos >= 1)
78
self->pointerPos -= 1.0;
78
self->pointerPos -= 1.0;
81
81
case 1: /* Saw down */
82
82
maxHarms = (int)(self->srOverFour/freq);
83
83
numh = sharp * 46.0 + 4.0;
84
84
if (numh > maxHarms)
86
86
for (i=0; i<self->bufsize; i++) {
87
87
pointer = self->pointerPos * 2.0 - 1.0;
88
88
val = -(pointer - MYTANH(numh * pointer) / MYTANH(numh));
91
91
if (self->pointerPos < 0)
92
92
self->pointerPos += 1.0;
93
93
else if (self->pointerPos >= 1)
94
self->pointerPos -= 1.0;
94
self->pointerPos -= 1.0;
97
97
case 2: /* Square */
98
98
maxHarms = (int)(self->srOverEight/freq);
99
99
numh = sharp * 46.0 + 4.0;
100
100
if (numh > maxHarms)
102
102
for (i=0; i<self->bufsize; i++) {
103
103
val = MYATAN(numh * MYSIN(TWOPI*self->pointerPos));
104
104
self->data[i] = val * self->oneOverPiOverTwo;
106
106
if (self->pointerPos < 0)
107
107
self->pointerPos += 1.0;
108
108
else if (self->pointerPos >= 1)
109
self->pointerPos -= 1.0;
109
self->pointerPos -= 1.0;
112
112
case 3: /* Triangle */
113
113
maxHarms = (int)(self->srOverFour/freq);
114
114
if ((sharp * 36.0) > maxHarms)
115
115
numh = (MYFLT)(maxHarms / 36.0);
118
118
for (i=0; i<self->bufsize; i++) {
119
119
v1 = MYTAN(MYSIN(TWOPI*self->pointerPos));
120
120
pointer = self->pointerPos + 0.25;
144
144
if (self->pointerPos < 0)
145
145
self->pointerPos += 1.0;
146
146
else if (self->pointerPos >= 1)
147
self->pointerPos -= 1.0;
147
self->pointerPos -= 1.0;
150
150
case 5: /* Bi-Pulse */
151
151
maxHarms = (int)(self->srOverEight/freq);
152
152
numh = MYFLOOR(sharp * 46.0 + 4.0);
153
153
if (numh > maxHarms)
155
155
if (MYFMOD(numh, 2.0) == 0.0)
157
157
for (i=0; i<self->bufsize; i++) {
215
215
MYFLT val, inc, freq, sharp, pointer, numh;
216
216
MYFLT v1, v2, inc2, fade;
219
219
MYFLT *fr = Stream_getData((Stream *)self->freq_stream);
220
220
if (fr[0] <= 0) {
270
270
maxHarms = (int)(self->srOverEight/freq);
271
271
numh = sharp * 46.0 + 4.0;
272
272
if (numh > maxHarms)
274
274
val = MYATAN(numh * MYSIN(TWOPI*self->pointerPos));
275
275
self->data[i] = val * self->oneOverPiOverTwo;
276
276
self->pointerPos += inc;
277
277
if (self->pointerPos < 0)
278
278
self->pointerPos += 1.0;
279
279
else if (self->pointerPos >= 1)
280
self->pointerPos -= 1.0;
280
self->pointerPos -= 1.0;
283
283
case 3: /* Triangle */
284
284
for (i=0; i<self->bufsize; i++) {
329
329
maxHarms = (int)(self->srOverEight/freq);
330
330
numh = MYFLOOR(sharp * 46.0 + 4.0);
331
331
if (numh > maxHarms)
333
333
if (MYFMOD(numh, 2.0) == 0.0)
335
335
val = MYTAN(MYPOW(MYSIN(TWOPI*self->pointerPos), numh));
396
396
MYFLT val, inc, freq, sharp, pointer, numh;
397
397
MYFLT v1, v2, inc2, fade;
400
400
freq = PyFloat_AS_DOUBLE(self->freq);
404
404
MYFLT *sh = Stream_getData((Stream *)self->sharp_stream);
405
405
inc = freq / self->sr;
407
407
switch (self->wavetype) {
408
408
case 0: /* Saw up */
409
409
maxHarms = (int)(self->srOverFour/freq);
458
458
numh = sharp * 46.0 + 4.0;
459
459
if (numh > maxHarms)
461
461
val = MYATAN(numh * MYSIN(TWOPI*self->pointerPos));
462
462
self->data[i] = val * self->oneOverPiOverTwo;
463
463
self->pointerPos += inc;
464
464
if (self->pointerPos < 0)
465
465
self->pointerPos += 1.0;
466
466
else if (self->pointerPos >= 1)
467
self->pointerPos -= 1.0;
467
self->pointerPos -= 1.0;
470
470
case 3: /* Triangle */
471
471
maxHarms = (int)(self->srOverFour/freq);
598
598
MYFLT val, inc, freq, sharp, pointer, numh;
599
599
MYFLT v1, v2, inc2, fade;
602
602
MYFLT *fr = Stream_getData((Stream *)self->freq_stream);
603
603
if (fr[0] <= 0) {
606
606
MYFLT *sh = Stream_getData((Stream *)self->sharp_stream);
608
608
switch (self->wavetype) {
609
609
case 0: /* Saw up */
610
610
for (i=0; i<self->bufsize; i++) {
664
664
maxHarms = (int)(self->srOverEight/freq);
665
665
numh = sharp * 46.0 + 4.0;
666
666
if (numh > maxHarms)
668
668
val = MYATAN(numh * MYSIN(TWOPI*self->pointerPos));
669
669
self->data[i] = val * self->oneOverPiOverTwo;
670
670
self->pointerPos += inc;
671
671
if (self->pointerPos < 0)
672
672
self->pointerPos += 1.0;
673
673
else if (self->pointerPos >= 1)
674
self->pointerPos -= 1.0;
674
self->pointerPos -= 1.0;
677
677
case 3: /* Triangle */
678
678
for (i=0; i<self->bufsize; i++) {
738
738
maxHarms = (int)(self->srOverEight/freq);
739
739
numh = MYFLOOR(sharp * 46.0 + 4.0);
740
740
if (numh > maxHarms)
742
742
if (MYFMOD(numh, 2.0) == 0.0)
744
744
val = MYTAN(MYPOW(MYSIN(TWOPI*self->pointerPos), numh));
826
826
int procmode, muladdmode;
827
827
procmode = self->modebuffer[2] + self->modebuffer[3] * 10;
828
828
muladdmode = self->modebuffer[0] + self->modebuffer[1] * 10;
830
830
switch (procmode) {
832
832
self->proc_func_ptr = LFO_generates_ii;
835
835
self->proc_func_ptr = LFO_generates_ai;
838
838
self->proc_func_ptr = LFO_generates_ia;
841
841
self->proc_func_ptr = LFO_generates_aa;
844
844
switch (muladdmode) {
846
846
self->muladd_func_ptr = LFO_postprocessing_ii;
849
849
self->muladd_func_ptr = LFO_postprocessing_ai;
852
852
self->muladd_func_ptr = LFO_postprocessing_revai;
855
855
self->muladd_func_ptr = LFO_postprocessing_ia;
858
858
self->muladd_func_ptr = LFO_postprocessing_aa;
861
861
self->muladd_func_ptr = LFO_postprocessing_revaa;
864
864
self->muladd_func_ptr = LFO_postprocessing_ireva;
867
867
self->muladd_func_ptr = LFO_postprocessing_areva;
870
870
self->muladd_func_ptr = LFO_postprocessing_revareva;
876
876
LFO_compute_next_data_frame(LFO *self)
878
(*self->proc_func_ptr)(self);
878
(*self->proc_func_ptr)(self);
879
879
(*self->muladd_func_ptr)(self);
883
883
LFO_traverse(LFO *self, visitproc visit, void *arg)
886
Py_VISIT(self->freq);
887
Py_VISIT(self->freq_stream);
888
Py_VISIT(self->sharp);
889
Py_VISIT(self->sharp_stream);
886
Py_VISIT(self->freq);
887
Py_VISIT(self->freq_stream);
888
Py_VISIT(self->sharp);
889
Py_VISIT(self->sharp_stream);
894
894
LFO_clear(LFO *self)
897
Py_CLEAR(self->freq);
898
Py_CLEAR(self->freq_stream);
899
Py_CLEAR(self->sharp);
900
Py_CLEAR(self->sharp_stream);
897
Py_CLEAR(self->freq);
898
Py_CLEAR(self->freq_stream);
899
Py_CLEAR(self->sharp);
900
Py_CLEAR(self->sharp_stream);
916
916
PyObject *freqtmp=NULL, *sharptmp=NULL, *multmp=NULL, *addtmp=NULL;
918
918
self = (LFO *)type->tp_alloc(type, 0);
920
920
self->freq = PyFloat_FromDouble(100);
921
921
self->sharp = PyFloat_FromDouble(0.5);
922
922
self->oneOverPiOverTwo = 1.0 / (PI / 2.0);
949
949
PyObject_CallMethod((PyObject *)self, "setSharp", "O", sharptmp);
953
953
PyObject_CallMethod((PyObject *)self, "setMul", "O", multmp);
957
957
PyObject_CallMethod((PyObject *)self, "setAdd", "O", addtmp);
960
960
PyObject_CallMethod(self->server, "addStream", "O", self->stream);
962
962
Server_generateSeed((Server *)self->server, LFO_ID);
964
964
self->sahCurrentValue = self->sahLastValue = rand()/((MYFLT)(RAND_MAX)*0.5) - 1.0;
966
966
(*self->mode_func_ptr)(self);
968
968
return (PyObject *)self;
971
971
static PyObject * LFO_getServer(LFO* self) { GET_SERVER };
972
972
static PyObject * LFO_getStream(LFO* self) { GET_STREAM };
973
static PyObject * LFO_setMul(LFO *self, PyObject *arg) { SET_MUL };
974
static PyObject * LFO_setAdd(LFO *self, PyObject *arg) { SET_ADD };
975
static PyObject * LFO_setSub(LFO *self, PyObject *arg) { SET_SUB };
976
static PyObject * LFO_setDiv(LFO *self, PyObject *arg) { SET_DIV };
973
static PyObject * LFO_setMul(LFO *self, PyObject *arg) { SET_MUL };
974
static PyObject * LFO_setAdd(LFO *self, PyObject *arg) { SET_ADD };
975
static PyObject * LFO_setSub(LFO *self, PyObject *arg) { SET_SUB };
976
static PyObject * LFO_setDiv(LFO *self, PyObject *arg) { SET_DIV };
978
978
static PyObject * LFO_play(LFO *self, PyObject *args, PyObject *kwds) { PLAY };
979
979
static PyObject * LFO_out(LFO *self, PyObject *args, PyObject *kwds) { OUT };
1015
1015
self->freq_stream = (Stream *)streamtmp;
1016
1016
self->modebuffer[2] = 1;
1019
1019
(*self->mode_func_ptr)(self);
1021
1021
Py_INCREF(Py_None);
1022
1022
return Py_None;
1025
1025
static PyObject *
1026
1026
LFO_setSharp(LFO *self, PyObject *arg)
1028
1028
PyObject *tmp, *streamtmp;
1030
1030
if (arg == NULL) {
1031
1031
Py_INCREF(Py_None);
1032
1032
return Py_None;
1035
1035
int isNumber = PyNumber_Check(arg);
1038
1038
Py_INCREF(tmp);
1039
1039
Py_DECREF(self->sharp);
1049
1049
self->sharp_stream = (Stream *)streamtmp;
1050
1050
self->modebuffer[3] = 1;
1053
1053
(*self->mode_func_ptr)(self);
1055
1055
Py_INCREF(Py_None);
1056
1056
return Py_None;
1059
1059
static PyObject *
1060
1060
LFO_setType(LFO *self, PyObject *arg)
1064
1064
if (arg == NULL) {
1065
1065
Py_INCREF(Py_None);
1066
1066
return Py_None;
1069
1069
int isInt = PyInt_Check(arg);
1071
1071
if (isInt == 1) {
1072
1072
tmp = PyInt_AsLong(arg);
1073
1073
if (tmp >= 0 && tmp < 8)