From 2103be3cd9f8abfcafe8693aa677fe0e6d4757af Mon Sep 17 00:00:00 2001 From: Martin Peach Date: Thu, 22 Jan 2009 18:51:25 +0000 Subject: tab2flist extracts a list of floats from a table at a given offset. The length of the list can be set via the second inlet. Points outside the table are returned as zeros. svn path=/trunk/externals/mrpeach/; revision=10597 --- tab2flist/tab2flist-help.pd | 29 ++++++++ tab2flist/tab2flist.c | 156 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 tab2flist/tab2flist-help.pd create mode 100644 tab2flist/tab2flist.c (limited to 'tab2flist') diff --git a/tab2flist/tab2flist-help.pd b/tab2flist/tab2flist-help.pd new file mode 100644 index 0000000..d0c0861 --- /dev/null +++ b/tab2flist/tab2flist-help.pd @@ -0,0 +1,29 @@ +#N canvas 650 129 535 246 10; +#X obj 117 117 tab2flist zig; +#X obj 10 -5 bng 15 250 50 0 empty empty empty 17 7 0 10 -4034 -257985 +-1; +#X obj 117 138 print; +#X obj 155 138 table zig; +#X text 110 208 2009 1 21 Martin Peach; +#X floatatom 192 89 5 0 0 0 - - -; +#X floatatom 64 48 5 0 0 0 - - -; +#X text 33 -8 Banging tab2flist outputs a list of floats from the table. +; +#X msg 36 19 set zag; +#X text 205 117 Argument is table name.; +#X text 115 155 Points outside the table will be output as zeroes. +; +#X text 98 47 A single float sets offset.; +#X text 89 18 Set the table by name.; +#X obj 215 138 table zag; +#X msg 86 69 5 10; +#X text 115 169 Negative length outputs a list as long as the table. +; +#X text 229 86 Float in second inlet sets length of list.; +#X text 118 68 Two floats set offset and length.; +#X connect 0 0 2 0; +#X connect 1 0 0 0; +#X connect 5 0 0 1; +#X connect 6 0 0 0; +#X connect 8 0 0 0; +#X connect 14 0 0 0; diff --git a/tab2flist/tab2flist.c b/tab2flist/tab2flist.c new file mode 100644 index 0000000..2b3bfd0 --- /dev/null +++ b/tab2flist/tab2flist.c @@ -0,0 +1,156 @@ +/* tab2flist started 20090121 by mrpeach */ +/* Message with two floats dumps a list of floats from a table at offset,length */ +/* Bang dumps the entire table as a list of floats */ +/* Floats at negative offsets will not be dumped. */ + +#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 *tab2flist_class; + +typedef struct _tab2flist +{ + t_object x_obj; + t_outlet *x_listout; + t_symbol *x_arrayname; + t_float x_offset; + t_float x_length; +} t_tab2flist; + +//static void tab2flist_list(t_tab2flist *x, t_symbol *s, int argc, t_atom *argv); +static void tab2flist_float(t_tab2flist *x, t_float f); +static void tab2flist_bang(t_tab2flist *x); +static void tab2flist_set(t_tab2flist *x, t_symbol *s); +static void *tab2flist_new(t_symbol *s); +void tab2flist_setup(void); + +static void tab2flist_bang(t_tab2flist *x) +{ + /* output a list of x_length floats from the table starting from x_offset */ + /* output zero for elements outside the table (e.g. negative x_offset) */ + + t_garray *a; + int n, i, tabpoints, listpoints; + int listsize; + t_atom *atomlist = NULL; +#ifdef USE_GETFLOATWORDS + t_word *vec; +#else + t_float *vec; +#endif + + /* Read in the array */ + if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) + pd_error(x, "tab2flist_list: %s: no such array", x->x_arrayname->s_name); +#ifdef USE_GETFLOATWORDS + else if (!garray_getfloatwords(a, &tabpoints, &vec)) +#else + else if (!garray_getfloatarray(a, &tabpoints, &vec)) +#endif + pd_error(x, "tab2flist_list: %s: bad template", x->x_arrayname->s_name); + else if (x->x_length != 0) + { + if (x->x_length > 0) listpoints = x->x_length; + else listsize = tabpoints; /* when x_length < 0, output the whole table */ + listsize = listpoints * sizeof(t_atom); + atomlist = getbytes(listsize); + if (atomlist == NULL) + { + pd_error(x, "tab2flist_list: unable to allocate %lu bytes for list", listsize); + return; + } + else + { + for (n = x->x_offset, i = 0; i < listpoints; ++n) + { + if ((n >= 0) && (n < tabpoints)) + { +#ifdef USE_GETFLOATWORDS + SETFLOAT(&atomlist[i], vec[n].w_float); +#else + SETFLOAT(&atomlist[i], vec[n]); +#endif + } + else + { +#ifdef USE_GETFLOATWORDS + SETFLOAT(&atomlist[i], 0); +#else + SETFLOAT(&atomlist[i], 0); +#endif + } + i++; + } + outlet_list(x->x_listout, &s_list, listpoints, atomlist); + freebytes(atomlist, listsize); + } + } +} + +#ifdef NOWAY + +static void tab2flist_list(t_tab2flist *x, t_symbol *s, int argc, t_atom *argv) +{ + int i; + /* expect a list of 2 floats for offset and packet length */ + + /* Check the incoming list for length = 2 */ + if (argc != 2) + { + pd_error(x, "tab2flist_list: list must contain exactly two floats (offset, length)"); + return; + } + + /* Check the incoming list for floatness... */ + for (i = 0; i < 2; ++i) + { + if (argv[i].a_type != A_FLOAT) + { + pd_error(x, "tab2flist_list: list must contain exactly two floats (offset, length)"); + return; + } + } + /* Read offset and packet size from incoming list */ + x->x_offset = argv[0].a_w.w_float; + x->x_length = argv[1].a_w.w_float; + +} +#endif + +static void tab2flist_float(t_tab2flist *x, t_float f) +{ + x->x_offset = f; +} + +static void tab2flist_set(t_tab2flist *x, t_symbol *s) +{ + x->x_arrayname = s; +} + +static void *tab2flist_new(t_symbol *s) +{ + t_tab2flist *x = (t_tab2flist *)pd_new(tab2flist_class); + x->x_listout = outlet_new(&x->x_obj, &s_list); + floatinlet_new(&x->x_obj, &x->x_length); + x->x_offset = 0; + x->x_length = -1; /* default to output the whole table */ + x->x_arrayname = s; + return (x); +} + +void tab2flist_setup(void) +{ + tab2flist_class = class_new(gensym("tab2flist"), (t_newmethod)tab2flist_new, + 0, sizeof(t_tab2flist), 0, A_DEFSYM, 0); + class_addbang(tab2flist_class, (t_method)tab2flist_bang); +// class_addlist(tab2flist_class, (t_method)tab2flist_list); + class_addfloat(tab2flist_class, (t_method)tab2flist_float); + class_addmethod(tab2flist_class, (t_method)tab2flist_set, gensym("set"), + A_SYMBOL, 0); +} + -- cgit v1.2.1