aboutsummaryrefslogtreecommitdiff
path: root/cyclone/sickle/Snapshot.c
diff options
context:
space:
mode:
Diffstat (limited to 'cyclone/sickle/Snapshot.c')
-rw-r--r--cyclone/sickle/Snapshot.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/cyclone/sickle/Snapshot.c b/cyclone/sickle/Snapshot.c
new file mode 100644
index 0000000..7c7e974
--- /dev/null
+++ b/cyclone/sickle/Snapshot.c
@@ -0,0 +1,161 @@
+/* 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. */
+
+#include "m_pd.h"
+#include "sickle/sic.h"
+
+/* CHECKME for a fixed minimum deltime, if any (5ms for c74's metro) */
+
+typedef struct _snapshot
+{
+ t_sic x_sic;
+ t_float x_value;
+ int x_rqoffset; /* requested */
+ int x_offset; /* effective (truncated) */
+ int x_stopped;
+ int x_on; /* !stopped && deltime > 0 */
+ float x_deltime;
+ int x_npoints;
+ int x_nleft;
+ int x_nblock;
+ float x_ksr;
+ t_clock *x_clock;
+} t_snapshot;
+
+static t_class *snapshot_class;
+
+static void snapshot_tick(t_snapshot *x)
+{
+ outlet_float(((t_object *)x)->ob_outlet, x->x_value);
+}
+
+static void snapshot_bang(t_snapshot *x)
+{
+ outlet_float(((t_object *)x)->ob_outlet, x->x_value);
+}
+
+static void snapshot_correct(t_snapshot *x)
+{
+ int wason = x->x_on;
+ x->x_offset =
+ (x->x_rqoffset < x->x_nblock ? x->x_rqoffset : x->x_nblock - 1);
+ x->x_npoints = x->x_deltime * x->x_ksr - x->x_nblock + x->x_offset;
+ if (x->x_on = (!x->x_stopped && x->x_deltime > 0.))
+ {
+ if (!wason) x->x_nleft = x->x_offset; /* CHECKME */
+ }
+ else if (wason) clock_unset(x->x_clock);
+}
+
+static void snapshot_start(t_snapshot *x)
+{
+ x->x_stopped = 0;
+ if (!x->x_on && x->x_deltime > 0.) /* CHECKED no default */
+ {
+ x->x_nleft = x->x_offset; /* CHECKME */
+ x->x_on = 1;
+ }
+}
+
+static void snapshot_stop(t_snapshot *x)
+{
+ x->x_stopped = 1;
+ if (x->x_on)
+ {
+ clock_unset(x->x_clock);
+ x->x_on = 0;
+ }
+}
+
+static void snapshot_float(t_snapshot *x, t_float f)
+{
+ /* CHECKED nonzero/zero, CHECKED incompatible: int only (float ignored) */
+ if (f != 0.)
+ snapshot_start(x);
+ else
+ snapshot_stop(x);
+}
+
+static void snapshot_ft1(t_snapshot *x, t_floatarg f)
+{
+ x->x_deltime = (f > 0. ? f : 0.); /* CHECKED */
+ /* CHECKED setting deltime to a positive value starts the clock
+ only if it was stopped by setting deltime to zero */
+ snapshot_correct(x);
+}
+
+static void snapshot_offset(t_snapshot *x, t_floatarg f)
+{
+ int i = (int)f; /* CHECKME */
+ x->x_rqoffset = (i >= 0 ? i : 0); /* CHECKME */
+ /* CHECKME if the change has an effect prior to next dsp_add call */
+ snapshot_correct(x);
+}
+
+static t_int *snapshot_perform(t_int *w)
+{
+ t_snapshot *x = (t_snapshot *)(w[1]);
+ t_float *in = (t_float *)(w[2]);
+ x->x_value = in[x->x_offset];
+ if (x->x_on)
+ {
+ /* CHECKME nleft vs offset */
+ if (x->x_nleft < x->x_nblock)
+ {
+ clock_delay(x->x_clock, 0);
+ x->x_nleft = x->x_npoints;
+ }
+ else x->x_nleft -= x->x_nblock;
+ }
+ return (w + 3);
+}
+
+static void snapshot_dsp(t_snapshot *x, t_signal **sp)
+{
+ x->x_nblock = sp[0]->s_n;
+ x->x_ksr = sp[0]->s_sr * 0.001;
+ snapshot_correct(x);
+ x->x_nleft = x->x_offset; /* CHECKME */
+ dsp_add(snapshot_perform, 2, x, sp[0]->s_vec);
+}
+
+static void snapshot_free(t_snapshot *x)
+{
+ if (x->x_clock) clock_free(x->x_clock);
+}
+
+static void *snapshot_new(t_floatarg f1, t_floatarg f2)
+{
+ t_snapshot *x = (t_snapshot *)pd_new(snapshot_class);
+ x->x_stopped = 0; /* CHECKED */
+ x->x_on = 0;
+ x->x_value = 0;
+ x->x_nblock = 64; /* redundant */
+ x->x_ksr = 44.1; /* redundant */
+ inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1"));
+ outlet_new((t_object *)x, &s_float);
+ x->x_clock = clock_new(x, (t_method)snapshot_tick);
+ snapshot_offset(x, f2); /* CHECKME (this is fixed at nblock-1 in Pd) */
+ snapshot_ft1(x, f1);
+ return (x);
+}
+
+void Snapshot_tilde_setup(void)
+{
+ snapshot_class = class_new(gensym("Snapshot~"),
+ (t_newmethod)snapshot_new,
+ (t_method)snapshot_free,
+ sizeof(t_snapshot), 0,
+ A_DEFFLOAT, A_DEFFLOAT, 0);
+ sic_setup(snapshot_class, snapshot_dsp, snapshot_float);
+ class_addbang(snapshot_class, snapshot_bang);
+ class_addmethod(snapshot_class, (t_method)snapshot_ft1,
+ gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(snapshot_class, (t_method)snapshot_offset,
+ gensym("offset"), A_FLOAT, 0);
+ class_addmethod(snapshot_class, (t_method)snapshot_start,
+ gensym("start"), 0);
+ class_addmethod(snapshot_class, (t_method)snapshot_stop,
+ gensym("stop"), 0);
+}