aboutsummaryrefslogtreecommitdiff
path: root/cyclone/sickle/bitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'cyclone/sickle/bitor.c')
-rw-r--r--cyclone/sickle/bitor.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/cyclone/sickle/bitor.c b/cyclone/sickle/bitor.c
new file mode 100644
index 0000000..e5c887b
--- /dev/null
+++ b/cyclone/sickle/bitor.c
@@ -0,0 +1,144 @@
+/* Copyright (c) 2002-2003 krzYszcz and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* FIXME find a way of setting a 32-bit mask in an argument */
+
+#include "m_pd.h"
+#include "unstable/forky.h"
+#include "sickle/sic.h"
+
+typedef struct _bitor
+{
+ t_sic x_sic;
+ t_glist *x_glist;
+ t_int x_mask; /* set by a 'bits' message or a creation argument */
+ int x_mode;
+ int x_convert1;
+} t_bitor;
+
+static t_class *bitor_class;
+
+static t_int *bitor_perform(t_int *w)
+{
+ t_bitor *x = (t_bitor *)(w[1]);
+ int nblock = (int)(w[2]);
+ t_float *in1 = (t_float *)(w[3]);
+ t_float *in2 = (t_float *)(w[4]);
+ t_float *out = (t_float *)(w[5]);
+ t_int mask = x->x_mask;
+ switch (x->x_mode)
+ {
+ /* LATER think about performance */
+ case 0:
+ /* CHECKED */
+ while (nblock--)
+ {
+ t_int i = ((*(t_int *)(t_float *)in1++) |
+ (*(t_int *)(t_float *)in2++));
+ *out++ = *(t_float *)&i;
+ }
+ break;
+ case 1:
+ /* CHECKED */
+ while (nblock--)
+ {
+ t_int i = (((t_int)*in1++) |
+ ((t_int)*in2++));
+ *out++ = (t_float)i;
+ }
+ break;
+ case 2:
+ /* CHECKED */
+ while (nblock--)
+ {
+ t_int i = (*(t_int *)(t_float *)in1++) | ((t_int)*in2++);
+ *out++ = *(t_float *)&i;
+ }
+ break;
+ case 3:
+ /* CHECKED */
+ while (nblock--)
+ {
+ t_int i = ((t_int)*in1++) | (*(t_int *)(t_float *)in2++);
+ *out++ = (t_float)i;
+ }
+ break;
+ }
+ return (w + 6);
+}
+
+static t_int *bitor_perform_noin2(t_int *w)
+{
+ t_bitor *x = (t_bitor *)(w[1]);
+ int nblock = (int)(w[2]);
+ t_float *in = (t_float *)(w[3]);
+ t_float *out = (t_float *)(w[4]);
+ t_int mask = x->x_mask;
+ /* LATER think about performance */
+ if (x->x_convert1) while (nblock--)
+ {
+ /* CHECKED */
+ t_int i = ((t_int)*in++) | mask;
+ *out++ = (t_float)i;
+ }
+ else while (nblock--)
+ {
+ /* CHECKED */
+ t_int i = (*(t_int *)(t_float *)in++) | mask;
+ *out++ = *(t_float *)&i;
+ }
+ return (w + 5);
+}
+
+static void bitor_dsp(t_bitor *x, t_signal **sp)
+{
+ if (forky_hasfeeders((t_object *)x, x->x_glist, 1, 0))
+ /* use the mask set by a second inlet's signal or float,
+ CHECKED (incompatible) second inlet's int is persistent */
+ dsp_add(bitor_perform, 5, x, sp[0]->s_n, sp[0]->s_vec,
+ sp[1]->s_vec, sp[2]->s_vec);
+ else /* use the mask set by a 'bits' message or a creation argument */
+ dsp_add(bitor_perform_noin2, 4, x, sp[0]->s_n, sp[0]->s_vec,
+ sp[1]->s_vec);
+}
+
+static void bitor_bits(t_bitor *x, t_symbol *s, int ac, t_atom *av)
+{
+ x->x_mask = forky_getbitmask(ac, av);
+}
+
+static void bitor_mode(t_bitor *x, t_floatarg f)
+{
+ int i = (int)f;
+ if (i < 0)
+ i = 0; /* CHECKED */
+ else if (i > 3)
+ i = 3; /* CHECKED */
+ x->x_mode = i;
+ x->x_convert1 = (x->x_mode == 1 || x->x_mode == 3);
+}
+
+static void *bitor_new(t_floatarg f1, t_floatarg f2)
+{
+ t_bitor *x = (t_bitor *)pd_new(bitor_class);
+ x->x_glist = canvas_getcurrent();
+ inlet_new((t_object *)x, (t_pd *)x, &s_signal, &s_signal);
+ outlet_new((t_object *)x, &s_signal);
+ x->x_mask = (t_int)f1; /* FIXME (how?) */
+ bitor_mode(x, f2);
+ return (x);
+}
+
+void bitor_tilde_setup(void)
+{
+ bitor_class = class_new(gensym("bitor~"),
+ (t_newmethod)bitor_new, 0,
+ sizeof(t_bitor), 0,
+ A_DEFFLOAT, A_DEFFLOAT, 0);
+ sic_setup(bitor_class, bitor_dsp, SIC_FLOATTOSIGNAL);
+ class_addmethod(bitor_class, (t_method)bitor_bits,
+ gensym("bits"), A_GIMME, 0);
+ class_addmethod(bitor_class, (t_method)bitor_mode,
+ gensym("mode"), A_FLOAT, 0);
+}