1
/* Copyright (c) 1997-1999 Miller Puckette.
2
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
5
/* sinusoidal oscillator and table lookup; see also tabosc4~ in d_array.c.
11
#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
13
/* machine-dependent definitions. These ifdefs really
14
should have been by CPU type and not by operating system! */
16
/* big-endian. Most significant byte is at low address in memory */
17
#define HIOFFSET 0 /* word offset to find MSB */
18
#define LOWOFFSET 1 /* word offset to find LSB */
19
#define int32 long /* a data type that has 32 bits */
23
/* little-endian; most significant byte is at highest address */
29
#if defined(__FreeBSD__) || defined(__APPLE__)
30
#include <machine/endian.h>
37
#if defined(__unix__) || defined(__APPLE__)
38
#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN)
39
#error No byte order defined
42
#if BYTE_ORDER == LITTLE_ENDIAN
46
#define HIOFFSET 0 /* word offset to find MSB */
47
#define LOWOFFSET 1 /* word offset to find LSB */
48
#endif /* __BYTE_ORDER */
49
#include <sys/types.h>
51
#endif /* __unix__ or __APPLE__*/
59
/* -------------------------- phasor~ ------------------------------ */
60
static t_class *phasor_class, *scalarphasor_class;
62
#if 1 /* in the style of R. Hoeldrich (ICMC 1995 Banff) */
64
typedef struct _phasor
69
float x_f; /* scalar frequency */
72
static void *phasor_new(t_floatarg f)
74
t_phasor *x = (t_phasor *)pd_new(phasor_class);
76
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
79
outlet_new(&x->x_obj, gensym("signal"));
83
static t_int *phasor_perform(t_int *w)
85
t_phasor *x = (t_phasor *)(w[1]);
86
t_float *in = (t_float *)(w[2]);
87
t_float *out = (t_float *)(w[3]);
89
double dphase = x->x_phase + (double)UNITBIT32;
92
float conv = x->x_conv;
95
normhipart = tf.tf_i[HIOFFSET];
100
tf.tf_i[HIOFFSET] = normhipart;
101
dphase += *in++ * conv;
102
*out++ = tf.tf_d - UNITBIT32;
105
tf.tf_i[HIOFFSET] = normhipart;
106
x->x_phase = tf.tf_d - UNITBIT32;
110
static void phasor_dsp(t_phasor *x, t_signal **sp)
112
x->x_conv = 1./sp[0]->s_sr;
113
dsp_add(phasor_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
116
static void phasor_ft1(t_phasor *x, t_float f)
121
static void phasor_setup(void)
123
phasor_class = class_new(gensym("phasor~"), (t_newmethod)phasor_new, 0,
124
sizeof(t_phasor), 0, A_DEFFLOAT, 0);
125
CLASS_MAINSIGNALIN(phasor_class, t_phasor, x_f);
126
class_addmethod(phasor_class, (t_method)phasor_dsp, gensym("dsp"), 0);
127
class_addmethod(phasor_class, (t_method)phasor_ft1,
128
gensym("ft1"), A_FLOAT, 0);
131
#endif /* Hoeldrich version */
133
/* ------------------------ cos~ ----------------------------- */
137
static t_class *cos_class;
145
static void *cos_new(void)
147
t_cos *x = (t_cos *)pd_new(cos_class);
148
outlet_new(&x->x_obj, gensym("signal"));
153
static t_int *cos_perform(t_int *w)
155
t_float *in = (t_float *)(w[1]);
156
t_float *out = (t_float *)(w[2]);
158
float *tab = cos_table, *addr, f1, f2, frac;
164
normhipart = tf.tf_i[HIOFFSET];
166
#if 0 /* this is the readable version of the code. */
169
dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
171
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
172
tf.tf_i[HIOFFSET] = normhipart;
173
frac = tf.tf_d - UNITBIT32;
176
*out++ = f1 + frac * (f2 - f1);
179
#if 1 /* this is the same, unwrapped by hand. */
180
dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
182
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
183
tf.tf_i[HIOFFSET] = normhipart;
186
dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
187
frac = tf.tf_d - UNITBIT32;
191
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
192
*out++ = f1 + frac * (f2 - f1);
193
tf.tf_i[HIOFFSET] = normhipart;
195
frac = tf.tf_d - UNITBIT32;
198
*out++ = f1 + frac * (f2 - f1);
203
static void cos_dsp(t_cos *x, t_signal **sp)
205
dsp_add(cos_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
208
static void cos_maketable(void)
211
float *fp, phase, phsinc = (2. * 3.14159) / COSTABSIZE;
214
if (cos_table) return;
215
cos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
216
for (i = COSTABSIZE + 1, fp = cos_table, phase = 0; i--;
217
fp++, phase += phsinc)
220
/* here we check at startup whether the byte alignment
221
is as we declared it. If not, the code has to be
222
recompiled the other way. */
223
tf.tf_d = UNITBIT32 + 0.5;
224
if ((unsigned)tf.tf_i[LOWOFFSET] != 0x80000000)
225
bug("cos~: unexpected machine alignment");
228
static void cos_setup(void)
230
cos_class = class_new(gensym("cos~"), (t_newmethod)cos_new, 0,
231
sizeof(t_cos), 0, A_DEFFLOAT, 0);
232
CLASS_MAINSIGNALIN(cos_class, t_cos, x_f);
233
class_addmethod(cos_class, (t_method)cos_dsp, gensym("dsp"), 0);
237
/* ------------------------ osc~ ----------------------------- */
239
static t_class *osc_class, *scalarosc_class;
246
float x_f; /* frequency if scalar */
249
static void *osc_new(t_floatarg f)
251
t_osc *x = (t_osc *)pd_new(osc_class);
253
outlet_new(&x->x_obj, gensym("signal"));
254
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
260
static t_int *osc_perform(t_int *w)
262
t_osc *x = (t_osc *)(w[1]);
263
t_float *in = (t_float *)(w[2]);
264
t_float *out = (t_float *)(w[3]);
266
float *tab = cos_table, *addr, f1, f2, frac;
267
double dphase = x->x_phase + UNITBIT32;
270
float conv = x->x_conv;
273
normhipart = tf.tf_i[HIOFFSET];
278
dphase += *in++ * conv;
279
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
280
tf.tf_i[HIOFFSET] = normhipart;
281
frac = tf.tf_d - UNITBIT32;
284
*out++ = f1 + frac * (f2 - f1);
289
dphase += *in++ * conv;
290
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
291
tf.tf_i[HIOFFSET] = normhipart;
292
frac = tf.tf_d - UNITBIT32;
297
dphase += *in++ * conv;
299
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
300
tf.tf_i[HIOFFSET] = normhipart;
301
*out++ = f1 + frac * (f2 - f1);
302
frac = tf.tf_d - UNITBIT32;
306
*out++ = f1 + frac * (f2 - f1);
309
tf.tf_d = UNITBIT32 * COSTABSIZE;
310
normhipart = tf.tf_i[HIOFFSET];
311
tf.tf_d = dphase + (UNITBIT32 * COSTABSIZE - UNITBIT32);
312
tf.tf_i[HIOFFSET] = normhipart;
313
x->x_phase = tf.tf_d - UNITBIT32 * COSTABSIZE;
317
static void osc_dsp(t_osc *x, t_signal **sp)
319
x->x_conv = COSTABSIZE/sp[0]->s_sr;
320
dsp_add(osc_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
323
static void osc_ft1(t_osc *x, t_float f)
325
x->x_phase = COSTABSIZE * f;
328
static void osc_setup(void)
330
osc_class = class_new(gensym("osc~"), (t_newmethod)osc_new, 0,
331
sizeof(t_osc), 0, A_DEFFLOAT, 0);
332
CLASS_MAINSIGNALIN(osc_class, t_osc, x_f);
333
class_addmethod(osc_class, (t_method)osc_dsp, gensym("dsp"), 0);
334
class_addmethod(osc_class, (t_method)osc_ft1, gensym("ft1"), A_FLOAT, 0);
339
/* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */
341
typedef struct vcfctl
349
typedef struct sigvcf
357
t_class *sigvcf_class;
359
static void *sigvcf_new(t_floatarg q)
361
t_sigvcf *x = (t_sigvcf *)pd_new(sigvcf_class);
362
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
363
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
364
outlet_new(&x->x_obj, gensym("signal"));
365
outlet_new(&x->x_obj, gensym("signal"));
366
x->x_ctl = &x->x_cspace;
367
x->x_cspace.c_re = 0;
368
x->x_cspace.c_im = 0;
370
x->x_cspace.c_isr = 0;
375
static void sigvcf_ft1(t_sigvcf *x, t_floatarg f)
377
x->x_ctl->c_q = (f > 0 ? f : 0.f);
380
static t_int *sigvcf_perform(t_int *w)
382
float *in1 = (float *)(w[1]);
383
float *in2 = (float *)(w[2]);
384
float *out1 = (float *)(w[3]);
385
float *out2 = (float *)(w[4]);
386
t_vcfctl *c = (t_vcfctl *)(w[5]);
387
int n = (t_int)(w[6]);
389
float re = c->c_re, re2;
392
float qinv = (q > 0? 1.0f/q : 0);
393
float ampcorrect = 2.0f - 2.0f / (q + 2.0f);
394
float isr = c->c_isr;
396
float *tab = cos_table, *addr, f1, f2, frac;
398
int normhipart, tabindex;
402
normhipart = tf.tf_i[HIOFFSET];
404
for (i = 0; i < n; i++)
406
float cf, cfindx, r, oneminusr;
409
cfindx = cf * (float)(COSTABSIZE/6.28318f);
410
r = (qinv > 0 ? 1 - cf * qinv : 0);
412
oneminusr = 1.0f - r;
413
dphase = ((double)(cfindx)) + UNITBIT32;
415
tabindex = tf.tf_i[HIOFFSET] & (COSTABSIZE-1);
416
addr = tab + tabindex;
417
tf.tf_i[HIOFFSET] = normhipart;
418
frac = tf.tf_d - UNITBIT32;
421
coefr = r * (f1 + frac * (f2 - f1));
423
addr = tab + ((tabindex - (COSTABSIZE/4)) & (COSTABSIZE-1));
426
coefi = r * (f1 + frac * (f2 - f1));
430
*out1++ = re = ampcorrect * oneminusr * f1
431
+ coefr * re2 - coefi * im;
432
*out2++ = im = coefi * re2 + coefr * im;
434
if (PD_BIGORSMALL(re))
436
if (PD_BIGORSMALL(im))
443
static void sigvcf_dsp(t_sigvcf *x, t_signal **sp)
445
x->x_ctl->c_isr = 6.28318f/sp[0]->s_sr;
446
dsp_add(sigvcf_perform, 6,
447
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,
448
x->x_ctl, sp[0]->s_n);
452
void sigvcf_setup(void)
454
sigvcf_class = class_new(gensym("vcf~"), (t_newmethod)sigvcf_new, 0,
455
sizeof(t_sigvcf), 0, A_DEFFLOAT, 0);
456
CLASS_MAINSIGNALIN(sigvcf_class, t_sigvcf, x_f);
457
class_addmethod(sigvcf_class, (t_method)sigvcf_dsp, gensym("dsp"), 0);
458
class_addmethod(sigvcf_class, (t_method)sigvcf_ft1,
459
gensym("ft1"), A_FLOAT, 0);
462
/* -------------------------- noise~ ------------------------------ */
463
static t_class *noise_class;
465
typedef struct _noise
471
static void *noise_new(void)
473
t_noise *x = (t_noise *)pd_new(noise_class);
474
static int init = 307;
475
x->x_val = (init *= 1319);
476
outlet_new(&x->x_obj, gensym("signal"));
480
static t_int *noise_perform(t_int *w)
482
t_sample *out = (t_sample *)(w[1]);
483
int *vp = (int *)(w[2]);
488
*out++ = ((float)((val & 0x7fffffff) - 0x40000000)) *
489
(float)(1.0 / 0x40000000);
490
val = val * 435898247 + 382842987;
496
static void noise_dsp(t_noise *x, t_signal **sp)
498
dsp_add(noise_perform, 3, sp[0]->s_vec, &x->x_val, sp[0]->s_n);
501
static void noise_setup(void)
503
noise_class = class_new(gensym("noise~"), (t_newmethod)noise_new, 0,
504
sizeof(t_noise), 0, 0);
505
class_addmethod(noise_class, (t_method)noise_dsp, gensym("dsp"), 0);
509
/* ----------------------- global setup routine ---------------- */
510
void d_osc_setup(void)