summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/d_osc.c
diff options
context:
space:
mode:
authorPeter D'Hoye <peter.dhoye@gmail.com>2009-05-22 21:58:48 +0000
committerPeter D'Hoye <peter.dhoye@gmail.com>2009-05-22 21:58:48 +0000
commit513389b4c1bc8afe4b2dc9947c534bfeb105e3da (patch)
tree10e673b35651ac567fed2eda0c679c7ade64cbc6 /apps/plugins/pdbox/PDa/src/d_osc.c
parent95fa7f6a2ef466444fbe3fe87efc6d5db6b77b36 (diff)
downloadrockbox-513389b4c1bc8afe4b2dc9947c534bfeb105e3da.tar.gz
rockbox-513389b4c1bc8afe4b2dc9947c534bfeb105e3da.zip
Add FS #10214. Initial commit of the original PDa code for the GSoC Pure Data plugin project of Wincent Balin. Stripped some non-sourcefiles and added a rockbox readme that needs a bit more info from Wincent. Is added to CATEGORIES and viewers, but not yet to SUBDIRS (ie doesn't build yet)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21044 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/d_osc.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/d_osc.c1070
1 files changed, 1070 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/src/d_osc.c b/apps/plugins/pdbox/PDa/src/d_osc.c
new file mode 100644
index 0000000000..8a3486d981
--- /dev/null
+++ b/apps/plugins/pdbox/PDa/src/d_osc.c
@@ -0,0 +1,1070 @@
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. */
4
5/* sinusoidal oscillator and table lookup; see also tabosc4~ in d_array.c.
6*/
7
8#include "m_pd.h"
9#include "math.h"
10
11#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
12
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__
40
41#include <endian.h>
42
43#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
44#error No byte order defined
45#endif
46
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 */
54
55#include <sys/types.h>
56#define int32 int32_t
57
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 */
63
64#endif /* MACOSX */
65#endif /* __linux__ */
66#endif /* MSW */
67#endif /* SGI */
68
69union tabfudge
70{
71 double tf_d;
72 int32 tf_i[2];
73};
74
75
76/* -------------------------- phasor~ ------------------------------ */
77static t_class *phasor_class, *scalarphasor_class;
78
79#if 1 /* in the style of R. Hoeldrich (ICMC 1995 Banff) */
80
81typedef struct _phasor
82{
83 t_object x_obj;
84 double x_phase;
85 float x_conv;
86 float x_f; /* scalar frequency */
87} t_phasor;
88
89static void *phasor_new(t_floatarg f)
90{
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);
98}
99
100static t_int *phasor_perform(t_int *w)
101{
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;
110
111 tf.tf_d = UNITBIT32;
112 normhipart = tf.tf_i[HIOFFSET];
113 tf.tf_d = dphase;
114
115 while (n--)
116 {
117 tf.tf_i[HIOFFSET] = normhipart;
118 dphase += *in++ * conv;
119 *out++ = tf.tf_d - UNITBIT32;
120 tf.tf_d = dphase;
121 }
122 tf.tf_i[HIOFFSET] = normhipart;
123 x->x_phase = tf.tf_d - UNITBIT32;
124 return (w+5);
125}
126
127static void phasor_dsp(t_phasor *x, t_signal **sp)
128{
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);
131}
132
133static void phasor_ft1(t_phasor *x, t_float f)
134{
135 x->x_phase = f;
136}
137
138static void phasor_setup(void)
139{
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);
146}
147
148#endif /* Hoeldrich version */
149
150/* ------------------------ cos~ ----------------------------- */
151
152float *cos_table;
153
154static t_class *cos_class;
155
156typedef struct _cos
157{
158 t_object x_obj;
159 float x_f;
160} t_cos;
161
162static void *cos_new(void)
163{
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);
168}
169
170static t_int *cos_perform(t_int *w)
171{
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;
179
180 tf.tf_d = UNITBIT32;
181 normhipart = tf.tf_i[HIOFFSET];
182
183#if 0 /* this is the readable version of the code. */
184 while (n--)
185 {
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);
194 }
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)
202 {
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;
211 }
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);
218}
219
220static void cos_dsp(t_cos *x, t_signal **sp)
221{
222 dsp_add(cos_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
223}
224
225static void cos_maketable(void)
226{
227 int i;
228 float *fp, phase, phsinc = (2. * 3.14159) / COSTABSIZE;
229 union tabfudge tf;
230
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);
236
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");
243}
244
245static void cos_setup(void)
246{
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();
252}
253
254/* ------------------------ osc~ ----------------------------- */
255
256static t_class *osc_class, *scalarosc_class;
257
258typedef struct _osc
259{
260 t_object x_obj;
261 double x_phase;
262 float x_conv;
263 float x_f; /* frequency if scalar */
264} t_osc;
265
266static void *osc_new(t_floatarg f)
267{
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);
275}
276
277static t_int *osc_perform(t_int *w)
278{
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;
288
289 tf.tf_d = UNITBIT32;
290 normhipart = tf.tf_i[HIOFFSET];
291#if 0
292 while (n--)
293 {
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);
302 }
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)
311 {
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;
320 }
321 f1 = addr[0];
322 f2 = addr[1];
323 *out++ = f1 + frac * (f2 - f1);
324#endif
325
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);
332}
333
334static void osc_dsp(t_osc *x, t_signal **sp)
335{
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);
338}
339
340static void osc_ft1(t_osc *x, t_float f)
341{
342 x->x_phase = COSTABSIZE * f;
343}
344
345static void osc_setup(void)
346{
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);
352
353 cos_maketable();
354}
355
356/* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */
357
358typedef struct vcfctl
359{
360 float c_re;
361 float c_im;
362 float c_q;
363 float c_isr;
364} t_vcfctl;
365
366typedef struct sigvcf
367{
368 t_object x_obj;
369 t_vcfctl x_cspace;
370 t_vcfctl *x_ctl;
371 float x_f;
372} t_sigvcf;
373
374t_class *sigvcf_class;
375
376static void *sigvcf_new(t_floatarg q)
377{
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);
390}
391
392static void sigvcf_ft1(t_sigvcf *x, t_floatarg f)
393{
394 x->x_ctl->c_q = (f > 0 ? f : 0.f);
395}
396
397static t_int *sigvcf_perform(t_int *w)
398{
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;
417
418 tf.tf_d = UNITBIT32;
419 normhipart = tf.tf_i[HIOFFSET];
420
421 for (i = 0; i < n; i++)
422 {
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));
439
440 addr = tab + ((tabindex - (COSTABSIZE/4)) & (COSTABSIZE-1));
441 f1 = addr[0];
442 f2 = addr[1];
443 coefi = r * (f1 + frac * (f2 - f1));
444
445 f1 = *in1++;
446 re2 = re;
447 *out1++ = re = ampcorrect * oneminusr * f1
448 + coefr * re2 - coefi * im;
449 *out2++ = im = coefi * re2 + coefr * im;
450 }
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);
458}
459
460static void sigvcf_dsp(t_sigvcf *x, t_signal **sp)
461{
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);
466
467}
468
469void sigvcf_setup(void)
470{
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);
477}
478
479/* -------------------------- noise~ ------------------------------ */
480static t_class *noise_class;
481
482typedef struct _noise
483{
484 t_object x_obj;
485 int x_val;
486} t_noise;
487
488static void *noise_new(void)
489{
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);
495}
496
497static t_int *noise_perform(t_int *w)
498{
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--)
504 {
505 *out++ = ((float)((val & 0x7fffffff) - 0x40000000)) *
506 (float)(1.0 / 0x40000000);
507 val = val * 435898247 + 382842987;
508 }
509 *vp = val;
510 return (w+4);
511}
512
513static void noise_dsp(t_noise *x, t_signal **sp)
514{
515 dsp_add(noise_perform, 3, sp[0]->s_vec, &x->x_val, sp[0]->s_n);
516}
517
518static void noise_setup(void)
519{
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);
523}
524
525
526/* ----------------------- global setup routine ---------------- */
527void d_osc_setup(void)
528{
529 phasor_setup();
530 cos_setup();
531 osc_setup();
532 sigvcf_setup();
533 noise_setup();
534}
535
536/* Copyright (c) 1997-1999 Miller Puckette.
537* For information on usage and redistribution, and for a DISCLAIMER OF ALL
538* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
539
540/* sinusoidal oscillator and table lookup; see also tabosc4~ in d_array.c.
541*/
542
543#include "m_pd.h"
544#include "math.h"
545
546#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
547
548 /* machine-dependent definitions. These ifdefs really
549 should have been by CPU type and not by operating system! */
550#ifdef IRIX
551 /* big-endian. Most significant byte is at low address in memory */
552#define HIOFFSET 0 /* word offset to find MSB */
553#define LOWOFFSET 1 /* word offset to find LSB */
554#define int32 long /* a data type that has 32 bits */
555#else
556#ifdef MSW
557 /* little-endian; most significant byte is at highest address */
558#define HIOFFSET 1
559#define LOWOFFSET 0
560#define int32 long
561#else
562#ifdef __FreeBSD__
563#include <machine/endian.h>
564#if BYTE_ORDER == LITTLE_ENDIAN
565#define HIOFFSET 1
566#define LOWOFFSET 0
567#else
568#define HIOFFSET 0 /* word offset to find MSB */
569#define LOWOFFSET 1 /* word offset to find LSB */
570#endif /* BYTE_ORDER */
571#include <sys/types.h>
572#define int32 int32_t
573#endif
574#ifdef __linux__
575
576#include <endian.h>
577
578#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
579#error No byte order defined
580#endif
581
582#if __BYTE_ORDER == __LITTLE_ENDIAN
583#define HIOFFSET 1
584#define LOWOFFSET 0
585#else
586#define HIOFFSET 0 /* word offset to find MSB */
587#define LOWOFFSET 1 /* word offset to find LSB */
588#endif /* __BYTE_ORDER */
589
590#include <sys/types.h>
591#define int32 int32_t
592
593#else
594#ifdef MACOSX
595#define HIOFFSET 0 /* word offset to find MSB */
596#define LOWOFFSET 1 /* word offset to find LSB */
597#define int32 int /* a data type that has 32 bits */
598
599#endif /* MACOSX */
600#endif /* __linux__ */
601#endif /* MSW */
602#endif /* SGI */
603
604union tabfudge
605{
606 double tf_d;
607 int32 tf_i[2];
608};
609
610
611/* -------------------------- phasor~ ------------------------------ */
612static t_class *phasor_class, *scalarphasor_class;
613
614#if 1 /* in the style of R. Hoeldrich (ICMC 1995 Banff) */
615
616typedef struct _phasor
617{
618 t_object x_obj;
619 double x_phase;
620 float x_conv;
621 float x_f; /* scalar frequency */
622} t_phasor;
623
624static void *phasor_new(t_floatarg f)
625{
626 t_phasor *x = (t_phasor *)pd_new(phasor_class);
627 x->x_f = f;
628 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
629 x->x_phase = 0;
630 x->x_conv = 0;
631 outlet_new(&x->x_obj, gensym("signal"));
632 return (x);
633}
634
635static t_int *phasor_perform(t_int *w)
636{
637 t_phasor *x = (t_phasor *)(w[1]);
638 t_float *in = (t_float *)(w[2]);
639 t_float *out = (t_float *)(w[3]);
640 int n = (int)(w[4]);
641 double dphase = x->x_phase + UNITBIT32;
642 union tabfudge tf;
643 int normhipart;
644 float conv = x->x_conv;
645
646 tf.tf_d = UNITBIT32;
647 normhipart = tf.tf_i[HIOFFSET];
648 tf.tf_d = dphase;
649
650 while (n--)
651 {
652 tf.tf_i[HIOFFSET] = normhipart;
653 dphase += *in++ * conv;
654 *out++ = tf.tf_d - UNITBIT32;
655 tf.tf_d = dphase;
656 }
657 tf.tf_i[HIOFFSET] = normhipart;
658 x->x_phase = tf.tf_d - UNITBIT32;
659 return (w+5);
660}
661
662static void phasor_dsp(t_phasor *x, t_signal **sp)
663{
664 x->x_conv = 1./sp[0]->s_sr;
665 dsp_add(phasor_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
666}
667
668static void phasor_ft1(t_phasor *x, t_float f)
669{
670 x->x_phase = f;
671}
672
673static void phasor_setup(void)
674{
675 phasor_class = class_new(gensym("phasor~"), (t_newmethod)phasor_new, 0,
676 sizeof(t_phasor), 0, A_DEFFLOAT, 0);
677 CLASS_MAINSIGNALIN(phasor_class, t_phasor, x_f);
678 class_addmethod(phasor_class, (t_method)phasor_dsp, gensym("dsp"), 0);
679 class_addmethod(phasor_class, (t_method)phasor_ft1,
680 gensym("ft1"), A_FLOAT, 0);
681}
682
683#endif /* Hoeldrich version */
684
685/* ------------------------ cos~ ----------------------------- */
686
687float *cos_table;
688
689static t_class *cos_class;
690
691typedef struct _cos
692{
693 t_object x_obj;
694 float x_f;
695} t_cos;
696
697static void *cos_new(void)
698{
699 t_cos *x = (t_cos *)pd_new(cos_class);
700 outlet_new(&x->x_obj, gensym("signal"));
701 x->x_f = 0;
702 return (x);
703}
704
705static t_int *cos_perform(t_int *w)
706{
707 t_float *in = (t_float *)(w[1]);
708 t_float *out = (t_float *)(w[2]);
709 int n = (int)(w[3]);
710 float *tab = cos_table, *addr, f1, f2, frac;
711 double dphase;
712 int normhipart;
713 union tabfudge tf;
714
715 tf.tf_d = UNITBIT32;
716 normhipart = tf.tf_i[HIOFFSET];
717
718#if 0 /* this is the readable version of the code. */
719 while (n--)
720 {
721 dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
722 tf.tf_d = dphase;
723 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
724 tf.tf_i[HIOFFSET] = normhipart;
725 frac = tf.tf_d - UNITBIT32;
726 f1 = addr[0];
727 f2 = addr[1];
728 *out++ = f1 + frac * (f2 - f1);
729 }
730#endif
731#if 1 /* this is the same, unwrapped by hand. */
732 dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
733 tf.tf_d = dphase;
734 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
735 tf.tf_i[HIOFFSET] = normhipart;
736 while (--n)
737 {
738 dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
739 frac = tf.tf_d - UNITBIT32;
740 tf.tf_d = dphase;
741 f1 = addr[0];
742 f2 = addr[1];
743 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
744 *out++ = f1 + frac * (f2 - f1);
745 tf.tf_i[HIOFFSET] = normhipart;
746 }
747 frac = tf.tf_d - UNITBIT32;
748 f1 = addr[0];
749 f2 = addr[1];
750 *out++ = f1 + frac * (f2 - f1);
751#endif
752 return (w+4);
753}
754
755static void cos_dsp(t_cos *x, t_signal **sp)
756{
757 dsp_add(cos_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
758}
759
760static void cos_maketable(void)
761{
762 int i;
763 float *fp, phase, phsinc = (2. * 3.14159) / COSTABSIZE;
764 union tabfudge tf;
765
766 if (cos_table) return;
767 cos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
768 for (i = COSTABSIZE + 1, fp = cos_table, phase = 0; i--;
769 fp++, phase += phsinc)
770 *fp = cos(phase);
771
772 /* here we check at startup whether the byte alignment
773 is as we declared it. If not, the code has to be
774 recompiled the other way. */
775 tf.tf_d = UNITBIT32 + 0.5;
776 if ((unsigned)tf.tf_i[LOWOFFSET] != 0x80000000)
777 bug("cos~: unexpected machine alignment");
778}
779
780static void cos_setup(void)
781{
782 cos_class = class_new(gensym("cos~"), (t_newmethod)cos_new, 0,
783 sizeof(t_cos), 0, A_DEFFLOAT, 0);
784 CLASS_MAINSIGNALIN(cos_class, t_cos, x_f);
785 class_addmethod(cos_class, (t_method)cos_dsp, gensym("dsp"), 0);
786 cos_maketable();
787}
788
789/* ------------------------ osc~ ----------------------------- */
790
791static t_class *osc_class, *scalarosc_class;
792
793typedef struct _osc
794{
795 t_object x_obj;
796 double x_phase;
797 float x_conv;
798 float x_f; /* frequency if scalar */
799} t_osc;
800
801static void *osc_new(t_floatarg f)
802{
803 t_osc *x = (t_osc *)pd_new(osc_class);
804 x->x_f = f;
805 outlet_new(&x->x_obj, gensym("signal"));
806 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
807 x->x_phase = 0;
808 x->x_conv = 0;
809 return (x);
810}
811
812static t_int *osc_perform(t_int *w)
813{
814 t_osc *x = (t_osc *)(w[1]);
815 t_float *in = (t_float *)(w[2]);
816 t_float *out = (t_float *)(w[3]);
817 int n = (int)(w[4]);
818 float *tab = cos_table, *addr, f1, f2, frac;
819 double dphase = x->x_phase + UNITBIT32;
820 int normhipart;
821 union tabfudge tf;
822 float conv = x->x_conv;
823
824 tf.tf_d = UNITBIT32;
825 normhipart = tf.tf_i[HIOFFSET];
826#if 0
827 while (n--)
828 {
829 tf.tf_d = dphase;
830 dphase += *in++ * conv;
831 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
832 tf.tf_i[HIOFFSET] = normhipart;
833 frac = tf.tf_d - UNITBIT32;
834 f1 = addr[0];
835 f2 = addr[1];
836 *out++ = f1 + frac * (f2 - f1);
837 }
838#endif
839#if 1
840 tf.tf_d = dphase;
841 dphase += *in++ * conv;
842 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
843 tf.tf_i[HIOFFSET] = normhipart;
844 frac = tf.tf_d - UNITBIT32;
845 while (--n)
846 {
847 tf.tf_d = dphase;
848 f1 = addr[0];
849 dphase += *in++ * conv;
850 f2 = addr[1];
851 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
852 tf.tf_i[HIOFFSET] = normhipart;
853 *out++ = f1 + frac * (f2 - f1);
854 frac = tf.tf_d - UNITBIT32;
855 }
856 f1 = addr[0];
857 f2 = addr[1];
858 *out++ = f1 + frac * (f2 - f1);
859#endif
860
861 tf.tf_d = UNITBIT32 * COSTABSIZE;
862 normhipart = tf.tf_i[HIOFFSET];
863 tf.tf_d = dphase + (UNITBIT32 * COSTABSIZE - UNITBIT32);
864 tf.tf_i[HIOFFSET] = normhipart;
865 x->x_phase = tf.tf_d - UNITBIT32 * COSTABSIZE;
866 return (w+5);
867}
868
869static void osc_dsp(t_osc *x, t_signal **sp)
870{
871 x->x_conv = COSTABSIZE/sp[0]->s_sr;
872 dsp_add(osc_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
873}
874
875static void osc_ft1(t_osc *x, t_float f)
876{
877 x->x_phase = COSTABSIZE * f;
878}
879
880static void osc_setup(void)
881{
882 osc_class = class_new(gensym("osc~"), (t_newmethod)osc_new, 0,
883 sizeof(t_osc), 0, A_DEFFLOAT, 0);
884 CLASS_MAINSIGNALIN(osc_class, t_osc, x_f);
885 class_addmethod(osc_class, (t_method)osc_dsp, gensym("dsp"), 0);
886 class_addmethod(osc_class, (t_method)osc_ft1, gensym("ft1"), A_FLOAT, 0);
887
888 cos_maketable();
889}
890
891/* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */
892
893typedef struct vcfctl
894{
895 float c_re;
896 float c_im;
897 float c_q;
898 float c_isr;
899} t_vcfctl;
900
901typedef struct sigvcf
902{
903 t_object x_obj;
904 t_vcfctl x_cspace;
905 t_vcfctl *x_ctl;
906 float x_f;
907} t_sigvcf;
908
909t_class *sigvcf_class;
910
911static void *sigvcf_new(t_floatarg q)
912{
913 t_sigvcf *x = (t_sigvcf *)pd_new(sigvcf_class);
914 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
915 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
916 outlet_new(&x->x_obj, gensym("signal"));
917 outlet_new(&x->x_obj, gensym("signal"));
918 x->x_ctl = &x->x_cspace;
919 x->x_cspace.c_re = 0;
920 x->x_cspace.c_im = 0;
921 x->x_cspace.c_q = q;
922 x->x_cspace.c_isr = 0;
923 x->x_f = 0;
924 return (x);
925}
926
927static void sigvcf_ft1(t_sigvcf *x, t_floatarg f)
928{
929 x->x_ctl->c_q = (f > 0 ? f : 0.f);
930}
931
932static t_int *sigvcf_perform(t_int *w)
933{
934 float *in1 = (float *)(w[1]);
935 float *in2 = (float *)(w[2]);
936 float *out1 = (float *)(w[3]);
937 float *out2 = (float *)(w[4]);
938 t_vcfctl *c = (t_vcfctl *)(w[5]);
939 int n = (t_int)(w[6]);
940 int i;
941 float re = c->c_re, re2;
942 float im = c->c_im;
943 float q = c->c_q;
944 float qinv = (q > 0? 1.0f/q : 0);
945 float ampcorrect = 2.0f - 2.0f / (q + 2.0f);
946 float isr = c->c_isr;
947 float coefr, coefi;
948 float *tab = cos_table, *addr, f1, f2, frac;
949 double dphase;
950 int normhipart, tabindex;
951 union tabfudge tf;
952
953 tf.tf_d = UNITBIT32;
954 normhipart = tf.tf_i[HIOFFSET];
955
956 for (i = 0; i < n; i++)
957 {
958 float cf, cfindx, r, oneminusr;
959 cf = *in2++ * isr;
960 if (cf < 0) cf = 0;
961 cfindx = cf * (float)(COSTABSIZE/6.28318f);
962 r = (qinv > 0 ? 1 - cf * qinv : 0);
963 if (r < 0) r = 0;
964 oneminusr = 1.0f - r;
965 dphase = ((double)(cfindx)) + UNITBIT32;
966 tf.tf_d = dphase;
967 tabindex = tf.tf_i[HIOFFSET] & (COSTABSIZE-1);
968 addr = tab + tabindex;
969 tf.tf_i[HIOFFSET] = normhipart;
970 frac = tf.tf_d - UNITBIT32;
971 f1 = addr[0];
972 f2 = addr[1];
973 coefr = r * (f1 + frac * (f2 - f1));
974
975 addr = tab + ((tabindex - (COSTABSIZE/4)) & (COSTABSIZE-1));
976 f1 = addr[0];
977 f2 = addr[1];
978 coefi = r * (f1 + frac * (f2 - f1));
979
980 f1 = *in1++;
981 re2 = re;
982 *out1++ = re = ampcorrect * oneminusr * f1
983 + coefr * re2 - coefi * im;
984 *out2++ = im = coefi * re2 + coefr * im;
985 }
986 if (PD_BIGORSMALL(re))
987 re = 0;
988 if (PD_BIGORSMALL(im))
989 im = 0;
990 c->c_re = re;
991 c->c_im = im;
992 return (w+7);
993}
994
995static void sigvcf_dsp(t_sigvcf *x, t_signal **sp)
996{
997 x->x_ctl->c_isr = 6.28318f/sp[0]->s_sr;
998 dsp_add(sigvcf_perform, 6,
999 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,
1000 x->x_ctl, sp[0]->s_n);
1001
1002}
1003
1004void sigvcf_setup(void)
1005{
1006 sigvcf_class = class_new(gensym("vcf~"), (t_newmethod)sigvcf_new, 0,
1007 sizeof(t_sigvcf), 0, A_DEFFLOAT, 0);
1008 CLASS_MAINSIGNALIN(sigvcf_class, t_sigvcf, x_f);
1009 class_addmethod(sigvcf_class, (t_method)sigvcf_dsp, gensym("dsp"), 0);
1010 class_addmethod(sigvcf_class, (t_method)sigvcf_ft1,
1011 gensym("ft1"), A_FLOAT, 0);
1012}
1013
1014/* -------------------------- noise~ ------------------------------ */
1015static t_class *noise_class;
1016
1017typedef struct _noise
1018{
1019 t_object x_obj;
1020 int x_val;
1021} t_noise;
1022
1023static void *noise_new(void)
1024{
1025 t_noise *x = (t_noise *)pd_new(noise_class);
1026 static int init = 307;
1027 x->x_val = (init *= 1319);
1028 outlet_new(&x->x_obj, gensym("signal"));
1029 return (x);
1030}
1031
1032static t_int *noise_perform(t_int *w)
1033{
1034 t_float *out = (t_float *)(w[1]);
1035 int *vp = (int *)(w[2]);
1036 int n = (int)(w[3]);
1037 int val = *vp;
1038 while (n--)
1039 {
1040 *out++ = ((float)((val & 0x7fffffff) - 0x40000000)) *
1041 (float)(1.0 / 0x40000000);
1042 val = val * 435898247 + 382842987;
1043 }
1044 *vp = val;
1045 return (w+4);
1046}
1047
1048static void noise_dsp(t_noise *x, t_signal **sp)
1049{
1050 dsp_add(noise_perform, 3, sp[0]->s_vec, &x->x_val, sp[0]->s_n);
1051}
1052
1053static void noise_setup(void)
1054{
1055 noise_class = class_new(gensym("noise~"), (t_newmethod)noise_new, 0,
1056 sizeof(t_noise), 0, 0);
1057 class_addmethod(noise_class, (t_method)noise_dsp, gensym("dsp"), 0);
1058}
1059
1060
1061/* ----------------------- global setup routine ---------------- */
1062void d_osc_setup(void)
1063{
1064 phasor_setup();
1065 cos_setup();
1066 osc_setup();
1067 sigvcf_setup();
1068 noise_setup();
1069}
1070