aboutsummaryrefslogtreecommitdiff
path: root/cyclone/hammer/Table.c
diff options
context:
space:
mode:
Diffstat (limited to 'cyclone/hammer/Table.c')
-rw-r--r--cyclone/hammer/Table.c438
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,