/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iem_matrix written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2007 */ #include "m_pd.h" #include "iemlib.h" /* ---------- matrix_bundle_line8~ - signal matrix multiplication object with message matrix-coeff. ----------- */ typedef struct matrix_bundle_line8_tilde { t_object x_obj; int *x_in2out_new; int *x_in2out_old; int *x_remaining_ticks; int *x_retarget; t_float **x_io; t_float *x_outsumbuf; int x_outsumbufsize; int x_n_in; /* columns */ int x_n_out; /* rows */ t_float x_inc8; t_float x_biginc; t_float x_raise_cur; t_float x_raise_end; t_float x_fall_cur; t_float x_fall_end; t_float x_msi; int x_remaining_ticks_start; t_float x_time_ms; t_float x_ms2tick; t_float x_8overn; } t_matrix_bundle_line8_tilde; t_class *matrix_bundle_line8_tilde_class; static void matrix_bundle_line8_tilde_time(t_matrix_bundle_line8_tilde *x, t_floatarg time_ms) { if(time_ms <= 0.0f) time_ms = 0.0f; x->x_time_ms = time_ms; x->x_remaining_ticks_start = (int)(x->x_time_ms * x->x_ms2tick); if(!x->x_remaining_ticks_start) x->x_remaining_ticks_start = 1; } static void matrix_bundle_line8_tilde_element(t_matrix_bundle_line8_tilde *x, t_symbol *s, int argc, t_atom *argv) { int inindex, outindex; if(argc < 2) { post("matrix_bundle_line8~ : bad list: output_row_index input_col_index !"); return; } if(x->x_time_ms <= 0.0f) { outindex = (int)atom_getint(argv); argv++; inindex = (int)atom_getint(argv) - 1; if(inindex >= x->x_n_in) inindex = x->x_n_in - 1; if(inindex < 0) inindex = 0; if(outindex >= x->x_n_out) outindex = x->x_n_out; if(outindex < 0) outindex = 0; x->x_in2out_old[inindex] = x->x_in2out_new[inindex] = outindex;/*retarget = 0*/ x->x_remaining_ticks[inindex] = x->x_retarget[inindex] = 0; x->x_fall_end = x->x_fall_cur = 0.0f; x->x_raise_end = x->x_raise_cur = 1.0f; } else { x->x_inc8 = x->x_8overn / (float)x->x_remaining_ticks_start; x->x_biginc = 1.0f / (float)x->x_remaining_ticks_start; x->x_fall_end = 0.0f; x->x_fall_cur = 1.0f; x->x_raise_end = 1.0f; x->x_raise_cur = 0.0f; outindex = (int)atom_getint(argv); argv++; inindex = (int)atom_getint(argv) - 1; if(inindex >= x->x_n_in) inindex = x->x_n_in - 1; if(inindex < 0) inindex = 0; if(outindex >= x->x_n_out) outindex = x->x_n_out; if(outindex < 0) outindex = 0; x->x_in2out_new[inindex] = outindex; if(x->x_in2out_new[inindex] == x->x_in2out_old[inindex]) x->x_retarget[inindex] = 0; else x->x_retarget[inindex] = 1; } } static void matrix_bundle_line8_tilde_list(t_matrix_bundle_line8_tilde *x, t_symbol *s, int argc, t_atom *argv) { int outindex, i, n=x->x_n_in; if(argc < n) { post("matrix_bundle_line8~ : bad list: (number_of_input_cols = %d) * output_row_index !", n); return; } if(x->x_time_ms <= 0.0f) { for(i=0; i= x->x_n_out) outindex = x->x_n_out; if(outindex < 0) outindex = 0; x->x_in2out_old[i] = x->x_in2out_new[i] = outindex;/*retarget = 0*/ x->x_remaining_ticks[i] = x->x_retarget[i] = 0; } x->x_fall_end = x->x_fall_cur = 0.0f; x->x_raise_end = x->x_raise_cur = 1.0f; } else { x->x_inc8 = x->x_8overn / (float)x->x_remaining_ticks_start; x->x_biginc = 1.0f / (float)x->x_remaining_ticks_start; x->x_fall_end = 0.0f; x->x_fall_cur = 1.0f; x->x_raise_end = 1.0f; x->x_raise_cur = 0.0f; for(i=0; ix_in2out_old[i] = x->x_in2out_new[i]; outindex = (int)atom_getint(argv); argv++; if(outindex >= x->x_n_out) outindex = x->x_n_out; if(outindex < 0) outindex = 0; x->x_in2out_new[i] = outindex; if(x->x_in2out_new[i] == x->x_in2out_old[i]) x->x_retarget[i] = 0; else x->x_retarget[i] = 1; } } } static void matrix_bundle_line8_tilde_bundle(t_matrix_bundle_line8_tilde *x, t_symbol *s, int argc, t_atom *argv) { matrix_bundle_line8_tilde_list(x, &s_list, argc, argv); } static void matrix_bundle_line8_tilde_stop(t_matrix_bundle_line8_tilde *x) { int i, n=x->x_n_in; x->x_fall_end = x->x_fall_cur; x->x_raise_end = x->x_raise_cur; for(i=0; ix_in2out_new[i] = x->x_in2out_old[i]; x->x_remaining_ticks[i] = x->x_retarget[i] = 0; } } /* the dsp thing */ static t_int *matrix_bundle_line8_tilde_perform_zero(t_int *w) { t_matrix_bundle_line8_tilde *x = (t_matrix_bundle_line8_tilde *)(w[1]); int n = (int)(w[2]); t_float **io = x->x_io; int n_in = x->x_n_in; int n_out = x->x_n_out; t_float *out; int j, i; for(j=0; jx_io; t_float *outsum; int *in2out_new = x->x_in2out_new; int *in2out_old = x->x_in2out_old; int n_in = x->x_n_in; /* columns */ int n_out = x->x_n_out; /* rows */ t_float *in, *out, mul; t_float inc8 = x->x_inc8; int i, j, endofticks=0; for(i=0; ix_retarget[i]) { x->x_remaining_ticks[i] = x->x_remaining_ticks_start; x->x_retarget[i] = 0; } } for(j=0; jx_outsumbuf + j*n; for(i=n; i; i -= 8, outsum += 8)/* reset out-buffer */ { outsum[0] = 0.0f; outsum[1] = 0.0f; outsum[2] = 0.0f; outsum[3] = 0.0f; outsum[4] = 0.0f; outsum[5] = 0.0f; outsum[6] = 0.0f; outsum[7] = 0.0f; } } for(j=0; jx_remaining_ticks[j]) { in = io[j]; if(in2out_new[j]) { outsum = x->x_outsumbuf + n*(in2out_new[j] - 1); mul = x->x_raise_cur; for(i=n; i; i -= 8, outsum += 8, in += 8)/* each new in */ { outsum[0] += in[0]*mul; outsum[1] += in[1]*mul; outsum[2] += in[2]*mul; outsum[3] += in[3]*mul; outsum[4] += in[4]*mul; outsum[5] += in[5]*mul; outsum[6] += in[6]*mul; outsum[7] += in[7]*mul; mul += inc8; } } // raise_cur = mul; in = io[j]; if(in2out_old[j]) { outsum = x->x_outsumbuf + n*(in2out_old[j] - 1); mul = x->x_fall_cur; for(i=n; i; i -= 8, outsum += 8, in += 8)/* each old in */ { outsum[0] += in[0]*mul; outsum[1] += in[1]*mul; outsum[2] += in[2]*mul; outsum[3] += in[3]*mul; outsum[4] += in[4]*mul; outsum[5] += in[5]*mul; outsum[6] += in[6]*mul; outsum[7] += in[7]*mul; mul -= inc8; } } // fall_cur = mul; if(!--x->x_remaining_ticks[j]) { endofticks = 1; } } else { in = io[j]; if(in2out_new[j]) { outsum = x->x_outsumbuf + n*(in2out_new[j] - 1); for(i=n; i; i -= 8, outsum += 8, in += 8)/* each in */ { outsum[0] += in[0]; outsum[1] += in[1]; outsum[2] += in[2]; outsum[3] += in[3]; outsum[4] += in[4]; outsum[5] += in[5]; outsum[6] += in[6]; outsum[7] += in[7]; } } } } if(x->x_remaining_ticks[j]) { x->x_raise_cur += x->x_biginc; x->x_fall_cur -= x->x_biginc; } if(endofticks) { x->x_fall_cur = x->x_fall_end; x->x_raise_cur = x->x_raise_end; } outsum = x->x_outsumbuf; for(j=0; js_n*x->x_n_out; if(!x->x_outsumbuf) { x->x_outsumbufsize = n; x->x_outsumbuf = (t_float *)getbytes(x->x_outsumbufsize * sizeof(t_float)); } else if(x->x_outsumbufsize != n) { x->x_outsumbuf = (t_float *)resizebytes(x->x_outsumbuf, x->x_outsumbufsize*sizeof(t_float), n*sizeof(t_float)); x->x_outsumbufsize = n; } n = x->x_n_in + x->x_n_out; for(i=0; ix_io[i] = sp[i]->s_vec; n = sp[0]->s_n; x->x_ms2tick = 0.001f * (float)(sp[0]->s_sr) / (float)n; x->x_8overn = 8.0f / (float)n; x->x_remaining_ticks_start = (int)(x->x_time_ms * x->x_ms2tick); if(!x->x_remaining_ticks_start) x->x_remaining_ticks_start = 1; if(n&7) { dsp_add(matrix_bundle_line8_tilde_perform_zero, 2, x, n); post("ERROR!!! matrix_bundle_line8_tilde~ : blocksize is %d and not a multiple of 8", n); } else dsp_add(matrix_bundle_line8_tilde_perf8, 2, x, n); } /* setup/setdown things */ static void matrix_bundle_line8_tilde_free(t_matrix_bundle_line8_tilde *x) { freebytes(x->x_in2out_new, x->x_n_in * sizeof(int)); freebytes(x->x_in2out_old, x->x_n_in * sizeof(int)); freebytes(x->x_remaining_ticks, x->x_n_in * sizeof(int)); freebytes(x->x_retarget, x->x_n_in * sizeof(int)); freebytes(x->x_io, (x->x_n_in + x->x_n_out) * sizeof(t_float *)); if(x->x_outsumbuf) freebytes(x->x_outsumbuf, x->x_outsumbufsize * sizeof(t_float)); } static void *matrix_bundle_line8_tilde_new(t_symbol *s, int argc, t_atom *argv) { t_matrix_bundle_line8_tilde *x = (t_matrix_bundle_line8_tilde *)pd_new(matrix_bundle_line8_tilde_class); int i, n; switch (argc) { case 0: x->x_n_in = x->x_n_out = 1; x->x_time_ms = 50.0f; break; case 1: x->x_n_in = x->x_n_out = (int)atom_getint(argv); x->x_time_ms = 50.0f; break; case 2: x->x_n_in = (int)atom_getint(argv); x->x_n_out = (int)atom_getint(argv+1); x->x_time_ms = 50.0f; break; default: x->x_n_in = (int)atom_getint(argv); x->x_n_out = (int)atom_getint(argv+1); x->x_time_ms = atom_getfloat(argv+2); break; } if(x->x_n_in < 1) x->x_n_in = 1; if(x->x_n_out < 1) x->x_n_out = 1; if(x->x_time_ms < 0.0f) x->x_time_ms = 50.0f; i = x->x_n_in - 1; while(i--) inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); i = x->x_n_out; while(i--) outlet_new(&x->x_obj, &s_signal); x->x_in2out_new = (int *)getbytes(x->x_n_in * sizeof(int)); x->x_in2out_old = (int *)getbytes(x->x_n_in * sizeof(int)); x->x_remaining_ticks = (int *)getbytes(x->x_n_in * sizeof(int)); x->x_retarget = (int *)getbytes(x->x_n_in * sizeof(int)); x->x_io = (t_float **)getbytes((x->x_n_in + x->x_n_out) * sizeof(t_float *)); x->x_outsumbuf = (t_float *)0; x->x_outsumbufsize = 0; x->x_raise_cur = 1.0f; x->x_raise_end = 1.0f; x->x_fall_cur = 0.0f; x->x_fall_end = 0.0f; x->x_inc8 = 0.0f; x->x_biginc = 0.0f; x->x_msi = 0; x->x_ms2tick = 0.001f * 44100.0f / 64.0f; x->x_8overn = 8.0f / 64.0f; x->x_remaining_ticks_start = (int)(x->x_time_ms * x->x_ms2tick); if(!x->x_remaining_ticks_start) x->x_remaining_ticks_start = 1; n = x->x_n_in; for(i=0; ix_in2out_new[i] = 0; x->x_in2out_old[i] = 0; x->x_remaining_ticks[i] = 0; x->x_retarget[i] = 0; } return(x); } void matrix_bundle_line8_tilde_setup(void) { matrix_bundle_line8_tilde_class = class_new(gensym("matrix_bundle_line8~"), (t_newmethod)matrix_bundle_line8_tilde_new, (t_method)matrix_bundle_line8_tilde_free, sizeof(t_matrix_bundle_line8_tilde), 0, A_GIMME, 0); CLASS_MAINSIGNALIN(matrix_bundle_line8_tilde_class, t_matrix_bundle_line8_tilde, x_msi); class_addmethod(matrix_bundle_line8_tilde_class, (t_method)matrix_bundle_line8_tilde_dsp, gensym("dsp"), 0); class_addlist(matrix_bundle_line8_tilde_class, (t_method)matrix_bundle_line8_tilde_list); class_addmethod(matrix_bundle_line8_tilde_class, (t_method)matrix_bundle_line8_tilde_element, gensym("element"), A_GIMME, 0); class_addmethod(matrix_bundle_line8_tilde_class, (t_method)matrix_bundle_line8_tilde_bundle, gensym("bundle"), A_GIMME, 0); class_addmethod(matrix_bundle_line8_tilde_class, (t_method)matrix_bundle_line8_tilde_stop, gensym("stop"), 0); class_addmethod(matrix_bundle_line8_tilde_class, (t_method)matrix_bundle_line8_tilde_time, gensym("time"), A_FLOAT, 0); // class_sethelpsymbol(matrix_bundle_line8_tilde_class, gensym("iemhelp/matrix_bundle_line8~-help")); }