aboutsummaryrefslogtreecommitdiff
path: root/shared/sickle
diff options
context:
space:
mode:
Diffstat (limited to 'shared/sickle')
-rw-r--r--shared/sickle/Makefile4
-rw-r--r--shared/sickle/Makefile.objects0
-rw-r--r--shared/sickle/Makefile.sources3
-rw-r--r--shared/sickle/arsic.c221
-rw-r--r--shared/sickle/arsic.h38
-rw-r--r--shared/sickle/sic.c119
-rw-r--r--shared/sickle/sic.h25
7 files changed, 410 insertions, 0 deletions
diff --git a/shared/sickle/Makefile b/shared/sickle/Makefile
new file mode 100644
index 0000000..5dcb2c8
--- /dev/null
+++ b/shared/sickle/Makefile
@@ -0,0 +1,4 @@
+ROOT_DIR = ../..
+include $(ROOT_DIR)/Makefile.common
+
+all: $(OBJECTS)
diff --git a/shared/sickle/Makefile.objects b/shared/sickle/Makefile.objects
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/shared/sickle/Makefile.objects
diff --git a/shared/sickle/Makefile.sources b/shared/sickle/Makefile.sources
new file mode 100644
index 0000000..5575605
--- /dev/null
+++ b/shared/sickle/Makefile.sources
@@ -0,0 +1,3 @@
+OTHER_SOURCES = \
+sic.c \
+arsic.c
diff --git a/shared/sickle/arsic.c b/shared/sickle/arsic.c
new file mode 100644
index 0000000..8f0e309
--- /dev/null
+++ b/shared/sickle/arsic.c
@@ -0,0 +1,221 @@
+/* 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. */
+
+/* generic array-based signal class */
+
+#include <stdio.h>
+#include <string.h>
+#include "m_pd.h"
+#include "shared.h"
+#include "common/vefl.h"
+#include "sickle/sic.h"
+#include "sickle/arsic.h"
+
+void arsic_clear(t_arsic *x)
+{
+ x->s_vecsize = 0;
+ memset(x->s_vectors, 0, x->s_nchannels * sizeof(*x->s_vectors));
+}
+
+void arsic_redraw(t_arsic *x)
+{
+ if (x->s_mononame)
+ {
+ t_garray *ap =
+ (t_garray *)pd_findbyclass(x->s_mononame, garray_class);
+ if (ap) garray_redraw(ap);
+ else if (x->s_vectors[0]) bug("arsic_redraw 1");
+ }
+ else if (*x->s_stub)
+ {
+ int ch = x->s_nchannels;
+ while (ch--)
+ {
+ t_garray *ap =
+ (t_garray *)pd_findbyclass(x->s_channames[ch], garray_class);
+ if (ap) garray_redraw(ap);
+ else if (x->s_vectors[ch]) bug("arsic_redraw 2");
+ }
+ }
+}
+
+void arsic_validate(t_arsic *x, int complain)
+{
+ arsic_clear(x);
+ x->s_vecsize = SHARED_INT_MAX;
+ if (x->s_mononame)
+ {
+ x->s_vectors[0] =
+ vefl_get(x->s_mononame, &x->s_vecsize, 1,
+ (complain ? (t_pd *)x : 0));
+ }
+ else if (*x->s_stub)
+ {
+ int ch;
+ for (ch = 0; ch < x->s_nchannels ; ch++)
+ {
+ int vsz = x->s_vecsize; /* ignore missing arrays */
+ x->s_vectors[ch] =
+ vefl_get(x->s_channames[ch], &vsz, 1,
+ (complain ? (t_pd *)x : 0));
+ if (vsz < x->s_vecsize) x->s_vecsize = vsz;
+ }
+ }
+ if (x->s_vecsize == SHARED_INT_MAX) x->s_vecsize = 0;
+}
+
+void arsic_check(t_arsic *x)
+{
+ x->s_playable = (!((t_sic *)x)->s_disabled && x->s_vecsize >= x->s_minsize);
+}
+
+int arsic_getnchannels(t_arsic *x)
+{
+ return (x->s_nchannels);
+}
+
+void arsic_setarray(t_arsic *x, t_symbol *s, int complain)
+{
+ if (s)
+ {
+ if (x->s_mononame) x->s_mononame = s;
+ else
+ {
+ x->s_stub = s->s_name;
+ if (*x->s_stub)
+ {
+ char buf[MAXPDSTRING];
+ int ch;
+ for (ch = 0; ch < x->s_nchannels; ch++)
+ {
+ sprintf(buf, "%d-%s", ch, x->s_stub);
+ x->s_channames[ch] = gensym(buf);
+ }
+ }
+ }
+ arsic_validate(x, complain);
+ }
+ arsic_check(x);
+}
+
+void arsic_setminsize(t_arsic *x, int i)
+{
+ x->s_minsize = i;
+}
+
+void arsic_dsp(t_arsic *x, t_signal **sp, t_perfroutine perf, int complain)
+{
+ t_int *ap = x->s_perfargs;
+ if (ap)
+ {
+ int i, nsigs = x->s_nperfargs - 2;
+ x->s_ksr = sp[0]->s_sr * 0.001;
+ arsic_validate(x, complain);
+ arsic_check(x);
+
+ /* LATER consider glist traversing, and, if we have no feeders,
+ choosing an optimized version of perform routine */
+
+ *ap++ = (t_int)x;
+ *ap++ = (t_int)sp[0]->s_n;
+ for (i = 0; i < nsigs; i++) *ap++ = (t_int)sp[i]->s_vec;
+ dsp_addv(perf, x->s_nperfargs, x->s_perfargs);
+ }
+ else bug("arsic_dsp");
+}
+
+void arsic_free(t_arsic *x)
+{
+ if (x->s_vectors)
+ freebytes(x->s_vectors, x->s_nchannels * sizeof(*x->s_vectors));
+ if (x->s_channames)
+ freebytes(x->s_channames,
+ x->s_nchannels * sizeof(*x->s_channames));
+ if (x->s_perfargs)
+ freebytes(x->s_perfargs, x->s_nperfargs * sizeof(*x->s_perfargs));
+}
+
+/* If nauxsigs is positive, then the number of signals is nchannels + nauxsigs;
+ otherwise the channels are not used as signals, and the number of signals is
+ nsigs -- provided that nsigs is positive -- or, if it is not, then an arsic
+ is not used in dsp (peek~). */
+void *arsic_new(t_class *c, t_symbol *s,
+ int nchannels, int nsigs, int nauxsigs)
+{
+ t_arsic *x;
+ t_symbol *mononame;
+ char *stub;
+ t_float **vectors;
+ int nperfargs = 0;
+ t_int *perfargs = 0;
+ t_symbol **channames = 0;
+ if (!s) s = &s_;
+ if (nchannels < 1)
+ {
+ nchannels = 1;
+ mononame = s;
+ stub = 0;
+ }
+ else
+ {
+ mononame = 0;
+ stub = s->s_name;
+ }
+ if (!(vectors = (t_float **)getbytes(nchannels * sizeof(*vectors))))
+ return (0);
+ if (nauxsigs > 0)
+ nperfargs = nchannels + nauxsigs + 2;
+ else if (nsigs > 0)
+ nperfargs = nsigs + 2;
+ if (nperfargs
+ && !(perfargs = (t_int *)getbytes(nperfargs * sizeof(*perfargs))))
+ {
+ freebytes(vectors, nchannels * sizeof(*vectors));
+ return (0);
+ }
+ if (stub &&
+ !(channames = (t_symbol **)getbytes(nchannels * sizeof(*channames))))
+ {
+ freebytes(vectors, nchannels * sizeof(*vectors));
+ if (perfargs) freebytes(perfargs, nperfargs * sizeof(*perfargs));
+ return (0);
+ }
+ x = (t_arsic *)pd_new(c);
+ x->s_vecsize = 0;
+ x->s_nchannels = nchannels;
+ x->s_vectors = vectors;
+ x->s_channames = channames;
+ x->s_nperfargs = nperfargs;
+ x->s_perfargs = perfargs;
+ x->s_mononame = mononame;
+ x->s_stub = stub;
+ x->s_ksr = sys_getsr() * 0.001;
+ ((t_sic *)x)->s_disabled = 0;
+ x->s_playable = 0;
+ x->s_minsize = 1;
+ arsic_setarray(x, s, 0);
+ return (x);
+}
+
+static void arsic_enable(t_arsic *x, t_floatarg f)
+{
+ ((t_sic *)x)->s_disabled = (f == 0);
+ arsic_check(x);
+}
+
+/* LATER somehow link this to sic_setup() */
+void arsic_setup(t_class *c, void *dspfn, void *floatfn)
+{
+ if (floatfn != SIC_NOMAINSIGNALIN)
+ {
+ if (floatfn)
+ {
+ class_domainsignalin(c, -1);
+ class_addfloat(c, floatfn);
+ }
+ else CLASS_MAINSIGNALIN(c, t_sic, s_f);
+ }
+ class_addmethod(c, (t_method)dspfn, gensym("dsp"), 0);
+ class_addmethod(c, (t_method)arsic_enable, gensym("enable"), 0);
+}
diff --git a/shared/sickle/arsic.h b/shared/sickle/arsic.h
new file mode 100644
index 0000000..a941279
--- /dev/null
+++ b/shared/sickle/arsic.h
@@ -0,0 +1,38 @@
+/* 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. */
+
+#ifndef __ARSIC_H__
+#define __ARSIC_H__
+
+typedef struct _arsic
+{
+ t_sic s_sic;
+ int s_vecsize; /* used also as a validation flag */
+ int s_nchannels;
+ t_float **s_vectors;
+ t_symbol **s_channames;
+ int s_nperfargs;
+ t_int *s_perfargs;
+ t_symbol *s_mononame; /* used also as an 'ismono' flag */
+ char *s_stub;
+ float s_ksr;
+ int s_playable;
+ int s_minsize;
+} t_arsic;
+
+void arsic_clear(t_arsic *x);
+void arsic_redraw(t_arsic *x);
+void arsic_validate(t_arsic *x, int complain);
+void arsic_check(t_arsic *x);
+int arsic_getnchannels(t_arsic *x);
+void arsic_setarray(t_arsic *x, t_symbol *s, int complain);
+void arsic_setminsize(t_arsic *x, int i);
+
+void arsic_dsp(t_arsic *x, t_signal **sp, t_perfroutine perf, int complain);
+void *arsic_new(t_class *c, t_symbol *s,
+ int nchannels, int nsigs, int nauxsigs);
+void arsic_free(t_arsic *x);
+void arsic_setup(t_class *c, void *dspfn, void *floatfn);
+
+#endif
diff --git a/shared/sickle/sic.c b/shared/sickle/sic.c
new file mode 100644
index 0000000..003120e
--- /dev/null
+++ b/shared/sickle/sic.c
@@ -0,0 +1,119 @@
+/* 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. */
+
+/* generic signal class */
+
+#include <math.h>
+#include "m_pd.h"
+#include "shared.h"
+#include "common/loud.h"
+#include "sickle/sic.h"
+
+//#define SIC_DEBUG
+
+#if defined(NT) || defined(MACOSX)
+/* cf pd/src/x_arithmetic.c */
+#define cosf cos
+#endif
+
+t_inlet *sic_inlet(t_sic *x, int ix, t_float df, int ax, int ac, t_atom *av)
+{
+ t_inlet *in = 0;
+ if (ax < ac)
+ {
+ if (av[ax].a_type == A_FLOAT)
+ df = av[ax].a_w.w_float;
+ else
+ loud_error((t_pd *)x, "bad argument %d (float expected)", ax + 1);
+ }
+ if (ix)
+ {
+ in = inlet_new((t_object *)x, (t_pd *)x, &s_signal, &s_signal);
+ /* this is persistent (in->i_un.iu_floatsignalvalue = df) */
+ pd_float((t_pd *)in, df);
+ }
+ else
+ {
+ in = ((t_object *)x)->ob_inlet;
+ pd_float((t_pd *)x, df);
+ }
+ return (in);
+}
+
+t_inlet *sic_newinlet(t_sic *x, t_float f)
+{
+ return (sic_inlet(x, 1, f, 0, 0, 0));
+}
+
+t_float *sic_makecostable(int *sizep)
+{
+ /* permanent cache (tables are never freed); LATER rethink */
+ static t_float *sic_costables[SIC_NCOSTABLES];
+ int ndx, sz;
+ /* round upwards -- always return at least requested number of elements,
+ unless the maximum of 2^SIC_NCOSTABLES is exceeded; LATER rethink */
+ /* (the minimum, at ndx 0, is 2^1) */
+ for (ndx = 0, sz = 2; ndx < (SIC_NCOSTABLES - 1); ndx++, sz <<= 1)
+ if (sz >= *sizep)
+ break;
+#ifdef SIC_DEBUG
+ post("request for a costable of %d points (effective %d, ndx %d)",
+ *sizep, sz, ndx);
+#endif
+ *sizep = sz;
+ if (sic_costables[ndx])
+ return (sic_costables[ndx]);
+ else if (sz == COSTABSIZE && cos_table)
+ return (sic_costables[ndx] = cos_table);
+ else
+ {
+ int cnt = sz + 1;
+ float phase = 0, phsinc = SHARED_2PI / sz;
+ t_float *table = (t_float *)getbytes(cnt * sizeof(*table)), *tp = table;
+ if (table)
+ {
+#ifdef SIC_DEBUG
+ post("got %d points of a costable", cnt);
+#endif
+ while (cnt--)
+ {
+ *tp++ = cosf(phase);
+ phase += phsinc;
+ }
+ }
+ return (sic_costables[ndx] = table);
+ }
+}
+
+static void sic_enable(t_sic *x, t_floatarg f)
+{
+ x->s_disabled = (f == 0);
+}
+
+void sic_setup(t_class *c, void *dspfn, void *floatfn)
+{
+ static int checked = 0;
+ if (!checked)
+ {
+ /* MSP: here we check at startup whether the byte alignment
+ is as we declared it. If not, the code has to be
+ recompiled the other way. */
+ t_shared_wrappy wrappy;
+ wrappy.w_d = SHARED_UNITBIT32 + 0.5;
+ if ((unsigned)wrappy.w_i[SHARED_LOWOFFSET] != 0x80000000)
+ bug("sic_setup: unexpected machine alignment");
+ checked = 1;
+ }
+ if (floatfn != SIC_NOMAINSIGNALIN)
+ {
+ if (floatfn)
+ {
+ class_domainsignalin(c, -1);
+ class_addfloat(c, floatfn);
+ }
+ else CLASS_MAINSIGNALIN(c, t_sic, s_f);
+ }
+ class_addmethod(c, (t_method)dspfn, gensym("dsp"), 0);
+ class_addmethod(c, (t_method)sic_enable, gensym("enable"), 0);
+}
diff --git a/shared/sickle/sic.h b/shared/sickle/sic.h
new file mode 100644
index 0000000..9dce95f
--- /dev/null
+++ b/shared/sickle/sic.h
@@ -0,0 +1,25 @@
+/* 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. */
+
+#ifndef __SIC_H__
+#define __SIC_H__
+
+typedef struct _sic
+{
+ t_object s_ob;
+ t_float s_f;
+ int s_disabled;
+} t_sic;
+
+#define SIC_FLOATTOSIGNAL ((void *)0)
+#define SIC_NOMAINSIGNALIN ((void *)-1)
+
+#define SIC_NCOSTABLES 16 /* this is oscbank~'s max, LATER rethink */
+
+t_inlet *sic_inlet(t_sic *x, int ix, t_float df, int ax, int ac, t_atom *av);
+t_inlet *sic_newinlet(t_sic *x, t_float f);
+t_float *sic_makecostable(int *sizep);
+void sic_setup(t_class *c, void *dspfn, void *floatfn);
+
+#endif