/* flist2tab started 20090121 by mrpeach */ /* loads table from a list of floats at offset specified by second inlet */ /* floats negative offsets will not be loaded. */ /* Table will be resized to fit all the floats at positive offsets */ #include "m_pd.h" #if (PD_MINOR_VERSION > 40) #define USE_GETFLOATWORDS *//* if garray_getfloatwords is implemented */ #endif /* garray_getfloatwords uses t_word but doesn't exist in some versions of pd */ /* garray_getfloatarray uses t_float but is not 64-bit */ static t_class *flist2tab_class; typedef struct _flist2tab { t_object x_obj; t_symbol *x_arrayname; t_float x_ft1; t_float x_offset; t_outlet *x_sizeout; } t_flist2tab; static void flist2tab_list(t_flist2tab *x, t_symbol *s, int argc, t_atom *argv); static void flist2tab_float(t_flist2tab *x, t_float f); static void flist2tab_set(t_flist2tab *x, t_symbol *s); static void *flist2tab_new(t_symbol *s); void flist2tab_setup(void); static void flist2tab_list(t_flist2tab *x, t_symbol *s, int argc, t_atom *argv) { t_garray *a; #ifdef USE_GETFLOATWORDS t_word *vec; #else t_float *vec; #endif int npoints, newsize, i; int offset = x->x_offset; /* first check the list for floatness... */ for (i = 0; i < argc; ++i) { if (argv[i].a_type != A_FLOAT) { pd_error(x, "flist2tab_list: list must be all floats"); return; } } /* then find the array again... */ if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "flist2tab_list: %s: no such array", x->x_arrayname->s_name); #ifdef USE_GETFLOATWORDS else if (!garray_getfloatwords(a, &npoints, &vec)) #else else if (!garray_getfloatarray(a, &npoints, &vec)) #endif pd_error(x, "fflist2tab_list: %s: bad template", x->x_arrayname->s_name); else /* put the list in a starting at offset */ { newsize = offset + argc; if (newsize >= npoints) { garray_resize(a, newsize); #ifdef USE_GETFLOATWORDS if (!garray_getfloatwords(a, &npoints, &vec)) #else if (!garray_getfloatarray(a, &npoints, &vec)) #endif pd_error(x, "fflist2tab_list: %s: bad template", x->x_arrayname->s_name); } for (i = 0; i < argc; ++i) { if (i+offset >= 0) #ifdef USE_GETFLOATWORDS vec[i+offset].w_float = argv[i].a_w.w_float; #else vec[i+offset] = argv[i].a_w.w_float; #endif } /* output the size of the array */ outlet_float(x->x_sizeout, npoints); } } static void flist2tab_float(t_flist2tab *x, t_float f) { int i, npoints, offset = x->x_offset; t_garray *a; #ifdef USE_GETFLOATWORDS t_word *vec; #else t_float *vec; #endif if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "flist2tab_float %s: no such array", x->x_arrayname->s_name); #ifdef USE_GETFLOATWORDS else if (!garray_getfloatwords(a, &npoints, &vec)) #else else if (!garray_getfloatarray(a, &npoints, &vec)) #endif pd_error(x, "flist2tab_float %s: bad template", x->x_arrayname->s_name); else if (offset >= 0) { if (offset >= npoints) { garray_resize(a, offset+1); #ifdef USE_GETFLOATWORDS if (!garray_getfloatwords(a, &npoints, &vec)) #else if (!garray_getfloatarray(a, &npoints, &vec)) #endif pd_error(x, "flist2tab_float %s: bad template", x->x_arrayname->s_name); } #ifdef USE_GETFLOATWORDS vec[offset].w_float = f; #else vec[offset] = f; #endif garray_redraw(a); /* output the size of the array */ outlet_float(x->x_sizeout, npoints); } } static void flist2tab_set(t_flist2tab *x, t_symbol *s) { x->x_arrayname = s; } static void *flist2tab_new(t_symbol *s) { t_flist2tab *x = (t_flist2tab *)pd_new(flist2tab_class); x->x_offset = 0; x->x_arrayname = s; x->x_sizeout = outlet_new(&x->x_obj, &s_float); floatinlet_new(&x->x_obj, &x->x_offset); return (x); } void flist2tab_setup(void) { flist2tab_class = class_new(gensym("flist2tab"), (t_newmethod)flist2tab_new, 0, sizeof(t_flist2tab), 0, A_DEFSYM, 0); class_addfloat(flist2tab_class, (t_method)flist2tab_float); class_addlist(flist2tab_class, (t_method)flist2tab_list); class_addmethod(flist2tab_class, (t_method)flist2tab_set, gensym("set"), A_SYMBOL, 0); }