/* 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); }