aboutsummaryrefslogtreecommitdiff
path: root/src/breakpoints.c
diff options
context:
space:
mode:
authorThomas O Fredericks <mrtof@users.sourceforge.net>2008-03-31 15:41:33 +0000
committerThomas O Fredericks <mrtof@users.sourceforge.net>2008-03-31 15:41:33 +0000
commitbbde9edb23856238349150fd1038d3a540a2bd15 (patch)
treef988c12bb9cc9887a8de66246df1cba092cc3f8d /src/breakpoints.c
parent906c8c819e6089dcdde1925e82bdb88a10c3a5b1 (diff)
Added breakpoint and breakpoints to tof externals
svn path=/trunk/externals/tof/; revision=9639
Diffstat (limited to 'src/breakpoints.c')
-rwxr-xr-xsrc/breakpoints.c449
1 files changed, 449 insertions, 0 deletions
diff --git a/src/breakpoints.c b/src/breakpoints.c
new file mode 100755
index 0000000..d98753d
--- /dev/null
+++ b/src/breakpoints.c
@@ -0,0 +1,449 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+#include <m_pd.h>
+
+//#define DEBUG
+/* ------------------------ breakpoints~ ----------------------------- */
+
+#define NONE 0
+#define ATTACK 1
+#define SUSTAIN -1
+#define STATES 100
+
+
+
+#include "breakpoints~.h"
+
+#define BACKGROUNDWIDTH "1"
+#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 <stdio.h>
+
+/*
+ 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;
+ }
+}
+
+
+
+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];
+ outlet_float(x->x_obj.ob_outlet,val);
+ 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_bang(t_breakpoints *x)
+{
+ t_atom a[2];
+
+ SETFLOAT(a,x->finalvalues[NONE]);
+ SETFLOAT(a+1,0);
+
+ OUT_LIST(x,2,a);
+
+ // we don't force the first value anymore, so the first value
+ //is actually with what we have left off at the end ...
+ //this reduces clicks
+
+ x->x_state = ATTACK;
+ x->x_val = x->finalvalues[NONE];
+
+ SETFLOAT(a,x->finalvalues[x->x_state]);
+ SETFLOAT(a+1,x->duration[x->x_state]);
+
+ OUT_LIST(x,2,a);
+ clock_delay(x->x_clock,x->duration[x->x_state]);
+}
+
+/*
+
+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]);
+ 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("send %s",x->d_sym->s_name);
+ #endif
+
+ x->c_sym = &s_;
+ if (argc) x->c_sym = atom_getsymbol(argv++),argc--;
+ #ifdef DEBUG
+ post("change %s",x->d_sym->s_name);
+ #endif
+
+ 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_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);
+
+
+}
+
+