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 */
22 /* little-endian; most significant byte is at highest address */
28 #include <machine/endian.h>
29 #if BYTE_ORDER == LITTLE_ENDIAN
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>
43 #if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
44 #error No byte order defined
47 #if __BYTE_ORDER == __LITTLE_ENDIAN
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>
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 */
65 #endif /* __linux__ */
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
86 float x_f
; /* scalar frequency */
89 static void *phasor_new(t_floatarg f
)
91 t_phasor
*x
= (t_phasor
*)pd_new(phasor_class
);
93 inlet_new(&x
->x_obj
, &x
->x_obj
.ob_pd
, &s_float
, gensym("ft1"));
96 outlet_new(&x
->x_obj
, gensym("signal"));
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]);
106 double dphase
= x
->x_phase
+ UNITBIT32
;
109 float conv
= x
->x_conv
;
112 normhipart
= tf
.tf_i
[HIOFFSET
];
117 tf
.tf_i
[HIOFFSET
] = normhipart
;
118 dphase
+= *in
++ * conv
;
119 *out
++ = tf
.tf_d
- UNITBIT32
;
122 tf
.tf_i
[HIOFFSET
] = normhipart
;
123 x
->x_phase
= tf
.tf_d
- UNITBIT32
;
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
)
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~ ----------------------------- */
154 static t_class
*cos_class
;
162 static void *cos_new(void)
164 t_cos
*x
= (t_cos
*)pd_new(cos_class
);
165 outlet_new(&x
->x_obj
, gensym("signal"));
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]);
175 float *tab
= cos_table
, *addr
, f1
, f2
, frac
;
181 normhipart
= tf
.tf_i
[HIOFFSET
];
183 #if 0 /* this is the readable version of the code. */
186 dphase
= (double)(*in
++ * (float)(COSTABSIZE
)) + UNITBIT32
;
188 addr
= tab
+ (tf
.tf_i
[HIOFFSET
] & (COSTABSIZE
-1));
189 tf
.tf_i
[HIOFFSET
] = normhipart
;
190 frac
= tf
.tf_d
- UNITBIT32
;
193 *out
++ = f1
+ frac
* (f2
- f1
);
196 #if 1 /* this is the same, unwrapped by hand. */
197 dphase
= (double)(*in
++ * (float)(COSTABSIZE
)) + UNITBIT32
;
199 addr
= tab
+ (tf
.tf_i
[HIOFFSET
] & (COSTABSIZE
-1));
200 tf
.tf_i
[HIOFFSET
] = normhipart
;
203 dphase
= (double)(*in
++ * (float)(COSTABSIZE
)) + UNITBIT32
;
204 frac
= tf
.tf_d
- UNITBIT32
;
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
;
215 *out
++ = f1
+ frac
* (f2
- f1
);
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)
228 float *fp
, phase
, phsinc
= (2. * 3.14159) / COSTABSIZE
;
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
)
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);
254 /* ------------------------ osc~ ----------------------------- */
256 static t_class
*osc_class
, *scalarosc_class
;
263 float x_f
; /* frequency if scalar */
266 static void *osc_new(t_floatarg f
)
268 t_osc
*x
= (t_osc
*)pd_new(osc_class
);
270 outlet_new(&x
->x_obj
, gensym("signal"));
271 inlet_new(&x
->x_obj
, &x
->x_obj
.ob_pd
, &s_float
, gensym("ft1"));
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]);
283 float *tab
= cos_table
, *addr
, f1
, f2
, frac
;
284 double dphase
= x
->x_phase
+ UNITBIT32
;
287 float conv
= x
->x_conv
;
290 normhipart
= tf
.tf_i
[HIOFFSET
];
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
;
301 *out
++ = f1
+ frac
* (f2
- f1
);
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
;
314 dphase
+= *in
++ * conv
;
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
;
323 *out
++ = f1
+ frac
* (f2
- f1
);
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
;
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);
356 /* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */
358 typedef struct vcfctl
366 typedef struct 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;
387 x
->x_cspace
.c_isr
= 0;
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]);
406 float re
= c
->c_re
, re2
;
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
;
413 float *tab
= cos_table
, *addr
, f1
, f2
, frac
;
415 int normhipart
, tabindex
;
419 normhipart
= tf
.tf_i
[HIOFFSET
];
421 for (i
= 0; i
< n
; i
++)
423 float cf
, cfindx
, r
, oneminusr
;
426 cfindx
= cf
* (float)(COSTABSIZE
/6.28318f
);
427 r
= (qinv
> 0 ? 1 - cf
* qinv
: 0);
429 oneminusr
= 1.0f
- r
;
430 dphase
= ((double)(cfindx
)) + UNITBIT32
;
432 tabindex
= tf
.tf_i
[HIOFFSET
] & (COSTABSIZE
-1);
433 addr
= tab
+ tabindex
;
434 tf
.tf_i
[HIOFFSET
] = normhipart
;
435 frac
= tf
.tf_d
- UNITBIT32
;
438 coefr
= r
* (f1
+ frac
* (f2
- f1
));
440 addr
= tab
+ ((tabindex
- (COSTABSIZE
/4)) & (COSTABSIZE
-1));
443 coefi
= r
* (f1
+ frac
* (f2
- f1
));
447 *out1
++ = re
= ampcorrect
* oneminusr
* f1
448 + coefr
* re2
- coefi
* im
;
449 *out2
++ = im
= coefi
* re2
+ coefr
* im
;
451 if (PD_BIGORSMALL(re
))
453 if (PD_BIGORSMALL(im
))
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
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"));
497 static t_int
*noise_perform(t_int
*w
)
499 t_float
*out
= (t_float
*)(w
[1]);
500 int *vp
= (int *)(w
[2]);
505 *out
++ = ((float)((val
& 0x7fffffff) - 0x40000000)) *
506 (float)(1.0 / 0x40000000);
507 val
= val
* 435898247 + 382842987;
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)