From bbde9edb23856238349150fd1038d3a540a2bd15 Mon Sep 17 00:00:00 2001 From: Thomas O Fredericks Date: Mon, 31 Mar 2008 15:41:33 +0000 Subject: Added breakpoint and breakpoints to tof externals svn path=/trunk/externals/tof/; revision=9639 --- src/breakpoints~.c | 479 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 479 insertions(+) create mode 100755 src/breakpoints~.c (limited to 'src/breakpoints~.c') diff --git a/src/breakpoints~.c b/src/breakpoints~.c new file mode 100755 index 0000000..b7135b2 --- /dev/null +++ b/src/breakpoints~.c @@ -0,0 +1,479 @@ +/* (C) Guenter Geiger */ + +#include + +//#define DEBUG +/* ------------------------ breakpoints~ ----------------------------- */ + +#define NONE 0 +#define ATTACK 1 +#define SUSTAIN -1 +#define STATES 100 + + + +#include "breakpoints~.h" + +#define BACKGROUNDWIDTH "2" +#include "w_breakpoints.h" + +static t_class *breakpoints_class; + + +#define OUT_LIST(x,nr,a) \ + outlet_list(x->x_obj.ob_outlet,&s_list,nr,(t_atom*)&a);\ + if (x->s_sym != &s_ && x->s_sym->s_thing) pd_list(x->s_sym->s_thing, &s_list, nr, (t_atom*)&a); + + +char dumpy[2000]; + +/* initialize envelope with argument vector */ + +#include + +/* + breakpoints crashes frequently when reallocating memory .... + I really don't know why, it crashes during resizebytes, + which means it is unable to realloc() the memory ????? + the pointer seems to be ok, I don't know what else could + cause the problem. for the moment we prevent from reallocating + by setting the STATES variable to 100 */ + +void breakpoints_resize(t_breakpoints* x,int ns) +{ + if (ns > x->args) { + int newargs = ns*sizeof(t_float); + + x->duration = resizebytes(x->duration,x->args*sizeof(t_float),newargs); + x->finalvalues = resizebytes(x->finalvalues,x->args*sizeof(t_float),newargs); + x->args = ns; + } +} + + /* this is the actual performance routine which acts on the samples. + It's called with a single pointer "w" which is our location in the + DSP call list. We return a new "w" which will point to the next item + after us. Meanwhile, w[0] is just a pointer to dsp-perform itself + (no use to us), w[1] and w[2] are the input and output vector locations, + and w[3] is the number of points to calculate. */ +static t_int *breakpointssig_perform(t_int *w) +{ + + t_breakpoints *x = (t_breakpoints *)(w[1]); + t_float *in = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + int n = (int)(w[4]); + + int state; + float f; + float val; + + while (n--) + { + + // STUFF + state = 0; + f = *(in++); + + while (x->duration[state] < f && state < x->last_state) state++; + + if (state == 0 || f >= x->duration[x->last_state]) { + val = x->finalvalues[state]; + + } else { + val = x->finalvalues[state-1] + (f - x->duration[state-1]) * + (x->finalvalues[state] - x->finalvalues[state-1]) / + (x->duration[state] - x->duration[state-1]); + + + + } + // STUFF END + + + *out++ = val; + } + return (w+5); +} + + + + /* called to start DSP. Here we call Pd back to add our perform + routine to a linear callback list which Pd in turn calls to grind + out the samples. */ +static void breakpointssig_dsp(t_breakpoints *x, t_signal **sp) +{ + dsp_add(breakpointssig_perform, 4, x,sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +void breakpoints_totaldur(t_breakpoints* x,t_float dur) +{ + int i; + float f = dur/x->duration[x->last_state]; + + if (dur < 10) { + post("breakpoints: duration too small %f",dur); + return; + } + + for (i=1;i<=x->last_state;i++) + x->duration[i]*=f; +} + + +static void breakpoints_dump(t_breakpoints* e) +{ + t_atom argv[50]; + int argc= 0; + t_atom* a = argv; + int i; + + SETFLOAT(a,e->finalvalues[0]);argc++; + for (i=1;i <= e->last_state;i++) { + SETFLOAT(argv+argc,e->duration[i] - e->duration[i-1]); + argc++; + SETFLOAT(argv+argc,e->finalvalues[i]); + argc++; + } + outlet_list(e->out2,&s_list,argc,(t_atom*)&argv); + if (e->d_sym != &s_) pd_list(e->d_sym->s_thing, &s_list, argc, argv); + //pd_float(x->s_sym->s_thing, val); + //EXTERN void pd_float(t_pd *x, t_float f); + //EXTERN void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv); + //EXTERN void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv); + ///////////////////////////////////////////////////// +} + +void breakpoints_init(t_breakpoints *x,int argc,t_atom* argv) +{ + t_float* dur; + t_float* val; + t_float tdur = 0; + + if (!argc) return; + + x->duration[0] = 0; + + x->last_state = argc>>1; + breakpoints_resize(x,argc>>1); + + dur = x->duration; + val = x->finalvalues; + + // get the first value + if (argc) { + *val = atom_getfloat(argv++); + *dur = 0.0; + x->max = *val; + x->min = *val; + } + dur++;val++;argc--; + // get the following + for (;argc > 0;argc--) { + tdur += atom_getfloat(argv++); +#ifdef DEBUG + post("dur =%f",tdur); +#endif + *dur++ = tdur; + argc--; + if (argc > 0) { + *val = atom_getfloat(argv++); + if (*val > x->max ) x->max = *val; + if (*val < x->min ) x->min = *val; + *val++; + } else { + *val = 0; + if (*val > x->max ) x->max = *val; + if (*val < x->min ) x->min = *val; + *val++; + } +#ifdef DEBUG + post("val =%f",*(val-1)); +#endif + + } + + if ( x->max == x->min ) { + if ( x->max == 0 ) { + x->max = 1; + } else { + if (x->max > 0) { + x->min = 0; + } else { + x->max = 0; + } + } + } + +} + + + + + +void breakpoints_list(t_breakpoints *x,t_symbol* s, int argc,t_atom* argv) +{ + breakpoints_init(x,argc,argv); + if (glist_isvisible(x->w.glist)) { + breakpoints_drawme(x, x->w.glist, 0); + } +} + +void breakpoints_setresize(t_breakpoints *x, t_floatarg f) +{ + x->resizeable = f; +} + + + + + +void breakpoints_float(t_breakpoints *x, t_floatarg f) +{ + int state = 0; + float val; + + + + while (x->duration[state] < f && state < x->last_state) state++; + + if (state == 0 || f >= x->duration[x->last_state]) { + val = x->finalvalues[state]*(x->max-x->min); + outlet_float(x->x_obj.ob_outlet,f); + if (x->s_sym != &s_) pd_float(x->s_sym->s_thing, f); + return; + } + + val = x->finalvalues[state-1] + + (f - x->duration[state-1])* + (x->finalvalues[state] - x->finalvalues[state-1])/ + (x->duration[state] - x->duration[state-1]); + + val *= (x->max - x->min); + outlet_float(x->x_obj.ob_outlet,val); + if (x->s_sym != &s_) pd_float(x->s_sym->s_thing, val); +} + + + + + + +/* + +void breakpoints_release(t_breakpoints* x) { + t_atom a[2]; + float del = x->duration[x->x_state] - x->duration[x->x_state-1]; + if (x->x_state <= x->sustain_state) { + x->x_state = x->sustain_state+1; // skip sustain state + clock_delay(x->x_clock,del); + SETFLOAT(a,x->finalvalues[x->x_state]*(x->max-x->min)); + SETFLOAT(a+1,del); + OUT_LIST(x,2,a); + } +} + +static void breakpoints_sustain(t_breakpoints *x, t_floatarg f) +{ + if (f > 0 && f < x->last_state) + x->sustain_state = f; + else + pd_error(x,"sustain value not betweem 0 and %f, ignoring message", x->last_state); +} + +*/ + +/* +static void breakpoints_tick(t_breakpoints* x) +{ + t_atom a[2]; + x->x_state++; + if (x->x_state <= x->last_state && x->x_state != x->sustain_state) { + float del = x->duration[x->x_state] - x->duration[x->x_state-1]; + clock_delay(x->x_clock,del); + SETFLOAT(a,x->finalvalues[x->x_state]*(x->max-x->min)); + SETFLOAT(a+1,del); + OUT_LIST(x,2,a); + } +// else +// clock_unset(x->x_clock); +} + +*/ + +/* +static void breakpoints_freeze(t_breakpoints* x, t_floatarg f) +{ + x->x_freeze = f; +} +*/ + +static void bindsym(t_pd* x,t_symbol* o,t_symbol* s) +{ + if (o != &s_) pd_unbind(x,o); + o = s; + pd_bind(x,s); +} + + + + + + + + +static void *breakpoints_new(t_symbol *s,int argc,t_atom* argv) +{ + t_breakpoints *x = (t_breakpoints *)pd_new(breakpoints_class); + + + + x->x_f = 0; + x->args = STATES; + x->finalvalues = getbytes( x->args*sizeof(t_float)); + x->duration = getbytes( x->args*sizeof(t_float)); +#ifdef DEBUG + post("finalvalues %x",x->finalvalues); +#endif + /* widget */ + + x->w.grabbed = 0; + x->resizing = 0; + x->resizeable = 0; + x->w.glist = (t_glist*) canvas_getcurrent(); + + x->w.width = 200; + if (argc) x->w.width = atom_getfloat(argv++),argc--; + x->w.height = 140; + if (argc) x->w.height = atom_getfloat(argv++),argc--; + + t_float initialDuration = 100; + if (argc) initialDuration = atom_getfloat(argv++),argc--; + + x->r_sym = &s_; + if (argc) { + t_symbol* n; + + n = atom_getsymbol(argv++); + bindsym(&x->x_obj.ob_pd,x->r_sym,n); + x->r_sym = n; + argc--; + } + #ifdef DEBUG + post("recv %s",x->r_sym->s_name); + #endif + /* + x->s_sym = &s_; + if (argc) x->s_sym = atom_getsymbol(argv++),argc--; + #ifdef DEBUG + post("send %s",x->s_sym->s_name); + #endif + */ + x->d_sym = &s_; + if (argc) x->d_sym = atom_getsymbol(argv++),argc--; + #ifdef DEBUG + post("dump %s",x->d_sym->s_name); + #endif + + x->c_sym = &s_; + if (argc) x->c_sym = atom_getsymbol(argv++),argc--; + + if (argc>2) + breakpoints_init(x,argc,argv); + else { + t_atom a[5]; + SETFLOAT(a,0); + SETFLOAT(a+1,50); + SETFLOAT(a+2,1); + SETFLOAT(a+3,50); + SETFLOAT(a+4,0); + breakpoints_init(x,5,a); + } + + x->x_val = 0.0; + x->x_state = NONE; + x->sustain_state = SUSTAIN; + x->x_freeze = 0; + + breakpoints_totaldur(x,initialDuration); + + outlet_new(&x->x_obj, gensym("signal")); + //outlet_new(&x->x_obj, &s_float); + x->out2 = outlet_new(&x->x_obj, &s_float); + x->out3 = outlet_new(&x->x_obj, &s_bang); + + //x->x_clock = clock_new(x, (t_method) breakpoints_tick); + return (x); +} + + + + +void breakpoints_motion(t_breakpoints *x, t_floatarg dx, t_floatarg dy); +void breakpoints_click(t_breakpoints *x, + t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, + t_floatarg alt); +void breakpoints_key(t_breakpoints *x, t_floatarg f); + +t_widgetbehavior breakpoints_widgetbehavior; + + + +static void breakpoints_free(t_breakpoints *x) { + + + if (x->r_sym != &s_) pd_unbind(&x->x_obj.ob_pd, x->r_sym); + +} + +void breakpoints_tilde_setup(void) +{ + breakpoints_class = class_new(gensym("breakpoints~"), (t_newmethod)breakpoints_new, (t_method)breakpoints_free, + sizeof(t_breakpoints), 0,A_GIMME,0); + + CLASS_MAINSIGNALIN(breakpoints_class, t_breakpoints, x_f); + /* here we tell Pd about the "dsp" method, which is called back + when DSP is turned on. */ + class_addmethod(breakpoints_class, (t_method)breakpointssig_dsp, gensym("dsp"), 0); + + + //class_addcreator((t_newmethod)breakpoints_new,gensym("breakpoints~"),A_GIMME,0); + //class_addfloat(breakpoints_class, breakpoints_float); + + //class_addbang(breakpoints_class,breakpoints_bang); + class_addlist(breakpoints_class,breakpoints_list); + //class_addmethod(breakpoints_class,(t_method)breakpoints_sustain,gensym("sustain"),A_FLOAT,A_NULL); + + class_addmethod(breakpoints_class, (t_method)breakpoints_motion, gensym("motion"),A_FLOAT, A_FLOAT, 0); + class_addmethod(breakpoints_class, (t_method)breakpoints_key, gensym("key"), + A_FLOAT, 0); + + class_addmethod(breakpoints_class,(t_method)breakpoints_totaldur,gensym("duration"),A_FLOAT,NULL); + //class_addmethod(breakpoints_class,(t_method)breakpoints_freeze,gensym("freeze"),A_FLOAT,NULL); + class_addmethod(breakpoints_class,(t_method)breakpoints_setresize,gensym("resize"),A_FLOAT,A_NULL); + + //class_addmethod(breakpoints_class,(t_method)breakpoints_release,gensym("release"),A_NULL); + breakpoints_widgetbehavior.w_getrectfn = breakpoints_getrect; + breakpoints_widgetbehavior.w_displacefn = breakpoints_displace; + breakpoints_widgetbehavior.w_selectfn = breakpoints_select; + breakpoints_widgetbehavior.w_activatefn = breakpoints_activate; + breakpoints_widgetbehavior.w_deletefn = breakpoints_delete; + breakpoints_widgetbehavior.w_visfn = breakpoints_vis; + breakpoints_widgetbehavior.w_clickfn = (t_clickfn) breakpoints_newclick; + //breakpoints_widgetbehavior.w_clickfn = NULL; +#if PD_MINOR_VERSION < 37 + breakpoints_widgetbehavior.w_propertiesfn = NULL; + //breakpoints_widgetbehavior.w_savefn = breakpoints_save; + breakpoints_widgetbehavior.w_savefn = NULL; +#endif + + class_setwidget(breakpoints_class,&breakpoints_widgetbehavior); +#if PD_MINOR_VERSION >= 37 + //class_setsavefn(breakpoints_class,&breakpoints_save); +#endif + class_addmethod(breakpoints_class,(t_method)breakpoints_dump,gensym("dump"),A_NULL); + + +} + + -- cgit v1.2.1