/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* This is a modified version of Joseph A. Sarlo's code. The most important changes are listed in "pd-lib-notes.txt" file. */ #include "m_pd.h" #include "shared.h" typedef struct _Bucket { t_object x_ob; int x_numbucks; t_float *x_bucks; /* CHECKED: no limit */ t_outlet **x_outs; short int x_frozen; /* 0 for thawed, 1 for frozen */ short int x_dir; /* 0 for L2R, 1 for R2L */ short int x_max5mode; /* 0 for classic Max 4.6 mode, 1 for Max 5 mode (with 2nd !0 argument) */ } t_Bucket; static t_class *Bucket_class; static void Bucket_bang(t_Bucket *x) { int i = x->x_numbucks; /* CHECKED: outlets output in right-to-left order */ while (i--) outlet_float(x->x_outs[i], x->x_bucks[i]); } static void Bucket_float(t_Bucket *x, t_float val) { int i; if (!x->x_frozen) Bucket_bang(x); if (!x->x_dir) { for (i = x->x_numbucks - 1; i > 0; i--) x->x_bucks[i] = x->x_bucks[i - 1]; x->x_bucks[0] = val; } else { for (i = 0; i < x->x_numbucks - 1; i++) x->x_bucks[i] = x->x_bucks[i + 1]; x->x_bucks[x->x_numbucks - 1] = val; } if (x->x_max5mode && !x->x_frozen) Bucket_bang(x); } static void Bucket_freeze(t_Bucket *x) { x->x_frozen = 1; } static void Bucket_thaw(t_Bucket *x) { x->x_frozen = 0; } static void Bucket_roll(t_Bucket *x) { if (x->x_dir) Bucket_float(x, x->x_bucks[0]); else Bucket_float(x, x->x_bucks[x->x_numbucks - 1]); } static void Bucket_rtol(t_Bucket *x) { x->x_dir = 1; } static void Bucket_ltor(t_Bucket *x) { x->x_dir = 0; } static void Bucket_set(t_Bucket *x, t_floatarg f) { int i = x->x_numbucks; while (i--) x->x_bucks[i] = f; if (!x->x_frozen) /* CHECKED */ Bucket_bang(x); } static void Bucket_free(t_Bucket *x) { if (x->x_bucks) freebytes(x->x_bucks, x->x_numbucks * sizeof(*x->x_bucks)); if (x->x_outs) freebytes(x->x_outs, x->x_numbucks * sizeof(*x->x_outs)); } static void *Bucket_new(t_floatarg val, t_floatarg max5mode) { t_Bucket *x; int nbucks = (int)val; t_float *bucks; t_outlet **outs; if (nbucks < 1) nbucks = 1; if (!(bucks = (t_float *)getbytes(nbucks * sizeof(*bucks)))) return (0); if (!(outs = (t_outlet **)getbytes(nbucks * sizeof(*outs)))) { freebytes(bucks, nbucks * sizeof(*bucks)); return (0); } x = (t_Bucket *)pd_new(Bucket_class); x->x_numbucks = nbucks; x->x_bucks = bucks; x->x_outs = outs; x->x_frozen = 0; x->x_dir = 0; x->x_max5mode = ((int)max5mode != 0); while (nbucks--) *outs++ = outlet_new((t_object *)x, &s_float); return (x); } void Bucket_setup(void) { Bucket_class = class_new(gensym("Bucket"), (t_newmethod)Bucket_new, (t_method)Bucket_free, sizeof(t_Bucket), 0, A_DEFFLOAT, A_DEFFLOAT, 0); class_addcreator((t_newmethod)Bucket_new, gensym("bucket"), A_DEFFLOAT, 0); class_addcreator((t_newmethod)Bucket_new, gensym("cyclone/bucket"), A_DEFFLOAT, 0); class_addbang(Bucket_class, Bucket_bang); class_addfloat(Bucket_class, Bucket_float); class_addmethod(Bucket_class, (t_method)Bucket_freeze, gensym("freeze"), 0); class_addmethod(Bucket_class, (t_method)Bucket_thaw, gensym("thaw"), 0); class_addmethod(Bucket_class, (t_method)Bucket_ltor, gensym("L2R"), 0); class_addmethod(Bucket_class, (t_method)Bucket_rtol, gensym("R2L"), 0); /* CHECKED (refman error) roll has no argument */ class_addmethod(Bucket_class, (t_method)Bucket_roll, gensym("roll"), 0); /* 3.5 additions */ class_addmethod(Bucket_class, (t_method)Bucket_set, gensym("set"), A_FLOAT, 0); class_addmethod(Bucket_class, (t_method)Bucket_ltor, gensym("l2r"), 0); class_addmethod(Bucket_class, (t_method)Bucket_rtol, gensym("r2l"), 0); // logpost(NULL, 4, "this is cyclone/Bucket %s, %dth %s build", // CYCLONE_VERSION, CYCLONE_BUILD, CYCLONE_RELEASE); } void bucket_setup(void) { Bucket_setup(); }