aboutsummaryrefslogtreecommitdiff
path: root/polystat
diff options
context:
space:
mode:
authorEd Kelly <edkelly@users.sourceforge.net>2006-11-24 13:45:33 +0000
committerEd Kelly <edkelly@users.sourceforge.net>2006-11-24 13:45:33 +0000
commit0c0b07d3bff68484d554b33d7693117863404d2a (patch)
tree141dec89b30d2153f610bf02a3827bfe0e381e2e /polystat
parenteacf70f4603c669a003f502e84a7d28435368344 (diff)
This commit was generated by cvs2svn to compensate for changes in r6421,
which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/ekext/; revision=6422
Diffstat (limited to 'polystat')
-rwxr-xr-xpolystat/help-polystat.pd92
-rwxr-xr-xpolystat/makefile105
-rwxr-xr-xpolystat/polystat.c268
3 files changed, 465 insertions, 0 deletions
diff --git a/polystat/help-polystat.pd b/polystat/help-polystat.pd
new file mode 100755
index 0000000..187cf7d
--- /dev/null
+++ b/polystat/help-polystat.pd
@@ -0,0 +1,92 @@
+#N canvas 0 0 785 462 10;
+#X obj 76 256 polystat;
+#X floatatom 76 351 5 0 0 1 voice - -;
+#X floatatom 88 337 5 0 0 1 instances - -;
+#X floatatom 101 323 5 0 0 1 voices - -;
+#X floatatom 114 309 5 0 0 1 voice - -;
+#X obj 127 292 print map;
+#X text 195 309 with most instances;
+#X obj 76 206 + 7;
+#X obj 76 164 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X floatatom 76 228 5 0 0 0 - - -;
+#X msg 213 184 clear \$1;
+#X floatatom 264 145 5 7 38 0 - - -;
+#X msg 213 162 8;
+#X msg 312 219 voices;
+#X msg 312 199 getmap;
+#X msg 312 239 clearall;
+#X msg 312 159 clear 12;
+#X obj 76 184 random 32;
+#X obj 26 142 metro 100;
+#X obj 26 123 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 247 162 f;
+#X obj 247 143 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X msg 312 179 print;
+#X text 360 199 outputs a list of the instances of voices 0 to HIGHEST
+;
+#X text 353 180 some stats;
+#X msg 340 323 \$1;
+#X text 374 239 resets the object;
+#X text 374 159 clears a specific voice;
+#X obj 26 26 polystat;
+#X text 88 26 outputs statistics about voice usage. See also;
+#X obj 416 24 polymap;
+#X obj 473 24 sieve;
+#X text 360 220 outputs a list of all the voices used;
+#X text 246 128 clear voice with most instances;
+#X text 202 53 most stealing: voice with most instances set to new
+value when another voice's instances are equal;
+#X text 201 84 first-past-the-post: voice with most instances only
+updated when another voice's instances exceed;
+#X text 218 144 V;
+#X text 218 133 |;
+#X text 218 125 |;
+#X text 217 113 clear most recent voice;
+#X obj 26 79 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 26 97 1;
+#X msg 49 97 0;
+#X obj 26 59 loadbang;
+#X obj 49 121 pipe 2000;
+#X msg 151 145 set \$1;
+#X msg 150 57 mode 0;
+#X msg 150 87 mode 1;
+#X obj 515 24 maskxor;
+#X text 44 389 Polyphony control objects by Ed Kelly \, November 2006
+;
+#X connect 0 0 1 0;
+#X connect 0 1 2 0;
+#X connect 0 2 3 0;
+#X connect 0 3 4 0;
+#X connect 0 4 5 0;
+#X connect 4 0 25 0;
+#X connect 7 0 9 0;
+#X connect 7 0 45 0;
+#X connect 8 0 17 0;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X connect 11 0 20 1;
+#X connect 12 0 10 0;
+#X connect 13 0 0 0;
+#X connect 14 0 0 0;
+#X connect 15 0 0 0;
+#X connect 16 0 0 0;
+#X connect 17 0 7 0;
+#X connect 18 0 8 0;
+#X connect 19 0 18 0;
+#X connect 20 0 10 0;
+#X connect 21 0 20 0;
+#X connect 22 0 0 0;
+#X connect 25 0 11 0;
+#X connect 40 0 41 0;
+#X connect 40 0 42 0;
+#X connect 41 0 19 0;
+#X connect 42 0 44 0;
+#X connect 43 0 40 0;
+#X connect 44 0 19 0;
+#X connect 45 0 12 0;
+#X connect 46 0 0 0;
+#X connect 47 0 0 0;
diff --git a/polystat/makefile b/polystat/makefile
new file mode 100755
index 0000000..5f30bf3
--- /dev/null
+++ b/polystat/makefile
@@ -0,0 +1,105 @@
+current:
+ echo make pd_linux, pd_nt, pd_irix5, pd_irix6 or pd_darwin, then make install
+
+clean: ; rm -f *.pd_* *.o
+
+# ----------------------- NT -----------------------
+
+pd_nt: polystat.dll
+
+INSTALL_PREFIX="C:\pd\extra"
+EXT=dll
+.SUFFIXES: .obj .dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+VC="D:\Program Files\Microsoft Visual Studio\Vc98"
+
+PDNTINCLUDE = /I. /I\tcl\include /I..\..\src /I$(VC)\include
+
+PDNTLDIR = $(VC)\lib
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ ..\..\bin\pd.lib
+
+.c.dll:
+ cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+ link /dll /export:$*_setup $*.obj $(PDNTLIB)
+
+# ----------------------- IRIX 5.x -----------------------
+
+pd_irix5: polystat.pd_irix5
+
+INSTALL_PREFIX=/usr/local
+EXT=pd_irix5
+.SUFFIXES: .pd_irix5
+
+SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2
+
+SGIINCLUDE = -I/usr/local/include
+
+.c.pd_irix5:
+ cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c
+ ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o
+ rm $*.o
+
+# ----------------------- IRIX 5.x -----------------------
+
+pd_irix6: polystat.pd_irix6
+
+INSTALL_PREFIX=/usr/local
+EXT=pd_irix6
+.SUFFIXES: .pd_irix6
+
+SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2
+
+SGIINCLUDE = -I/usr/local/include
+
+.c.pd_irix6:
+ cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c
+ ld -elf -shared -rdata_shared -o $*.pd_irix6 $*.o
+ rm $*.o
+
+# ----------------------- LINUX i386 -----------------------
+
+pd_linux: polystat.pd_linux
+
+INSTALL_PREFIX=/usr/local
+EXT=pd_linux
+.SUFFIXES: .pd_linux
+
+LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer \
+ -Wall -W -Wshadow -Wstrict-prototypes -Werror \
+ -Wno-unused -Wno-parentheses -Wno-switch
+
+LINUXINCLUDE = -I/usr/local/include
+
+.c.pd_linux:
+ cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
+ ld -export_dynamic -shared -o $*.pd_linux $*.o -lc -lm
+ strip --strip-unneeded $*.pd_linux
+ rm $*.o
+
+# ----------------------- Mac OSX -----------------------
+
+pd_darwin: polystat.pd_darwin
+
+INSTALL_PREFIX=/usr/local
+EXT=pd_darwin
+.SUFFIXES: .pd_darwin
+
+DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \
+ -Wno-unused -Wno-parentheses -Wno-switch
+
+.c.pd_darwin:
+ cc $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
+ cc -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o
+ rm -f $*.o
+
+# ----------------------------------------------
+
+install::
+ install -d $(INSTALL_PREFIX)/lib/pd/extra
+# install -m 644 *.$(EXT) $(INSTALL_PREFIX)/lib/pd/externs
+ install -m 644 polystat.$(EXT) $(INSTALL_PREFIX)/lib/pd/extra
+ install -m 644 *.pd $(INSTALL_PREFIX)/lib/pd/doc/5.reference
diff --git a/polystat/polystat.c b/polystat/polystat.c
new file mode 100755
index 0000000..47603fb
--- /dev/null
+++ b/polystat/polystat.c
@@ -0,0 +1,268 @@
+#include "m_pd.h"
+#include <math.h>
+#include <string.h>
+#define MAXENTRIES 512
+#define LASTENTRY 511
+
+static t_class *polystat_class;
+
+typedef struct _map
+{
+ t_atom map[MAXENTRIES];
+ t_atom maxlist[MAXENTRIES];
+ t_atom outlist[MAXENTRIES];
+} t_map;
+
+typedef struct _polystat
+{
+ t_object x_obj;
+ t_map x_map;
+ t_int voices, max, maxval, maxindex, maxflag, maxcount, highest, mode;
+ t_outlet *voice, *value, *vars, *maxvox, *mapped;
+} t_polystat;
+
+void polystat_float(t_polystat *x, t_floatarg fin)
+{
+ int voice = (int)fin;
+ int inst;
+ int maxindex = (int)x->maxindex + 1;
+ if(voice >= 0 && voice < MAXENTRIES)
+ {
+ int instances = atom_getfloatarg(voice, MAXENTRIES, x->x_map.map);
+ if(instances == 0)x->voices++;
+ inst = instances + 1;
+ SETFLOAT(&x->x_map.map[voice], inst);
+ if(x->mode == 0)
+ {
+ if(inst >= x->max && voice != x->maxval)
+ {
+ x->maxflag = x->maxcount >= MAXENTRIES ? 1 : x->maxflag == 1 ? 1 : 0;
+ x->maxcount += 1;
+ x->maxcount = x->maxcount > MAXENTRIES ? MAXENTRIES : x->maxcount;
+ x->maxindex = maxindex % MAXENTRIES;
+ SETFLOAT(&x->x_map.maxlist[x->maxindex], voice);
+ x->maxval = voice;
+ x->max = inst;
+ outlet_float(x->maxvox, voice);
+ }
+ else if(inst >= x->max && voice == x->maxval)
+ {
+ x->max = inst;
+ outlet_float(x->maxvox, voice);
+ }
+ }
+ else if(x->mode != 0)
+ {
+ if(inst > x->max && voice != x->maxval)
+ {
+ x->maxflag = x->maxcount >= MAXENTRIES ? 1 : x->maxflag == 1 ? 1 : 0;
+ x->maxcount += 1;
+ x->maxcount = x->maxcount > MAXENTRIES ? MAXENTRIES : x->maxcount;
+ x->maxindex = (float)(maxindex % MAXENTRIES);
+ SETFLOAT(&x->x_map.maxlist[x->maxindex], voice);
+ x->maxval = voice;
+ x->max = inst;
+ outlet_float(x->maxvox, voice);
+ }
+ else if(inst > x->max && voice == x->maxval)
+ {
+ x->max = inst;
+ outlet_float(x->maxvox, voice);
+ }
+ }
+ x->highest = voice > x->highest ? voice : x->highest;
+ outlet_float(x->vars, x->voices);
+ outlet_float(x->value, inst);
+ outlet_float(x->voice, voice);
+ }
+}
+
+void polystat_clear(t_polystat *x, t_floatarg fin)
+{
+ int inst = (int)fin;
+ int indexed = (int)(x->maxindex+(MAXENTRIES*x->maxflag));
+ int modindex = 0;
+ int counted = 0;
+ float current = atom_getfloatarg(inst, MAXENTRIES, x->x_map.map);
+ float voice;
+ voice = 0;
+ if(x->voices > 0 && current > 0)
+ {
+ x->voices--;
+ SETFLOAT(&x->x_map.map[inst], 0);
+ current = 0;
+ if(current == 0 && x->maxcount > 0)
+ {
+ indexed--;
+ x->maxcount--;
+ modindex = (indexed+MAXENTRIES) % MAXENTRIES;
+ voice = atom_getfloatarg(modindex, MAXENTRIES, x->x_map.maxlist);
+ current = atom_getfloatarg(voice, MAXENTRIES, x->x_map.map);
+ }
+ if(x->maxcount == 0 || current == 0)
+ {
+ x->max = 0;
+ x->maxval = 0;
+ x->maxindex = 0;
+ }
+ else if(x->maxcount > 0 || current > 0)
+ {
+ x->max = current;
+ x->maxval = voice;
+ x->maxindex = modindex;
+ }
+ }
+ outlet_float(x->maxvox, x->maxval);
+ outlet_float(x->vars, x->voices);
+ outlet_float(x->value, x->max);
+}
+
+void polystat_print(t_polystat *x, t_symbol *s)
+{
+ post("most_instances = %d at voice %d, voices = %d, highest_voice = %d", x->max, x->maxval, x->voices, x->highest);
+}
+
+void polystat_get(t_polystat *x, t_floatarg fin)
+{
+ int inst = (int)fin;
+ float voice, instances;
+ voice = instances = 0;
+ if(x->voices>0 && inst>=0 && inst<MAXENTRIES)
+ {
+ instances = atom_getfloatarg(inst, MAXENTRIES, x->x_map.map);
+ voice = inst;
+ }
+ if(instances>0)
+ {
+ outlet_float(x->value, instances);
+ outlet_float(x->voice, voice);
+ }
+}
+
+void polystat_clearall(t_polystat *x)
+{
+ int i;
+ for(i=0;i<MAXENTRIES;i++)
+ {
+ SETFLOAT(&x->x_map.map[i],0);
+ SETFLOAT(&x->x_map.maxlist[i],0);
+ }
+ x->voices = x->max = x->maxval = x->maxindex = x->highest = x->maxcount = 0;
+ outlet_float(x->vars, x->voices);
+}
+
+void polystat_getmap(t_polystat *x, t_symbol *s) //output map. terminate map at highest voice.
+{
+ if(x->voices>0)
+ {
+ outlet_list(x->mapped, gensym("list"), x->highest+1, x->x_map.map);
+ }
+}
+
+void polystat_setmap(t_polystat *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ float arg, max, maxval, high;
+ max = maxval = high = 0;
+ for(i=0;i<argc;i++)
+ {
+ arg = atom_getfloat(argv+i);
+ if(arg != 0)
+ {
+ if(x->mode==0)
+ {
+ if(arg>=maxval)
+ {
+ maxval = arg;
+ max = i;
+ }
+ }
+ else if(x->mode!=0)
+ {
+ if(arg>maxval)
+ {
+ maxval = arg;
+ max = i;
+ }
+ }
+ x->highest = i;
+ SETFLOAT(&x->x_map.map[i], arg);
+ SETFLOAT(&x->x_map.maxlist[i], 0);
+ }
+ }
+ x->max = max;
+ x->maxval = maxval;
+ SETFLOAT(&x->x_map.maxlist[0], max);
+}
+
+void polystat_bang(t_polystat *x, t_symbol *s)
+{
+ outlet_float(x->vars, x->voices);
+ outlet_float(x->value, x->maxval);
+ outlet_float(x->voice, x->max);
+}
+
+void polystat_voices(t_polystat *x, t_symbol *s) //list all voices
+{
+ int i, mindex, current;
+ mindex=0;
+ for(i=0;i<(x->highest+1);i++)
+ {
+ current = atom_getfloatarg(i, MAXENTRIES, x->x_map.map);
+ if(current>0)
+ {
+ SETFLOAT(&x->x_map.outlist[mindex],(float)i);
+ mindex++;
+ }
+ }
+ outlet_list(x->mapped, gensym("list"), x->voices, x->x_map.outlist);
+}
+
+void polystat_mode(t_polystat *x, t_floatarg fmode)
+{
+ x->mode = fmode;
+}
+
+void *polystat_new(t_floatarg f)
+{
+ t_polystat *x = (t_polystat *)pd_new(polystat_class);
+ x->mode = f;
+ x->max = x->maxval = x->voices = x->maxindex = x->maxcount = x->highest = 0;
+ //memset(x->x_map.map, 0, MAXENTRIES);
+ //memset(x->x_map.nomap, 1, MAXENTRIES);
+ int i;
+ for(i=0;i<MAXENTRIES;i++)
+ {
+ SETFLOAT(x->x_map.map+i, 0);
+ SETFLOAT(x->x_map.maxlist+i, 0);
+ }
+ x->voice = outlet_new(&x->x_obj, &s_float);
+ x->value = outlet_new(&x->x_obj, &s_float);
+ x->vars = outlet_new(&x->x_obj, &s_float);
+ x->maxvox = outlet_new(&x->x_obj, &s_float);
+ x->mapped = outlet_new(&x->x_obj, &s_list);
+ return (void *)x;
+}
+
+void polystat_setup(void)
+{
+
+ polystat_class = class_new(gensym("polystat"),
+ (t_newmethod)polystat_new,
+ 0, sizeof(t_polystat),
+ 0, A_DEFFLOAT, 0);
+ post("|^^^^^^^^^^^^polystat^^^^^^^^^^^^|");
+ post("|->^^^^polyphony statistics^^^^<-|");
+ post("|^^^^^^^^Edward Kelly 2006^^^^^^^|");
+ class_sethelpsymbol(polystat_class, gensym("help-polystat"));
+ class_addfloat(polystat_class, polystat_float);
+ class_addmethod(polystat_class, (t_method)polystat_clear, gensym("clear"), A_DEFFLOAT, 0);
+ class_addmethod(polystat_class, (t_method)polystat_get, gensym("get"), A_DEFFLOAT, 0);
+ class_addmethod(polystat_class, (t_method)polystat_clearall, gensym("clearall"), A_DEFFLOAT, 0);
+ class_addmethod(polystat_class, (t_method)polystat_getmap, gensym("getmap"), A_DEFFLOAT, 0);
+ class_addmethod(polystat_class, (t_method)polystat_setmap, gensym("setmap"), A_GIMME, 0);
+ class_addmethod(polystat_class, (t_method)polystat_voices, gensym("voices"), A_DEFFLOAT, 0);
+ class_addmethod(polystat_class, (t_method)polystat_mode, gensym("mode"), A_DEFFLOAT, 0);
+ class_addmethod(polystat_class, (t_method)polystat_print, gensym("print"), A_DEFFLOAT, 0);
+ class_addbang(polystat_class, (t_method)polystat_bang);
+}