aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormusil <tmusil@users.sourceforge.net>2013-06-28 17:25:22 +0000
committermusil <tmusil@users.sourceforge.net>2013-06-28 17:25:22 +0000
commita7e6303e3e7e87bf90b21821d2e419ed4799783c (patch)
treeba035867b2a15a2bdb945184a120e926e3127113 /src
initial check in of double precision library of iemsvn2git-root
svn path=/trunk/externals/iem/iem_dp/; revision=17167
Diffstat (limited to 'src')
-rwxr-xr-xsrc/add__.c74
-rwxr-xr-xsrc/add~~.c272
-rwxr-xr-xsrc/delay~~.c390
-rwxr-xr-xsrc/div__.c79
-rwxr-xr-xsrc/div~~.c321
-rwxr-xr-xsrc/dptohex.c69
-rwxr-xr-xsrc/dptosym.c70
-rwxr-xr-xsrc/ftohex.c49
-rwxr-xr-xsrc/iem_dp.c127
-rwxr-xr-xsrc/iem_dp.h49
-rw-r--r--src/iemlib.h115
-rwxr-xr-xsrc/makefile_d_fat71
-rwxr-xr-xsrc/makefile_d_ppc72
-rwxr-xr-xsrc/makefile_darwin77
-rwxr-xr-xsrc/makefile_linux75
-rwxr-xr-xsrc/max__.c80
-rwxr-xr-xsrc/max~~.c297
-rwxr-xr-xsrc/min__.c80
-rwxr-xr-xsrc/min~~.c297
-rwxr-xr-xsrc/mul__.c78
-rwxr-xr-xsrc/mul~~.c272
-rwxr-xr-xsrc/phasor~~.c89
-rwxr-xr-xsrc/print~~.c99
-rwxr-xr-xsrc/random__.c93
-rwxr-xr-xsrc/samphold~~.c128
-rwxr-xr-xsrc/sub__.c78
-rwxr-xr-xsrc/sub~~.c272
-rwxr-xr-xsrc/symtodp.c133
-rwxr-xr-xsrc/tabread4_dp.c95
-rwxr-xr-xsrc/tabread4~~.c128
-rwxr-xr-xsrc/tabread_dp.c82
-rwxr-xr-xsrc/tabread~~.c117
-rwxr-xr-xsrc/tabwrite_dp.c85
-rwxr-xr-xsrc/tabwrite~~.c154
-rwxr-xr-xsrc/vline~~.c220
-rwxr-xr-xsrc/wrap~~.c73
36 files changed, 4860 insertions, 0 deletions
diff --git a/src/add__.c b/src/add__.c
new file mode 100755
index 0000000..2f9499f
--- /dev/null
+++ b/src/add__.c
@@ -0,0 +1,74 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* ------------------------ add__ or +__ ---------------------------- */
+/* based on miller's +, which is part of pd, only with double precision */
+
+static t_class *add___class;
+
+typedef struct _add__
+{
+ t_object x_obj;
+ t_float x_coarse_left;
+ t_float x_fine_left;
+ t_float x_coarse_right;
+ t_float x_fine_right;
+ t_outlet *x_out_coarse;
+ t_outlet *x_out_fine;
+} t_add__;
+
+static void add___bang(t_add__ *x)
+{
+ double dsum;
+ t_float fsum;
+
+ dsum = iem_dp_calc_sum(x->x_coarse_left, x->x_fine_left) + iem_dp_calc_sum(x->x_coarse_right, x->x_fine_right);
+ fsum = iem_dp_cast_to_float(dsum);
+ outlet_float(x->x_out_fine, iem_dp_calc_residual(dsum, fsum));
+ outlet_float(x->x_out_coarse, fsum);
+}
+
+static void add___float(t_add__ *x, t_floatarg f)
+{
+ x->x_coarse_left = f;
+ add___bang(x);
+}
+
+static void *add___new(t_symbol *s, int ac, t_atom *av)
+{
+ t_add__ *x = (t_add__ *)pd_new(add___class);
+
+ floatinlet_new(&x->x_obj, &x->x_fine_left);
+ floatinlet_new(&x->x_obj, &x->x_coarse_right);
+ floatinlet_new(&x->x_obj, &x->x_fine_right);
+ x->x_coarse_left = 0.0f;
+ x->x_fine_left = 0.0f;
+ if((ac > 0) && (IS_A_FLOAT(av, 0)))
+ x->x_coarse_right = atom_getfloatarg(0, ac, av);
+ else
+ x->x_coarse_right = 0.0f;
+ if((ac > 1) && (IS_A_FLOAT(av, 1)))
+ x->x_fine_right = atom_getfloatarg(1, ac, av);
+ else
+ x->x_fine_right = 0.0f;
+ x->x_out_coarse = outlet_new(&x->x_obj, &s_float);
+ x->x_out_fine = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void add___setup(void)
+{
+ add___class = class_new(gensym("add__"), (t_newmethod)add___new, 0, sizeof(t_add__), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)add___new, gensym("+__"), A_GIMME, 0);
+ class_addcreator((t_newmethod)add___new, gensym("+''"), A_GIMME, 0);
+ class_addbang(add___class, add___bang);
+ class_addfloat(add___class, add___float);
+}
diff --git a/src/add~~.c b/src/add~~.c
new file mode 100755
index 0000000..bcad79d
--- /dev/null
+++ b/src/add~~.c
@@ -0,0 +1,272 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* -------------------------- add~~ ------------------------------ */
+/* based on miller's +~ which is part of pd */
+
+static t_class *add_tilde_tilde_class, *scalaradd_tilde_tilde_class;
+
+typedef struct _add_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_in2_coarse;
+ t_sample *x_in2_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+} t_add_tilde_tilde;
+
+typedef struct _scalaradd_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+ t_sample x_in2_coarse;
+ t_sample x_in2_fine;
+} t_scalaradd_tilde_tilde;
+
+static void *add_tilde_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+ if(((argc==1)&&(argv->a_type == A_FLOAT))||(argc>=2)&&(argv->a_type == A_FLOAT)&&((argv+1)->a_type == A_FLOAT))
+ {
+ t_scalaradd_tilde_tilde *x = (t_scalaradd_tilde_tilde *)pd_new(scalaradd_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ floatinlet_new(&x->x_obj, &x->x_in2_coarse);
+ floatinlet_new(&x->x_obj, &x->x_in2_fine);
+ x->x_in2_coarse = atom_getfloatarg(0, argc, argv);
+ if(argc>=2)
+ x->x_in2_fine = atom_getfloatarg(1, argc, argv);
+ else
+ x->x_in2_fine = 0;
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+ else /* either no arguments or symbols */
+ {
+ t_add_tilde_tilde *x = (t_add_tilde_tilde *)pd_new(add_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+}
+
+static t_int *add_tilde_tilde_perform(t_int *w)
+{
+ t_add_tilde_tilde *x = (t_add_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double d;
+ t_float f;
+
+ while(n--)
+ {
+ d = iem_dp_calc_sum(*in1c++, *in1f++) + iem_dp_calc_sum(*in2c++, *in2f++);
+ f = iem_dp_cast_to_float(d);
+ *outf++ = iem_dp_calc_residual(d, f);
+ *outc++ = f;
+ }
+ return(w+3);
+}
+
+static t_int *add_tilde_tilde_perf8(t_int *w)
+{
+ t_add_tilde_tilde *x = (t_add_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+
+ for(; n; n -= 8, in1c += 8, in1f += 8, in2c += 8, in2f += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(in1c[0], in1f[0]) + iem_dp_calc_sum(in2c[0], in2f[0]);
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(in1c[1], in1f[1]) + iem_dp_calc_sum(in2c[1], in2f[1]);
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(in1c[2], in1f[2]) + iem_dp_calc_sum(in2c[2], in2f[2]);
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(in1c[3], in1f[3]) + iem_dp_calc_sum(in2c[3], in2f[3]);
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(in1c[4], in1f[4]) + iem_dp_calc_sum(in2c[4], in2f[4]);
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(in1c[5], in1f[5]) + iem_dp_calc_sum(in2c[5], in2f[5]);
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(in1c[6], in1f[6]) + iem_dp_calc_sum(in2c[6], in2f[6]);
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(in1c[7], in1f[7]) + iem_dp_calc_sum(in2c[7], in2f[7]);
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static t_int *scalaradd_tilde_tilde_perform(t_int *w)
+{
+ t_scalaradd_tilde_tilde *x = (t_scalaradd_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *inc = x->x_in1_coarse;
+ t_sample *inf = x->x_in1_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double d, g=iem_dp_calc_sum(x->x_in2_coarse, x->x_in2_fine);
+ t_float f;
+
+ while(n--)
+ {
+ d = iem_dp_calc_sum(*inc++, *inf++) + g;
+ f = iem_dp_cast_to_float(d);
+ *outf++ = iem_dp_calc_residual(d, f);
+ *outc++ = f;
+ }
+ return(w+3);
+}
+
+static t_int *scalaradd_tilde_tilde_perf8(t_int *w)
+{
+ t_scalaradd_tilde_tilde *x = (t_scalaradd_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *inc = x->x_in1_coarse;
+ t_sample *inf = x->x_in1_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double g=iem_dp_calc_sum(x->x_in2_coarse, x->x_in2_fine);
+
+ for(; n; n -= 8, inc += 8, inf += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(inc[0], inf[0]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(inc[1], inf[1]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(inc[2], inf[2]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(inc[3], inf[3]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(inc[4], inf[4]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(inc[5], inf[5]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(inc[6], inf[6]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(inc[7], inf[7]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static void add_tilde_tilde_dsp(t_add_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_in2_coarse = sp[2]->s_vec;
+ x->x_in2_fine = sp[3]->s_vec;
+ x->x_out_coarse = sp[4]->s_vec;
+ x->x_out_fine = sp[5]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(add_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ else
+ dsp_add(add_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+}
+
+static void scalaradd_tilde_tilde_dsp(t_scalaradd_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_out_coarse = sp[2]->s_vec;
+ x->x_out_fine = sp[3]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(scalaradd_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ else
+ dsp_add(scalaradd_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+}
+
+void add_tilde_tilde_setup(void)
+{
+ add_tilde_tilde_class = class_new(gensym("+~~"), (t_newmethod)add_tilde_tilde_new, 0,
+ sizeof(t_add_tilde_tilde), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)add_tilde_tilde_new, gensym("add~~"), A_GIMME, 0);
+ CLASS_MAINSIGNALIN(add_tilde_tilde_class, t_add_tilde_tilde, x_f);
+ class_addmethod(add_tilde_tilde_class, (t_method)add_tilde_tilde_dsp, gensym("dsp"), 0);
+ scalaradd_tilde_tilde_class = class_new(gensym("+~~"), 0, 0,
+ sizeof(t_scalaradd_tilde_tilde), 0, 0);
+ CLASS_MAINSIGNALIN(scalaradd_tilde_tilde_class, t_scalaradd_tilde_tilde, x_f);
+ class_addmethod(scalaradd_tilde_tilde_class, (t_method)scalaradd_tilde_tilde_dsp, gensym("dsp"), 0);
+}
diff --git a/src/delay~~.c b/src/delay~~.c
new file mode 100755
index 0000000..41930f7
--- /dev/null
+++ b/src/delay~~.c
@@ -0,0 +1,390 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* 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 "iemlib.h"
+#include "iem_dp.h"
+
+#define DEFDELVS_TT 64 /* LATER get this from canvas at DSP time */
+#define XTRASAMPS_TT 4
+#define SAMPBLK_TT 4
+
+/* ----------------------------- delwrite~~ ----------------------------- */
+
+typedef struct delwrite_tilde_tilde_ctl
+ {
+ int c_n;
+ t_sample *c_vec;
+ int c_phase;
+ } t_delwrite_tilde_tilde_ctl;
+
+typedef struct _delwrite_tilde_tilde
+ {
+ t_object x_obj;
+ t_symbol *x_sym;
+ double x_deltime;
+ t_delwrite_tilde_tilde_ctl x_cspace;
+ int x_sortno; /* DSP sort number at which this was last put on chain */
+ int x_rsortno; /* DSP sort # for first delread or write in chain */
+ int x_vecsize; /* vector size for delread~ to use */
+ t_float x_f;
+ } t_delwrite_tilde_tilde;
+
+//extern static int delread_zero;
+
+static t_class *delwrite_tilde_tilde_class;
+
+static void delwrite_tilde_tilde_updatesr (t_delwrite_tilde_tilde *x, t_float sr) /* added by Mathieu Bouchard */
+{
+ int nsamps = (int)(x->x_deltime * (double)sr * (double)(0.001));
+ if (nsamps < 1) nsamps = 1;
+ nsamps += ((- nsamps) & (SAMPBLK_TT - 1));
+ nsamps += DEFDELVS_TT;
+ if(x->x_cspace.c_n != nsamps)
+ {
+ x->x_cspace.c_vec = (t_sample *)resizebytes(x->x_cspace.c_vec,
+ (x->x_cspace.c_n + XTRASAMPS_TT) * sizeof(t_sample),
+ (nsamps + XTRASAMPS_TT) * sizeof(t_sample));
+ x->x_cspace.c_n = nsamps;
+ x->x_cspace.c_phase = XTRASAMPS_TT;
+ }
+}
+
+ /* routine to check that all delwrites/delreads/vds have same vecsize */
+static void delwrite_tilde_tilde_checkvecsize(t_delwrite_tilde_tilde *x, int vecsize)
+{
+ if (x->x_rsortno != ugen_getsortno())
+ {
+ x->x_vecsize = vecsize;
+ x->x_rsortno = ugen_getsortno();
+ }
+ /*
+ LATER this should really check sample rate and blocking, once that is
+ supported. Probably we don't actually care about vecsize.
+ For now just suppress this check. */
+#if 0
+ else if (vecsize != x->x_vecsize)
+ pd_error(x, "delread/delwrite/vd vector size mismatch");
+#endif
+}
+
+static void *delwrite_tilde_tilde_new(t_symbol *s, t_floatarg coarse_msec, t_floatarg fine_msec)
+{
+ t_delwrite_tilde_tilde *x = (t_delwrite_tilde_tilde *)pd_new(delwrite_tilde_tilde_class);
+
+ if(!*s->s_name)
+ s = gensym("delwrite~~");
+
+ pd_bind(&x->x_obj.ob_pd, s);
+ x->x_sym = s;
+ x->x_deltime = iem_dp_calc_sum(coarse_msec, fine_msec);
+ x->x_cspace.c_n = 0;
+ x->x_cspace.c_vec = (t_sample *)getbytes(XTRASAMPS_TT * sizeof(t_sample));
+ x->x_sortno = 0;
+ x->x_vecsize = 0;
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *delwrite_tilde_tilde_perform(t_int *w)
+{
+ t_float *in = (t_float *)(w[1]);
+ t_delwrite_tilde_tilde_ctl *c = (t_delwrite_tilde_tilde_ctl *)(w[2]);
+ int n = (int)(w[3]);
+ int phase = c->c_phase, nsamps = c->c_n;
+ t_sample *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS_TT);
+
+ phase += n;
+ while (n--)
+ {
+ t_sample f = *in++;
+ if(IEM_DENORMAL(f))
+ f = 0;
+ *bp++ = f;
+ if (bp == ep)
+ {
+ vp[0] = ep[-4];
+ vp[1] = ep[-3];
+ vp[2] = ep[-2];
+ vp[3] = ep[-1];
+ bp = vp + XTRASAMPS_TT;
+ phase -= nsamps;
+ }
+ }
+ c->c_phase = phase;
+ return (w+4);
+}
+
+static void delwrite_tilde_tilde_dsp(t_delwrite_tilde_tilde *x, t_signal **sp)
+{
+ dsp_add(delwrite_tilde_tilde_perform, 3, sp[0]->s_vec, &x->x_cspace, sp[0]->s_n);
+ x->x_sortno = ugen_getsortno();
+ delwrite_tilde_tilde_checkvecsize(x, sp[0]->s_n);
+ delwrite_tilde_tilde_updatesr(x, sp[0]->s_sr);
+}
+
+static void delwrite_tilde_tilde_free(t_delwrite_tilde_tilde *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, x->x_sym);
+ freebytes(x->x_cspace.c_vec,
+ (x->x_cspace.c_n + XTRASAMPS_TT) * sizeof(t_sample));
+}
+
+static void delwrite_tilde_tilde_setup(void)
+{
+ delwrite_tilde_tilde_class = class_new(gensym("delwrite~~"),
+ (t_newmethod)delwrite_tilde_tilde_new, (t_method)delwrite_tilde_tilde_free,
+ sizeof(t_delwrite_tilde_tilde), 0, A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(delwrite_tilde_tilde_class, t_delwrite_tilde_tilde, x_f);
+ class_addmethod(delwrite_tilde_tilde_class, (t_method)delwrite_tilde_tilde_dsp,
+ gensym("dsp"), 0);
+}
+
+/* ----------------------------- delread~~ ----------------------------- */
+static t_class *delread_tilde_tilde_class;
+
+typedef struct _delread_tilde_tilde
+ {
+ t_object x_obj;
+ t_symbol *x_sym;
+ t_float x_fine;
+ double x_deltime; /* delay in msec */
+ int x_delsamps; /* delay in samples */
+ t_float x_sr; /* samples per msec */
+ t_float x_n; /* vector size */
+ int x_zerodel; /* 0 or vecsize depending on read/write order */
+ } t_delread_tilde_tilde;
+
+static void delread_tilde_tilde_list(t_delread_tilde_tilde *x, t_symbol *s, int ac, t_atom *av);
+
+static void *delread_tilde_tilde_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_symbol *delname;
+ t_delread_tilde_tilde *x = (t_delread_tilde_tilde *)pd_new(delread_tilde_tilde_class);
+
+ if((ac > 0) && IS_A_SYMBOL(av, 0))
+ delname = atom_getsymbolarg(0, ac, av);
+ else
+ delname = &s_;
+ x->x_sym = delname;
+ x->x_sr = 1;
+ x->x_n = 1;
+ x->x_zerodel = 0;
+ delread_tilde_tilde_list(x, &s_list, ac-1, av+1);
+ floatinlet_new(&x->x_obj, &x->x_fine);
+ outlet_new(&x->x_obj, &s_signal);
+ return (x);
+}
+
+static void delread_tilde_tilde_list(t_delread_tilde_tilde *x, t_symbol *s, int ac, t_atom *av)
+{
+ t_float coarse, fine;
+ t_delwrite_tilde_tilde *delwriter = (t_delwrite_tilde_tilde *)pd_findbyclass(x->x_sym, delwrite_tilde_tilde_class);
+
+ if((ac > 0) && (IS_A_FLOAT(av, 0)))
+ coarse = atom_getfloatarg(0, ac, av);
+ else
+ coarse = 0.0;
+ if((ac > 1) && (IS_A_FLOAT(av, 1)))
+ fine = atom_getfloatarg(1, ac, av);
+ else
+ fine = 0.0;
+ x->x_deltime = iem_dp_calc_sum(coarse, fine);
+ if(delwriter)
+ {
+ int delsize = delwriter->x_cspace.c_n;
+
+ x->x_delsamps = (int)(0.5 + (double)x->x_sr * x->x_deltime) + x->x_n - x->x_zerodel;
+ if(x->x_delsamps < x->x_n)
+ x->x_delsamps = x->x_n;
+ else if(x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS_TT)
+ x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS_TT;
+ }
+}
+
+static void delread_tilde_tilde_double(t_delread_tilde_tilde *x, double d)
+{
+ t_delwrite_tilde_tilde *delwriter = (t_delwrite_tilde_tilde *)pd_findbyclass(x->x_sym, delwrite_tilde_tilde_class);
+
+ x->x_deltime = d;
+ if(delwriter)
+ {
+ int delsize = delwriter->x_cspace.c_n;
+
+ x->x_delsamps = (int)(0.5 + (double)x->x_sr * x->x_deltime) + x->x_n - x->x_zerodel;
+ if(x->x_delsamps < x->x_n)
+ x->x_delsamps = x->x_n;
+ else if(x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS_TT)
+ x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS_TT;
+ }
+}
+
+static void delread_tilde_tilde_float(t_delread_tilde_tilde *x, t_float coarse)
+{
+ t_delwrite_tilde_tilde *delwriter = (t_delwrite_tilde_tilde *)pd_findbyclass(x->x_sym, delwrite_tilde_tilde_class);
+
+ x->x_deltime = iem_dp_calc_sum(coarse, x->x_fine);
+ if(delwriter)
+ {
+ int delsize = delwriter->x_cspace.c_n;
+
+ x->x_delsamps = (int)(0.5 + (double)x->x_sr * x->x_deltime) + x->x_n - x->x_zerodel;
+ if(x->x_delsamps < x->x_n)
+ x->x_delsamps = x->x_n;
+ else if(x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS_TT)
+ x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS_TT;
+ }
+}
+
+static t_int *delread_tilde_tilde_perform(t_int *w)
+{
+ t_sample *out = (t_float *)(w[1]);
+ t_delwrite_tilde_tilde_ctl *c = (t_delwrite_tilde_tilde_ctl *)(w[2]);
+ int delsamps = *(int *)(w[3]);
+ int n = (int)(w[4]);
+ int phase = c->c_phase - delsamps, nsamps = c->c_n;
+ t_sample *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS_TT);
+
+ if(phase < 0)
+ phase += nsamps;
+ bp = vp + phase;
+ while(n--)
+ {
+ *out++ = *bp++;
+ if(bp == ep)
+ bp -= nsamps;
+ }
+ return (w+5);
+}
+
+static void delread_tilde_tilde_dsp(t_delread_tilde_tilde *x, t_signal **sp)
+{
+ t_delwrite_tilde_tilde *delwriter = (t_delwrite_tilde_tilde *)pd_findbyclass(x->x_sym, delwrite_tilde_tilde_class);
+ x->x_sr = sp[0]->s_sr * 0.001;
+ x->x_n = sp[0]->s_n;
+ if(delwriter)
+ {
+ delwrite_tilde_tilde_checkvecsize(delwriter, sp[0]->s_n);
+ x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
+ 0 : delwriter->x_vecsize);
+ delread_tilde_tilde_double(x, x->x_deltime);
+ dsp_add(delread_tilde_tilde_perform, 4,
+ sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n);
+ }
+ else if (*x->x_sym->s_name)
+ error("delread~~: %s: no such delwrite~~",x->x_sym->s_name);
+}
+
+static void delread_tilde_tilde_setup(void)
+{
+ delread_tilde_tilde_class = class_new(gensym("delread~~"),
+ (t_newmethod)delread_tilde_tilde_new, 0,
+ sizeof(t_delread_tilde_tilde), 0, A_GIMME, 0);
+ class_addmethod(delread_tilde_tilde_class, (t_method)delread_tilde_tilde_dsp,
+ gensym("dsp"), 0);
+ class_addfloat(delread_tilde_tilde_class, (t_method)delread_tilde_tilde_float);
+}
+
+/* ----------------------------- vd~~ ----------------------------- */
+static t_class *vd_tilde_tilde_class;
+
+typedef struct _vd_tilde_tilde
+ {
+ t_object x_obj;
+ t_symbol *x_sym;
+ t_float x_sr; /* samples per msec */
+ int x_zerodel; /* 0 or vecsize depending on read/write order */
+ t_float x_f;
+ } t_vd_tilde_tilde;
+
+static void *vd_tilde_tilde_new(t_symbol *s)
+{
+ t_vd_tilde_tilde *x = (t_vd_tilde_tilde *)pd_new(vd_tilde_tilde_class);
+
+ if(!*s->s_name)
+ s = gensym("vd~~");
+ x->x_sym = s;
+ x->x_sr = 1;
+ x->x_zerodel = 0;
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *vd_tilde_tilde_perform(t_int *w)
+{
+ t_sample *cin = (t_sample *)(w[1]);
+ t_sample *fin = (t_sample *)(w[2]);
+ t_sample *out = (t_sample *)(w[3]);
+ t_delwrite_tilde_tilde_ctl *ctl = (t_delwrite_tilde_tilde_ctl *)(w[4]);
+ t_vd_tilde_tilde *x = (t_vd_tilde_tilde *)(w[5]);
+ int n = (int)(w[6]);
+
+ int nsamps = ctl->c_n;
+ double limit = (double)nsamps - (double)n - 1.0;
+ t_sample fn = n-1;
+ t_sample *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase;
+ t_sample zerodel = x->x_zerodel;
+ while (n--)
+ {
+ double delsamps = (double)x->x_sr * iem_dp_calc_sum(*cin++, *fin++) - (double)zerodel;
+ t_sample frac;
+ int idelsamps;
+ t_sample a, b, c, d, cminusb;
+
+ if(delsamps < 1.00001)
+ delsamps = 1.00001;
+ if(delsamps > limit)
+ delsamps = limit;
+ delsamps += (double)fn;
+ fn = fn - 1.0f;
+ idelsamps = (int)delsamps;
+ frac = (t_sample)(delsamps - (double)idelsamps);
+ bp = wp - idelsamps;
+ if(bp < vp + 4)
+ bp += nsamps;
+ d = bp[-3];
+ c = bp[-2];
+ b = bp[-1];
+ a = bp[0];
+ cminusb = c - b;
+ *out++ = b + frac * ( cminusb - 0.1666667f * (1.-frac) *
+ ( (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b) ) );
+ }
+ return (w+7);
+}
+
+static void vd_tilde_tilde_dsp(t_vd_tilde_tilde *x, t_signal **sp)
+{
+ t_delwrite_tilde_tilde *delwriter = (t_delwrite_tilde_tilde *)pd_findbyclass(x->x_sym, delwrite_tilde_tilde_class);
+ x->x_sr = sp[0]->s_sr * 0.001;
+ if(delwriter)
+ {
+ delwrite_tilde_tilde_checkvecsize(delwriter, sp[0]->s_n);
+ x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
+ 0 : delwriter->x_vecsize);
+ dsp_add(vd_tilde_tilde_perform, 6, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec,
+ &delwriter->x_cspace, x, sp[0]->s_n);
+ }
+ else
+ error("vd~~: %s: no such delwrite~~", x->x_sym->s_name);
+}
+
+static void vd_tilde_tilde_setup(void)
+{
+ vd_tilde_tilde_class = class_new(gensym("vd~~"), (t_newmethod)vd_tilde_tilde_new, 0,
+ sizeof(t_vd_tilde_tilde), 0, A_DEFSYM, 0);
+ class_addmethod(vd_tilde_tilde_class, (t_method)vd_tilde_tilde_dsp, gensym("dsp"), 0);
+ CLASS_MAINSIGNALIN(vd_tilde_tilde_class, t_vd_tilde_tilde, x_f);
+}
+
+/********************/
+
+void delay_tilde_tilde_setup(void)
+{
+ delwrite_tilde_tilde_setup();
+ delread_tilde_tilde_setup();
+ vd_tilde_tilde_setup();
+} \ No newline at end of file
diff --git a/src/div__.c b/src/div__.c
new file mode 100755
index 0000000..769187b
--- /dev/null
+++ b/src/div__.c
@@ -0,0 +1,79 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* ------------------------ div__ or /__ ---------------------------- */
+/* based on miller's /, which is part of pd, only with double precision */
+
+static t_class *div___class;
+
+typedef struct _div__
+{
+ t_object x_obj;
+ t_float x_coarse_left;
+ t_float x_fine_left;
+ t_float x_coarse_right;
+ t_float x_fine_right;
+ t_outlet *x_out_coarse;
+ t_outlet *x_out_fine;
+} t_div__;
+
+static void div___bang(t_div__ *x)
+{
+ double ddiv, nom;
+ t_float fdiv;
+
+ nom = iem_dp_calc_sum(x->x_coarse_right, x->x_fine_right);
+ ddiv = (nom ? iem_dp_calc_sum(x->x_coarse_left, x->x_fine_left) / nom : 0);
+ fdiv = (t_float)ddiv;
+ outlet_float(x->x_out_fine, iem_dp_calc_residual(ddiv, fdiv));
+ outlet_float(x->x_out_coarse, fdiv);
+}
+
+static void div___float(t_div__ *x, t_floatarg f)
+{
+ x->x_coarse_left = f;
+ div___bang(x);
+}
+
+static void *div___new(t_symbol *s, int ac, t_atom *av)
+{
+ t_div__ *x = (t_div__ *)pd_new(div___class);
+
+ floatinlet_new(&x->x_obj, &x->x_fine_left);
+ floatinlet_new(&x->x_obj, &x->x_coarse_right);
+ floatinlet_new(&x->x_obj, &x->x_fine_right);
+ x->x_coarse_left = 0.0f;
+ x->x_fine_left = 0.0f;
+ if((ac > 0) && (IS_A_FLOAT(av, 0)))
+ x->x_coarse_right = atom_getfloatarg(0, ac, av);
+ else
+ x->x_coarse_right = 0.0f;
+ if((ac > 1) && (IS_A_FLOAT(av, 1)))
+ x->x_fine_right = atom_getfloatarg(1, ac, av);
+ else
+ x->x_fine_right = 0.0f;
+ x->x_out_coarse = outlet_new(&x->x_obj, &s_float);
+ x->x_out_fine = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void div___free(t_div__ *x)
+{
+}
+
+void div___setup(void)
+{
+ div___class = class_new(gensym("div__"), (t_newmethod)div___new, 0, sizeof(t_div__), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)div___new, gensym("/__"), A_GIMME, 0);
+ class_addcreator((t_newmethod)div___new, gensym("/''"), A_GIMME, 0);
+ class_addbang(div___class, div___bang);
+ class_addfloat(div___class, div___float);
+}
diff --git a/src/div~~.c b/src/div~~.c
new file mode 100755
index 0000000..07a7b68
--- /dev/null
+++ b/src/div~~.c
@@ -0,0 +1,321 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* -------------------------- div~~ ------------------------------ */
+/* based on miller's /~ which is part of pd */
+
+static t_class *div_tilde_tilde_class, *scalardiv_tilde_tilde_class;
+
+typedef struct _div_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_in2_coarse;
+ t_sample *x_in2_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+} t_div_tilde_tilde;
+
+typedef struct _scalardiv_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+ t_sample x_in2_coarse;
+ t_sample x_in2_fine;
+} t_scalardiv_tilde_tilde;
+
+static void *div_tilde_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+ if(((argc==1)&&(argv->a_type == A_FLOAT))||(argc>=2)&&(argv->a_type == A_FLOAT)&&((argv+1)->a_type == A_FLOAT))
+ {
+ t_scalardiv_tilde_tilde *x = (t_scalardiv_tilde_tilde *)pd_new(scalardiv_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ floatinlet_new(&x->x_obj, &x->x_in2_coarse);
+ floatinlet_new(&x->x_obj, &x->x_in2_fine);
+ x->x_in2_coarse = atom_getfloatarg(0, argc, argv);
+ if(argc>=2)
+ x->x_in2_fine = atom_getfloatarg(1, argc, argv);
+ else
+ x->x_in2_fine = 0;
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+ else /* either no arguments or symbols */
+ {
+ t_div_tilde_tilde *x = (t_div_tilde_tilde *)pd_new(div_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+}
+
+static t_int *div_tilde_tilde_perform(t_int *w)
+{
+ t_div_tilde_tilde *x = (t_div_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double d, nom;
+ t_float f;
+
+ while(n--)
+ {
+ nom = iem_dp_calc_sum(*in2c++, *in2f++);
+ d = (nom ? iem_dp_calc_sum(*in1c++, *in1f++) / nom : 0);
+ f = iem_dp_cast_to_float(d);
+ *outf++ = iem_dp_calc_residual(d, f);
+ *outc++ = f;
+ }
+ return(w+3);
+}
+
+static t_int *div_tilde_tilde_perf8(t_int *w)
+{
+ t_div_tilde_tilde *x = (t_div_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+
+ for(; n; n -= 8, in1c += 8, in1f += 8, in2c += 8, in2f += 8, outc += 8, outf += 8)
+ {
+ double d, nom;
+ t_float f;
+
+ nom = iem_dp_calc_sum(in2c[0], in2f[0]);
+ d = (nom ? iem_dp_calc_sum(in1c[0], in1f[0]) / nom : 0);
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ nom = iem_dp_calc_sum(in2c[1], in2f[1]);
+ d = (nom ? iem_dp_calc_sum(in1c[1], in1f[1]) / nom : 0);
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ nom = iem_dp_calc_sum(in2c[2], in2f[2]);
+ d = (nom ? iem_dp_calc_sum(in1c[2], in1f[2]) / nom : 0);
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ nom = iem_dp_calc_sum(in2c[3], in2f[3]);
+ d = (nom ? iem_dp_calc_sum(in1c[3], in1f[3]) / nom : 0);
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ nom = iem_dp_calc_sum(in2c[4], in2f[4]);
+ d = (nom ? iem_dp_calc_sum(in1c[4], in1f[4]) / nom : 0);
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ nom = iem_dp_calc_sum(in2c[5], in2f[5]);
+ d = (nom ? iem_dp_calc_sum(in1c[5], in1f[5]) / nom : 0);
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ nom = iem_dp_calc_sum(in2c[6], in2f[6]);
+ d = (nom ? iem_dp_calc_sum(in1c[6], in1f[6]) / nom : 0);
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ nom = iem_dp_calc_sum(in2c[7], in2f[7]);
+ d = (nom ? iem_dp_calc_sum(in1c[7], in1f[7]) / nom : 0);
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static t_int *scalardiv_tilde_tilde_perform(t_int *w)
+{
+ t_scalardiv_tilde_tilde *x = (t_scalardiv_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *inc = x->x_in1_coarse;
+ t_sample *inf = x->x_in1_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double d, g=iem_dp_calc_sum(x->x_in2_coarse, x->x_in2_fine);
+ t_float f;
+
+ if(g)
+ {
+ double h=1.0/g;
+
+ while(n--)
+ {
+ d = iem_dp_calc_sum(*inc++, *inf++) * h;
+ f = iem_dp_cast_to_float(d);
+ *outf++ = iem_dp_calc_residual(d, f);
+ *outc++ = f;
+ }
+ }
+ else
+ {
+ while(n--)
+ {
+ *outf++ = 0;
+ *outc++ = 0;
+ }
+ }
+ return(w+3);
+}
+
+static t_int *scalardiv_tilde_tilde_perf8(t_int *w)
+{
+ t_scalardiv_tilde_tilde *x = (t_scalardiv_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *inc = x->x_in1_coarse;
+ t_sample *inf = x->x_in1_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double g=iem_dp_calc_sum(x->x_in2_coarse, x->x_in2_fine);
+
+ if(g)
+ {
+ double h=1.0/g;
+
+ for(; n; n -= 8, inc += 8, inf += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(inc[0], inf[0]) * h;
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(inc[1], inf[1]) * h;
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(inc[2], inf[2]) * h;
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(inc[3], inf[3]) * h;
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(inc[4], inf[4]) * h;
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(inc[5], inf[5]) * h;
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(inc[6], inf[6]) * h;
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(inc[7], inf[7]) * h;
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ }
+ else
+ {
+ for(; n; n -= 8, outc += 8, outf += 8)
+ {
+ outf[0] = 0;
+ outc[0] = 0;
+ outf[1] = 0;
+ outc[1] = 0;
+ outf[2] = 0;
+ outc[2] = 0;
+ outf[3] = 0;
+ outc[3] = 0;
+ outf[4] = 0;
+ outc[4] = 0;
+ outf[5] = 0;
+ outc[5] = 0;
+ outf[6] = 0;
+ outc[6] = 0;
+ outf[7] = 0;
+ outc[7] = 0;
+ }
+ }
+ return(w+3);
+}
+
+static void div_tilde_tilde_dsp(t_div_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_in2_coarse = sp[2]->s_vec;
+ x->x_in2_fine = sp[3]->s_vec;
+ x->x_out_coarse = sp[4]->s_vec;
+ x->x_out_fine = sp[5]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(div_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ else
+ dsp_add(div_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+}
+
+static void scalardiv_tilde_tilde_dsp(t_scalardiv_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_out_coarse = sp[2]->s_vec;
+ x->x_out_fine = sp[3]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(scalardiv_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ else
+ dsp_add(scalardiv_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+}
+
+void div_tilde_tilde_setup(void)
+{
+ div_tilde_tilde_class = class_new(gensym("/~~"), (t_newmethod)div_tilde_tilde_new, 0,
+ sizeof(t_div_tilde_tilde), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)div_tilde_tilde_new, gensym("div~~"), A_GIMME, 0);
+ CLASS_MAINSIGNALIN(div_tilde_tilde_class, t_div_tilde_tilde, x_f);
+ class_addmethod(div_tilde_tilde_class, (t_method)div_tilde_tilde_dsp, gensym("dsp"), 0);
+ scalardiv_tilde_tilde_class = class_new(gensym("/~~"), 0, 0,
+ sizeof(t_scalardiv_tilde_tilde), 0, 0);
+ CLASS_MAINSIGNALIN(scalardiv_tilde_tilde_class, t_scalardiv_tilde_tilde, x_f);
+ class_addmethod(scalardiv_tilde_tilde_class, (t_method)scalardiv_tilde_tilde_dsp, gensym("dsp"), 0);
+}
diff --git a/src/dptohex.c b/src/dptohex.c
new file mode 100755
index 0000000..0392fc4
--- /dev/null
+++ b/src/dptohex.c
@@ -0,0 +1,69 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2013 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* -------------------------- dptohex ------------------------------ */
+/* double float to 16 digits of hexadecimal converter */
+
+/* double float is only internal used */
+/* to transfer this value, we divide this double value into use one float casted value */
+/* and into the difference to the accurate double value. */
+
+/* double float (sign_1 + exp_12 + mant_51) */
+
+static t_class *dptohex_class;
+
+typedef struct _dptohex
+{
+ t_object x_obj;
+ t_float x_float_casted_value;
+ t_float x_residual;
+} t_dptohex;
+
+static void dptohex_bang(t_dptohex *x)
+{
+ char buf[100];
+ union tabfudge_d tf;
+
+ tf.tf_d = iem_dp_calc_sum(x->x_float_casted_value, x->x_residual);
+ sprintf(buf, "#%08X%08X", tf.tf_i[HIOFFSET], tf.tf_i[LOWOFFSET]);
+ outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
+}
+
+static void dptohex_float(t_dptohex *x, t_floatarg f)
+{
+ x->x_float_casted_value = f;
+ dptohex_bang(x);
+}
+
+static void *dptohex_new(void)
+{
+ t_dptohex *x = (t_dptohex *)pd_new(dptohex_class);
+
+ floatinlet_new(&x->x_obj, &x->x_residual);
+ x->x_float_casted_value = 0.0f;
+ x->x_residual = 0.0f;
+ outlet_new(&x->x_obj, &s_symbol);
+ return (x);
+}
+
+static void dptohex_free(t_dptohex *x)
+{
+}
+
+void dptohex_setup(void)
+{
+ dptohex_class = class_new(gensym("dptohex"),
+ (t_newmethod)dptohex_new, (t_method)dptohex_free, sizeof(t_dptohex), 0, 0);
+ class_addbang(dptohex_class, dptohex_bang);
+ class_addfloat(dptohex_class, dptohex_float);
+}
diff --git a/src/dptosym.c b/src/dptosym.c
new file mode 100755
index 0000000..058299f
--- /dev/null
+++ b/src/dptosym.c
@@ -0,0 +1,70 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* -------------------------- dptosym ------------------------------ */
+/* double float to symbol-string of a double value converter */
+
+/* double float is only internal used */
+/* to transfer this value, we divide this double value into use one float casted value */
+/* and into the difference to the accurate double value. */
+
+/* double float (sign_1 + exp_12 + mant_51) */
+
+static t_class *dptosym_class;
+
+typedef struct _dptosym
+{
+ t_object x_obj;
+ t_float x_float_casted_value;
+ t_float x_residual;
+ t_outlet *x_out_sym;
+ t_outlet *x_out_any;
+} t_dptosym;
+
+static void dptosym_bang(t_dptosym *x)
+{
+ char buf[100];
+ double d=iem_dp_calc_sum(x->x_float_casted_value, x->x_residual);
+ t_atom at_dummy;
+
+ sprintf(buf, "\"%.18g", d);
+ outlet_anything(x->x_out_any, gensym(buf), 0, &at_dummy);
+ outlet_symbol(x->x_out_sym, gensym(buf+1));
+}
+
+static void dptosym_float(t_dptosym *x, t_floatarg f)
+{
+ x->x_float_casted_value = f;
+// post("dptosym float float: %.12g + %.12g", x->x_float_casted_value, x->x_residual);
+ dptosym_bang(x);
+}
+
+static void *dptosym_new(void)
+{
+ t_dptosym *x = (t_dptosym *)pd_new(dptosym_class);
+
+ floatinlet_new(&x->x_obj, &x->x_residual);
+ x->x_float_casted_value = 0.0f;
+ x->x_residual = 0.0f;
+ x->x_out_sym = outlet_new(&x->x_obj, &s_symbol);
+ x->x_out_any = outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void dptosym_setup(void)
+{
+ dptosym_class = class_new(gensym("dptosym"),
+ (t_newmethod)dptosym_new, 0, sizeof(t_dptosym), 0, 0);
+ class_addbang(dptosym_class, dptosym_bang);
+ class_addfloat(dptosym_class, dptosym_float);
+}
diff --git a/src/ftohex.c b/src/ftohex.c
new file mode 100755
index 0000000..62cde68
--- /dev/null
+++ b/src/ftohex.c
@@ -0,0 +1,49 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* -------------------------- ftohex ------------------------------ */
+/* float to 8 digits of hexadecimal converter */
+
+/* float (sign_1 + exp_8 + mant_23) */
+
+
+static t_class *ftohex_class;
+
+typedef struct _ftohex
+{
+ t_object x_obj;
+} t_ftohex;
+
+static void ftohex_float(t_ftohex *x, t_floatarg f)
+{
+ char buf[100];
+ union tabfudge_f tf;
+
+ tf.tf_f = f;
+ sprintf(buf, "#%08X", (unsigned int)tf.tf_l);
+ outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
+}
+
+static void *ftohex_new(void)
+{
+ t_ftohex *x = (t_ftohex *)pd_new(ftohex_class);
+ outlet_new(&x->x_obj, &s_symbol);
+ return (x);
+}
+
+void ftohex_setup(void)
+{
+ ftohex_class = class_new(gensym("ftohex"),
+ (t_newmethod)ftohex_new, 0, sizeof(t_ftohex), 0, 0);
+ class_addfloat(ftohex_class, ftohex_float);
+}
diff --git a/src/iem_dp.c b/src/iem_dp.c
new file mode 100755
index 0000000..5b238b2
--- /dev/null
+++ b/src/iem_dp.c
@@ -0,0 +1,127 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+ * iem_dp written by IOhannes m zmoelnig, Thomas Musil,
+ * Copyright (c) IEM KUG Graz Austria 2000 - 2008 */
+
+/* iem_dp means double precision, it is a library of external pd objects */
+/* which deal with array access and delay lines */
+/* the way how objects comunicate with other objects in double precision is, */
+/* to send two values on two different outputs to two different inputs */
+/* one value is the float casted value of the original double value */
+/* the other value is the difference in double of the original minus the float casted value */
+/* the receiving inlets only cast them to double and add them */
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+
+//static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
+
+t_float iem_dp_cast_to_float(double d)
+{
+ return((t_float)d);
+}
+
+double iem_dp_cast_to_double(t_float f)
+{
+ return((double)f);
+}
+
+t_float iem_dp_calc_residual(double d, t_float f)
+{
+ return(iem_dp_cast_to_float(d - iem_dp_cast_to_double(f)));
+}
+
+double iem_dp_calc_sum(t_float f, t_float r)
+{
+ return(iem_dp_cast_to_double(f) + iem_dp_cast_to_double(r));
+}
+
+static t_class *iem_dp_class;
+
+static void *iem_dp_new(void)
+{
+ t_object *x = (t_object *)pd_new(iem_dp_class);
+
+ return (x);
+}
+
+
+void ftohex_setup(void);
+void symtodp_setup(void);
+void dptosym_setup(void);
+void dptohex_setup(void);
+void vline_tilde_tilde_setup(void);
+void samphold_tilde_tilde_setup(void);
+void wrap_tilde_tilde_setup(void);
+void phasor_tilde_tilde_setup(void);
+void print_tilde_tilde_setup(void);
+void add___setup(void);
+void sub___setup(void);
+void mul___setup(void);
+void div___setup(void);
+void add_tilde_tilde_setup(void);
+void sub_tilde_tilde_setup(void);
+void mul_tilde_tilde_setup(void);
+void div_tilde_tilde_setup(void);
+void tabwrite_dp_setup(void);
+void tabread_dp_setup(void);
+void tabread4_dp_setup(void);
+void tabwrite_tilde_tilde_setup(void);
+void tabread_tilde_tilde_setup(void);
+void tabread4_tilde_tilde_setup(void);
+void max_dp_setup(void);
+void min_dp_setup(void);
+void max_tilde_tilde_setup(void);
+void min_tilde_tilde_setup(void);
+void random_dp_setup(void);
+void delay_tilde_tilde_setup(void);
+//void listtodp_setup(void);
+//void dqnsymtodp_setup(void);
+//void dptodqnsym_setup(void);
+
+/* ------------------------ setup routine ------------------------- */
+
+void iem_dp_setup(void)
+{
+ iem_dp_class = class_new(gensym("iem_dp"), iem_dp_new, 0,
+ sizeof(t_object), CLASS_NOINLET, 0);
+
+ ftohex_setup();
+ symtodp_setup();
+ dptosym_setup();
+ dptohex_setup();
+ vline_tilde_tilde_setup();
+ samphold_tilde_tilde_setup();
+ wrap_tilde_tilde_setup();
+ phasor_tilde_tilde_setup();
+ print_tilde_tilde_setup();
+ add___setup();
+ sub___setup();
+ mul___setup();
+ div___setup();
+ add_tilde_tilde_setup();
+ sub_tilde_tilde_setup();
+ mul_tilde_tilde_setup();
+ div_tilde_tilde_setup();
+ tabwrite_dp_setup();
+ tabread_dp_setup();
+ tabread4_dp_setup();
+ tabwrite_tilde_tilde_setup();
+ tabread_tilde_tilde_setup();
+ tabread4_tilde_tilde_setup();
+ max_dp_setup();
+ min_dp_setup();
+ max_tilde_tilde_setup();
+ min_tilde_tilde_setup();
+ random_dp_setup();
+ delay_tilde_tilde_setup();
+// listtodp_setup();
+// dqnsymtodp_setup();
+// dptodqnsym_setup();
+
+ post("iem_dp (R-1.19) library loaded! (c) IOhannes m zmoelnig, Thomas Musil 06.2013");
+ post(" zmoelnig%ciem.at iem KUG Graz Austria", '@');
+ post(" musil%ciem.at iem KUG Graz Austria", '@');
+}
diff --git a/src/iem_dp.h b/src/iem_dp.h
new file mode 100755
index 0000000..18789d2
--- /dev/null
+++ b/src/iem_dp.h
@@ -0,0 +1,49 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2013 */
+/* double precision library */
+
+#ifndef __IEM_DP_H__
+#define __IEM_DP_H__
+
+/* #ifdef __i386__ */
+
+/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */
+
+/*
+#define PD_BIGORSMALL(f) ((((*(unsigned int*)&(f))&0x60000000)==0) || \
+ (((*(unsigned int*)&(f))&0x60000000)==0x60000000))
+#else
+#define PD_BIGORSMALL(f) 0
+#endif
+
+#endif
+*/
+
+t_float iem_dp_cast_to_float(double d);
+double iem_dp_cast_to_double(t_float f);
+t_float iem_dp_calc_residual(double d, t_float f);
+
+double iem_dp_calc_sum(t_float f, t_float r);
+
+extern int ugen_getsortno(void);
+
+#endif
+
+/*
+#ifdef Z_USE_WORD_ARRAYS
+
+#define zarray_t t_word
+#define zarray_getarray garray_getfloatwords
+#define zarray_getfloat(pointer, index) (pointer[index].w_float)
+#define zarray_setfloat(pointer, index, value) (pointer[index].w_float = value)
+
+#else
+
+#define zarray_t t_float
+#define zarray_getarray garray_getfloatarray
+#define zarray_getfloat(pointer, index) (pointer[index])
+#define zarray_setfloat(pointer, index, value) (pointer[index] = value)
+
+#endif*/
diff --git a/src/iemlib.h b/src/iemlib.h
new file mode 100644
index 0000000..b2718fa
--- /dev/null
+++ b/src/iemlib.h
@@ -0,0 +1,115 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2011 */
+
+#ifndef __IEMLIB_H__
+#define __IEMLIB_H__
+
+
+#define IS_A_POINTER(atom,index) ((atom+index)->a_type == A_POINTER)
+#define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT)
+#define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL)
+#define IS_A_DOLLAR(atom,index) ((atom+index)->a_type == A_DOLLAR)
+#define IS_A_DOLLSYM(atom,index) ((atom+index)->a_type == A_DOLLSYM)
+#define IS_A_SEMI(atom,index) ((atom+index)->a_type == A_SEMI)
+#define IS_A_COMMA(atom,index) ((atom+index)->a_type == A_COMMA)
+
+/* now miller's code starts :
+ for 4 point interpolation
+ for lookup tables
+ for denormal floats
+ */
+
+#ifdef MSW
+int sys_noloadbang;
+//t_symbol *iemgui_key_sym=0;
+#include <io.h>
+#else
+extern int sys_noloadbang;
+//extern t_symbol *iemgui_key_sym;
+#include <unistd.h>
+#endif
+
+#define DEFDELVS 64
+#define XTRASAMPS 4
+#define SAMPBLK 4
+
+#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
+
+ /* machine-dependent definitions. These ifdefs really
+ should have been by CPU type and not by operating system! */
+#ifdef IRIX
+ /* big-endian. Most significant byte is at low address in memory */
+#define HIOFFSET 0 /* word offset to find MSB */
+#define LOWOFFSET 1 /* word offset to find LSB */
+#define int32 long /* a data type that has 32 bits */
+#endif /* IRIX */
+
+#ifdef MSW
+ /* little-endian; most significant byte is at highest address */
+#define HIOFFSET 1
+#define LOWOFFSET 0
+#define int32 long
+#endif /* MSW */
+
+#if defined(__FreeBSD__) || defined(__APPLE__)
+#include <machine/endian.h>
+#endif
+
+#ifdef __linux__
+#include <endian.h>
+#endif
+
+#if defined(__unix__) || defined(__APPLE__)
+#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN)
+#error No byte order defined
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define HIOFFSET 1
+#define LOWOFFSET 0
+#else
+#define HIOFFSET 0 /* word offset to find MSB */
+#define LOWOFFSET 1 /* word offset to find LSB */
+#endif /* __BYTE_ORDER */
+#include <sys/types.h>
+#define int32 int32_t
+#endif /* __unix__ or __APPLE__*/
+
+union tabfudge_d
+{
+ double tf_d;
+ int32 tf_i[2];
+};
+
+union tabfudge_f
+{
+ float tf_f;
+ long tf_l;
+};
+
+#if defined __i386__ || defined __x86_64__
+#define IEM_DENORMAL(f) ((((*(unsigned int*)&(f))&0x60000000)==0) || \
+(((*(unsigned int*)&(f))&0x60000000)==0x60000000))
+/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */
+#else
+
+#define IEM_DENORMAL(f) 0
+
+#endif
+
+/* on 64bit systems we cannot use garray_getfloatarray... */
+#if ((defined PD_MAJOR_VERSION && defined PD_MINOR_VERSION) && (PD_MAJOR_VERSION > 0 || PD_MINOR_VERSION > 40))
+# define iemarray_t t_word
+# define iemarray_getarray garray_getfloatwords
+# define iemarray_getfloat(pointer, index) (pointer[index].w_float)
+# define iemarray_setfloat(pointer, index, fvalue) (pointer[index].w_float = fvalue)
+#else
+# define iemarray_t t_float
+# define iemarray_getarray garray_getfloatarray
+# define iemarray_getfloat(pointer, index) (pointer[index])
+# define iemarray_setfloat(pointer, index, fvalue) (pointer[index] = fvalue)
+#endif
+
+#endif
diff --git a/src/makefile_d_fat b/src/makefile_d_fat
new file mode 100755
index 0000000..06fa3e9
--- /dev/null
+++ b/src/makefile_d_fat
@@ -0,0 +1,71 @@
+current: all
+
+.SUFFIXES: .d_fat
+
+PD_INSTALL_PATH ?= "/Applications/Pd.app/Contents/Resources"
+
+INCLUDE = -I. -I$(PD_INSTALL_PATH)/src
+
+CFLAGS =-DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \
+ -Wno-unused -Wno-parentheses -Wno-switch -fPIC
+
+LFLAGS = -bundle -undefined suppress -flat_namespace
+
+# the sources
+
+SRC = symtodp.c \
+ dptosym.c \
+ dptohex.c \
+ ftohex.c \
+ vline~~.c \
+ samphold~~.c \
+ wrap~~.c \
+ phasor~~.c \
+ print~~.c \
+ add__.c \
+ sub__.c \
+ mul__.c \
+ div__.c \
+ add~~.c \
+ sub~~.c \
+ mul~~.c \
+ div~~.c \
+ tabwrite_dp.c \
+ tabread_dp.c \
+ tabread4_dp.c \
+ tabwrite~~.c \
+ tabread~~.c \
+ tabread4~~.c \
+ max__.c \
+ min__.c \
+ max~~.c \
+ min~~.c \
+ random__.c \
+ delay~~.c \
+ iem_dp.c
+
+TARGET = iem_dp.d_fat
+
+
+OBJ = $(SRC:.c=.o)
+
+#
+# ------------------ targets ------------------------------------
+#
+
+clean:
+ rm ../$(TARGET)
+ rm *.o
+
+all: $(OBJ)
+ @echo :: $(OBJ)
+ $(CC) -arch i386 -arch ppc $(LFLAGS) -o $(TARGET) *.o
+ strip -S -x $(TARGET)
+ mv $(TARGET) ..
+
+$(OBJ) : %.o : %.c
+ $(CC) -arch i386 -arch ppc $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c
+
+
+
+
diff --git a/src/makefile_d_ppc b/src/makefile_d_ppc
new file mode 100755
index 0000000..4d66bde
--- /dev/null
+++ b/src/makefile_d_ppc
@@ -0,0 +1,72 @@
+current: all
+
+.SUFFIXES: .d_ppc
+
+PD_INSTALL_PATH = "/Applications/Pd.app/Contents/Resources"
+
+INCLUDE = -I. -I$(PD_INSTALL_PATH)/src
+
+CFLAGS =-DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \
+ -Wno-unused -Wno-parentheses -Wno-switch
+
+LFLAGS = -bundle -undefined suppress -flat_namespace
+
+# the sources
+
+SRC = symtodp.c \
+ dptosym.c \
+ dptohex.c \
+ ftohex.c \
+ vline~~.c \
+ samphold~~.c \
+ wrap~~.c \
+ phasor~~.c \
+ print~~.c \
+ add__.c \
+ sub__.c \
+ mul__.c \
+ div__.c \
+ add~~.c \
+ sub~~.c \
+ mul~~.c \
+ div~~.c \
+ tabwrite_dp.c \
+ tabread_dp.c \
+ tabread4_dp.c \
+ tabwrite~~.c \
+ tabread~~.c \
+ tabread4~~.c \
+ max__.c \
+ min__.c \
+ max~~.c \
+ min~~.c \
+ random__.c \
+ delay~~.c \
+ iem_dp.c
+
+TARGET = iem_dp.d_ppc
+
+
+OBJ = $(SRC:.c=.o)
+
+#
+# ------------------ targets ------------------------------------
+#
+
+clean:
+ rm ../$(TARGET)
+ rm *.o
+
+all: $(OBJ)
+ @echo :: $(OBJ)
+ $(CC) $(LFLAGS) -o $(TARGET) *.o
+ strip -S -x $(TARGET)
+ mv $(TARGET) ..
+
+$(OBJ) : %.o : %.c
+ touch $*.c
+ $(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c
+
+
+
+
diff --git a/src/makefile_darwin b/src/makefile_darwin
new file mode 100755
index 0000000..740af11
--- /dev/null
+++ b/src/makefile_darwin
@@ -0,0 +1,77 @@
+current: all
+
+.SUFFIXES: .pd_darwin
+
+PD_INSTALL_PATH = "/Applications/Pd.app/Contents/Resources"
+
+INCLUDE = -I. -I$(PD_INSTALL_PATH)/src
+
+LIB = -ldl -lm -lpthread
+
+CFLAGS = -DPD -DUNIX -g -Wall -W -Werror -Wno-unused \
+ -Wno-parentheses -Wno-switch -O2 -fno-strict-aliasing \
+ $(INCLUDE) $(UCFLAGS) $(AFLAGS) \
+
+MACOSXLINKFLAGS = -bundle -bundle_loader $(PD_INSTALL_PATH)/bin/pd
+
+SYSTEM = $(shell uname -m)
+
+# the sources
+
+SRC = symtodp.c \
+ dptosym.c \
+ dptohex.c \
+ ftohex.c \
+ vline~~.c \
+ samphold~~.c \
+ wrap~~.c \
+ phasor~~.c \
+ print~~.c \
+ add__.c \
+ sub__.c \
+ mul__.c \
+ div__.c \
+ add~~.c \
+ sub~~.c \
+ mul~~.c \
+ div~~.c \
+ tabwrite_dp.c \
+ tabread_dp.c \
+ tabread4_dp.c \
+ tabwrite~~.c \
+ tabread~~.c \
+ tabread4~~.c \
+ max__.c \
+ min__.c \
+ max~~.c \
+ min~~.c \
+ random__.c \
+ delay~~.c \
+ iem_dp.c
+
+TARGET = iem_dp.pd_darwin
+
+
+OBJ = $(SRC:.c=.o)
+
+#
+# ------------------ targets ------------------------------------
+#
+
+clean:
+ rm ../$(TARGET)
+ rm *.o
+
+all: $(OBJ)
+ @echo :: $(OBJ)
+ $(CC) $(MACOSXLINKFLAGS) -o $(TARGET) *.o $(LIB)
+ strip -S -x $(TARGET)
+ mv $(TARGET) ..
+
+$(OBJ) : %.o : %.c
+ touch $*.c
+ $(CC) $(CFLAGS) -DPD $(INCLUDE) -c -o $*.o $*.c
+
+
+
+
diff --git a/src/makefile_linux b/src/makefile_linux
new file mode 100755
index 0000000..14c495a
--- /dev/null
+++ b/src/makefile_linux
@@ -0,0 +1,75 @@
+current: all
+
+.SUFFIXES: .pd_linux
+
+INCLUDE = -I. -I/usr/local/src/pd/src
+
+LDFLAGS = -export-dynamic -shared
+LIB = -ldl -lm -lpthread
+
+#select either the DBG and OPT compiler flags below:
+
+CFLAGS = -DPD -DUNIX -W -Werror -Wno-unused \
+ -Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer -fno-strict-aliasing \
+ -DDL_OPEN -fPIC
+
+SYSTEM = $(shell uname -m)
+
+# the sources
+
+SRC = symtodp.c \
+ dptosym.c \
+ dptohex.c \
+ ftohex.c \
+ vline~~.c \
+ samphold~~.c \
+ wrap~~.c \
+ phasor~~.c \
+ print~~.c \
+ add__.c \
+ sub__.c \
+ mul__.c \
+ div__.c \
+ add~~.c \
+ sub~~.c \
+ mul~~.c \
+ div~~.c \
+ tabwrite_dp.c \
+ tabread_dp.c \
+ tabread4_dp.c \
+ tabwrite~~.c \
+ tabread~~.c \
+ tabread4~~.c \
+ max__.c \
+ min__.c \
+ max~~.c \
+ min~~.c \
+ random__.c \
+ delay~~.c \
+ iem_dp.c
+
+TARGET = iem_dp.pd_linux
+
+
+OBJ = $(SRC:.c=.o)
+
+#
+# ------------------ targets ------------------------------------
+#
+
+clean:
+ rm ../$(TARGET)
+ rm *.o
+
+all: $(OBJ)
+ @echo :: $(OBJ)
+ $(LD) $(LDFLAGS) -o $(TARGET) *.o $(LIB)
+ strip --strip-unneeded $(TARGET)
+ mv $(TARGET) ..
+
+$(OBJ) : %.o : %.c
+ $(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c
+
+
+
+
diff --git a/src/max__.c b/src/max__.c
new file mode 100755
index 0000000..6ce2125
--- /dev/null
+++ b/src/max__.c
@@ -0,0 +1,80 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* ------------------------ max_dp ---------------------------- */
+/* based on miller's max, which is part of pd, only with double precision */
+
+static t_class *max_dp_class;
+
+typedef struct _max_dp
+{
+ t_object x_obj;
+ t_float x_coarse_left;
+ t_float x_fine_left;
+ t_float x_coarse_right;
+ t_float x_fine_right;
+ t_outlet *x_out_coarse;
+ t_outlet *x_out_fine;
+} t_max_dp;
+
+static void max_dp_bang(t_max_dp *x)
+{
+ double dleft, dright;
+
+ dleft = iem_dp_calc_sum(x->x_coarse_left, x->x_fine_left);
+ dright = iem_dp_calc_sum(x->x_coarse_right, x->x_fine_right);
+ if(dleft > dright)
+ {
+ outlet_float(x->x_out_fine, x->x_fine_left);
+ outlet_float(x->x_out_coarse, x->x_coarse_left);
+ }
+ else
+ {
+ outlet_float(x->x_out_fine, x->x_fine_right);
+ outlet_float(x->x_out_coarse, x->x_coarse_right);
+ }
+}
+
+static void max_dp_float(t_max_dp *x, t_floatarg f)
+{
+ x->x_coarse_left = f;
+ max_dp_bang(x);
+}
+
+static void *max_dp_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_max_dp *x = (t_max_dp *)pd_new(max_dp_class);
+
+ floatinlet_new(&x->x_obj, &x->x_fine_left);
+ floatinlet_new(&x->x_obj, &x->x_coarse_right);
+ floatinlet_new(&x->x_obj, &x->x_fine_right);
+ x->x_coarse_left = 0.0f;
+ x->x_fine_left = 0.0f;
+ if((ac > 0) && (IS_A_FLOAT(av, 0)))
+ x->x_coarse_right = atom_getfloatarg(0, ac, av);
+ else
+ x->x_coarse_right = 0.0f;
+ if((ac > 1) && (IS_A_FLOAT(av, 1)))
+ x->x_fine_right = atom_getfloatarg(1, ac, av);
+ else
+ x->x_fine_right = 0.0f;
+ x->x_out_coarse = outlet_new(&x->x_obj, &s_float);
+ x->x_out_fine = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void max_dp_setup(void)
+{
+ max_dp_class = class_new(gensym("max__"), (t_newmethod)max_dp_new, 0, sizeof(t_max_dp), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)max_dp_new, gensym("max''"), A_GIMME, 0);
+ class_addbang(max_dp_class, max_dp_bang);
+ class_addfloat(max_dp_class, max_dp_float);
+}
diff --git a/src/max~~.c b/src/max~~.c
new file mode 100755
index 0000000..c94d8ec
--- /dev/null
+++ b/src/max~~.c
@@ -0,0 +1,297 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* -------------------------- max~~ ------------------------------ */
+/* based on miller's max~ which is part of pd */
+
+static t_class *max_tilde_tilde_class, *scalarmax_tilde_tilde_class;
+
+typedef struct _max_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_in2_coarse;
+ t_sample *x_in2_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+} t_max_tilde_tilde;
+
+typedef struct _scalarmax_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+ t_sample x_in2_coarse;
+ t_sample x_in2_fine;
+} t_scalarmax_tilde_tilde;
+
+static void *max_tilde_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+ if(((argc==1)&&(argv->a_type == A_FLOAT))||(argc>=2)&&(argv->a_type == A_FLOAT)&&((argv+1)->a_type == A_FLOAT))
+ {
+ t_scalarmax_tilde_tilde *x = (t_scalarmax_tilde_tilde *)pd_new(scalarmax_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ floatinlet_new(&x->x_obj, &x->x_in2_coarse);
+ floatinlet_new(&x->x_obj, &x->x_in2_fine);
+ x->x_in2_coarse = atom_getfloatarg(0, argc, argv);
+ if(argc>=2)
+ x->x_in2_fine = atom_getfloatarg(1, argc, argv);
+ else
+ x->x_in2_fine = 0;
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+ else /* either no arguments or symbols */
+ {
+ t_max_tilde_tilde *x = (t_max_tilde_tilde *)pd_new(max_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+}
+
+static t_int *max_tilde_tilde_perform(t_int *w)
+{
+ t_max_tilde_tilde *x = (t_max_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+
+ while(n--)
+ {
+ t_sample i1c = *in1c++;
+ t_sample i1f = *in1f++;
+ t_sample i2c = *in2c++;
+ t_sample i2f = *in2f++;
+ double dleft = iem_dp_calc_sum(i1c, i1f);
+ double dright = iem_dp_calc_sum(i2c, i2f);
+
+ if(dleft > dright)
+ {
+ *outf++ = i1f;
+ *outc++ = i1c;
+ }
+ else
+ {
+ *outf++ = i2f;
+ *outc++ = i2c;
+ }
+ }
+ return(w+3);
+}
+
+static t_int *max_tilde_tilde_perf8(t_int *w)
+{
+ t_max_tilde_tilde *x = (t_max_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+
+ for(; n; n -= 8, in1c += 8, in1f += 8, in2c += 8, in2f += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(in1c[0], in1f[0]) + iem_dp_calc_sum(in2c[0], in2f[0]);
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(in1c[1], in1f[1]) + iem_dp_calc_sum(in2c[1], in2f[1]);
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(in1c[2], in1f[2]) + iem_dp_calc_sum(in2c[2], in2f[2]);
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(in1c[3], in1f[3]) + iem_dp_calc_sum(in2c[3], in2f[3]);
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(in1c[4], in1f[4]) + iem_dp_calc_sum(in2c[4], in2f[4]);
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(in1c[5], in1f[5]) + iem_dp_calc_sum(in2c[5], in2f[5]);
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(in1c[6], in1f[6]) + iem_dp_calc_sum(in2c[6], in2f[6]);
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(in1c[7], in1f[7]) + iem_dp_calc_sum(in2c[7], in2f[7]);
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static t_int *scalarmax_tilde_tilde_perform(t_int *w)
+{
+ t_scalarmax_tilde_tilde *x = (t_scalarmax_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample i2c = x->x_in2_coarse;
+ t_sample i2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double dright = iem_dp_calc_sum(i2c, i2f);
+
+ while(n--)
+ {
+ t_sample i1c = *in1c++;
+ t_sample i1f = *in1f++;
+ double dleft = iem_dp_calc_sum(i1c, i1f);
+
+ if(dleft > dright)
+ {
+ *outf++ = i1f;
+ *outc++ = i1c;
+ }
+ else
+ {
+ *outf++ = i2f;
+ *outc++ = i2c;
+ }
+ }
+ return(w+3);
+}
+
+static t_int *scalarmax_tilde_tilde_perf8(t_int *w)
+{
+ t_scalarmax_tilde_tilde *x = (t_scalarmax_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *inc = x->x_in1_coarse;
+ t_sample *inf = x->x_in1_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double g=iem_dp_calc_sum(x->x_in2_coarse, x->x_in2_fine);
+
+ for(; n; n -= 8, inc += 8, inf += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(inc[0], inf[0]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(inc[1], inf[1]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(inc[2], inf[2]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(inc[3], inf[3]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(inc[4], inf[4]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(inc[5], inf[5]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(inc[6], inf[6]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(inc[7], inf[7]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static void max_tilde_tilde_dsp(t_max_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_in2_coarse = sp[2]->s_vec;
+ x->x_in2_fine = sp[3]->s_vec;
+ x->x_out_coarse = sp[4]->s_vec;
+ x->x_out_fine = sp[5]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(max_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ else
+ dsp_add(max_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ //dsp_add(max_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+
+}
+
+static void scalarmax_tilde_tilde_dsp(t_scalarmax_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_out_coarse = sp[2]->s_vec;
+ x->x_out_fine = sp[3]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(scalarmax_tilde_tilde_perform, 2, sp[0]->s_n);
+ else
+ dsp_add(scalarmax_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ //dsp_add(scalarmax_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+
+}
+
+void max_tilde_tilde_setup(void)
+{
+ max_tilde_tilde_class = class_new(gensym("max~~"), (t_newmethod)max_tilde_tilde_new, 0,
+ sizeof(t_max_tilde_tilde), 0, A_GIMME, 0);
+ CLASS_MAINSIGNALIN(max_tilde_tilde_class, t_max_tilde_tilde, x_f);
+ class_addmethod(max_tilde_tilde_class, (t_method)max_tilde_tilde_dsp, gensym("dsp"), 0);
+ scalarmax_tilde_tilde_class = class_new(gensym("max~~"), 0, 0,
+ sizeof(t_scalarmax_tilde_tilde), 0, 0);
+ CLASS_MAINSIGNALIN(scalarmax_tilde_tilde_class, t_scalarmax_tilde_tilde, x_f);
+ class_addmethod(scalarmax_tilde_tilde_class, (t_method)scalarmax_tilde_tilde_dsp, gensym("dsp"), 0);
+}
diff --git a/src/min__.c b/src/min__.c
new file mode 100755
index 0000000..028bb4d
--- /dev/null
+++ b/src/min__.c
@@ -0,0 +1,80 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* ------------------------ min_dp ---------------------------- */
+/* based on miller's min, which is part of pd, only with double precision */
+
+static t_class *min_dp_class;
+
+typedef struct _min_dp
+{
+ t_object x_obj;
+ t_float x_coarse_left;
+ t_float x_fine_left;
+ t_float x_coarse_right;
+ t_float x_fine_right;
+ t_outlet *x_out_coarse;
+ t_outlet *x_out_fine;
+} t_min_dp;
+
+static void min_dp_bang(t_min_dp *x)
+{
+ double dleft, dright;
+
+ dleft = iem_dp_calc_sum(x->x_coarse_left, x->x_fine_left);
+ dright = iem_dp_calc_sum(x->x_coarse_right, x->x_fine_right);
+ if(dleft < dright)
+ {
+ outlet_float(x->x_out_fine, x->x_fine_left);
+ outlet_float(x->x_out_coarse, x->x_coarse_left);
+ }
+ else
+ {
+ outlet_float(x->x_out_fine, x->x_fine_right);
+ outlet_float(x->x_out_coarse, x->x_coarse_right);
+ }
+}
+
+static void min_dp_float(t_min_dp *x, t_floatarg f)
+{
+ x->x_coarse_left = f;
+ min_dp_bang(x);
+}
+
+static void *min_dp_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_min_dp *x = (t_min_dp *)pd_new(min_dp_class);
+
+ floatinlet_new(&x->x_obj, &x->x_fine_left);
+ floatinlet_new(&x->x_obj, &x->x_coarse_right);
+ floatinlet_new(&x->x_obj, &x->x_fine_right);
+ x->x_coarse_left = 0.0f;
+ x->x_fine_left = 0.0f;
+ if((ac > 0) && (IS_A_FLOAT(av, 0)))
+ x->x_coarse_right = atom_getfloatarg(0, ac, av);
+ else
+ x->x_coarse_right = 0.0f;
+ if((ac > 1) && (IS_A_FLOAT(av, 1)))
+ x->x_fine_right = atom_getfloatarg(1, ac, av);
+ else
+ x->x_fine_right = 0.0f;
+ x->x_out_coarse = outlet_new(&x->x_obj, &s_float);
+ x->x_out_fine = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void min_dp_setup(void)
+{
+ min_dp_class = class_new(gensym("min__"), (t_newmethod)min_dp_new, 0, sizeof(t_min_dp), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)min_dp_new, gensym("min''"), A_GIMME, 0);
+ class_addbang(min_dp_class, min_dp_bang);
+ class_addfloat(min_dp_class, min_dp_float);
+}
diff --git a/src/min~~.c b/src/min~~.c
new file mode 100755
index 0000000..333d980
--- /dev/null
+++ b/src/min~~.c
@@ -0,0 +1,297 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* -------------------------- min~~ ------------------------------ */
+/* based on miller's min~ which is part of pd */
+
+static t_class *min_tilde_tilde_class, *scalarmin_tilde_tilde_class;
+
+typedef struct _min_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_in2_coarse;
+ t_sample *x_in2_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+} t_min_tilde_tilde;
+
+typedef struct _scalarmin_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+ t_sample x_in2_coarse;
+ t_sample x_in2_fine;
+} t_scalarmin_tilde_tilde;
+
+static void *min_tilde_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+ if(((argc==1)&&(argv->a_type == A_FLOAT))||(argc>=2)&&(argv->a_type == A_FLOAT)&&((argv+1)->a_type == A_FLOAT))
+ {
+ t_scalarmin_tilde_tilde *x = (t_scalarmin_tilde_tilde *)pd_new(scalarmin_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ floatinlet_new(&x->x_obj, &x->x_in2_coarse);
+ floatinlet_new(&x->x_obj, &x->x_in2_fine);
+ x->x_in2_coarse = atom_getfloatarg(0, argc, argv);
+ if(argc>=2)
+ x->x_in2_fine = atom_getfloatarg(1, argc, argv);
+ else
+ x->x_in2_fine = 0;
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+ else /* either no arguments or symbols */
+ {
+ t_min_tilde_tilde *x = (t_min_tilde_tilde *)pd_new(min_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+}
+
+static t_int *min_tilde_tilde_perform(t_int *w)
+{
+ t_min_tilde_tilde *x = (t_min_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+
+ while(n--)
+ {
+ t_sample i1c = *in1c++;
+ t_sample i1f = *in1f++;
+ t_sample i2c = *in2c++;
+ t_sample i2f = *in2f++;
+ double dleft = iem_dp_calc_sum(i1c, i1f);
+ double dright = iem_dp_calc_sum(i2c, i2f);
+
+ if(dleft < dright)
+ {
+ *outf++ = i1f;
+ *outc++ = i1c;
+ }
+ else
+ {
+ *outf++ = i2f;
+ *outc++ = i2c;
+ }
+ }
+ return(w+3);
+}
+
+static t_int *min_tilde_tilde_perf8(t_int *w)
+{
+ t_min_tilde_tilde *x = (t_min_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+
+ for(; n; n -= 8, in1c += 8, in1f += 8, in2c += 8, in2f += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(in1c[0], in1f[0]) + iem_dp_calc_sum(in2c[0], in2f[0]);
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(in1c[1], in1f[1]) + iem_dp_calc_sum(in2c[1], in2f[1]);
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(in1c[2], in1f[2]) + iem_dp_calc_sum(in2c[2], in2f[2]);
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(in1c[3], in1f[3]) + iem_dp_calc_sum(in2c[3], in2f[3]);
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(in1c[4], in1f[4]) + iem_dp_calc_sum(in2c[4], in2f[4]);
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(in1c[5], in1f[5]) + iem_dp_calc_sum(in2c[5], in2f[5]);
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(in1c[6], in1f[6]) + iem_dp_calc_sum(in2c[6], in2f[6]);
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(in1c[7], in1f[7]) + iem_dp_calc_sum(in2c[7], in2f[7]);
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static t_int *scalarmin_tilde_tilde_perform(t_int *w)
+{
+ t_scalarmin_tilde_tilde *x = (t_scalarmin_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample i2c = x->x_in2_coarse;
+ t_sample i2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double dright = iem_dp_calc_sum(i2c, i2f);
+
+ while(n--)
+ {
+ t_sample i1c = *in1c++;
+ t_sample i1f = *in1f++;
+ double dleft = iem_dp_calc_sum(i1c, i1f);
+
+ if(dleft < dright)
+ {
+ *outf++ = i1f;
+ *outc++ = i1c;
+ }
+ else
+ {
+ *outf++ = i2f;
+ *outc++ = i2c;
+ }
+ }
+ return(w+3);
+}
+
+static t_int *scalarmin_tilde_tilde_perf8(t_int *w)
+{
+ t_scalarmin_tilde_tilde *x = (t_scalarmin_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *inc = x->x_in1_coarse;
+ t_sample *inf = x->x_in1_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double g=iem_dp_calc_sum(x->x_in2_coarse, x->x_in2_fine);
+
+ for(; n; n -= 8, inc += 8, inf += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(inc[0], inf[0]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(inc[1], inf[1]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(inc[2], inf[2]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(inc[3], inf[3]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(inc[4], inf[4]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(inc[5], inf[5]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(inc[6], inf[6]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(inc[7], inf[7]) + g;
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static void min_tilde_tilde_dsp(t_min_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_in2_coarse = sp[2]->s_vec;
+ x->x_in2_fine = sp[3]->s_vec;
+ x->x_out_coarse = sp[4]->s_vec;
+ x->x_out_fine = sp[5]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(min_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ else
+ dsp_add(min_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ //dsp_add(min_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+
+}
+
+static void scalarmin_tilde_tilde_dsp(t_scalarmin_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_out_coarse = sp[2]->s_vec;
+ x->x_out_fine = sp[3]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(scalarmin_tilde_tilde_perform, 2, sp[0]->s_n);
+ else
+ dsp_add(scalarmin_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ //dsp_add(scalarmin_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+
+}
+
+void min_tilde_tilde_setup(void)
+{
+ min_tilde_tilde_class = class_new(gensym("min~~"), (t_newmethod)min_tilde_tilde_new, 0,
+ sizeof(t_min_tilde_tilde), 0, A_GIMME, 0);
+ CLASS_MAINSIGNALIN(min_tilde_tilde_class, t_min_tilde_tilde, x_f);
+ class_addmethod(min_tilde_tilde_class, (t_method)min_tilde_tilde_dsp, gensym("dsp"), 0);
+ scalarmin_tilde_tilde_class = class_new(gensym("min~~"), 0, 0,
+ sizeof(t_scalarmin_tilde_tilde), 0, 0);
+ CLASS_MAINSIGNALIN(scalarmin_tilde_tilde_class, t_scalarmin_tilde_tilde, x_f);
+ class_addmethod(scalarmin_tilde_tilde_class, (t_method)scalarmin_tilde_tilde_dsp, gensym("dsp"), 0);
+}
diff --git a/src/mul__.c b/src/mul__.c
new file mode 100755
index 0000000..81331a8
--- /dev/null
+++ b/src/mul__.c
@@ -0,0 +1,78 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* ------------------------ mul__ or *__ ---------------------------- */
+/* based on miller's *, which is part of pd, only with double precision */
+
+static t_class *mul___class;
+
+typedef struct _mul__
+{
+ t_object x_obj;
+ t_float x_coarse_left;
+ t_float x_fine_left;
+ t_float x_coarse_right;
+ t_float x_fine_right;
+ t_outlet *x_out_coarse;
+ t_outlet *x_out_fine;
+} t_mul__;
+
+static void mul___bang(t_mul__ *x)
+{
+ double dprod;
+ t_float fprod;
+
+ dprod = iem_dp_calc_sum(x->x_coarse_left, x->x_fine_left) * iem_dp_calc_sum(x->x_coarse_right, x->x_fine_right);
+ fprod = iem_dp_cast_to_float(dprod);
+ outlet_float(x->x_out_fine, iem_dp_calc_residual(dprod, fprod));
+ outlet_float(x->x_out_coarse, fprod);
+}
+
+static void mul___float(t_mul__ *x, t_floatarg f)
+{
+ x->x_coarse_left = f;
+ mul___bang(x);
+}
+
+static void *mul___new(t_symbol *s, int ac, t_atom *av)
+{
+ t_mul__ *x = (t_mul__ *)pd_new(mul___class);
+
+ floatinlet_new(&x->x_obj, &x->x_fine_left);
+ floatinlet_new(&x->x_obj, &x->x_coarse_right);
+ floatinlet_new(&x->x_obj, &x->x_fine_right);
+ x->x_coarse_left = 0.0f;
+ x->x_fine_left = 0.0f;
+ if((ac > 0) && (IS_A_FLOAT(av, 0)))
+ x->x_coarse_right = atom_getfloatarg(0, ac, av);
+ else
+ x->x_coarse_right = 0.0f;
+ if((ac > 1) && (IS_A_FLOAT(av, 1)))
+ x->x_fine_right = atom_getfloatarg(1, ac, av);
+ else
+ x->x_fine_right = 0.0f;
+ x->x_out_coarse = outlet_new(&x->x_obj, &s_float);
+ x->x_out_fine = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void mul___free(t_mul__ *x)
+{
+}
+
+void mul___setup(void)
+{
+ mul___class = class_new(gensym("mul__"), (t_newmethod)mul___new, 0, sizeof(t_mul__), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)mul___new, gensym("*__"), A_GIMME, 0);
+ class_addcreator((t_newmethod)mul___new, gensym("*''"), A_GIMME, 0);
+ class_addbang(mul___class, mul___bang);
+ class_addfloat(mul___class, mul___float);
+}
diff --git a/src/mul~~.c b/src/mul~~.c
new file mode 100755
index 0000000..9f094c1
--- /dev/null
+++ b/src/mul~~.c
@@ -0,0 +1,272 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* -------------------------- mul~~ ------------------------------ */
+/* based on miller's *~ which is part of pd */
+
+static t_class *mul_tilde_tilde_class, *scalarmul_tilde_tilde_class;
+
+typedef struct _mul_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_in2_coarse;
+ t_sample *x_in2_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+} t_mul_tilde_tilde;
+
+typedef struct _scalarmul_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+ t_sample x_in2_coarse;
+ t_sample x_in2_fine;
+} t_scalarmul_tilde_tilde;
+
+static void *mul_tilde_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+ if(((argc==1)&&(argv->a_type == A_FLOAT))||(argc>=2)&&(argv->a_type == A_FLOAT)&&((argv+1)->a_type == A_FLOAT))
+ {
+ t_scalarmul_tilde_tilde *x = (t_scalarmul_tilde_tilde *)pd_new(scalarmul_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ floatinlet_new(&x->x_obj, &x->x_in2_coarse);
+ floatinlet_new(&x->x_obj, &x->x_in2_fine);
+ x->x_in2_coarse = atom_getfloatarg(0, argc, argv);
+ if(argc>=2)
+ x->x_in2_fine = atom_getfloatarg(1, argc, argv);
+ else
+ x->x_in2_fine = 0;
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+ else /* either no arguments or symbols */
+ {
+ t_mul_tilde_tilde *x = (t_mul_tilde_tilde *)pd_new(mul_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+}
+
+static t_int *mul_tilde_tilde_perform(t_int *w)
+{
+ t_mul_tilde_tilde *x = (t_mul_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double d;
+ t_float f;
+
+ while(n--)
+ {
+ d = iem_dp_calc_sum(*in1c++, *in1f++) * iem_dp_calc_sum(*in2c++, *in2f++);
+ f = iem_dp_cast_to_float(d);
+ *outf++ = iem_dp_calc_residual(d, f);
+ *outc++ = f;
+ }
+ return(w+3);
+}
+
+static t_int *mul_tilde_tilde_perf8(t_int *w)
+{
+ t_mul_tilde_tilde *x = (t_mul_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+
+ for(; n; n -= 8, in1c += 8, in1f += 8, in2c += 8, in2f += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(in1c[0], in1f[0]) * iem_dp_calc_sum(in2c[0], in2f[0]);
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(in1c[1], in1f[1]) * iem_dp_calc_sum(in2c[1], in2f[1]);
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(in1c[2], in1f[2]) * iem_dp_calc_sum(in2c[2], in2f[2]);
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(in1c[3], in1f[3]) * iem_dp_calc_sum(in2c[3], in2f[3]);
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(in1c[4], in1f[4]) * iem_dp_calc_sum(in2c[4], in2f[4]);
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(in1c[5], in1f[5]) * iem_dp_calc_sum(in2c[5], in2f[5]);
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(in1c[6], in1f[6]) * iem_dp_calc_sum(in2c[6], in2f[6]);
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(in1c[7], in1f[7]) * iem_dp_calc_sum(in2c[7], in2f[7]);
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static t_int *scalarmul_tilde_tilde_perform(t_int *w)
+{
+ t_scalarmul_tilde_tilde *x = (t_scalarmul_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *inc = x->x_in1_coarse;
+ t_sample *inf = x->x_in1_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double d, g=iem_dp_calc_sum(x->x_in2_coarse, x->x_in2_fine);
+ t_float f;
+
+ while(n--)
+ {
+ d = iem_dp_calc_sum(*inc++, *inf++) * g;
+ f = iem_dp_cast_to_float(d);
+ *outf++ = iem_dp_calc_residual(d, f);
+ *outc++ = f;
+ }
+return(w+3);
+}
+
+static t_int *scalarmul_tilde_tilde_perf8(t_int *w)
+{
+ t_scalarmul_tilde_tilde *x = (t_scalarmul_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *inc = x->x_in1_coarse;
+ t_sample *inf = x->x_in1_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double g=iem_dp_calc_sum(x->x_in2_coarse, x->x_in2_fine);
+
+ for(; n; n -= 8, inc += 8, inf += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(inc[0], inf[0]) * g;
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(inc[1], inf[1]) * g;
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(inc[2], inf[2]) * g;
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(inc[3], inf[3]) * g;
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(inc[4], inf[4]) * g;
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(inc[5], inf[5]) * g;
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(inc[6], inf[6]) * g;
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(inc[7], inf[7]) * g;
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static void mul_tilde_tilde_dsp(t_mul_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_in2_coarse = sp[2]->s_vec;
+ x->x_in2_fine = sp[3]->s_vec;
+ x->x_out_coarse = sp[4]->s_vec;
+ x->x_out_fine = sp[5]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(mul_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ else
+ dsp_add(mul_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+}
+
+static void scalarmul_tilde_tilde_dsp(t_scalarmul_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_out_coarse = sp[2]->s_vec;
+ x->x_out_fine = sp[3]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(scalarmul_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ else
+ dsp_add(scalarmul_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+}
+
+void mul_tilde_tilde_setup(void)
+{
+ mul_tilde_tilde_class = class_new(gensym("*~~"), (t_newmethod)mul_tilde_tilde_new, 0,
+ sizeof(t_mul_tilde_tilde), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)mul_tilde_tilde_new, gensym("mul~~"), A_GIMME, 0);
+ CLASS_MAINSIGNALIN(mul_tilde_tilde_class, t_mul_tilde_tilde, x_f);
+ class_addmethod(mul_tilde_tilde_class, (t_method)mul_tilde_tilde_dsp, gensym("dsp"), 0);
+ scalarmul_tilde_tilde_class = class_new(gensym("*~~"), 0, 0,
+ sizeof(t_scalarmul_tilde_tilde), 0, 0);
+ CLASS_MAINSIGNALIN(scalarmul_tilde_tilde_class, t_scalarmul_tilde_tilde, x_f);
+ class_addmethod(scalarmul_tilde_tilde_class, (t_method)scalarmul_tilde_tilde_dsp, gensym("dsp"), 0);
+}
diff --git a/src/phasor~~.c b/src/phasor~~.c
new file mode 100755
index 0000000..a6504f7
--- /dev/null
+++ b/src/phasor~~.c
@@ -0,0 +1,89 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* -------------------------- phasor~~ ------------------------------ */
+/* based on miller's phasor~ which is part of pd */
+
+static t_class *phasor_tilde_tilde_class, *scalarphasor_tilde_tilde_class;
+
+typedef struct _phasor_tilde_tilde
+{
+ t_object x_obj;
+ double x_phase;
+ double x_rcp_sr;
+ t_float x_freq;
+} t_phasor_tilde_tilde;
+
+static void *phasor_tilde_tilde_new(t_floatarg freq)
+{
+ t_phasor_tilde_tilde *x = (t_phasor_tilde_tilde *)pd_new(phasor_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ x->x_phase = 0;
+ x->x_rcp_sr = 0;
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_freq = freq;
+ return(x);
+}
+
+static t_int *phasor_tilde_tilde_perform(t_int *w)
+{
+ t_phasor_tilde_tilde *x = (t_phasor_tilde_tilde *)(w[1]);
+ t_sample *freq_in = (t_sample *)(w[2]);
+ t_sample *outc = (t_sample *)(w[3]);
+ t_sample *outf = (t_sample *)(w[4]);
+ int n = (int)(w[5]);
+ double dphase = x->x_phase;
+ double rcp_sr = x->x_rcp_sr;
+ double fin;
+ t_float fphase;
+ int k;
+
+ while(n--)
+ {
+ fin = (double)*freq_in++;
+
+ k = (int)dphase;
+ if(dphase >= 0)
+ dphase -= (double)k;
+ else
+ dphase -= (double)(k-1);
+
+ fphase = iem_dp_cast_to_float(dphase);
+ *outf++ = iem_dp_calc_residual(dphase, fphase);
+ *outc++ = fphase;
+
+ dphase += fin * rcp_sr;
+ }
+ x->x_phase = dphase;
+ return(w+6);
+}
+
+static void phasor_tilde_tilde_dsp(t_phasor_tilde_tilde *x, t_signal **sp)
+{
+ x->x_rcp_sr = (double)(1.0)/(double)(sp[0]->s_sr);
+ dsp_add(phasor_tilde_tilde_perform, 5, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
+}
+
+static void phasor_tilde_tilde_ft1(t_phasor_tilde_tilde *x, t_floatarg ph)
+{
+ x->x_phase = (double)ph;
+}
+
+void phasor_tilde_tilde_setup(void)
+{
+ phasor_tilde_tilde_class = class_new(gensym("phasor~~"), (t_newmethod)phasor_tilde_tilde_new, 0,
+ sizeof(t_phasor_tilde_tilde), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(phasor_tilde_tilde_class, t_phasor_tilde_tilde, x_freq);
+ class_addmethod(phasor_tilde_tilde_class, (t_method)phasor_tilde_tilde_dsp, gensym("dsp"), 0);
+ class_addmethod(phasor_tilde_tilde_class, (t_method)phasor_tilde_tilde_ft1, gensym("ft1"), A_FLOAT, 0);
+}
diff --git a/src/print~~.c b/src/print~~.c
new file mode 100755
index 0000000..ceb17b5
--- /dev/null
+++ b/src/print~~.c
@@ -0,0 +1,99 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+/* -------------------------- print~~ ------------------------------ */
+/* based on miller's print~ which is part of pd */
+
+static t_class *print_tilde_tilde_class;
+
+typedef struct _print_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_symbol *x_sym;
+ int x_count;
+} t_print_tilde_tilde;
+
+static void *print_tilde_tilde_new(t_symbol *s)
+{
+ t_print_tilde_tilde *x = (t_print_tilde_tilde *)pd_new(print_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ x->x_sym = (s->s_name[0] ? s : gensym("print~~"));
+ x->x_count = 0;
+ x->x_f = 0;
+ return(x);
+}
+
+static t_int *print_tilde_tilde_perform(t_int *w)
+{
+ t_print_tilde_tilde *x = (t_print_tilde_tilde *)(w[1]);
+ t_sample *inc = (t_sample *)(w[2]);
+ t_sample *inf = (t_sample *)(w[3]);
+ int n = (int)(w[4]);
+
+ if(x->x_count)
+ {
+ post("%s:", x->x_sym->s_name);
+ while(n >= 4)
+ {
+ post("%-20.14g %-20.14g %-20.14g %-20.14g", iem_dp_calc_sum(inc[0], inf[0]), iem_dp_calc_sum(inc[1], inf[1]),
+ iem_dp_calc_sum(inc[2], inf[2]), iem_dp_calc_sum(inc[3], inf[3]));
+ n -= 4;
+ inc += 4;
+ inf += 4;
+ }
+ if(n)
+ {
+ if(n == 3)
+ {
+ post("%-20.14g %-20.14g %-20.14g", iem_dp_calc_sum(inc[0], inf[0]), iem_dp_calc_sum(inc[1], inf[1]),
+ iem_dp_calc_sum(inc[2], inf[2]));
+ }
+ else if(n == 2)
+ {
+ post("%-20.14g %-20.14g", iem_dp_calc_sum(inc[0], inf[0]), iem_dp_calc_sum(inc[1], inf[1]));
+ }
+ else if(n == 1)
+ {
+ post("%-20.14g", iem_dp_calc_sum(inc[0], inf[0]));
+ }
+ }
+ x->x_count--;
+ }
+ return(w+5);
+}
+
+static void print_tilde_tilde_float(t_print_tilde_tilde *x, t_floatarg f)
+{
+ if(f < 0)
+ f = 0;
+ x->x_count = f;
+}
+
+static void print_tilde_tilde_bang(t_print_tilde_tilde *x)
+{
+ x->x_count = 1;
+}
+
+static void print_tilde_tilde_dsp(t_print_tilde_tilde *x, t_signal **sp)
+{
+ dsp_add(print_tilde_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+void print_tilde_tilde_setup(void)
+{
+ print_tilde_tilde_class = class_new(gensym("print~~"), (t_newmethod)print_tilde_tilde_new, 0,
+ sizeof(t_print_tilde_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(print_tilde_tilde_class, t_print_tilde_tilde, x_f);
+ class_addmethod(print_tilde_tilde_class, (t_method)print_tilde_tilde_dsp, gensym("dsp"), 0);
+ class_addbang(print_tilde_tilde_class, print_tilde_tilde_bang);
+ class_addfloat(print_tilde_tilde_class, print_tilde_tilde_float);
+}
diff --git a/src/random__.c b/src/random__.c
new file mode 100755
index 0000000..bb6990b
--- /dev/null
+++ b/src/random__.c
@@ -0,0 +1,93 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* ------------------------ random_dp ---------------------------- */
+/* based on miller's random, which is part of pd, only with double precision */
+
+static t_class *random_dp_class;
+
+typedef struct _random_dp
+{
+ t_object x_obj;
+ t_float x_max_coarse;
+ t_float x_max_fine;
+ unsigned int x_state;
+ t_outlet *x_out_coarse;
+ t_outlet *x_out_fine;
+} t_random_dp;
+
+
+static int makeseed(void)
+{
+ static unsigned int random_nextseed = 1489853723;
+ random_nextseed = random_nextseed * 435898247 + 938284287;
+ return (random_nextseed & 0x7fffffff);
+}
+
+static void *random_dp_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_random_dp *x = (t_random_dp *)pd_new(random_dp_class);
+
+ if((ac > 0) && (IS_A_FLOAT(av, 0)))
+ x->x_max_coarse = atom_getfloatarg(0, ac, av);
+ else
+ x->x_max_coarse = 0.0f;
+ if((ac > 1) && (IS_A_FLOAT(av, 1)))
+ x->x_max_fine = atom_getfloatarg(1, ac, av);
+ else
+ x->x_max_fine = 0.0f;
+ x->x_state = makeseed();
+ floatinlet_new(&x->x_obj, &x->x_max_coarse);
+ floatinlet_new(&x->x_obj, &x->x_max_fine);
+ x->x_out_coarse = outlet_new(&x->x_obj, &s_float);
+ x->x_out_fine = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void random_dp_bang(t_random_dp *x)
+{
+ int n = (int)iem_dp_calc_sum(x->x_max_coarse, x->x_max_fine);
+ int nval;
+ int range = (n < 1 ? 1 : n);
+ unsigned int randval = x->x_state;
+ t_float fine, coarse;
+
+ x->x_state = randval = randval * 472940017 + 832416023;
+ nval = ((double)range) * ((double)randval) * (1./4294967296.);
+ if(nval >= range)
+ nval = range-1;
+ coarse = iem_dp_cast_to_float((double)nval);
+ outlet_float(x->x_out_fine, iem_dp_calc_residual((double)nval, coarse));
+ outlet_float(x->x_out_coarse, coarse);
+}
+
+static void random_dp_seed(t_random_dp *x, t_symbol *s, int ac, t_atom *av)
+{
+ t_float fine, coarse;
+
+ if((ac > 0) && (IS_A_FLOAT(av, 0)))
+ coarse = atom_getfloatarg(0, ac, av);
+ else
+ coarse = 0.0f;
+ if((ac > 1) && (IS_A_FLOAT(av, 1)))
+ fine = atom_getfloatarg(1, ac, av);
+ else
+ fine = 0.0f;
+ x->x_state = (int)iem_dp_calc_sum(coarse, fine);
+}
+
+void random_dp_setup(void)
+{
+ random_dp_class = class_new(gensym("random__"), (t_newmethod)random_dp_new, 0, sizeof(t_random_dp), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)random_dp_new, gensym("random''"), A_GIMME, 0);
+ class_addbang(random_dp_class, random_dp_bang);
+ class_addmethod(random_dp_class, (t_method)random_dp_seed, gensym("seed"), A_GIMME, 0);
+}
diff --git a/src/samphold~~.c b/src/samphold~~.c
new file mode 100755
index 0000000..f39129f
--- /dev/null
+++ b/src/samphold~~.c
@@ -0,0 +1,128 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+/* ---------------- samphold~~ - double precision sample and hold ----------------- */
+/* based on miller's samphold~ which is part of pd */
+
+typedef struct samphold_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_in2_coarse;
+ t_sample *x_in2_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+ double x_lastin;
+ double x_lastout;
+} t_samphold_tilde_tilde;
+
+t_class *samphold_tilde_tilde_class;
+
+static void *samphold_tilde_tilde_new(void)
+{
+ t_samphold_tilde_tilde *x = (t_samphold_tilde_tilde *)pd_new(samphold_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_lastin = 0;
+ x->x_lastout = 0;
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *samphold_tilde_tilde_perform(t_int *w)
+{
+ t_samphold_tilde_tilde *x = (t_samphold_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]), i;
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double lastin = x->x_lastin;
+ double d_lastout = x->x_lastout;
+ t_float f_lastout = 0.0f;
+
+ for(i = 0; i < n; i++, in1c++, in1f++)
+ {
+ double next = iem_dp_calc_sum(*in2c++, *in2f++);
+
+ if(next < lastin)
+ d_lastout = iem_dp_calc_sum(*in1c, *in1f);
+ f_lastout = iem_dp_cast_to_float(d_lastout);
+ *outf++ = iem_dp_calc_residual(d_lastout, f_lastout);
+ *outc++ = f_lastout;
+ lastin = next;
+ }
+ x->x_lastin = lastin;
+ x->x_lastout = d_lastout;
+ return(w+3);
+}
+
+static void samphold_tilde_tilde_dsp(t_samphold_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_in2_coarse = sp[2]->s_vec;
+ x->x_in2_fine = sp[3]->s_vec;
+ x->x_out_coarse = sp[4]->s_vec;
+ x->x_out_fine = sp[5]->s_vec;
+ dsp_add(samphold_tilde_tilde_perform, 2, x, sp[0]->s_n);
+}
+
+static void samphold_tilde_tilde_reset(t_samphold_tilde_tilde *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_float coarse, fine;
+
+ if((argc > 0) && (IS_A_FLOAT(argv, 0)))
+ coarse = atom_getfloatarg(0, argc, argv);
+ else
+ coarse = 1.0e20f;
+ if((argc > 1) && (IS_A_FLOAT(argv, 1)))
+ fine = atom_getfloatarg(1, argc, argv);
+ else
+ fine = 0.0f;
+ x->x_lastin = iem_dp_calc_sum(coarse, fine);
+}
+
+static void samphold_tilde_tilde_set(t_samphold_tilde_tilde *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_float coarse, fine;
+
+ if((argc > 0) && (IS_A_FLOAT(argv, 0)))
+ coarse = atom_getfloatarg(0, argc, argv);
+ else
+ coarse = 0.0f;
+ if((argc > 1) && (IS_A_FLOAT(argv, 1)))
+ fine = atom_getfloatarg(1, argc, argv);
+ else
+ fine = 0.0f;
+ x->x_lastout = iem_dp_calc_sum(coarse, fine);
+}
+
+void samphold_tilde_tilde_setup(void)
+{
+ samphold_tilde_tilde_class = class_new(gensym("samphold~~"),
+ (t_newmethod)samphold_tilde_tilde_new, 0, sizeof(t_samphold_tilde_tilde), 0, 0);
+ CLASS_MAINSIGNALIN(samphold_tilde_tilde_class, t_samphold_tilde_tilde, x_f);
+ class_addmethod(samphold_tilde_tilde_class, (t_method)samphold_tilde_tilde_set,
+ gensym("set"), A_GIMME, 0);
+ class_addmethod(samphold_tilde_tilde_class, (t_method)samphold_tilde_tilde_reset,
+ gensym("reset"), A_GIMME, 0);
+ class_addmethod(samphold_tilde_tilde_class, (t_method)samphold_tilde_tilde_dsp,
+ gensym("dsp"), 0);
+}
diff --git a/src/sub__.c b/src/sub__.c
new file mode 100755
index 0000000..8bd08ec
--- /dev/null
+++ b/src/sub__.c
@@ -0,0 +1,78 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* ------------------------ sub__ or -__ ---------------------------- */
+/* based on miller's -, which is part of pd, only with double precision */
+
+static t_class *sub___class;
+
+typedef struct _sub__
+{
+ t_object x_obj;
+ t_float x_coarse_left;
+ t_float x_fine_left;
+ t_float x_coarse_right;
+ t_float x_fine_right;
+ t_outlet *x_out_coarse;
+ t_outlet *x_out_fine;
+} t_sub__;
+
+static void sub___bang(t_sub__ *x)
+{
+ double ddiff;
+ t_float fdiff;
+
+ ddiff = iem_dp_calc_sum(x->x_coarse_left, x->x_fine_left) - iem_dp_calc_sum(x->x_coarse_right, x->x_fine_right);
+ fdiff = iem_dp_cast_to_float(ddiff);
+ outlet_float(x->x_out_fine, iem_dp_calc_residual(ddiff, fdiff));
+ outlet_float(x->x_out_coarse, fdiff);
+}
+
+static void sub___float(t_sub__ *x, t_floatarg f)
+{
+ x->x_coarse_left = f;
+ sub___bang(x);
+}
+
+static void *sub___new(t_symbol *s, int ac, t_atom *av)
+{
+ t_sub__ *x = (t_sub__ *)pd_new(sub___class);
+
+ floatinlet_new(&x->x_obj, &x->x_fine_left);
+ floatinlet_new(&x->x_obj, &x->x_coarse_right);
+ floatinlet_new(&x->x_obj, &x->x_fine_right);
+ x->x_coarse_left = 0.0f;
+ x->x_fine_left = 0.0f;
+ if((ac > 0) && (IS_A_FLOAT(av, 0)))
+ x->x_coarse_right = atom_getfloatarg(0, ac, av);
+ else
+ x->x_coarse_right = 0.0f;
+ if((ac > 1) && (IS_A_FLOAT(av, 1)))
+ x->x_fine_right = atom_getfloatarg(1, ac, av);
+ else
+ x->x_fine_right = 0.0f;
+ x->x_out_coarse = outlet_new(&x->x_obj, &s_float);
+ x->x_out_fine = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void sub___free(t_sub__ *x)
+{
+}
+
+void sub___setup(void)
+{
+ sub___class = class_new(gensym("sub__"), (t_newmethod)sub___new, 0, sizeof(t_sub__), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)sub___new, gensym("-__"), A_GIMME, 0);
+ class_addcreator((t_newmethod)sub___new, gensym("-''"), A_GIMME, 0);
+ class_addbang(sub___class, sub___bang);
+ class_addfloat(sub___class, sub___float);
+}
diff --git a/src/sub~~.c b/src/sub~~.c
new file mode 100755
index 0000000..82a28ad
--- /dev/null
+++ b/src/sub~~.c
@@ -0,0 +1,272 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* -------------------------- sub~~ ------------------------------ */
+/* based on miller's -~ which is part of pd */
+
+static t_class *sub_tilde_tilde_class, *scalarsub_tilde_tilde_class;
+
+typedef struct _sub_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_in2_coarse;
+ t_sample *x_in2_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+} t_sub_tilde_tilde;
+
+typedef struct _scalarsub_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_sample *x_in1_coarse;
+ t_sample *x_in1_fine;
+ t_sample *x_out_coarse;
+ t_sample *x_out_fine;
+ t_sample x_in2_coarse;
+ t_sample x_in2_fine;
+} t_scalarsub_tilde_tilde;
+
+static void *sub_tilde_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+ if(((argc==1)&&(argv->a_type == A_FLOAT))||(argc>=2)&&(argv->a_type == A_FLOAT)&&((argv+1)->a_type == A_FLOAT))
+ {
+ t_scalarsub_tilde_tilde *x = (t_scalarsub_tilde_tilde *)pd_new(scalarsub_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ floatinlet_new(&x->x_obj, &x->x_in2_coarse);
+ floatinlet_new(&x->x_obj, &x->x_in2_fine);
+ x->x_in2_coarse = atom_getfloatarg(0, argc, argv);
+ if(argc>=2)
+ x->x_in2_fine = atom_getfloatarg(1, argc, argv);
+ else
+ x->x_in2_fine = 0;
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+ else /* either no arguments or symbols */
+ {
+ t_sub_tilde_tilde *x = (t_sub_tilde_tilde *)pd_new(sub_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+ }
+}
+
+static t_int *sub_tilde_tilde_perform(t_int *w)
+{
+ t_sub_tilde_tilde *x = (t_sub_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double d;
+ t_float f;
+
+ while(n--)
+ {
+ d = iem_dp_calc_sum(*in1c++, *in1f++) - iem_dp_calc_sum(*in2c++, *in2f++);
+ f = iem_dp_cast_to_float(d);
+ *outf++ = iem_dp_calc_residual(d, f);
+ *outc++ = f;
+ }
+ return(w+3);
+}
+
+static t_int *sub_tilde_tilde_perf8(t_int *w)
+{
+ t_sub_tilde_tilde *x = (t_sub_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *in1c = x->x_in1_coarse;
+ t_sample *in1f = x->x_in1_fine;
+ t_sample *in2c = x->x_in2_coarse;
+ t_sample *in2f = x->x_in2_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+
+ for(; n; n -= 8, in1c += 8, in1f += 8, in2c += 8, in2f += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(in1c[0], in1f[0]) - iem_dp_calc_sum(in2c[0], in2f[0]);
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(in1c[1], in1f[1]) - iem_dp_calc_sum(in2c[1], in2f[1]);
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(in1c[2], in1f[2]) - iem_dp_calc_sum(in2c[2], in2f[2]);
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(in1c[3], in1f[3]) - iem_dp_calc_sum(in2c[3], in2f[3]);
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(in1c[4], in1f[4]) - iem_dp_calc_sum(in2c[4], in2f[4]);
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(in1c[5], in1f[5]) - iem_dp_calc_sum(in2c[5], in2f[5]);
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(in1c[6], in1f[6]) - iem_dp_calc_sum(in2c[6], in2f[6]);
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(in1c[7], in1f[7]) - iem_dp_calc_sum(in2c[7], in2f[7]);
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static t_int *scalarsub_tilde_tilde_perform(t_int *w)
+{
+ t_scalarsub_tilde_tilde *x = (t_scalarsub_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *inc = x->x_in1_coarse;
+ t_sample *inf = x->x_in1_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double d, g=iem_dp_calc_sum(x->x_in2_coarse, x->x_in2_fine);
+ t_float f;
+
+ while(n--)
+ {
+ d = iem_dp_calc_sum(*inc++, *inf++) - g;
+ f = iem_dp_cast_to_float(d);
+ *outf++ = iem_dp_calc_residual(d, f);
+ *outc++ = f;
+ }
+ return(w+3);
+}
+
+static t_int *scalarsub_tilde_tilde_perf8(t_int *w)
+{
+ t_scalarsub_tilde_tilde *x = (t_scalarsub_tilde_tilde *)(w[1]);
+ int n = (int)(w[2]);
+ t_sample *inc = x->x_in1_coarse;
+ t_sample *inf = x->x_in1_fine;
+ t_sample *outc = x->x_out_coarse;
+ t_sample *outf = x->x_out_fine;
+ double g=iem_dp_calc_sum(x->x_in2_coarse, x->x_in2_fine);
+
+ for(; n; n -= 8, inc += 8, inf += 8, outc += 8, outf += 8)
+ {
+ double d;
+ t_float f;
+
+ d = iem_dp_calc_sum(inc[0], inf[0]) - g;
+ f = iem_dp_cast_to_float(d);
+ outf[0] = iem_dp_calc_residual(d, f);
+ outc[0] = f;
+
+ d = iem_dp_calc_sum(inc[1], inf[1]) - g;
+ f = iem_dp_cast_to_float(d);
+ outf[1] = iem_dp_calc_residual(d, f);
+ outc[1] = f;
+
+ d = iem_dp_calc_sum(inc[2], inf[2]) - g;
+ f = iem_dp_cast_to_float(d);
+ outf[2] = iem_dp_calc_residual(d, f);
+ outc[2] = f;
+
+ d = iem_dp_calc_sum(inc[3], inf[3]) - g;
+ f = iem_dp_cast_to_float(d);
+ outf[3] = iem_dp_calc_residual(d, f);
+ outc[3] = f;
+
+ d = iem_dp_calc_sum(inc[4], inf[4]) - g;
+ f = iem_dp_cast_to_float(d);
+ outf[4] = iem_dp_calc_residual(d, f);
+ outc[4] = f;
+
+ d = iem_dp_calc_sum(inc[5], inf[5]) - g;
+ f = iem_dp_cast_to_float(d);
+ outf[5] = iem_dp_calc_residual(d, f);
+ outc[5] = f;
+
+ d = iem_dp_calc_sum(inc[6], inf[6]) - g;
+ f = iem_dp_cast_to_float(d);
+ outf[6] = iem_dp_calc_residual(d, f);
+ outc[6] = f;
+
+ d = iem_dp_calc_sum(inc[7], inf[7]) - g;
+ f = iem_dp_cast_to_float(d);
+ outf[7] = iem_dp_calc_residual(d, f);
+ outc[7] = f;
+ }
+ return(w+3);
+}
+
+static void sub_tilde_tilde_dsp(t_sub_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_in2_coarse = sp[2]->s_vec;
+ x->x_in2_fine = sp[3]->s_vec;
+ x->x_out_coarse = sp[4]->s_vec;
+ x->x_out_fine = sp[5]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(sub_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ else
+ dsp_add(sub_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+}
+
+static void scalarsub_tilde_tilde_dsp(t_scalarsub_tilde_tilde *x, t_signal **sp)
+{
+ x->x_in1_coarse = sp[0]->s_vec;
+ x->x_in1_fine = sp[1]->s_vec;
+ x->x_out_coarse = sp[2]->s_vec;
+ x->x_out_fine = sp[3]->s_vec;
+ if(sp[0]->s_n&7)
+ dsp_add(scalarsub_tilde_tilde_perform, 2, x, sp[0]->s_n);
+ else
+ dsp_add(scalarsub_tilde_tilde_perf8, 2, x, sp[0]->s_n);
+}
+
+void sub_tilde_tilde_setup(void)
+{
+ sub_tilde_tilde_class = class_new(gensym("-~~"), (t_newmethod)sub_tilde_tilde_new, 0,
+ sizeof(t_sub_tilde_tilde), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)sub_tilde_tilde_new, gensym("sub~~"), A_GIMME, 0);
+ CLASS_MAINSIGNALIN(sub_tilde_tilde_class, t_sub_tilde_tilde, x_f);
+ class_addmethod(sub_tilde_tilde_class, (t_method)sub_tilde_tilde_dsp, gensym("dsp"), 0);
+ scalarsub_tilde_tilde_class = class_new(gensym("-~~"), 0, 0,
+ sizeof(t_scalarsub_tilde_tilde), 0, 0);
+ CLASS_MAINSIGNALIN(scalarsub_tilde_tilde_class, t_scalarsub_tilde_tilde, x_f);
+ class_addmethod(scalarsub_tilde_tilde_class, (t_method)scalarsub_tilde_tilde_dsp, gensym("dsp"), 0);
+}
diff --git a/src/symtodp.c b/src/symtodp.c
new file mode 100755
index 0000000..9b889f7
--- /dev/null
+++ b/src/symtodp.c
@@ -0,0 +1,133 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2013 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* -------------------------- symtodp ------------------------------ */
+/* symbol double precision number to double float converter */
+
+/* double float is only internal used */
+/* to transfer this value, we divide this double value into use one float casted value */
+/* and into the difference to the accurate double value. */
+
+/* double float (sign_1 + exp_12 + mant_51) */
+
+static t_class *symtodp_class;
+
+typedef struct _symtodp
+{
+ t_object x_obj;
+ double x_inner_double_value;
+ t_outlet *x_out_floatcasted;
+ t_outlet *x_out_residual;
+} t_symtodp;
+
+static double symtodp_calc_list_sum(int ac, t_atom *av)
+{
+ int i;
+ char str[1000], buf[100], *dummy;
+
+ str[0] = 0;
+ for(i=0; i<ac; i++)
+ {
+ if(IS_A_FLOAT(av, i))
+ {
+ sprintf(buf, "%g", (float)atom_getfloatarg(i, ac, av));
+ strcat(str, buf);
+ }
+ }
+ // post("listtodp string: %s", str);
+
+ return(strtod(str, &dummy));
+}
+
+static void symtodp_bang(t_symtodp *x)
+{
+ t_float float_casted_value;
+
+ float_casted_value = iem_dp_cast_to_float(x->x_inner_double_value);
+ outlet_float(x->x_out_residual, iem_dp_calc_residual(x->x_inner_double_value, float_casted_value));
+ outlet_float(x->x_out_floatcasted, float_casted_value);
+}
+
+static void symtodp_float(t_symtodp *x, t_floatarg f)
+{
+ x->x_inner_double_value = (double)f;
+ symtodp_bang(x);
+}
+
+static void symtodp_symbol(t_symtodp *x, t_symbol *s)
+{
+ char *dummy;
+
+ if((s->s_name[0] == '"') && (s->s_name[1]))
+ {
+ if((s->s_name[1] == '.') || (s->s_name[1] == '+') || (s->s_name[1] == '-') || ((s->s_name[1] >= '0') && (s->s_name[1] <= '9')))
+ {
+ x->x_inner_double_value = strtod(s->s_name+1, &dummy);
+ symtodp_bang(x);
+ }
+ }
+ else if((s->s_name[0] == '.') || (s->s_name[0] == '+') || (s->s_name[0] == '-') || ((s->s_name[0] >= '0') && (s->s_name[0] <= '9')))
+ {
+ x->x_inner_double_value = strtod(s->s_name, &dummy);
+ symtodp_bang(x);
+ }
+}
+
+static void symtodp_list(t_symtodp *x, t_symbol *s, int ac, t_atom *av)
+{
+ if(ac > 0)
+ {
+ x->x_inner_double_value = symtodp_calc_list_sum(ac, av);
+ // post("listtodp double: %.18g", x->x_inner_double_value);
+ symtodp_bang(x);
+ }
+}
+
+static void symtodp_anything(t_symtodp *x, t_symbol *s, int ac, t_atom *av)
+{
+ char *dummy;
+
+ if((s->s_name[0] == '"') && (s->s_name[1]))
+ {
+ if((s->s_name[1] == '.') || (s->s_name[1] == '+') || (s->s_name[1] == '-') || ((s->s_name[1] >= '0') && (s->s_name[1] <= '9')))
+ {
+ x->x_inner_double_value = strtod(s->s_name+1, &dummy);
+ symtodp_bang(x);
+ }
+ }
+}
+
+static void *symtodp_new(void)
+{
+ t_symtodp *x = (t_symtodp *)pd_new(symtodp_class);
+
+ x->x_inner_double_value = 0.0;
+ x->x_out_floatcasted = outlet_new(&x->x_obj, &s_float);
+ x->x_out_residual = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void symtodp_free(t_symtodp *x)
+{
+}
+
+void symtodp_setup(void)
+{
+ symtodp_class = class_new(gensym("symtodp"),
+ (t_newmethod)symtodp_new, (t_method)symtodp_free, sizeof(t_symtodp), 0, 0);
+ class_addbang(symtodp_class, symtodp_bang);
+ class_addfloat(symtodp_class, symtodp_float);
+ class_addsymbol(symtodp_class, symtodp_symbol);
+ class_addlist(symtodp_class, symtodp_list);
+ class_addanything(symtodp_class, symtodp_anything);
+}
diff --git a/src/tabread4_dp.c b/src/tabread4_dp.c
new file mode 100755
index 0000000..6c05079
--- /dev/null
+++ b/src/tabread4_dp.c
@@ -0,0 +1,95 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+/* -------------------------- tabread4__ ------------------------------ */
+/* based on miller's tabread4 which is part of pd */
+
+static t_class *tabread4_dp_class;
+
+typedef struct _tabread4_dp
+{
+ t_object x_obj;
+ t_symbol *x_arrayname;
+ t_float x_residual;
+} t_tabread4_dp;
+
+static void *tabread4_dp_new(t_symbol *s)
+{
+ t_tabread4_dp *x = (t_tabread4_dp *)pd_new(tabread4_dp_class);
+
+ x->x_arrayname = s;
+ floatinlet_new(&x->x_obj, &x->x_residual);
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void tabread4_dp_float(t_tabread4_dp *x, t_floatarg f)
+{
+ t_garray *ga;
+ iemarray_t *vec;
+ int npoints;
+
+ if(!(ga = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+ {
+ if(*x->x_arrayname->s_name)
+ pd_error(x, "tabread4__: %s: no such array", x->x_arrayname->s_name);
+ iemarray_setfloat(vec, 0, 0.0f);
+ }
+ else if (!iemarray_getarray(ga, &npoints, &vec))
+ {
+ pd_error(x, "%s: bad template for tabread4__", x->x_arrayname->s_name);
+ iemarray_setfloat(vec, 0, 0.0f);
+ }
+ else
+ {
+ double findex = iem_dp_calc_sum(f, x->x_residual);
+ double frac;
+ int index = findex;
+ int maxindex = npoints - 3;
+ t_sample a, b, c, d, cmb;
+
+ if(index < 1)
+ index = 1, frac = 0;
+ else if (index > maxindex)
+ index = maxindex, frac = 1;
+ else frac = findex - index;
+
+ vec += index;
+
+ a = iemarray_getfloat(vec,-1);
+ b = iemarray_getfloat(vec, 0);
+ c = iemarray_getfloat(vec, 1);
+ d = iemarray_getfloat(vec, 2);
+
+ cmb = c-b;
+ outlet_float(x->x_obj.ob_outlet, (npoints ? b+frac*(cmb-0.1666667f*(1.-frac)*((d-a-3.0f*cmb)*frac+(d+2.0f*a-3.0f*b))) : 0));
+ }
+}
+
+static void tabread4_dp_set(t_tabread4_dp *x, t_symbol *s)
+{
+ x->x_arrayname = s;
+}
+
+static void tabread4_dp_free(t_tabread4_dp *x)
+{
+}
+
+void tabread4_dp_setup(void)
+{
+ tabread4_dp_class = class_new(gensym("tabread4__"),
+ (t_newmethod)tabread4_dp_new, (t_method)tabread4_dp_free,
+ sizeof(t_tabread4_dp), 0, A_DEFSYM, 0);
+ class_addcreator((t_newmethod)tabread4_dp_new, gensym("tabread4''"), A_DEFSYM, 0);
+ class_addfloat(tabread4_dp_class, (t_method)tabread4_dp_float);
+ class_addmethod(tabread4_dp_class, (t_method)tabread4_dp_set, gensym("set"), A_SYMBOL, 0);
+}
+
diff --git a/src/tabread4~~.c b/src/tabread4~~.c
new file mode 100755
index 0000000..83f6603
--- /dev/null
+++ b/src/tabread4~~.c
@@ -0,0 +1,128 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+/* -------------------------- tabread4~~ ------------------------------ */
+/* based on miller's tabread4~ which is part of pd */
+
+static t_class *tabread4_tilde_tilde_class;
+
+typedef struct _tabread4_tilde_tilde
+{
+ t_object x_obj;
+ int x_npoints;
+ iemarray_t *x_vec;
+ t_symbol *x_arrayname;
+ t_float x_f;
+} t_tabread4_tilde_tilde;
+
+static void *tabread4_tilde_tilde_new(t_symbol *s)
+{
+ t_tabread4_tilde_tilde *x = (t_tabread4_tilde_tilde *)pd_new(tabread4_tilde_tilde_class);
+ x->x_arrayname = s;
+ x->x_vec = 0;
+ x->x_npoints=0;
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *tabread4_tilde_tilde_perform(t_int *w)
+{
+ t_tabread4_tilde_tilde *x = (t_tabread4_tilde_tilde *)(w[1]);
+ t_sample *in0 = (t_sample *)(w[2]);
+ t_sample *in1 = (t_sample *)(w[3]);
+ t_sample *out = (t_sample *)(w[4]);
+ int n = (int)(w[5]);
+ int maxindex;
+ iemarray_t *buf = x->x_vec, *wp;
+ int i;
+
+ maxindex = x->x_npoints - 3;
+ if (!buf){
+ while (n--) *out++ = 0;
+ return (w+6);
+ }
+ // post("xxx");
+ for (i = 0; i < n; i++)
+ {
+ t_sample in0_s=*in0++;
+ t_sample in1_s=*in1++;
+ double findex = iem_dp_calc_sum(in0_s, in1_s);
+ long int index = findex;
+ double frac;
+ t_sample a, b, c, d, cminusb;
+
+ if (index < 1)
+ index = 1, frac = 0;
+ else if (index > maxindex)
+ index = maxindex, frac = 1;
+ else frac = findex - index;
+
+ // post("%f + %f = %f", in0_s, in1_s, findex);
+ // post("%f - %f = %d", findex, frac, index);
+
+ wp = buf + index;
+
+ a = iemarray_getfloat(wp,-1);
+ b = iemarray_getfloat(wp, 0);
+ c = iemarray_getfloat(wp, 1);
+ d = iemarray_getfloat(wp, 2);
+
+ cminusb = c-b;
+ *out++ = b + frac * (cminusb - 0.1666667f * (1.-frac) *
+ ((d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)));
+ }
+ return (w+6);
+}
+
+static void tabread4_tilde_tilde_set(t_tabread4_tilde_tilde *x, t_symbol *s)
+{
+ t_garray *a;
+
+ x->x_arrayname = s;
+ if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+ {
+ if (*s->s_name)
+ pd_error(x, "tabread4~~: %s: no such array", x->x_arrayname->s_name);
+ iemarray_setfloat(x->x_vec, 0, 0.0f);
+ }
+ else if (!iemarray_getarray(a, &x->x_npoints, &x->x_vec))
+ {
+ pd_error(x, "%s: bad template for tabread4~~", x->x_arrayname->s_name);
+ iemarray_setfloat(x->x_vec, 0, 0.0f);
+ }
+ else garray_usedindsp(a);
+}
+
+static void tabread4_tilde_tilde_dsp(t_tabread4_tilde_tilde *x, t_signal **sp)
+{
+ tabread4_tilde_tilde_set(x, x->x_arrayname);
+
+ dsp_add(tabread4_tilde_tilde_perform, 5, x,
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
+
+}
+
+static void tabread4_tilde_tilde_free(t_tabread4_tilde_tilde *x)
+{
+}
+
+void tabread4_tilde_tilde_setup(void)
+{
+ tabread4_tilde_tilde_class = class_new(gensym("tabread4~~"),
+ (t_newmethod)tabread4_tilde_tilde_new, (t_method)tabread4_tilde_tilde_free,
+ sizeof(t_tabread4_tilde_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(tabread4_tilde_tilde_class, t_tabread4_tilde_tilde, x_f);
+ class_addmethod(tabread4_tilde_tilde_class, (t_method)tabread4_tilde_tilde_dsp, gensym("dsp"), 0);
+ class_addmethod(tabread4_tilde_tilde_class, (t_method)tabread4_tilde_tilde_set, gensym("set"), A_SYMBOL, 0);
+}
diff --git a/src/tabread_dp.c b/src/tabread_dp.c
new file mode 100755
index 0000000..c995adb
--- /dev/null
+++ b/src/tabread_dp.c
@@ -0,0 +1,82 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+/* -------------------------- tabread__ ------------------------------ */
+/* based on miller's tabread which is part of pd */
+
+static t_class *tabread_dp_class;
+
+typedef struct _tabread_dp
+{
+ t_object x_obj;
+ t_symbol *x_arrayname;
+ t_float x_residual;
+} t_tabread_dp;
+
+static void *tabread_dp_new(t_symbol *s)
+{
+ t_tabread_dp *x = (t_tabread_dp *)pd_new(tabread_dp_class);
+
+ x->x_arrayname = s;
+ floatinlet_new(&x->x_obj, &x->x_residual);
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void tabread_dp_float(t_tabread_dp *x, t_floatarg f)
+{
+ t_garray *a;
+ iemarray_t *vec;
+ int npoints;
+
+ if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+ {
+ if (*x->x_arrayname->s_name)
+ pd_error(x, "tabread__: %s: no such array", x->x_arrayname->s_name);
+ vec = 0;
+ }
+ else if (!iemarray_getarray(a, &npoints, &vec))
+ {
+ pd_error(x, "%s: bad template for tabread__", x->x_arrayname->s_name);
+ vec = 0;
+ }
+ else
+ {
+ double findex = iem_dp_calc_sum(f, x->x_residual);
+ int n = findex;
+
+ if(n < 0)
+ n = 0;
+ else if(n >= npoints)
+ n = npoints - 1;
+ outlet_float(x->x_obj.ob_outlet, (npoints ? iemarray_getfloat(vec, n) : 0));
+ }
+}
+
+static void tabread_dp_set(t_tabread_dp *x, t_symbol *s)
+{
+ x->x_arrayname = s;
+}
+
+static void tabread_dp_free(t_tabread_dp *x)
+{
+}
+
+void tabread_dp_setup(void)
+{
+ tabread_dp_class = class_new(gensym("tabread__"),
+ (t_newmethod)tabread_dp_new, (t_method)tabread_dp_free,
+ sizeof(t_tabread_dp), 0, A_DEFSYM, 0);
+ class_addcreator((t_newmethod)tabread_dp_new, gensym("tabread''"), A_DEFSYM, 0);
+ class_addfloat(tabread_dp_class, (t_method)tabread_dp_float);
+ class_addmethod(tabread_dp_class, (t_method)tabread_dp_set, gensym("set"), A_SYMBOL, 0);
+}
+
diff --git a/src/tabread~~.c b/src/tabread~~.c
new file mode 100755
index 0000000..6f5a3ce
--- /dev/null
+++ b/src/tabread~~.c
@@ -0,0 +1,117 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+/* -------------------------- tabread~~ ------------------------------ */
+/* based on miller's tabread~ which is part of pd */
+
+/******************** tabread~ ***********************/
+
+static t_class *tabread_tilde_tilde_class;
+
+typedef struct _tabread_tilde_tilde
+ {
+ t_object x_obj;
+ int x_npoints;
+ iemarray_t *x_vec;
+ t_symbol *x_arrayname;
+ t_float x_f;
+ } t_tabread_tilde_tilde;
+
+static void *tabread_tilde_tilde_new(t_symbol *s)
+{
+ t_tabread_tilde_tilde *x = (t_tabread_tilde_tilde *)pd_new(tabread_tilde_tilde_class);
+ x->x_arrayname = s;
+ x->x_npoints=0;
+ x->x_vec = 0;
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *tabread_tilde_tilde_perform(t_int *w)
+{
+ t_tabread_tilde_tilde *x = (t_tabread_tilde_tilde *)(w[1]);
+ t_sample *in0 = (t_sample *)(w[2]);
+ t_sample *in1 = (t_sample *)(w[3]);
+ t_sample *out = (t_sample *)(w[4]);
+ int n = (int)(w[5]);
+ int maxindexminusone;
+ iemarray_t *buf = x->x_vec;
+ int i;
+
+ maxindexminusone = x->x_npoints - 1;
+ if(!buf)
+ {
+ while(n--)
+ *out++ = 0;
+ return(w+6);
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ t_sample in0_s=*in0++;
+ t_sample in1_s=*in1++;
+ double findex = iem_dp_calc_sum(in0_s, in1_s);
+ int index = (int)findex;
+
+ if (index < 0)
+ index = 0;
+ else if (index > maxindexminusone)
+ index = maxindexminusone;
+ *out++ = iemarray_getfloat(buf, index);
+ }
+ return (w+6);
+}
+
+void tabread_tilde_tilde_set(t_tabread_tilde_tilde *x, t_symbol *s)
+{
+ t_garray *a;
+
+ x->x_arrayname = s;
+ if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+ {
+ if (*s->s_name)
+ pd_error(x, "tabread~: %s: no such array", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else if (!iemarray_getarray(a, &x->x_npoints, &x->x_vec))
+ {
+ pd_error(x, "%s: bad template for tabread~", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else garray_usedindsp(a);
+}
+
+static void tabread_tilde_tilde_dsp(t_tabread_tilde_tilde *x, t_signal **sp)
+{
+ tabread_tilde_tilde_set(x, x->x_arrayname);
+
+ dsp_add(tabread_tilde_tilde_perform, 5, x,
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
+
+}
+
+static void tabread_tilde_tilde_free(t_tabread_tilde_tilde *x)
+{
+}
+
+void tabread_tilde_tilde_setup(void)
+{
+ tabread_tilde_tilde_class = class_new(gensym("tabread~~"),
+ (t_newmethod)tabread_tilde_tilde_new, (t_method)tabread_tilde_tilde_free,
+ sizeof(t_tabread_tilde_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(tabread_tilde_tilde_class, t_tabread_tilde_tilde, x_f);
+ class_addmethod(tabread_tilde_tilde_class, (t_method)tabread_tilde_tilde_dsp,
+ gensym("dsp"), 0);
+ class_addmethod(tabread_tilde_tilde_class, (t_method)tabread_tilde_tilde_set,
+ gensym("set"), A_SYMBOL, 0);
+}
diff --git a/src/tabwrite_dp.c b/src/tabwrite_dp.c
new file mode 100755
index 0000000..9f81012
--- /dev/null
+++ b/src/tabwrite_dp.c
@@ -0,0 +1,85 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+/* -------------------------- tabwrite__ ------------------------------ */
+/* based on miller's tabwrite which is part of pd */
+
+static t_class *tabwrite_dp_class;
+
+typedef struct _tabwrite_dp
+{
+ t_object x_obj;
+ t_symbol *x_arrayname;
+ t_float x_float_casted_index;
+ t_float x_residual_index;
+} t_tabwrite_dp;
+
+static void *tabwrite_dp_new(t_symbol *s)
+{
+ t_tabwrite_dp *x = (t_tabwrite_dp *)pd_new(tabwrite_dp_class);
+
+ x->x_arrayname = s;
+ x->x_float_casted_index = 0.0f;
+ x->x_residual_index = 0.0f;
+ floatinlet_new(&x->x_obj, &x->x_float_casted_index);
+ floatinlet_new(&x->x_obj, &x->x_residual_index);
+ return (x);
+}
+
+static void tabwrite_dp_float(t_tabwrite_dp *x, t_floatarg fvalue)
+{
+ t_garray *a;
+ iemarray_t *vec;
+ int npoints;
+
+ if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+ {
+ if (*x->x_arrayname->s_name)
+ pd_error(x, "tabwrite__: %s: no such array", x->x_arrayname->s_name);
+ vec = 0;
+ }
+ else if (!iemarray_getarray(a, &npoints, &vec))
+ {
+ pd_error(x, "%s: bad template for tabwrite__", x->x_arrayname->s_name);
+ vec = 0;
+ }
+ else
+ {
+ double findex = iem_dp_calc_sum(x->x_float_casted_index, x->x_residual_index);
+ int n = findex;
+
+ if(n < 0)
+ n = 0;
+ else if(n >= npoints)
+ n = npoints - 1;
+ if(npoints)
+ {
+ iemarray_setfloat(vec, n, fvalue);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tabwrite_dp_set(t_tabwrite_dp *x, t_symbol *s)
+{
+ x->x_arrayname = s;
+}
+
+void tabwrite_dp_setup(void)
+{
+ tabwrite_dp_class = class_new(gensym("tabwrite__"),
+ (t_newmethod)tabwrite_dp_new, 0,
+ sizeof(t_tabwrite_dp), 0, A_DEFSYM, 0);
+ class_addcreator((t_newmethod)tabwrite_dp_new, gensym("tabwrite''"), A_DEFSYM, 0);
+ class_addfloat(tabwrite_dp_class, (t_method)tabwrite_dp_float);
+ class_addmethod(tabwrite_dp_class, (t_method)tabwrite_dp_set, gensym("set"), A_SYMBOL, 0);
+}
+
diff --git a/src/tabwrite~~.c b/src/tabwrite~~.c
new file mode 100755
index 0000000..55bec48
--- /dev/null
+++ b/src/tabwrite~~.c
@@ -0,0 +1,154 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+/* -------------------------- tabwrite~~ ------------------------------ */
+/* based on miller's tabwrite~ which is part of pd */
+
+static t_class *tabwrite_tilde_tilde_class;
+
+typedef struct _tabwrite_tilde_tilde
+{
+ t_object x_obj;
+ int x_phase;
+ int x_nsampsintab;
+ iemarray_t *x_vec;
+ t_symbol *x_arrayname;
+ t_float x_f;
+} t_tabwrite_tilde_tilde;
+
+static void *tabwrite_tilde_tilde_new(t_symbol *s)
+{
+ t_tabwrite_tilde_tilde *x = (t_tabwrite_tilde_tilde *)pd_new(tabwrite_tilde_tilde_class);
+
+ x->x_phase = 0x7fffffff;
+ x->x_arrayname = s;
+ x->x_vec = 0;
+ x->x_nsampsintab=0;
+ x->x_f = 0;
+ return (x);
+}
+
+static void tabwrite_tilde_tilde_redraw(t_tabwrite_tilde_tilde *x)
+{
+ t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
+ if(!a)
+ bug("tabwrite~~_redraw");
+ else
+ garray_redraw(a);
+}
+
+static t_int *tabwrite_tilde_tilde_perform(t_int *w)
+{
+ t_tabwrite_tilde_tilde *x = (t_tabwrite_tilde_tilde *)(w[1]);
+ t_sample *in = (t_sample *)(w[2]);
+ int n = (int)(w[3]);
+ int phase = x->x_phase, endphase = x->x_nsampsintab;
+ iemarray_t *vec = x->x_vec;
+
+ if(!x->x_vec)
+ return(w+4);
+
+ if(endphase > phase)
+ {
+ int nxfer = endphase - phase;
+ int i;
+
+ vec += phase;
+ if(nxfer > n)
+ nxfer = n;
+ phase += nxfer;
+ for(i=0; i<nxfer; i++)
+ {
+ t_sample f = *in++;
+
+ /* if(PD_BIGORSMALL(f))
+ f = 0; */
+ iemarray_setfloat(vec, i, f);
+ }
+ if(phase >= endphase)
+ {
+ tabwrite_tilde_tilde_redraw(x);
+ phase = 0x7fffffff;
+ }
+ x->x_phase = phase;
+ }
+ else
+ x->x_phase = 0x7fffffff;
+ return (w+4);
+}
+
+static void tabwrite_tilde_tilde_set(t_tabwrite_tilde_tilde *x, t_symbol *s)
+{
+ t_garray *a;
+
+ x->x_arrayname = s;
+ if(!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+ {
+ if(*s->s_name)
+ pd_error(x, "tabwrite~~: %s: no such array", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else if(!iemarray_getarray(a, &x->x_nsampsintab, &x->x_vec))
+ {
+ pd_error(x, "%s: bad template for tabwrite~~", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else
+ garray_usedindsp(a);
+}
+
+static void tabwrite_tilde_tilde_dsp(t_tabwrite_tilde_tilde *x, t_signal **sp)
+{
+ tabwrite_tilde_tilde_set(x, x->x_arrayname);
+ dsp_add(tabwrite_tilde_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
+}
+
+static void tabwrite_tilde_tilde_bang(t_tabwrite_tilde_tilde *x)
+{
+ x->x_phase = 0;
+}
+
+static void tabwrite_tilde_tilde_start(t_tabwrite_tilde_tilde *x, t_symbol *s, int ac, t_atom *av)
+{
+ double fi=0;
+ int ii=0;
+ t_float f=0, c=0;
+
+ if((ac > 0)&&((av+0)->a_type == A_FLOAT))
+ c = atom_getfloatarg(0, ac, av);
+ if((ac > 1)&&((av+1)->a_type == A_FLOAT))
+ f = atom_getfloatarg(1, ac, av);
+ fi = iem_dp_calc_sum(c, f);
+ ii = (int)fi;
+ x->x_phase = (ii > 0 ? ii : 0);
+}
+
+static void tabwrite_tilde_tilde_stop(t_tabwrite_tilde_tilde *x)
+{
+ if(x->x_phase != 0x7fffffff)
+ {
+ tabwrite_tilde_tilde_redraw(x);
+ x->x_phase = 0x7fffffff;
+ }
+}
+
+void tabwrite_tilde_tilde_setup(void)
+{
+ tabwrite_tilde_tilde_class = class_new(gensym("tabwrite~~"),
+ (t_newmethod)tabwrite_tilde_tilde_new, 0,
+ sizeof(t_tabwrite_tilde_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(tabwrite_tilde_tilde_class, t_tabwrite_tilde_tilde, x_f);
+ class_addmethod(tabwrite_tilde_tilde_class, (t_method)tabwrite_tilde_tilde_dsp, gensym("dsp"), 0);
+ class_addmethod(tabwrite_tilde_tilde_class, (t_method)tabwrite_tilde_tilde_set, gensym("set"), A_SYMBOL, 0);
+ class_addmethod(tabwrite_tilde_tilde_class, (t_method)tabwrite_tilde_tilde_start, gensym("start"), A_GIMME, 0);
+ class_addmethod(tabwrite_tilde_tilde_class, (t_method)tabwrite_tilde_tilde_stop, gensym("stop"), 0);
+ class_addbang(tabwrite_tilde_tilde_class, tabwrite_tilde_tilde_bang);
+}
diff --git a/src/vline~~.c b/src/vline~~.c
new file mode 100755
index 0000000..204724d
--- /dev/null
+++ b/src/vline~~.c
@@ -0,0 +1,220 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+
+/* -------------------------- vline~~ ------------------------------ */
+/* based on miller's vline~ which is part of pd */
+
+static t_class *vline_tilde_tilde_class;
+
+typedef struct _vseg_tt
+{
+ double s_targettime;
+ double s_starttime;
+ double s_target;
+ struct _vseg_tt *s_next;
+} t_vseg_tt;
+
+typedef struct _vline_tilde_tilde
+{
+ t_object x_obj;
+ double x_value;
+ double x_inc;
+ double x_referencetime;
+ double x_samppermsec;
+ double x_msecpersamp;
+ double x_targettime;
+ double x_target;
+ t_float x_inlet2_fine_target;
+ t_float x_inlet3_coarse_ramp_duration;
+ t_float x_inlet4_fine_ramp_duration;
+ t_float x_inlet5_coarse_delay;
+ t_float x_inlet6_fine_delay;
+ t_vseg_tt *x_list;
+} t_vline_tilde_tilde;
+
+static t_int *vline_tilde_tilde_perform(t_int *w)
+{
+ t_vline_tilde_tilde *x = (t_vline_tilde_tilde *)(w[1]);
+ t_float *out_float_cast = (t_float *)(w[2]);
+ t_float *out_residual = (t_float *)(w[3]);
+ t_float f_val;
+ int n = (int)(w[4]), i;
+ double d_val = x->x_value;
+ double inc = x->x_inc;
+ double msecpersamp = x->x_msecpersamp;
+ double samppermsec = x->x_samppermsec;
+ double timenow = clock_gettimesince(x->x_referencetime) - (double)n * msecpersamp;
+ t_vseg_tt *seg_list = x->x_list;
+
+ for(i = 0; i < n; i++)
+ {
+ double timenext = timenow + msecpersamp;
+checknext_tt:
+ if(seg_list)
+ {
+ /* has starttime elapsed? If so update value and increment */
+ if(seg_list->s_starttime < timenext)
+ {
+ if(x->x_targettime <= timenext)
+ d_val = x->x_target, inc = 0;
+ /* if zero-length segment bash output value */
+ if(seg_list->s_targettime <= seg_list->s_starttime)
+ {
+ d_val = seg_list->s_target;
+ inc = 0;
+ }
+ else
+ {
+ double incpermsec = (seg_list->s_target - d_val)/(seg_list->s_targettime - seg_list->s_starttime);
+
+ d_val += incpermsec * (timenext - seg_list->s_starttime);
+ inc = incpermsec * msecpersamp;
+ }
+ x->x_inc = inc;
+ x->x_target = seg_list->s_target;
+ x->x_targettime = seg_list->s_targettime;
+ x->x_list = seg_list->s_next;
+ t_freebytes(seg_list, sizeof(*seg_list));
+ seg_list = x->x_list;
+ goto checknext_tt;
+ }
+ }
+ if(x->x_targettime <= timenext)
+ {
+ d_val = x->x_target;
+ inc = x->x_inc = 0;
+ x->x_targettime = 1e20;
+ }
+ f_val = iem_dp_cast_to_float(d_val);
+ *out_residual++ = iem_dp_calc_residual(d_val, f_val);
+ *out_float_cast++ = f_val;
+ d_val += inc;
+ timenow = timenext;
+ }
+ x->x_value = d_val;
+ return (w+5);
+}
+
+static void vline_tilde_tilde_stop(t_vline_tilde_tilde *x)
+{
+ t_vseg_tt *s1, *s2;
+
+ for (s1 = x->x_list; s1; s1 = s2)
+ s2 = s1->s_next, t_freebytes(s1, sizeof(*s1));
+ x->x_list = 0;
+ x->x_inc = 0;
+ x->x_inlet2_fine_target = x->x_inlet3_coarse_ramp_duration = 0;
+ x->x_inlet4_fine_ramp_duration = x->x_inlet5_coarse_delay = x->x_inlet6_fine_delay = 0;
+ x->x_target = x->x_value;
+ x->x_targettime = 1e20;
+}
+
+static void vline_tilde_tilde_float(t_vline_tilde_tilde *x, t_float inlet1_coarse_target) /* coarse target value */
+{
+ double timenow = clock_gettimesince(x->x_referencetime);
+ double inlet12_target = iem_dp_calc_sum(inlet1_coarse_target, x->x_inlet2_fine_target);
+ double inlet34_ramp_duration = iem_dp_calc_sum(x->x_inlet3_coarse_ramp_duration, x->x_inlet4_fine_ramp_duration);
+ double inlet56_delay = iem_dp_calc_sum(x->x_inlet5_coarse_delay, x->x_inlet6_fine_delay);
+ double starttime = timenow + inlet56_delay;
+ t_vseg_tt *s1, *s2, *deletefrom = 0, *snew;
+
+ if(inlet34_ramp_duration < 0)
+ inlet34_ramp_duration = 0;
+
+/* if (PD_BIGORSMALL(inlet12_target))
+ inlet12_target = 0; */
+
+ /* negative delay input means stop and jump immediately to new value */
+ if (inlet56_delay < 0)
+ {
+ x->x_value = inlet12_target;
+ vline_tilde_tilde_stop(x);
+ return;
+ }
+ snew = (t_vseg_tt *)t_getbytes(sizeof(*snew));
+ /* check if we supplant the first item in the list. We supplant
+ an item by having an earlier starttime, or an equal starttime unless
+ the equal one was instantaneous and the new one isn't (in which case
+ we'll do a jump-and-slide starting at that time.) */
+ if (!x->x_list || x->x_list->s_starttime > starttime ||
+ (x->x_list->s_starttime == starttime &&
+ (x->x_list->s_targettime > x->x_list->s_starttime || inlet34_ramp_duration <= 0)))
+ {
+ deletefrom = x->x_list;
+ x->x_list = snew;
+ }
+ else
+ {
+ for (s1 = x->x_list; s2 = s1->s_next; s1 = s2)
+ {
+ if (s2->s_starttime > starttime ||
+ (s2->s_starttime == starttime &&
+ (s2->s_targettime > s2->s_starttime || inlet34_ramp_duration <= 0)))
+ {
+ deletefrom = s2;
+ s1->s_next = snew;
+ goto vl_didit_tt;
+ }
+ }
+ s1->s_next = snew;
+ deletefrom = 0;
+vl_didit_tt: ;
+ }
+ while (deletefrom)
+ {
+ s1 = deletefrom->s_next;
+ t_freebytes(deletefrom, sizeof(*deletefrom));
+ deletefrom = s1;
+ }
+ snew->s_next = 0;
+ snew->s_target = inlet12_target;
+ snew->s_starttime = starttime;
+ snew->s_targettime = starttime + inlet34_ramp_duration;
+ x->x_inlet3_coarse_ramp_duration = x->x_inlet4_fine_ramp_duration = 0;
+ x->x_inlet5_coarse_delay = x->x_inlet6_fine_delay = 0;
+}
+
+static void vline_tilde_tilde_dsp(t_vline_tilde_tilde *x, t_signal **sp)
+{
+ dsp_add(vline_tilde_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+ x->x_samppermsec = ((double)(sp[0]->s_sr)) / 1000.0;
+ x->x_msecpersamp = ((double)1000.0) / sp[0]->s_sr;
+}
+
+static void *vline_tilde_tilde_new(t_floatarg init_val)
+{
+ t_vline_tilde_tilde *x = (t_vline_tilde_tilde *)pd_new(vline_tilde_tilde_class);
+
+ outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ floatinlet_new(&x->x_obj, &x->x_inlet2_fine_target);
+ floatinlet_new(&x->x_obj, &x->x_inlet3_coarse_ramp_duration);
+ floatinlet_new(&x->x_obj, &x->x_inlet4_fine_ramp_duration);
+ floatinlet_new(&x->x_obj, &x->x_inlet5_coarse_delay);
+ floatinlet_new(&x->x_obj, &x->x_inlet6_fine_delay);
+ x->x_inlet2_fine_target = x->x_inlet3_coarse_ramp_duration = 0;
+ x->x_inlet4_fine_ramp_duration = x->x_inlet5_coarse_delay = x->x_inlet6_fine_delay = 0;
+ x->x_value = x->x_inc = 0;
+ x->x_referencetime = clock_getlogicaltime();
+ x->x_list = 0;
+ x->x_samppermsec = 0;
+ x->x_targettime = 1e20;
+ return (x);
+}
+
+void vline_tilde_tilde_setup(void)
+{
+ vline_tilde_tilde_class = class_new(gensym("vline~~"), (t_newmethod)vline_tilde_tilde_new,
+ (t_method)vline_tilde_tilde_stop, sizeof(t_vline_tilde_tilde), 0, 0);
+ class_addfloat(vline_tilde_tilde_class, (t_method)vline_tilde_tilde_float);
+ class_addmethod(vline_tilde_tilde_class, (t_method)vline_tilde_tilde_dsp, gensym("dsp"), 0);
+ class_addmethod(vline_tilde_tilde_class, (t_method)vline_tilde_tilde_stop, gensym("stop"), 0);
+}
diff --git a/src/wrap~~.c b/src/wrap~~.c
new file mode 100755
index 0000000..3c0794d
--- /dev/null
+++ b/src/wrap~~.c
@@ -0,0 +1,73 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2007 */
+/* double precision library */
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_dp.h"
+
+/* -------------------------- wrap~~ ------------------------------ */
+/* based on miller's wrap~ which is part of pd */
+
+static t_class *wrap_tilde_tilde_class;
+
+typedef struct _wrap_tilde_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+} t_wrap_tilde_tilde;
+
+static void *wrap_tilde_tilde_new(void)
+{
+ t_wrap_tilde_tilde *x = (t_wrap_tilde_tilde *)pd_new(wrap_tilde_tilde_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return(x);
+}
+
+static t_int *wrap_tilde_tilde_perform(t_int *w)
+{
+ t_sample *inc = (t_sample *)(w[1]);
+ t_sample *inf = (t_sample *)(w[2]);
+ t_sample *outc = (t_sample *)(w[3]);
+ t_sample *outf = (t_sample *)(w[4]);
+ int n = (int)(w[5]);
+
+ while(n--)
+ {
+ double coarse = *inc++;
+ double fine = *inf++;
+ double d=iem_dp_calc_sum(coarse, fine);
+ int k=(int)d;
+ t_float f;
+
+ if(d > 0)
+ d -= (double)k;
+ else
+ d -= (double)(k-1);
+
+ f = iem_dp_cast_to_float(d);
+ *outf++ = iem_dp_calc_residual(d, f);
+ *outc++ = f;
+ }
+ return(w+6);
+}
+
+static void wrap_tilde_tilde_dsp(t_wrap_tilde_tilde *x, t_signal **sp)
+{
+ dsp_add(wrap_tilde_tilde_perform, 5, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n);
+}
+
+void wrap_tilde_tilde_setup(void)
+{
+ wrap_tilde_tilde_class = class_new(gensym("wrap~~"), (t_newmethod)wrap_tilde_tilde_new, 0,
+ sizeof(t_wrap_tilde_tilde), 0, 0);
+ CLASS_MAINSIGNALIN(wrap_tilde_tilde_class, t_wrap_tilde_tilde, x_f);
+ class_addmethod(wrap_tilde_tilde_class, (t_method)wrap_tilde_tilde_dsp, gensym("dsp"), 0);
+}