diff options
Diffstat (limited to 'cyclone/hammer/Table.c')
-rw-r--r-- | cyclone/hammer/Table.c | 438 |
1 files changed, 360 insertions, 78 deletions
diff --git a/cyclone/hammer/Table.c b/cyclone/hammer/Table.c index d60d3ca..eb30d28 100644 --- a/cyclone/hammer/Table.c +++ b/cyclone/hammer/Table.c @@ -2,32 +2,54 @@ * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ +/* Write access is totally encapsulated in tablecommon calls, in order + to simplify proper handling of the distribution cache. Direct read + access from table calls is allowed (for speed). */ + #include <stdio.h> #include <string.h> #include "m_pd.h" #include "g_canvas.h" #include "common/loud.h" #include "common/grow.h" +#include "common/rand.h" #include "hammer/file.h" #define TABLE_DEBUG #define TABLE_INISIZE 256 /* LATER rethink */ -#define TABLE_DEFLENGTH 128 -#define TABLE_MINLENGTH 2 -#define TABLE_MAXLENGTH 16383 +#define TABLE_DEFLENGTH 128 /* CHECKED */ +#define TABLE_MINLENGTH 2 /* CHECKED */ +#define TABLE_MAXLENGTH 16383 /* CHECKED, LATER rethink */ +#define TABLE_MINRANGE 2 /* CHECKED */ +#define TABLE_MAXQ 32768 /* CHECKME */ typedef struct _tablecommon { t_pd c_pd; - struct _table *c_refs; /* used in read-banging and dirty flag handling */ - int c_embedflag; /* common field (CHECKED in 'TEXT') */ - int c_loading; - int c_relinked; + struct _table *c_refs; + int c_increation; + int c_volatile; + int c_selfmodified; + int c_entered; /* a counter, LATER rethink */ + /* CHECKED flags, etc. are common fields */ + int c_visflag; + int c_embedflag; + int c_dontsaveflag; + int c_notenamesflag; + int c_signedflag; + int c_range; + int c_left; + int c_top; + int c_right; + int c_bottom; int c_size; /* as allocated */ int c_length; /* as used */ int *c_table; int c_tableini[TABLE_INISIZE]; + int c_cacheisfresh; + int *c_cache; + int c_cacheini[TABLE_INISIZE]; t_symbol *c_filename; t_canvas *c_lastcanvas; t_hammerfile *c_filehandle; @@ -42,6 +64,9 @@ typedef struct _table t_float x_value; int x_valueset; int x_head; + int x_loadflag; + int x_loadndx; + unsigned int x_seed; t_hammerfile *x_filehandle; t_outlet *x_bangout; struct _table *x_next; @@ -50,13 +75,13 @@ typedef struct _table static t_class *table_class; static t_class *tablecommon_class; -static void tablecommon_modified(t_tablecommon *cc, int relinked) +static void tablecommon_modified(t_tablecommon *cc, int relocated) { - if (cc->c_loading) + if (cc->c_increation) return; - if (relinked) + if (relocated) { - cc->c_relinked = 1; + cc->c_volatile = 1; } if (cc->c_embedflag) { @@ -67,6 +92,87 @@ static void tablecommon_modified(t_tablecommon *cc, int relinked) } } +static int tablecommon_getindex(t_tablecommon *cc, int ndx) +{ + int mx = cc->c_length - 1; + /* CHECKED ndx silently clipped */ + return (ndx < 0 ? 0 : (ndx > mx ? mx : ndx)); +} + +static int tablecommon_getvalue(t_tablecommon *cc, int ndx) +{ + int mx = cc->c_length - 1; + /* CHECKED ndx silently clipped */ + return (cc->c_table[ndx < 0 ? 0 : (ndx > mx ? mx : ndx)]); +} + +static void tablecommon_setvalue(t_tablecommon *cc, int ndx, int v) +{ + int mx = cc->c_length - 1; + /* CHECKED ndx silently clipped, value not clipped */ + cc->c_table[ndx < 0 ? 0 : (ndx > mx ? mx : ndx)] = v; + tablecommon_modified(cc, 0); +} + +static int tablecommon_loadvalue(t_tablecommon *cc, int ndx, int v) +{ + /* CHECKME */ + if (ndx < cc->c_length) + { + cc->c_table[ndx] = v; + tablecommon_modified(cc, 0); + return (1); + } + else return (0); +} + +static void tablecommon_setall(t_tablecommon *cc, int v) +{ + int ndx = cc->c_length; + int *ptr = cc->c_table; + while (ndx--) *ptr++ = v; + tablecommon_modified(cc, 0); +} + +static void tablecommon_setatoms(t_tablecommon *cc, int ndx, int ac, t_atom *av) +{ + if (ac > 1 && av->a_type == A_FLOAT) + { + /* CHECKME resizing */ + int last = tablecommon_getindex(cc, ndx + ac - 1); + int *ptr = cc->c_table + ndx; + for (av++; ndx <= last; ndx++, av++) + *ptr++ = (av->a_type == A_FLOAT ? (int)av->a_w.w_float : 0); + tablecommon_modified(cc, 0); + } +} + +static void tablecommon_setlength(t_tablecommon *cc, int length) +{ + int relocate; + if (length < TABLE_MINLENGTH) + length = TABLE_MINLENGTH; + else if (length > TABLE_MAXLENGTH) + length = TABLE_MAXLENGTH; + if (relocate = (length > cc->c_size)) + { + cc->c_table = grow_nodata(&length, &cc->c_size, cc->c_table, + TABLE_INISIZE, cc->c_tableini, + sizeof(*cc->c_table)); + /* FIXME cache */ + } + cc->c_length = length; + tablecommon_setall(cc, 0); /* CHECKME */ + /* CHECKME head */ + tablecommon_modified(cc, relocate); +} + +static int tablecommon_quantile(t_tablecommon *cc, float f) +{ + /* FIXME */ + return (0); +} + static void tablecommon_doread(t_tablecommon *cc, t_symbol *fn, t_canvas *cv) { /* FIXME */ @@ -89,7 +195,35 @@ static void tablecommon_writehook(t_pd *z, t_symbol *fn, int ac, t_atom *av) static void table_embedhook(t_pd *z, t_binbuf *bb, t_symbol *bindsym) { - /* FIXME */ + t_table *x = (t_table *)z; + t_tablecommon *cc = x->x_common; + if (cc->c_embedflag) + { + int ndx = 0, left = cc->c_length; + int *ptr = cc->c_table; + binbuf_addv(bb, "ssi;", bindsym, gensym("size"), cc->c_length); + binbuf_addv(bb, "ssiiii;", bindsym, gensym("flags"), 1, + cc->c_dontsaveflag, cc->c_notenamesflag, cc->c_signedflag); + binbuf_addv(bb, "ssi;", bindsym, gensym("tabrange"), cc->c_range); + binbuf_addv(bb, "ssiiiii;", bindsym, gensym("_coords"), + cc->c_left, cc->c_top, cc->c_right, cc->c_bottom, + cc->c_visflag); + while (left > 0) + { + int cnt = (left > 128 ? 128 : left); + left -= cnt; + ndx += cnt; + binbuf_addv(bb, "ssi", bindsym, gensym("set"), ndx); + while (cnt--) + { + t_atom at; + SETFLOAT(&at, (float)*ptr); + binbuf_add(bb, 1, &at); + ptr++; + } + binbuf_addsemi(bb); + } + } } static void tablecommon_editorhook(t_pd *z, t_symbol *s, int ac, t_atom *av) @@ -97,6 +231,29 @@ static void tablecommon_editorhook(t_pd *z, t_symbol *s, int ac, t_atom *av) /* FIXME */ } +static void tablecommon_free(t_tablecommon *cc) +{ + if (cc->c_table != cc->c_tableini) + freebytes(cc->c_table, cc->c_size * sizeof(*cc->c_table)); + if (cc->c_cache != cc->c_cacheini) + freebytes(cc->c_cache, cc->c_size * sizeof(*cc->c_cache)); +} + +static void *tablecommon_new(void) +{ + t_tablecommon *cc = (t_tablecommon *)pd_new(tablecommon_class); + cc->c_visflag = 0; + cc->c_embedflag = 0; + cc->c_dontsaveflag = 0; + cc->c_notenamesflag = 0; + cc->c_signedflag = 0; + cc->c_size = TABLE_INISIZE; + cc->c_length = TABLE_DEFLENGTH; + cc->c_table = cc->c_tableini; + cc->c_cache = cc->c_cacheini; + return (cc); +} + static t_tablecommon *table_checkcommon(t_table *x) { if (x->x_name && @@ -119,9 +276,9 @@ static void table_unbind(t_table *x) if (!(cc->c_refs = x->x_next)) { hammerfile_free(cc->c_filehandle); - cc->c_loading = 1; /* disable dirty-flag handling, LATER rethink */ - if (cc->c_table != cc->c_tableini) - freebytes(cc->c_table, cc->c_size * sizeof(*cc->c_table)); + /* disable canvas dirty-flag handling, LATER rethink */ + cc->c_increation = 1; + tablecommon_free(cc); if (x->x_name) pd_unbind(&cc->c_pd, x->x_name); pd_free(&cc->c_pd); } @@ -152,13 +309,9 @@ static void table_bind(t_table *x, t_symbol *name) cc = (t_tablecommon *)pd_findbyclass(name, tablecommon_class); if (!cc) { - cc = (t_tablecommon *)pd_new(tablecommon_class); + cc = (t_tablecommon *)tablecommon_new(); cc->c_refs = 0; - cc->c_embedflag = 0; - cc->c_loading = 0; - cc->c_size = TABLE_INISIZE; - cc->c_length = TABLE_DEFLENGTH; - cc->c_table = cc->c_tableini; + cc->c_increation = 0; if (name) { pd_bind(&cc->c_pd, name); @@ -198,42 +351,38 @@ static int table_rebind(t_table *x, t_symbol *name) static void table_dooutput(t_table *x, int ndx) { - t_tablecommon *cc = x->x_common; - /* CHECKED ndx silently truncated */ - if (ndx < 0) - ndx = 0; - else if (ndx > cc->c_length) - ndx = cc->c_length - 1; - outlet_float(((t_object *)x)->ob_outlet, (t_float)cc->c_table[ndx]); -} - -static void table_setvalue(t_table *x, int ndx, int v) -{ - t_tablecommon *cc = x->x_common; - /* CHECKED ndx silently truncated */ - if (ndx < 0) - ndx = 0; - else if (ndx > cc->c_length) - ndx = cc->c_length - 1; - cc->c_table[ndx] = v; /* CHECKED no truncation */ + outlet_float(((t_object *)x)->ob_outlet, + (t_float)tablecommon_getvalue(x->x_common, ndx)); } static void table_bang(t_table *x) { - /* FIXME */ + /* CHECKME */ + outlet_float(((t_object *)x)->ob_outlet, + (t_float)tablecommon_quantile(x->x_common, + rand_unipolar(&x->x_seed))); } static void table_float(t_table *x, t_float f) { - int ndx = (int)f; /* CHECKED floats are truncated */ - if (x->x_valueset) + if (x->x_loadflag) { - table_setvalue(x, ndx, x->x_value); - x->x_valueset = 0; + /* CHECKME */ + if (tablecommon_loadvalue(x->x_common, x->x_loadndx, (int)f)) + x->x_loadndx++; + } + else + { + int ndx = (int)f; /* CHECKED floats are truncated */ + if (x->x_valueset) + { + tablecommon_setvalue(x->x_common, ndx, x->x_value); + x->x_valueset = 0; + } + else table_dooutput(x, ndx); + /* CHECKME if head is updated */ + x->x_head = ndx; } - else table_dooutput(x, ndx); - /* CHECKME if head is updated */ - x->x_head = ndx; } static void table_ft1(t_table *x, t_floatarg f) @@ -242,6 +391,60 @@ static void table_ft1(t_table *x, t_floatarg f) x->x_valueset = 1; } +static void table_size(t_table *x, t_floatarg f) +{ + tablecommon_setlength(x->x_common, (int)f); +} + +static void table_set(t_table *x, t_symbol *s, int ac, t_atom *av) +{ + if (ac > 1 && av->a_type == A_FLOAT) + { + int ndx = tablecommon_getindex(x->x_common, (int)av->a_w.w_float); + tablecommon_setatoms(x->x_common, ndx, ac - 1, av + 1); + } +} + +static void table_flags(t_table *x, t_symbol *s, int ac, t_atom *av) +{ + t_tablecommon *cc = x->x_common; + int i = 0, v; + while (ac && av->a_type == A_FLOAT + && loud_checkint((t_pd *)x, av->a_w.w_float, &v, gensym("flags"))) + { + /* CHECKED order, modifying only explicitly specified flags */ + if (i == 0) + cc->c_embedflag = (v != 0); + else if (i == 1) + cc->c_dontsaveflag = (v != 0); + else if (i == 2) + cc->c_notenamesflag = (v != 0); + else if (i == 3) + cc->c_signedflag = (v != 0); + else + break; + i++; ac--; av++; + } +} + +static void table_tabrange(t_table *x, t_floatarg f) +{ + int i = (int)f; + x->x_common->c_range = (i > TABLE_MINRANGE ? i : TABLE_MINRANGE); +} + +static void table__coords(t_table *x, t_floatarg fl, t_floatarg ft, + t_floatarg fr, t_floatarg fb, t_floatarg fv) +{ + t_tablecommon *cc = x->x_common; + /* FIXME constraints */ + cc->c_left = (int)fl; + cc->c_top = (int)ft; + cc->c_right = (int)fr; + cc->c_bottom = (int)fb; + cc->c_visflag = ((int)fv != 0); +} + static void table_cancel(t_table *x) { x->x_valueset = 0; @@ -249,13 +452,27 @@ static void table_cancel(t_table *x) static void table_clear(t_table *x) { - t_tablecommon *cc = x->x_common; - int ndx = cc->c_length; - int *ptr = cc->c_table; - while (ndx--) *ptr++ = 0; + tablecommon_setall(x->x_common, 0); /* CHECKME head */ } +static void table_const(t_table *x, t_floatarg f) +{ + tablecommon_setall(x->x_common, (int)f); + /* CHECKME head */ +} + +static void table_load(t_table *x) +{ + x->x_loadflag = 1; + x->x_loadndx = 0; /* CHECKED rewind, head not affected */ +} + +static void table_normal(t_table *x) +{ + x->x_loadflag = 0; +} + static void table_next(t_table *x) { table_dooutput(x, x->x_head++); @@ -272,14 +489,13 @@ static void table_prev(t_table *x) static void table_goto(t_table *x, t_floatarg f) { - t_tablecommon *cc = x->x_common; - int ndx = (int)f; /* CHECKED floats are truncated */ - /* CHECKED ndx silently truncated */ - if (ndx < 0) - ndx = 0; - else if (ndx > cc->c_length) - ndx = cc->c_length - 1; - x->x_head = ndx; + /* CHECKED floats are truncated */ + x->x_head = tablecommon_getindex(x->x_common, (int)f); +} + +static void table_send(t_table *x, t_symbol *s, t_floatarg f) +{ + /* FIXME */ } static void table_length(t_table *x) @@ -287,6 +503,11 @@ static void table_length(t_table *x) outlet_float(((t_object *)x)->ob_outlet, (t_float)x->x_common->c_length); } +static void table_sum(t_table *x) +{ + /* FIXME */ +} + static void table_min(t_table *x) { /* FIXME */ @@ -297,23 +518,59 @@ static void table_max(t_table *x) /* FIXME */ } -static void table_refer(t_table *x, t_symbol *s) +static void table_getbits(t_table *x, t_floatarg f1, + t_floatarg f2, t_floatarg f3) { - if (!table_rebind(x, s)) + /* FIXME */ +} + +static void table_setbits(t_table *x, t_floatarg f1, + t_floatarg f2, t_floatarg f3, t_floatarg f4) +{ + /* FIXME */ +} + +static void table_inv(t_table *x, t_floatarg f) +{ + /* FIXME */ +} + +static void table_quantile(t_table *x, t_floatarg f) +{ + /* CHECKME */ + outlet_float(((t_object *)x)->ob_outlet, + (t_float)tablecommon_quantile(x->x_common, + f / ((float)TABLE_MAXQ))); +} + +static void table_fquantile(t_table *x, t_floatarg f) +{ + /* CHECKME constraints */ + outlet_float(((t_object *)x)->ob_outlet, + (t_float)tablecommon_quantile(x->x_common, f)); +} + +static void table_dump(t_table *x) +{ + t_tablecommon *cc = x->x_common; + t_outlet *out = ((t_object *)x)->ob_outlet; + int ndx = cc->c_length; + int *ptr = cc->c_table; + /* CHECKME */ + while (ndx--) { - /* LATER consider complaining */ + outlet_float(out, (t_float)*ptr++); + /* FIXME ptr may be invalid after outlet_float()... consider calling + tablecommon_getindex() rather than patching in selfmod tests */ } } -static void table_flags(t_table *x, t_float f1, t_float f2) +static void table_refer(t_table *x, t_symbol *s) { - int i1; - if (loud_checkint((t_pd *)x, f1, &i1, gensym("flags"))) + if (!table_rebind(x, s)) { - t_tablecommon *cc = x->x_common; - cc->c_embedflag = (i1 != 0); + /* LATER consider complaining */ } - /* FIXME don't save flag */ } static void table_read(t_table *x, t_symbol *s) @@ -334,12 +591,6 @@ static void table_write(t_table *x, t_symbol *s) hammerpanel_save(cc->c_filehandle, 0, 0); /* CHECKME default name */ } -static void table_dump(t_table *x) -{ - t_tablecommon *cc = x->x_common; - /* FIXME */ -} - static void table_open(t_table *x) { t_tablecommon *cc = x->x_common; @@ -389,6 +640,8 @@ static void *table_new(t_symbol *s) x->x_canvas = canvas_getcurrent(); x->x_valueset = 0; x->x_head = 0; + x->x_loadflag = 0; + rand_seed(&x->x_seed, 0); inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); outlet_new((t_object *)x, &s_float); x->x_bangout = outlet_new((t_object *)x, &s_bang); @@ -407,32 +660,61 @@ void Table_setup(void) class_addfloat(table_class, table_float); class_addmethod(table_class, (t_method)table_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(table_class, (t_method)table_size, + gensym("size"), A_FLOAT, 0); + class_addmethod(table_class, (t_method)table_set, + gensym("set"), A_GIMME, 0); + class_addmethod(table_class, (t_method)table_flags, + gensym("flags"), A_GIMME, 0); + class_addmethod(table_class, (t_method)table_tabrange, + gensym("tabrange"), A_FLOAT, 0); + class_addmethod(table_class, (t_method)table__coords, + gensym("_coords"), + A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); class_addmethod(table_class, (t_method)table_cancel, gensym("cancel"), 0); class_addmethod(table_class, (t_method)table_clear, gensym("clear"), 0); + class_addmethod(table_class, (t_method)table_const, + gensym("const"), A_FLOAT, 0); + class_addmethod(table_class, (t_method)table_load, + gensym("load"), 0); + class_addmethod(table_class, (t_method)table_normal, + gensym("normal"), 0); class_addmethod(table_class, (t_method)table_next, gensym("next"), 0); class_addmethod(table_class, (t_method)table_prev, gensym("prev"), 0); class_addmethod(table_class, (t_method)table_goto, gensym("goto"), A_FLOAT, 0); + class_addmethod(table_class, (t_method)table_send, + gensym("send"), A_SYMBOL, A_FLOAT, 0); class_addmethod(table_class, (t_method)table_length, gensym("length"), 0); + class_addmethod(table_class, (t_method)table_sum, + gensym("sum"), 0); class_addmethod(table_class, (t_method)table_min, gensym("min"), 0); class_addmethod(table_class, (t_method)table_max, gensym("max"), 0); + class_addmethod(table_class, (t_method)table_getbits, + gensym("getbits"), A_FLOAT, A_FLOAT, A_FLOAT, 0); + class_addmethod(table_class, (t_method)table_setbits, + gensym("setbits"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); + class_addmethod(table_class, (t_method)table_inv, + gensym("inv"), A_FLOAT, 0); + class_addmethod(table_class, (t_method)table_quantile, + gensym("quantile"), A_FLOAT, 0); + class_addmethod(table_class, (t_method)table_fquantile, + gensym("fquantile"), A_FLOAT, 0); + class_addmethod(table_class, (t_method)table_dump, + gensym("dump"), 0); class_addmethod(table_class, (t_method)table_refer, gensym("refer"), A_SYMBOL, 0); - class_addmethod(table_class, (t_method)table_flags, - gensym("flags"), A_FLOAT, A_FLOAT, 0); class_addmethod(table_class, (t_method)table_read, gensym("read"), A_DEFSYM, 0); class_addmethod(table_class, (t_method)table_write, gensym("write"), A_DEFSYM, 0); - class_addmethod(table_class, (t_method)table_dump, - gensym("dump"), 0); class_addmethod(table_class, (t_method)table_open, gensym("open"), 0); class_addmethod(table_class, (t_method)table_wclose, |