aboutsummaryrefslogtreecommitdiff
path: root/cyclone/sickle/poke.c
diff options
context:
space:
mode:
Diffstat (limited to 'cyclone/sickle/poke.c')
-rw-r--r--cyclone/sickle/poke.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/cyclone/sickle/poke.c b/cyclone/sickle/poke.c
new file mode 100644
index 0000000..d0fb22a
--- /dev/null
+++ b/cyclone/sickle/poke.c
@@ -0,0 +1,155 @@
+/* Copyright (c) 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. */
+
+/* LATER: 'click' method */
+
+#include "m_pd.h"
+#include "unstable/fragile.h"
+#include "sickle/sic.h"
+#include "sickle/arsic.h"
+
+#define POKE_MAXCHANNELS 4 /* LATER implement arsic resizing feature */
+
+typedef struct _poke
+{
+ t_arsic x_arsic;
+ int x_maxchannels;
+ int x_effchannel; /* effective channel (clipped reqchannel) */
+ int x_reqchannel; /* requested channel */
+ t_sample *x_indexptr;
+ t_clock *x_clock;
+ double x_clocklasttick;
+ int x_clockset;
+} t_poke;
+
+static t_class *poke_class;
+
+static void poke_tick(t_poke *x)
+{
+ arsic_redraw((t_arsic *)x); /* LATER redraw only dirty channel(s!) */
+ x->x_clockset = 0;
+ x->x_clocklasttick = clock_getsystime();
+}
+
+static void poke_set(t_poke *x, t_symbol *s)
+{
+ arsic_setarray((t_arsic *)x, s, 1);
+}
+
+static void poke_bang(t_poke *x)
+{
+ arsic_redraw((t_arsic *)x);
+}
+
+/* CHECKED: index 0-based, negative values block input, overflowed are clipped.
+ LATER revisit: incompatibly, the code below is nop for any out-of-range index
+ (see also peek.c) */
+/* CHECKED: value never clipped, 'clip' not understood */
+/* CHECKED: no float-to-signal conversion. 'Float' message is ignored
+ when dsp is on -- whether a signal is connected to the left inlet, or not
+ (if not, current index is set to zero). Incompatible (revisit LATER) */
+static void poke_float(t_poke *x, t_float f)
+{
+ t_arsic *sic = (t_arsic *)x;
+ t_float *vp;
+ arsic_validate(sic, 0); /* LATER rethink (efficiency, and complaining) */
+ if (vp = sic->s_vectors[x->x_effchannel])
+ {
+ int ndx = (int)*x->x_indexptr;
+ if (ndx >= 0 && ndx < sic->s_vecsize)
+ {
+ double timesince;
+ vp[ndx] = f;
+ timesince = clock_gettimesince(x->x_clocklasttick);
+ if (timesince > 1000) poke_tick(x);
+ else if (!x->x_clockset)
+ {
+ clock_delay(x->x_clock, 1000 - timesince);
+ x->x_clockset = 1;
+ }
+ }
+ }
+}
+
+static void poke_ft2(t_poke *x, t_floatarg f)
+{
+ if ((x->x_reqchannel = (f > 1 ? (int)f - 1 : 0)) > x->x_maxchannels)
+ x->x_effchannel = x->x_maxchannels - 1;
+ else
+ x->x_effchannel = x->x_reqchannel;
+}
+
+static t_int *poke_perform(t_int *w)
+{
+ t_arsic *sic = (t_arsic *)(w[1]);
+ int nblock = (int)(w[2]);
+ t_float *in1 = (t_float *)(w[3]);
+ t_float *in2 = (t_float *)(w[4]);
+ t_poke *x = (t_poke *)sic;
+ t_float *vp = sic->s_vectors[x->x_effchannel];
+ if (vp && sic->s_playable)
+ {
+ int vecsize = sic->s_vecsize;
+ while (nblock--)
+ {
+ t_float f = *in1++;
+ int ndx = (int)*in2++;
+ if (ndx >= 0 && ndx < vecsize)
+ vp[ndx] = f;
+ }
+ }
+ return (w + sic->s_nperfargs + 1);
+}
+
+static void poke_dsp(t_poke *x, t_signal **sp)
+{
+ arsic_dsp((t_arsic *)x, sp, poke_perform, 0);
+}
+
+static void poke_free(t_poke *x)
+{
+ if (x->x_clock) clock_free(x->x_clock);
+ arsic_free((t_arsic *)x);
+}
+
+static void *poke_new(t_symbol *s, t_floatarg f)
+{
+ int ch = (f > 0 ? (int)f : 0);
+ t_poke *x = (t_poke *)arsic_new(poke_class, s,
+ (ch ? POKE_MAXCHANNELS : 0), 2, 0);
+ if (x)
+ {
+ t_inlet *in2;
+ if (ch > POKE_MAXCHANNELS)
+ ch = POKE_MAXCHANNELS;
+ x->x_maxchannels = (ch ? POKE_MAXCHANNELS : 1);
+ x->x_effchannel = x->x_reqchannel = (ch ? ch - 1 : 0);
+ /* CHECKED: no float-to-signal conversion.
+ Floats in 2nd inlet are ignored when dsp is on, but only if a signal
+ is connected to this inlet. Incompatible (revisit LATER). */
+ in2 = inlet_new((t_object *)x, (t_pd *)x, &s_signal, &s_signal);
+ x->x_indexptr = fragile_inlet_signalscalar(in2);
+ inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft2"));
+ x->x_clock = clock_new(x, (t_method)poke_tick);
+ x->x_clocklasttick = clock_getsystime();
+ x->x_clockset = 0;
+ }
+ return (x);
+}
+
+void poke_tilde_setup(void)
+{
+ poke_class = class_new(gensym("poke~"),
+ (t_newmethod)poke_new,
+ (t_method)poke_free,
+ sizeof(t_poke), 0,
+ A_DEFSYM, A_DEFFLOAT, 0);
+ arsic_setup(poke_class, poke_dsp, poke_float);
+ class_addbang(poke_class, poke_bang); /* LATER rethink */
+ class_addfloat(poke_class, poke_float);
+ class_addmethod(poke_class, (t_method)poke_set,
+ gensym("set"), A_SYMBOL, 0);
+ class_addmethod(poke_class, (t_method)poke_ft2,
+ gensym("ft2"), A_FLOAT, 0);
+}