Fix some greedy sed changes in imported code. Also provide a sys/types.h for compatib...
[kugel-rb.git] / apps / plugins / pdbox / PDa / src / d_osc.c
blob35b43b82c6ec4b5c8e965c3c4963141488f0768e
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.
6 */
8 #include "m_pd.h"
9 #include "math.h"
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! */
15 #ifdef IRIX
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 */
20 #else
21 #ifdef MSW
22 /* little-endian; most significant byte is at highest address */
23 #define HIOFFSET 1
24 #define LOWOFFSET 0
25 #define int32 long
26 #else
27 #ifdef __FreeBSD__
28 #include <machine/endian.h>
29 #if BYTE_ORDER == LITTLE_ENDIAN
30 #define HIOFFSET 1
31 #define LOWOFFSET 0
32 #else
33 #define HIOFFSET 0 /* word offset to find MSB */
34 #define LOWOFFSET 1 /* word offset to find LSB */
35 #endif /* BYTE_ORDER */
36 #include <sys/types.h>
37 #define int32 int32_t
38 #endif
39 #ifdef __linux__
41 #include <endian.h>
43 #if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
44 #error No byte order defined
45 #endif
47 #if __BYTE_ORDER == __LITTLE_ENDIAN
48 #define HIOFFSET 1
49 #define LOWOFFSET 0
50 #else
51 #define HIOFFSET 0 /* word offset to find MSB */
52 #define LOWOFFSET 1 /* word offset to find LSB */
53 #endif /* __BYTE_ORDER */
55 #include <sys/types.h>
56 #define int32 int32_t
58 #else
59 #ifdef MACOSX
60 #define HIOFFSET 0 /* word offset to find MSB */
61 #define LOWOFFSET 1 /* word offset to find LSB */
62 #define int32 int /* a data type that has 32 bits */
64 #endif /* MACOSX */
65 #endif /* __linux__ */
66 #endif /* MSW */
67 #endif /* SGI */
69 union tabfudge
71 double tf_d;
72 int32 tf_i[2];
76 /* -------------------------- phasor~ ------------------------------ */
77 static t_class *phasor_class, *scalarphasor_class;
79 #if 1 /* in the style of R. Hoeldrich (ICMC 1995 Banff) */
81 typedef struct _phasor
83 t_object x_obj;
84 double x_phase;
85 float x_conv;
86 float x_f; /* scalar frequency */
87 } t_phasor;
89 static void *phasor_new(t_floatarg f)
91 t_phasor *x = (t_phasor *)pd_new(phasor_class);
92 x->x_f = f;
93 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
94 x->x_phase = 0;
95 x->x_conv = 0;
96 outlet_new(&x->x_obj, gensym("signal"));
97 return (x);
100 static t_int *phasor_perform(t_int *w)
102 t_phasor *x = (t_phasor *)(w[1]);
103 t_float *in = (t_float *)(w[2]);
104 t_float *out = (t_float *)(w[3]);
105 int n = (int)(w[4]);
106 double dphase = x->x_phase + UNITBIT32;
107 union tabfudge tf;
108 int normhipart;
109 float conv = x->x_conv;
111 tf.tf_d = UNITBIT32;
112 normhipart = tf.tf_i[HIOFFSET];
113 tf.tf_d = dphase;
115 while (n--)
117 tf.tf_i[HIOFFSET] = normhipart;
118 dphase += *in++ * conv;
119 *out++ = tf.tf_d - UNITBIT32;
120 tf.tf_d = dphase;
122 tf.tf_i[HIOFFSET] = normhipart;
123 x->x_phase = tf.tf_d - UNITBIT32;
124 return (w+5);
127 static void phasor_dsp(t_phasor *x, t_signal **sp)
129 x->x_conv = 1./sp[0]->s_sr;
130 dsp_add(phasor_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
133 static void phasor_ft1(t_phasor *x, t_float f)
135 x->x_phase = f;
138 static void phasor_setup(void)
140 phasor_class = class_new(gensym("phasor~"), (t_newmethod)phasor_new, 0,
141 sizeof(t_phasor), 0, A_DEFFLOAT, 0);
142 CLASS_MAINSIGNALIN(phasor_class, t_phasor, x_f);
143 class_addmethod(phasor_class, (t_method)phasor_dsp, gensym("dsp"), 0);
144 class_addmethod(phasor_class, (t_method)phasor_ft1,
145 gensym("ft1"), A_FLOAT, 0);
148 #endif /* Hoeldrich version */
150 /* ------------------------ cos~ ----------------------------- */
152 float *cos_table;
154 static t_class *cos_class;
156 typedef struct _cos
158 t_object x_obj;
159 float x_f;
160 } t_cos;
162 static void *cos_new(void)
164 t_cos *x = (t_cos *)pd_new(cos_class);
165 outlet_new(&x->x_obj, gensym("signal"));
166 x->x_f = 0;
167 return (x);
170 static t_int *cos_perform(t_int *w)
172 t_float *in = (t_float *)(w[1]);
173 t_float *out = (t_float *)(w[2]);
174 int n = (int)(w[3]);
175 float *tab = cos_table, *addr, f1, f2, frac;
176 double dphase;
177 int normhipart;
178 union tabfudge tf;
180 tf.tf_d = UNITBIT32;
181 normhipart = tf.tf_i[HIOFFSET];
183 #if 0 /* this is the readable version of the code. */
184 while (n--)
186 dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
187 tf.tf_d = dphase;
188 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
189 tf.tf_i[HIOFFSET] = normhipart;
190 frac = tf.tf_d - UNITBIT32;
191 f1 = addr[0];
192 f2 = addr[1];
193 *out++ = f1 + frac * (f2 - f1);
195 #endif
196 #if 1 /* this is the same, unwrapped by hand. */
197 dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
198 tf.tf_d = dphase;
199 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
200 tf.tf_i[HIOFFSET] = normhipart;
201 while (--n)
203 dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
204 frac = tf.tf_d - UNITBIT32;
205 tf.tf_d = dphase;
206 f1 = addr[0];
207 f2 = addr[1];
208 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
209 *out++ = f1 + frac * (f2 - f1);
210 tf.tf_i[HIOFFSET] = normhipart;
212 frac = tf.tf_d - UNITBIT32;
213 f1 = addr[0];
214 f2 = addr[1];
215 *out++ = f1 + frac * (f2 - f1);
216 #endif
217 return (w+4);
220 static void cos_dsp(t_cos *x, t_signal **sp)
222 dsp_add(cos_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
225 static void cos_maketable(void)
227 int i;
228 float *fp, phase, phsinc = (2. * 3.14159) / COSTABSIZE;
229 union tabfudge tf;
231 if (cos_table) return;
232 cos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
233 for (i = COSTABSIZE + 1, fp = cos_table, phase = 0; i--;
234 fp++, phase += phsinc)
235 *fp = cos(phase);
237 /* here we check at startup whether the byte alignment
238 is as we declared it. If not, the code has to be
239 recompiled the other way. */
240 tf.tf_d = UNITBIT32 + 0.5;
241 if ((unsigned)tf.tf_i[LOWOFFSET] != 0x80000000)
242 bug("cos~: unexpected machine alignment");
245 static void cos_setup(void)
247 cos_class = class_new(gensym("cos~"), (t_newmethod)cos_new, 0,
248 sizeof(t_cos), 0, A_DEFFLOAT, 0);
249 CLASS_MAINSIGNALIN(cos_class, t_cos, x_f);
250 class_addmethod(cos_class, (t_method)cos_dsp, gensym("dsp"), 0);
251 cos_maketable();
254 /* ------------------------ osc~ ----------------------------- */
256 static t_class *osc_class, *scalarosc_class;
258 typedef struct _osc
260 t_object x_obj;
261 double x_phase;
262 float x_conv;
263 float x_f; /* frequency if scalar */
264 } t_osc;
266 static void *osc_new(t_floatarg f)
268 t_osc *x = (t_osc *)pd_new(osc_class);
269 x->x_f = f;
270 outlet_new(&x->x_obj, gensym("signal"));
271 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
272 x->x_phase = 0;
273 x->x_conv = 0;
274 return (x);
277 static t_int *osc_perform(t_int *w)
279 t_osc *x = (t_osc *)(w[1]);
280 t_float *in = (t_float *)(w[2]);
281 t_float *out = (t_float *)(w[3]);
282 int n = (int)(w[4]);
283 float *tab = cos_table, *addr, f1, f2, frac;
284 double dphase = x->x_phase + UNITBIT32;
285 int normhipart;
286 union tabfudge tf;
287 float conv = x->x_conv;
289 tf.tf_d = UNITBIT32;
290 normhipart = tf.tf_i[HIOFFSET];
291 #if 0
292 while (n--)
294 tf.tf_d = dphase;
295 dphase += *in++ * conv;
296 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
297 tf.tf_i[HIOFFSET] = normhipart;
298 frac = tf.tf_d - UNITBIT32;
299 f1 = addr[0];
300 f2 = addr[1];
301 *out++ = f1 + frac * (f2 - f1);
303 #endif
304 #if 1
305 tf.tf_d = dphase;
306 dphase += *in++ * conv;
307 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
308 tf.tf_i[HIOFFSET] = normhipart;
309 frac = tf.tf_d - UNITBIT32;
310 while (--n)
312 tf.tf_d = dphase;
313 f1 = addr[0];
314 dphase += *in++ * conv;
315 f2 = addr[1];
316 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
317 tf.tf_i[HIOFFSET] = normhipart;
318 *out++ = f1 + frac * (f2 - f1);
319 frac = tf.tf_d - UNITBIT32;
321 f1 = addr[0];
322 f2 = addr[1];
323 *out++ = f1 + frac * (f2 - f1);
324 #endif
326 tf.tf_d = UNITBIT32 * COSTABSIZE;
327 normhipart = tf.tf_i[HIOFFSET];
328 tf.tf_d = dphase + (UNITBIT32 * COSTABSIZE - UNITBIT32);
329 tf.tf_i[HIOFFSET] = normhipart;
330 x->x_phase = tf.tf_d - UNITBIT32 * COSTABSIZE;
331 return (w+5);
334 static void osc_dsp(t_osc *x, t_signal **sp)
336 x->x_conv = COSTABSIZE/sp[0]->s_sr;
337 dsp_add(osc_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
340 static void osc_ft1(t_osc *x, t_float f)
342 x->x_phase = COSTABSIZE * f;
345 static void osc_setup(void)
347 osc_class = class_new(gensym("osc~"), (t_newmethod)osc_new, 0,
348 sizeof(t_osc), 0, A_DEFFLOAT, 0);
349 CLASS_MAINSIGNALIN(osc_class, t_osc, x_f);
350 class_addmethod(osc_class, (t_method)osc_dsp, gensym("dsp"), 0);
351 class_addmethod(osc_class, (t_method)osc_ft1, gensym("ft1"), A_FLOAT, 0);
353 cos_maketable();
356 /* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */
358 typedef struct vcfctl
360 float c_re;
361 float c_im;
362 float c_q;
363 float c_isr;
364 } t_vcfctl;
366 typedef struct sigvcf
368 t_object x_obj;
369 t_vcfctl x_cspace;
370 t_vcfctl *x_ctl;
371 float x_f;
372 } t_sigvcf;
374 t_class *sigvcf_class;
376 static void *sigvcf_new(t_floatarg q)
378 t_sigvcf *x = (t_sigvcf *)pd_new(sigvcf_class);
379 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
380 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
381 outlet_new(&x->x_obj, gensym("signal"));
382 outlet_new(&x->x_obj, gensym("signal"));
383 x->x_ctl = &x->x_cspace;
384 x->x_cspace.c_re = 0;
385 x->x_cspace.c_im = 0;
386 x->x_cspace.c_q = q;
387 x->x_cspace.c_isr = 0;
388 x->x_f = 0;
389 return (x);
392 static void sigvcf_ft1(t_sigvcf *x, t_floatarg f)
394 x->x_ctl->c_q = (f > 0 ? f : 0.f);
397 static t_int *sigvcf_perform(t_int *w)
399 float *in1 = (float *)(w[1]);
400 float *in2 = (float *)(w[2]);
401 float *out1 = (float *)(w[3]);
402 float *out2 = (float *)(w[4]);
403 t_vcfctl *c = (t_vcfctl *)(w[5]);
404 int n = (t_int)(w[6]);
405 int i;
406 float re = c->c_re, re2;
407 float im = c->c_im;
408 float q = c->c_q;
409 float qinv = (q > 0? 1.0f/q : 0);
410 float ampcorrect = 2.0f - 2.0f / (q + 2.0f);
411 float isr = c->c_isr;
412 float coefr, coefi;
413 float *tab = cos_table, *addr, f1, f2, frac;
414 double dphase;
415 int normhipart, tabindex;
416 union tabfudge tf;
418 tf.tf_d = UNITBIT32;
419 normhipart = tf.tf_i[HIOFFSET];
421 for (i = 0; i < n; i++)
423 float cf, cfindx, r, oneminusr;
424 cf = *in2++ * isr;
425 if (cf < 0) cf = 0;
426 cfindx = cf * (float)(COSTABSIZE/6.28318f);
427 r = (qinv > 0 ? 1 - cf * qinv : 0);
428 if (r < 0) r = 0;
429 oneminusr = 1.0f - r;
430 dphase = ((double)(cfindx)) + UNITBIT32;
431 tf.tf_d = dphase;
432 tabindex = tf.tf_i[HIOFFSET] & (COSTABSIZE-1);
433 addr = tab + tabindex;
434 tf.tf_i[HIOFFSET] = normhipart;
435 frac = tf.tf_d - UNITBIT32;
436 f1 = addr[0];
437 f2 = addr[1];
438 coefr = r * (f1 + frac * (f2 - f1));
440 addr = tab + ((tabindex - (COSTABSIZE/4)) & (COSTABSIZE-1));
441 f1 = addr[0];
442 f2 = addr[1];
443 coefi = r * (f1 + frac * (f2 - f1));
445 f1 = *in1++;
446 re2 = re;
447 *out1++ = re = ampcorrect * oneminusr * f1
448 + coefr * re2 - coefi * im;
449 *out2++ = im = coefi * re2 + coefr * im;
451 if (PD_BIGORSMALL(re))
452 re = 0;
453 if (PD_BIGORSMALL(im))
454 im = 0;
455 c->c_re = re;
456 c->c_im = im;
457 return (w+7);
460 static void sigvcf_dsp(t_sigvcf *x, t_signal **sp)
462 x->x_ctl->c_isr = 6.28318f/sp[0]->s_sr;
463 dsp_add(sigvcf_perform, 6,
464 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,
465 x->x_ctl, sp[0]->s_n);
469 void sigvcf_setup(void)
471 sigvcf_class = class_new(gensym("vcf~"), (t_newmethod)sigvcf_new, 0,
472 sizeof(t_sigvcf), 0, A_DEFFLOAT, 0);
473 CLASS_MAINSIGNALIN(sigvcf_class, t_sigvcf, x_f);
474 class_addmethod(sigvcf_class, (t_method)sigvcf_dsp, gensym("dsp"), 0);
475 class_addmethod(sigvcf_class, (t_method)sigvcf_ft1,
476 gensym("ft1"), A_FLOAT, 0);
479 /* -------------------------- noise~ ------------------------------ */
480 static t_class *noise_class;
482 typedef struct _noise
484 t_object x_obj;
485 int x_val;
486 } t_noise;
488 static void *noise_new(void)
490 t_noise *x = (t_noise *)pd_new(noise_class);
491 static int init = 307;
492 x->x_val = (init *= 1319);
493 outlet_new(&x->x_obj, gensym("signal"));
494 return (x);
497 static t_int *noise_perform(t_int *w)
499 t_float *out = (t_float *)(w[1]);
500 int *vp = (int *)(w[2]);
501 int n = (int)(w[3]);
502 int val = *vp;
503 while (n--)
505 *out++ = ((float)((val & 0x7fffffff) - 0x40000000)) *
506 (float)(1.0 / 0x40000000);
507 val = val * 435898247 + 382842987;
509 *vp = val;
510 return (w+4);
513 static void noise_dsp(t_noise *x, t_signal **sp)
515 dsp_add(noise_perform, 3, sp[0]->s_vec, &x->x_val, sp[0]->s_n);
518 static void noise_setup(void)
520 noise_class = class_new(gensym("noise~"), (t_newmethod)noise_new, 0,
521 sizeof(t_noise), 0, 0);
522 class_addmethod(noise_class, (t_method)noise_dsp, gensym("dsp"), 0);
526 /* ----------------------- global setup routine ---------------- */
527 void d_osc_setup(void)
529 phasor_setup();
530 cos_setup();
531 osc_setup();
532 sigvcf_setup();
533 noise_setup();