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