aboutsummaryrefslogtreecommitdiff
path: root/src/mul~~.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mul~~.c')
-rwxr-xr-xsrc/mul~~.c272
1 files changed, 272 insertions, 0 deletions
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);
+}