aboutsummaryrefslogtreecommitdiff
path: root/shared/sickle/sic.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/sickle/sic.c')
-rw-r--r--shared/sickle/sic.c119
1 files changed, 119 insertions, 0 deletions
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);
+}