diff options
Diffstat (limited to 'iem_t3_lib/src/t3_line~.c')
-rw-r--r-- | iem_t3_lib/src/t3_line~.c | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/iem_t3_lib/src/t3_line~.c b/iem_t3_lib/src/t3_line~.c new file mode 100644 index 0000000..8d386f0 --- /dev/null +++ b/iem_t3_lib/src/t3_line~.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_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */ + + +#include "m_pd.h" +#include "iemlib.h" + +/* -------------------------- t3_line~ ------------------------------ */ +static t_class *t3_line_tilde_class; + +typedef struct _t3_line_tilde +{ + t_object x_obj; + t_clock *x_clock; + t_float *x_beg; + double x_cur_val; + double x_dst_val; + double x_inlet_val; + double x_inc64; + double x_inc; + double x_ms2samps; + double x_ticks2ms; + double x_inlet_time; + double x_dst_time; + int x_cur_samps; + int x_dur_samps; + int x_n; + int x_t3_bang_samps; + int x_transient; +} t_t3_line_tilde; + +static void t3_line_tilde_nontransient(t_float *vec, t_t3_line_tilde *x, int n) +{ + int cur_samps = x->x_cur_samps, i; + double inc = x->x_inc; + double cur_val = x->x_cur_val; + + if(cur_samps) + { + if(cur_samps > n) + { + x->x_cur_samps -= n; + while(n--) + { + cur_val += inc; + *vec++ = (t_float)cur_val; + } + x->x_cur_val += x->x_inc64; + } + else if(cur_samps == n) + { + x->x_cur_samps = 0; + while(n--) + { + cur_val += inc; + *vec++ = (t_float)cur_val; + } + x->x_cur_val = x->x_dst_val; + } + else + { + for(i=0; i<cur_samps; i++) + { + cur_val += inc; + *vec++ = (t_float)cur_val; + } + x->x_cur_val = cur_val = x->x_dst_val; + for(i=cur_samps; i<n; i++) + *vec++ = (t_float)cur_val; + x->x_cur_samps = 0; + } + } + else + { + while(n--) + *vec++ = (t_float)cur_val; + } +} + +static t_int *t3_line_tilde_perform(t_int *w) +{ + t_float *out = (t_float *)(w[1]); + t_t3_line_tilde *x = (t_t3_line_tilde *)(w[2]); + int n = (int)(w[3]); + + if(x->x_transient) + { + t_float *trans = x->x_beg; + + while(n--) + *out++ = *trans++; + x->x_transient = 0; + } + else + t3_line_tilde_nontransient(out, x, n); + return(w+4); +} + +static void t3_line_tilde_tick(t_t3_line_tilde *x) +{ + t_float *trans = x->x_beg; + int n = x->x_n, t3_bang_samps, cur_samps, i; + double inc, cur_val; + + if(!x->x_transient) + t3_line_tilde_nontransient(trans, x, n); + t3_bang_samps = x->x_t3_bang_samps; + x->x_dst_val = x->x_inlet_val; + if(x->x_inlet_time <= 0.0) + { + x->x_inlet_time = 0.0; + x->x_dst_time = 0.0; + x->x_dur_samps = 0; + x->x_cur_samps = 0; + cur_val = x->x_cur_val = x->x_dst_val; + for(i=t3_bang_samps; i<n; i++) + trans[i] = (t_float)cur_val; + } + else + { + int diff, end; + + x->x_dst_time = x->x_inlet_time; + x->x_inlet_time = 0.0; + cur_samps = (int)(x->x_dst_time * x->x_ms2samps); + if(!cur_samps) + cur_samps = 1; + x->x_dur_samps = cur_samps; + x->x_cur_samps = cur_samps; + cur_val = x->x_cur_val = (double)trans[t3_bang_samps]; + inc = x->x_inc = (x->x_dst_val - cur_val)/(double)cur_samps; + x->x_inc64 = (double)x->x_n * inc; + diff = n - t3_bang_samps; + if(cur_samps > diff) + { + for(i=t3_bang_samps; i<n; i++) + { + cur_val += inc; + trans[i] = (t_float)cur_val; + } + x->x_cur_val += (double)diff * inc; + x->x_cur_samps -= diff; + } + else if(cur_samps == diff) + { + for(i=t3_bang_samps; i<n; i++) + { + cur_val += inc; + trans[i] = (t_float)cur_val; + } + x->x_cur_val = x->x_dst_val; + x->x_cur_samps = 0; + } + else + { + end = t3_bang_samps + cur_samps; + for(i=t3_bang_samps; i<end; i++) + { + cur_val += inc; + trans[i] = (t_float)cur_val; + } + cur_val = x->x_cur_val = x->x_dst_val; + x->x_cur_samps = 0; + for(i=end; i<n; i++) + trans[i] = (t_float)cur_val; + } + } + x->x_transient = 1; +} + +static void t3_line_tilde_list(t_t3_line_tilde *x, t_symbol *s, int ac, t_atom *av) +{ + if((ac >= 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)) + { + int t3_bang_samps, ticks; + double time; + + x->x_inlet_val = (double)atom_getfloatarg(1, ac, av); + t3_bang_samps = (int)((t_float)atom_getfloatarg(0, ac, av)*x->x_ms2samps); + if(t3_bang_samps < 0) + t3_bang_samps = 0; + ticks = t3_bang_samps / x->x_n; + x->x_t3_bang_samps = t3_bang_samps - x->x_n * ticks; + if((ac >= 3)&&IS_A_FLOAT(av,2)) + { + time = (double)atom_getfloatarg(2, ac, av); + if(time < 0.0) + time = 0.0; + x->x_inlet_time = time; + } + if(ticks < 1) + t3_line_tilde_tick(x); + else + clock_delay(x->x_clock, (double)ticks * x->x_ticks2ms); + } +} + +static void t3_line_tilde_ft1(t_t3_line_tilde *x, t_float time) +{ + if(time < 0.0) + time = 0.0; + x->x_inlet_time = (double)time; +} + +static void t3_line_tilde_stop(t_t3_line_tilde *x) +{ + clock_unset(x->x_clock); + x->x_cur_samps = x->x_dur_samps = x->x_transient = 0; + x->x_inc = x->x_inc64 = x->x_inlet_time = x->x_dst_time = 0.0; +} + +static void t3_line_tilde_dsp(t_t3_line_tilde *x, t_signal **sp) +{ + int i; + t_float val, *trans; + + if(sp[0]->s_n > x->x_n) + { + freebytes(x->x_beg, x->x_n*sizeof(t_float)); + x->x_n = (int)sp[0]->s_n; + x->x_beg = (t_float *)getbytes(x->x_n*sizeof(t_float)); + } + else + x->x_n = (int)sp[0]->s_n; + i = x->x_n; + val = x->x_cur_val; + trans = x->x_beg; + while(i--) + *trans++ = val; + x->x_ms2samps = 0.001*(double)sp[0]->s_sr; + x->x_ticks2ms = (double)x->x_n / x->x_ms2samps; + dsp_add(t3_line_tilde_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); +} + +static void t3_line_tilde_free(t_t3_line_tilde *x) +{ + if(x->x_beg) + freebytes(x->x_beg, x->x_n*sizeof(t_float)); + clock_free(x->x_clock); +} + +static void *t3_line_tilde_new(t_floatarg init_val) +{ + t_t3_line_tilde *x = (t_t3_line_tilde *)pd_new(t3_line_tilde_class); + int i; + + x->x_n = (int)sys_getblksize(); + x->x_beg = (t_float *)getbytes(x->x_n*sizeof(t_float)); + x->x_inlet_val = x->x_cur_val = x->x_dst_val = init_val; + x->x_t3_bang_samps = x->x_cur_samps = x->x_dur_samps = x->x_transient = 0; + x->x_inlet_time = x->x_dst_time = 0.0; + x->x_inc64 = x->x_inc = 0.0; + x->x_ms2samps = 0.001 * (double)sys_getsr(); + x->x_ticks2ms = (double)x->x_n / x->x_ms2samps; + x->x_clock = clock_new(x, (t_method)t3_line_tilde_tick); + outlet_new(&x->x_obj, &s_signal); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); + return (x); +} + +void t3_line_tilde_setup(void) +{ + t3_line_tilde_class = class_new(gensym("t3_line~"), (t_newmethod)t3_line_tilde_new, + (t_method)t3_line_tilde_free, sizeof(t_t3_line_tilde), 0, A_DEFFLOAT, 0); + class_addmethod(t3_line_tilde_class, (t_method)t3_line_tilde_dsp, gensym("dsp"), 0); + class_addmethod(t3_line_tilde_class, (t_method)t3_line_tilde_stop, gensym("stop"), 0); + class_addmethod(t3_line_tilde_class, (t_method)t3_line_tilde_ft1, gensym("ft1"), A_FLOAT, 0); + class_addlist(t3_line_tilde_class, (t_method)t3_line_tilde_list); +// class_sethelpsymbol(t3_line_tilde_class, gensym("iemhelp/help-t3_line~")); +} |