aboutsummaryrefslogtreecommitdiff
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
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
-rwxr-xr-xmaskxor/help-maskxor.pd39
-rwxr-xr-xmaskxor/makefile105
-rwxr-xr-xmaskxor/maskxor.c118
-rwxr-xr-xpolymap/help-polymap.pd62
-rwxr-xr-xpolymap/makefile105
-rwxr-xr-xpolymap/polymap.c206
-rwxr-xr-xpolystat/help-polystat.pd92
-rwxr-xr-xpolystat/makefile105
-rwxr-xr-xpolystat/polystat.c268
-rwxr-xr-xsieve/help-sieve.pd79
-rwxr-xr-xsieve/makefile105
-rwxr-xr-xsieve/sieve.c285
12 files changed, 1569 insertions, 0 deletions
diff --git a/maskxor/help-maskxor.pd b/maskxor/help-maskxor.pd
new file mode 100755
index 0000000..23fd1b7
--- /dev/null
+++ b/maskxor/help-maskxor.pd
@@ -0,0 +1,39 @@
+#N canvas 0 0 665 304 10;
+#X obj 368 207 maskxor;
+#X obj 457 63 t b b;
+#X msg 38 157 bang;
+#X floatatom 390 247 5 0 0 0 - - -;
+#X floatatom 368 264 5 0 0 0 - - -;
+#X floatatom 254 122 5 0 0 0 - - -;
+#X msg 457 46 bang;
+#X msg 457 80 listl 1 1 0 0 0 1 1;
+#X msg 500 97 listr 0 1 1 0 2 1 0;
+#X text 39 56 Maskxor takes two lists - listr and listl \, to set up
+a map where map = listl ^ listr.;
+#X text 37 93 Floats will only pass through if map[(int)float] > 0
+\, so if the corresponding element is greater than zero in either listl
+\, or listr \, but not both.;
+#X text 76 148 outputs the map \, the xor-ed element and (if this is
+greater than zero) the last float in.;
+#X obj 412 227 print MASK;
+#X text 41 22 Maskxor - exclusive-OR mask map by Edward Kelly. This
+is GNU software.;
+#X msg 39 193 clear;
+#X text 79 192 resets the object;
+#X text 29 283 Polyphony control objects by Ed Kelly November 2006
+;
+#X text 397 282 See also;
+#X obj 458 280 sieve;
+#X obj 501 280 polymap;
+#X obj 558 280 polystat;
+#X connect 0 0 4 0;
+#X connect 0 1 3 0;
+#X connect 0 2 12 0;
+#X connect 1 0 7 0;
+#X connect 1 1 8 0;
+#X connect 2 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 1 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 0;
+#X connect 14 0 0 0;
diff --git a/maskxor/makefile b/maskxor/makefile
new file mode 100755
index 0000000..950cfa2
--- /dev/null
+++ b/maskxor/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: maskxor.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: maskxor.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: maskxor.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: maskxor.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: maskxor.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 maskxor.$(EXT) $(INSTALL_PREFIX)/lib/pd/extra
+ install -m 644 *.pd $(INSTALL_PREFIX)/lib/pd/doc/5.reference
diff --git a/maskxor/maskxor.c b/maskxor/maskxor.c
new file mode 100755
index 0000000..b75379f
--- /dev/null
+++ b/maskxor/maskxor.c
@@ -0,0 +1,118 @@
+#include "m_pd.h"
+#include <math.h>
+#define MAXENTRIES 512
+
+static t_class *maskxor_class;
+
+typedef struct _mask
+{
+ t_atom maskxor[MAXENTRIES];
+ t_atom maskl[MAXENTRIES];
+ t_atom maskr[MAXENTRIES];
+} t_mask;
+
+typedef struct _maskxor
+{
+ t_object x_obj;
+ t_mask masking;
+ t_float total;
+ t_float f_in, yes;
+ t_outlet *thru, *bool, *mask;
+} t_maskxor;
+
+void maskxor_float(t_maskxor *x, t_floatarg fin)
+{
+ int input = (int)fin;
+ if(input>=0 && input<MAXENTRIES)
+ {
+ x->f_in = fin;
+ x->yes = atom_getfloatarg(input, MAXENTRIES, x->masking.maskxor);
+ outlet_float(x->bool, x->yes);
+ if(x->yes) outlet_float(x->thru, x->f_in);
+ }
+}
+
+void maskxor_bang(t_maskxor *x, t_symbol *s)
+{
+ outlet_list(x->mask, &s_list, x->total, x->masking.maskxor);
+ outlet_float(x->bool, x->yes);
+ if(x->yes)outlet_float(x->thru, x->f_in);
+}
+
+void maskxor_listl(t_maskxor *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ float listr_element, listl_element, xor_element;
+ if(x->total < argc && argc < MAXENTRIES) x->total = argc;
+ for(i=0;i<x->total;i++)
+ {
+ listl_element = atom_getfloat(argv+i);
+ SETFLOAT(&x->masking.maskl[i], listl_element);
+ listr_element = atom_getfloatarg(i,MAXENTRIES,x->masking.maskr);
+ xor_element = (float)((int)listl_element ^ (int)listr_element);
+ SETFLOAT(&x->masking.maskxor[i], xor_element);
+ }
+ outlet_list(x->mask, &s_list, x->total, x->masking.maskxor);
+}
+
+void maskxor_listr(t_maskxor *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ float listr_element;
+ if(x->total < argc && argc < MAXENTRIES)
+ {
+ x->total = argc;
+ }
+ for(i=0;i<x->total;i++)
+ {
+ listr_element = atom_getfloat(argv+i);
+ SETFLOAT(&x->masking.maskr[i], listr_element);
+ }
+}
+
+void maskxor_clear(t_maskxor *x)
+{
+ int i;
+ for(i=0;i<=MAXENTRIES;i++)
+ {
+ SETFLOAT(&x->masking.maskl[i], 0);
+ SETFLOAT(&x->masking.maskr[i], 0);
+ SETFLOAT(&x->masking.maskxor[i], 0);
+ }
+ x->total=1;
+ x->yes = x->f_in = 0;
+}
+
+void *maskxor_new(t_symbol *s)
+{
+ int i;
+ t_maskxor *x = (t_maskxor *)pd_new(maskxor_class);
+ x->total = 1;
+ for(i=0;i<MAXENTRIES;i++)
+ {
+ SETFLOAT(&x->masking.maskr[i], 0);
+ SETFLOAT(&x->masking.maskl[i], 0);
+ SETFLOAT(&x->masking.maskxor[i], 0);
+ }
+ x->thru = outlet_new(&x->x_obj, &s_float);
+ x->bool = outlet_new(&x->x_obj, &s_float);
+ x->mask = outlet_new(&x->x_obj, &s_list);
+ return (void *)x;
+}
+
+void maskxor_setup(void)
+{
+ maskxor_class = class_new(gensym("maskxor"),
+ (t_newmethod)maskxor_new,
+ 0, sizeof(t_maskxor),
+ CLASS_DEFAULT, A_DEFFLOAT, 0);
+ post("|..-.--.-..-maskxor.-...--.-..|");
+ post("| exclusive-or mask-map |");
+ post("|.--.- Edward Kelly 2006 ---.-|");
+ class_sethelpsymbol(maskxor_class, gensym("help-maskxor"));
+ class_addfloat(maskxor_class, maskxor_float);
+ class_addmethod(maskxor_class, (t_method)maskxor_listl, gensym("listl"), A_GIMME, 0, 0);
+ class_addmethod(maskxor_class, (t_method)maskxor_listr, gensym("listr"), A_GIMME, 0, 0);
+ class_addbang(maskxor_class, (t_method)maskxor_bang);
+ class_addmethod(maskxor_class, (t_method)maskxor_clear, gensym("clear"), A_DEFFLOAT, 0);
+}
diff --git a/polymap/help-polymap.pd b/polymap/help-polymap.pd
new file mode 100755
index 0000000..292f95e
--- /dev/null
+++ b/polymap/help-polymap.pd
@@ -0,0 +1,62 @@
+#N canvas 0 0 690 434 10;
+#X obj 502 26 sieve;
+#X obj 545 26 maskxor;
+#X obj 26 26 polymap;
+#X obj 438 26 polystat;
+#X text 82 26 two-dimensional polyphony-restricted map. see also;
+#X text 23 47 Poly map contains a 32x32 matrix in which values may
+be stored. However \, only a set number of these values may be stored
+as set by the right inlet \, and if this total is reached no more may
+be stored until one is set to 0 again.;
+#X floatatom 338 258 5 1 16 1 max_poly - -;
+#X obj 92 334 polymap 3;
+#X msg 45 199 note 4 2 1;
+#X msg 68 233 note 10 4 0.756;
+#X msg 77 250 note 11 4 1;
+#X msg 57 216 note 6 8 3;
+#X floatatom 116 364 5 0 0 3 new_y - -;
+#X msg 223 199 note 4 2 0;
+#X msg 230 216 note 6 8 0;
+#X msg 237 233 note 10 4 0;
+#X msg 244 250 note 11 4 0;
+#X floatatom 170 364 5 0 0 3 polyphony - -;
+#X floatatom 61 364 5 0 0 3 freed_x - -;
+#X obj 226 361 print overflow;
+#X text 24 149 noteons;
+#X msg 337 297 print;
+#X msg 337 317 print32;
+#X text 379 297 print first 16x16;
+#X text 392 317 print whole matrix;
+#X msg 337 277 clear;
+#X msg 18 165 note 1 1 1;
+#X msg 32 182 note 2 2 1;
+#X text 377 277 clear matrix;
+#X msg 337 235 note 1 0 1;
+#X msg 209 165 note 1 1 0;
+#X msg 216 182 note 2 2 0;
+#X text 416 235 voice_x and voice_y both start at 1;
+#X text 158 335 initialization argument sets maximum polyphony;
+#X text 23 100 Values are stored as messages in the form [note x y
+value( where value is either 0 or some other value.;
+#X text 217 147 noteoffs;
+#X connect 6 0 7 1;
+#X connect 7 0 18 0;
+#X connect 7 1 12 0;
+#X connect 7 2 17 0;
+#X connect 7 3 19 0;
+#X connect 8 0 7 0;
+#X connect 9 0 7 0;
+#X connect 10 0 7 0;
+#X connect 11 0 7 0;
+#X connect 13 0 7 0;
+#X connect 14 0 7 0;
+#X connect 15 0 7 0;
+#X connect 16 0 7 0;
+#X connect 21 0 7 0;
+#X connect 22 0 7 0;
+#X connect 25 0 7 0;
+#X connect 26 0 7 0;
+#X connect 27 0 7 0;
+#X connect 29 0 7 0;
+#X connect 30 0 7 0;
+#X connect 31 0 7 0;
diff --git a/polymap/makefile b/polymap/makefile
new file mode 100755
index 0000000..cfe340f
--- /dev/null
+++ b/polymap/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: polymap.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: polymap.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: polymap.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: polymap.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: polymap.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 polymap.$(EXT) $(INSTALL_PREFIX)/lib/pd/extra
+ install -m 644 *.pd $(INSTALL_PREFIX)/lib/pd/doc/5.reference
diff --git a/polymap/polymap.c b/polymap/polymap.c
new file mode 100755
index 0000000..02192b1
--- /dev/null
+++ b/polymap/polymap.c
@@ -0,0 +1,206 @@
+#include "m_pd.h"
+#include <math.h>
+#include <string.h>
+#define MAXPOLY 32
+#define POLYMAP 512
+
+/* The polymap is a two-dimensional array, but here instead of this we have a one dimensional array of length MAXPOLY^2 */
+
+static t_class *polymap_class;
+
+typedef struct _map
+{
+ t_atom polybins[MAXPOLY];
+ t_atom polymap[POLYMAP];
+ t_atom note[3];
+} t_map;
+
+typedef struct _polymap
+{
+ t_object x_obj;
+ t_map x_map;
+ t_float maxpoly, polynow;
+ t_outlet *note, *new, *poly, *overflow;
+} t_polymap;
+
+
+/* perhaps polymap_note could be called from the sieve function, thus only setting up a matrix when a relevant sequencer is mentioned */
+void polymap_note(t_polymap *x, t_floatarg whosent, t_floatarg whoam, t_floatarg ono)
+{
+ int voicenow, mapindex, voicepoly, whosentme;
+ SETFLOAT(&x->x_map.note[0], whosent);
+ SETFLOAT(&x->x_map.note[1], whoam);
+ SETFLOAT(&x->x_map.note[2], ono);
+ whosentme = (int)whosent;
+ mapindex = (int)((whosent-1)+(whoam-1)*32);
+ if(ono==0)
+ {
+ voicenow = atom_getfloatarg(mapindex, POLYMAP, x->x_map.polymap);
+ if(voicenow>0&&mapindex>=0)
+ {
+ voicepoly = atom_getfloatarg(whosentme, MAXPOLY, x->x_map.polybins);
+ voicepoly--;
+ x->polynow--;
+ SETFLOAT(&x->x_map.polybins[whosentme], voicepoly);
+ SETFLOAT(&x->x_map.polymap[mapindex], 0);
+ outlet_float(x->poly, x->polynow);
+ if(x->polynow<x->maxpoly)
+ {
+ outlet_float(x->note, whosentme);
+ }
+ }
+ else outlet_list(x->overflow, &s_list, 3, x->x_map.note);
+ }
+ else
+ {
+ voicenow = atom_getfloatarg(mapindex, POLYMAP, x->x_map.polymap);
+ if(voicenow==0&&x->polynow<x->maxpoly&&mapindex>=0)
+ {
+ voicepoly = atom_getfloatarg(whosentme, MAXPOLY, x->x_map.polybins);
+ voicepoly++;
+ x->polynow++;
+ SETFLOAT(&x->x_map.polybins[whosentme], voicepoly);
+ SETFLOAT(&x->x_map.polymap[mapindex], 1);
+ outlet_float(x->poly, x->polynow);
+ outlet_float(x->new, whoam);
+ }
+ else if(voicenow==0) outlet_list(x->overflow, &s_list, 3, x->x_map.note);
+ }
+}
+
+void polymap_print(t_polymap *x)
+{
+ int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, indx;
+ post("polymap - first 16x16");
+ post(" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16");
+ for(indx=0;indx<16;indx++)
+ {
+ a = atom_getfloatarg((indx*32), POLYMAP, x->x_map.polymap);
+ b = atom_getfloatarg((indx*32)+1, POLYMAP, x->x_map.polymap);
+ c = atom_getfloatarg((indx*32)+2, POLYMAP, x->x_map.polymap);
+ d = atom_getfloatarg((indx*32)+3, POLYMAP, x->x_map.polymap);
+ e = atom_getfloatarg((indx*32)+4, POLYMAP, x->x_map.polymap);
+ f = atom_getfloatarg((indx*32)+5, POLYMAP, x->x_map.polymap);
+ g = atom_getfloatarg((indx*32)+6, POLYMAP, x->x_map.polymap);
+ h = atom_getfloatarg((indx*32)+7, POLYMAP, x->x_map.polymap);
+ i = atom_getfloatarg((indx*32)+8, POLYMAP, x->x_map.polymap);
+ j = atom_getfloatarg((indx*32)+9, POLYMAP, x->x_map.polymap);
+ k = atom_getfloatarg((indx*32)+10, POLYMAP, x->x_map.polymap);
+ l = atom_getfloatarg((indx*32)+11, POLYMAP, x->x_map.polymap);
+ m = atom_getfloatarg((indx*32)+12, POLYMAP, x->x_map.polymap);
+ n = atom_getfloatarg((indx*32)+13, POLYMAP, x->x_map.polymap);
+ o = atom_getfloatarg((indx*32)+14, POLYMAP, x->x_map.polymap);
+ p = atom_getfloatarg((indx*32)+15, POLYMAP, x->x_map.polymap);
+ if(indx<9)
+ post("%d :%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", indx+1, a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
+ else if(indx>=9)
+ post("%d:%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", indx+1, a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
+ }
+}
+
+void polymap_print32(t_polymap *x)
+{
+ int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, aa, bb, cc, dd, ee, ff, gg, hh, ii, jj, kk, ll, mm, nn, oo, pp, indx;
+ post("polymap - all 32x32");
+ post(" 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32");
+ post(" 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 ");
+ for(indx=0;indx<32;indx++)
+ {
+ a = atom_getfloatarg((indx*32), POLYMAP, x->x_map.polymap);
+ b = atom_getfloatarg((indx*32)+1, POLYMAP, x->x_map.polymap);
+ c = atom_getfloatarg((indx*32)+2, POLYMAP, x->x_map.polymap);
+ d = atom_getfloatarg((indx*32)+3, POLYMAP, x->x_map.polymap);
+ e = atom_getfloatarg((indx*32)+4, POLYMAP, x->x_map.polymap);
+ f = atom_getfloatarg((indx*32)+5, POLYMAP, x->x_map.polymap);
+ g = atom_getfloatarg((indx*32)+6, POLYMAP, x->x_map.polymap);
+ h = atom_getfloatarg((indx*32)+7, POLYMAP, x->x_map.polymap);
+ i = atom_getfloatarg((indx*32)+8, POLYMAP, x->x_map.polymap);
+ j = atom_getfloatarg((indx*32)+9, POLYMAP, x->x_map.polymap);
+ k = atom_getfloatarg((indx*32)+10, POLYMAP, x->x_map.polymap);
+ l = atom_getfloatarg((indx*32)+11, POLYMAP, x->x_map.polymap);
+ m = atom_getfloatarg((indx*32)+12, POLYMAP, x->x_map.polymap);
+ n = atom_getfloatarg((indx*32)+13, POLYMAP, x->x_map.polymap);
+ o = atom_getfloatarg((indx*32)+14, POLYMAP, x->x_map.polymap);
+ p = atom_getfloatarg((indx*32)+15, POLYMAP, x->x_map.polymap);
+ aa = atom_getfloatarg((indx*32)+16, POLYMAP, x->x_map.polymap);
+ bb = atom_getfloatarg((indx*32)+17, POLYMAP, x->x_map.polymap);
+ cc = atom_getfloatarg((indx*32)+18, POLYMAP, x->x_map.polymap);
+ dd = atom_getfloatarg((indx*32)+19, POLYMAP, x->x_map.polymap);
+ ee = atom_getfloatarg((indx*32)+20, POLYMAP, x->x_map.polymap);
+ ff = atom_getfloatarg((indx*32)+21, POLYMAP, x->x_map.polymap);
+ gg = atom_getfloatarg((indx*32)+22, POLYMAP, x->x_map.polymap);
+ hh = atom_getfloatarg((indx*32)+23, POLYMAP, x->x_map.polymap);
+ ii = atom_getfloatarg((indx*32)+24, POLYMAP, x->x_map.polymap);
+ jj = atom_getfloatarg((indx*32)+25, POLYMAP, x->x_map.polymap);
+ kk = atom_getfloatarg((indx*32)+26, POLYMAP, x->x_map.polymap);
+ ll = atom_getfloatarg((indx*32)+27, POLYMAP, x->x_map.polymap);
+ mm = atom_getfloatarg((indx*32)+28, POLYMAP, x->x_map.polymap);
+ nn = atom_getfloatarg((indx*32)+29, POLYMAP, x->x_map.polymap);
+ oo = atom_getfloatarg((indx*32)+30, POLYMAP, x->x_map.polymap);
+ pp = atom_getfloatarg((indx*32)+31, POLYMAP, x->x_map.polymap);
+ if(indx<9)
+ post("%d :%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", indx+1, a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,aa,bb,cc,dd,ee,ff,gg,hh,ii,jj,kk,ll,mm,nn,oo,pp);
+ else if(indx>=9)
+ post("%d:%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", indx+1, a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,aa,bb,cc,dd,ee,ff,gg,hh,ii,jj,kk,ll,mm,nn,oo,pp);
+ }
+}
+
+void polymap_clear(t_polymap *x)
+{
+ int i;
+ for(i=0;i<POLYMAP;i++)
+ {
+ SETFLOAT(&x->x_map.polymap[i], 0);
+ }
+ for(i=0;i<MAXPOLY;i++)
+ {
+ SETFLOAT(&x->x_map.polybins[i], 0);
+ }
+ for(i=0;i<2;i++)
+ {
+ SETFLOAT(&x->x_map.note[i], 0);
+ }
+ x->polynow=0;
+ outlet_float(x->poly, x->polynow);
+}
+
+void *polymap_new(t_floatarg poly)
+{
+ t_polymap *x = (t_polymap *)pd_new(polymap_class);
+ int i;
+ for(i=0;i<POLYMAP;i++)
+ {
+ SETFLOAT(&x->x_map.polymap[i], 0);
+ }
+ for(i=0;i<MAXPOLY;i++)
+ {
+ SETFLOAT(&x->x_map.polybins[i], 0);
+ }
+ for(i=0;i<2;i++)
+ {
+ SETFLOAT(&x->x_map.note[i], 0);
+ }
+ x->maxpoly = poly > 0 ? poly : 1;
+ floatinlet_new(&x->x_obj, &x->maxpoly);
+ x->note = outlet_new(&x->x_obj, &s_float);
+ x->new = outlet_new(&x->x_obj, &s_float);
+ x->poly = outlet_new(&x->x_obj, &s_float);
+ x->overflow = outlet_new(&x->x_obj, &s_list);
+ return (void *)x;
+}
+
+void polymap_setup(void)
+{
+ polymap_class = class_new(gensym("polymap"),
+ (t_newmethod)polymap_new,
+ 0, sizeof(t_polymap),
+ 0, A_DEFFLOAT, 0);
+ post("|. . . . . . . . .polymap. . . . . . . . .|");
+ post("|_- polyphonic chain reaction regulator -_|");
+ post("| . . . . . .Edward Kelly 2006. . . . . . |");
+ class_sethelpsymbol(polymap_class, gensym("help-polymap"));
+ class_addmethod(polymap_class, (t_method)polymap_note, gensym("note"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(polymap_class, (t_method)polymap_clear, gensym("clear"), A_DEFFLOAT, 0);
+ class_addmethod(polymap_class, (t_method)polymap_print, gensym("print"), A_DEFFLOAT, 0);
+ class_addmethod(polymap_class, (t_method)polymap_print32, gensym("print32"), A_DEFFLOAT, 0);
+}
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);
+}
diff --git a/sieve/help-sieve.pd b/sieve/help-sieve.pd
new file mode 100755
index 0000000..1e82e8a
--- /dev/null
+++ b/sieve/help-sieve.pd
@@ -0,0 +1,79 @@
+#N canvas 439 25 595 461 10;
+#X obj 94 346 sieve;
+#X msg 147 276 set 2 1;
+#X msg 198 276 set 7 0.86;
+#X msg 148 198 map 0 1 0 0 0 3 0 2 0 0.7;
+#X msg 147 229 get 0;
+#X msg 147 250 get 1;
+#X floatatom 37 384 5 0 0 0 - - -;
+#X floatatom 81 382 5 0 0 0 - - -;
+#X obj 129 379 print MAPOUT;
+#X obj 218 379 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 218 397 print EXACT;
+#X obj 37 419 print MAPPED;
+#X obj 81 399 print VALUE;
+#X msg 147 324 clear;
+#X text 189 228 get map;
+#X text 189 249 get inverted map;
+#X floatatom 309 406 5 0 0 0 - - -;
+#X floatatom 350 406 5 0 0 0 - - -;
+#X obj 341 363 prepend map;
+#X obj 395 405 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 189 323 clear object;
+#X text 277 277 set [location \, value];
+#X msg 147 297 set 2 0;
+#X text 201 297 unset location;
+#X text 332 196 set map;
+#X floatatom 35 318 5 0 0 0 - - -;
+#X obj 29 184 vradio 15 1 0 4 empty empty mode 0 -6 0 10 -262144 -1
+-1 0;
+#X msg 29 248 mode \$1;
+#X text 62 170 : 0=exact \, 1=nearest \, 2=shunt up \, 3=shunt down
+;
+#X obj 341 383 sieve;
+#X obj 22 19 sieve;
+#X text 62 19 takes integers and maps them to floats if they are set.
+;
+#X text 63 32 in the default mode (mode 0) integers without an associated
+float are blocked \, so a map will sieve the input.;
+#X text 64 60 mode 1 forces the sieve to choose the nearest index \,
+so that inputs are sent to alternative outputs. The rightmost output
+bangs only if the input is exact.;
+#X text 64 101 In modes 2 and 3 the sieve chooses the next map up or
+the next map down. If the input is higher than the highest mapped integer
+in mode 2 \, or lower than the lowest in mode 3 \, then the shunting
+is wrapped and the lowest or highest is chosen respectively.;
+#X text 294 330 when the inverted map is sent to another;
+#X text 298 344 sieve object \, the input is segregated.;
+#X text 38 440 Polyphony control objects by Ed Kelly \, November 2006
+;
+#X text 411 439 See also;
+#X obj 476 438 polymap;
+#X obj 476 417 polystat;
+#X obj 532 438 maskxor;
+#X connect 0 0 6 0;
+#X connect 0 1 7 0;
+#X connect 0 2 8 0;
+#X connect 0 2 18 0;
+#X connect 0 3 9 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 11 0;
+#X connect 7 0 12 0;
+#X connect 9 0 10 0;
+#X connect 13 0 0 0;
+#X connect 13 0 18 0;
+#X connect 18 0 29 0;
+#X connect 22 0 0 0;
+#X connect 25 0 0 0;
+#X connect 25 0 29 0;
+#X connect 26 0 27 0;
+#X connect 27 0 0 0;
+#X connect 29 0 16 0;
+#X connect 29 1 17 0;
+#X connect 29 3 19 0;
diff --git a/sieve/makefile b/sieve/makefile
new file mode 100755
index 0000000..e0f86ef
--- /dev/null
+++ b/sieve/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: sieve.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: sieve.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: sieve.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: sieve.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: sieve.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 sieve.$(EXT) $(INSTALL_PREFIX)/lib/pd/extra
+ install -m 644 *.pd $(INSTALL_PREFIX)/lib/pd/doc/5.reference
diff --git a/sieve/sieve.c b/sieve/sieve.c
new file mode 100755
index 0000000..cd6c7d5
--- /dev/null
+++ b/sieve/sieve.c
@@ -0,0 +1,285 @@
+/* takes a map like 0 1 3 4 7 and only returns the number if it is present */
+/* in the map, or returns the closest, or the next up or down (wrapped)*/
+#include "m_pd.h"
+#include <math.h>
+#include <string.h>
+#define MAXENTRIES 512
+#define LASTENTRY 511
+
+static t_class *sieve_class;
+
+/* mode = 0 : block when absent, 1: nearest when absent, 2: shunt when absent */
+typedef struct _map
+{
+ t_atom map[MAXENTRIES];
+ t_atom nomap[MAXENTRIES];
+} t_map;
+
+typedef struct _sieve
+{
+ t_object x_obj;
+ t_map x_map;
+ t_float input, mode, max, outmap;
+ t_outlet *mapped, *value, *mapout, *inst;
+} t_sieve;
+
+void sieve_float(t_sieve *x, t_floatarg fin)
+{
+ int i, ip, in, arg, arga, argb, argaout, argbout, argxa, argxb, itest, itesta, itestb, iresult;
+ itest = itesta = itestb = iresult = arga = argb = arg = 0;
+ float test, testa, testb, fresult;
+ test = testa = testb = fresult = 0;
+ x->input = arg = fin;// < 0 ? 0 : fin > LASTENTRY ? LASTENTRY : (int)fin;
+ if (x->mode == 0)
+ {
+ test = fin < 0 ? 0 : atom_getfloatarg(arg, MAXENTRIES, x->x_map.map);
+ if(test!=0)
+ {
+ outlet_bang(x->inst);
+ outlet_float(x->value, test);
+ outlet_float(x->mapped, arg);
+ }
+ }
+ else if (x->mode == 1)
+ {
+ test = fin < 0 ? 0 : atom_getfloatarg(arg, MAXENTRIES, x->x_map.map);
+ if(test!=0)
+ {
+ outlet_bang(x->inst);
+ outlet_float(x->value, test);
+ outlet_float(x->mapped, arg);
+ }
+ else
+ {
+ arga = argb = arg;
+ while(itest == 0 && (arga > -1 || argb < MAXENTRIES))
+ {
+ arga--;
+ argb++;
+ argxa = arga >= 0 ? arga : 0;
+ argxb = argb <= LASTENTRY ? argb : LASTENTRY;
+ testa = atom_getfloatarg(argxa, MAXENTRIES, x->x_map.map);
+ testb = atom_getfloatarg(argxb, MAXENTRIES, x->x_map.map);
+ itesta = testa != 0 ? 1 : 0;
+ itestb = testb != 0 ? 1 : 0;
+ itest = fin < 0 ? 0 : itesta + itestb;
+ }
+ switch(itest)
+ {
+ case 2:
+ if (x->mode == 1)
+ {
+ outlet_float(x->value, testb);
+ outlet_float(x->mapped, argb);
+ }
+ else
+ {
+ outlet_float(x->value, testa);
+ outlet_float(x->mapped, arga);
+ }
+ case 1:
+ iresult = itesta == 1 ? arga : argb;
+ fresult = itesta == 1 ? testa : testb;
+ outlet_float(x->value, fresult);
+ outlet_float(x->mapped, iresult);
+ case 0:
+ break;
+ }
+ }
+ }
+ else if (x->mode==2)
+ {
+ itest = 0;
+ test = fin < 0 ? 0 : atom_getfloatarg(arg, MAXENTRIES, x->x_map.map);
+ if(test!=0)
+ {
+ outlet_bang(x->inst);
+ outlet_float(x->value, test);
+ outlet_float(x->mapped, arg);
+ }
+ else
+ {
+ arga = arg;
+ while(itest == 0 && (x->max > 0))
+ {
+ arga = (arga + 1) <= LASTENTRY ? (arga + 1) : 0;
+ testa = atom_getfloatarg(arga, MAXENTRIES, x->x_map.map);
+ itest = testa != 0 ? 1 : 0;
+ }
+ if(x->max > 0 && fin >= 0)
+ {
+ outlet_float(x->value, testa);
+ outlet_float(x->mapped, arga);
+ }
+ }
+ }
+ else if (x->mode == 3)
+ {
+ itest = 0;
+ test = fin < 0 ? 0 : atom_getfloatarg(arg, MAXENTRIES, x->x_map.map);
+ if(test!=0)
+ {
+ outlet_bang(x->inst);
+ outlet_float(x->value, test);
+ outlet_float(x->mapped, arg);
+ }
+ else
+ {
+ arga = arg;
+ while(itest == 0 && (x->max > 0))
+ {
+ argb = arga - 1;
+ arga = argb >= 0 ? argb : LASTENTRY;
+ testa = atom_getfloatarg(arga, MAXENTRIES, x->x_map.map);
+ itest = testa != 0 ? 1 : 0;
+ }
+ }
+ outlet_float(x->value, testa);
+ outlet_float(x->mapped, arga);
+ }
+}
+
+void sieve_set(t_sieve *x, t_floatarg fmap, t_floatarg fval)
+{
+ float fvaller;
+ if(fmap < MAXENTRIES && fmap >= 0)
+ {
+ int imap = (int)fmap;
+ fvaller = fval != 0 ? 0 : 1;
+ SETFLOAT(&x->x_map.map[imap], fval);
+ SETFLOAT(&x->x_map.nomap[imap], fvaller);
+ x->max = fmap > x->max ? fmap : x->max;
+ }
+}
+
+void sieve_get(t_sieve *x, t_floatarg inv)
+{
+ if(inv!=0)
+ {
+ outlet_list(x->mapout, gensym("list"), x->max+1, x->x_map.nomap);
+ }
+ else outlet_list(x->mapout, gensym("list"), x->max+1, x->x_map.map);
+ x->outmap = inv;
+}
+
+void sieve_clear(t_sieve *x)
+{
+ //memset(x->x_map.map, 0, MAXENTRIES);
+ int i;
+ for(i=0;i<MAXENTRIES;i++)
+ {
+ SETFLOAT(&x->x_map.map[i], 0);
+ SETFLOAT(&x->x_map.nomap[i], 1);
+ }
+ //memset(x->x_map.nomap, 1, MAXENTRIES);
+ x->max = 0;
+}
+
+void sieve_map(t_sieve *x, t_symbol *s, int argc, t_atom *argv)
+{
+ //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.nomap+i, 1);
+ }
+ x->max = 0;
+ float arg;
+ for(i=0;i<argc;i++)
+ {
+ arg = atom_getfloat(argv+i);
+ if(arg != 0)
+ {
+ SETFLOAT(&x->x_map.map[i], arg);
+ SETFLOAT(&x->x_map.nomap[i], 0);
+ x->max = i;
+ }
+ }
+ if (x->max > 0 && x->outmap == 0)
+ {
+ outlet_list(x->mapout, gensym("list"), x->max+1, x->x_map.map);
+ }
+ else if (x->max > 0 && x->outmap == 1)
+ {
+ outlet_list(x->mapout, gensym("list"), x->max+1, x->x_map.nomap);
+ }
+}
+
+void sieve_mode(t_sieve *x, t_floatarg fmode)
+{
+ x->mode = fmode < 0 ? 0 : fmode > 3 ? 3 : fmode;
+}
+
+void sieve_debug(t_sieve *x)
+{
+ float ele0, ele1, ele2, ele3, ele4, ele5, ele6, ele7, ele8, ele9;
+ float nle0, nle1, nle2, nle3, nle4, nle5, nle6, nle7, nle8, nle9;
+ ele0 = atom_getfloatarg(0, MAXENTRIES, x->x_map.map);
+ ele1 = atom_getfloatarg(1, MAXENTRIES, x->x_map.map);
+ ele2 = atom_getfloatarg(2, MAXENTRIES, x->x_map.map);
+ ele3 = atom_getfloatarg(3, MAXENTRIES, x->x_map.map);
+ ele4 = atom_getfloatarg(4, MAXENTRIES, x->x_map.map);
+ ele5 = atom_getfloatarg(5, MAXENTRIES, x->x_map.map);
+ ele6 = atom_getfloatarg(6, MAXENTRIES, x->x_map.map);
+ ele7 = atom_getfloatarg(7, MAXENTRIES, x->x_map.map);
+ ele8 = atom_getfloatarg(8, MAXENTRIES, x->x_map.map);
+ ele9 = atom_getfloatarg(9, MAXENTRIES, x->x_map.map);
+ nle0 = atom_getfloatarg(0, MAXENTRIES, x->x_map.nomap);
+ nle1 = atom_getfloatarg(1, MAXENTRIES, x->x_map.nomap);
+ nle2 = atom_getfloatarg(2, MAXENTRIES, x->x_map.nomap);
+ nle3 = atom_getfloatarg(3, MAXENTRIES, x->x_map.nomap);
+ nle4 = atom_getfloatarg(4, MAXENTRIES, x->x_map.nomap);
+ nle5 = atom_getfloatarg(5, MAXENTRIES, x->x_map.nomap);
+ nle6 = atom_getfloatarg(6, MAXENTRIES, x->x_map.nomap);
+ nle7 = atom_getfloatarg(7, MAXENTRIES, x->x_map.nomap);
+ nle8 = atom_getfloatarg(8, MAXENTRIES, x->x_map.nomap);
+ nle9 = atom_getfloatarg(9, MAXENTRIES, x->x_map.nomap);
+ /* post("blocksize = %d, scales = %d, vectorsize = %d, offset = %d",
+ x->N, x->scales, x->vecsize, x->offset); */
+ post("mode = %d, max = %d", x->mode, x->max);
+ post("first 10 elements = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", ele0, ele1, ele2, ele3, ele4, ele5, ele6, ele7, ele8, ele9);
+ post("first 10 elements = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", nle0, nle1, nle2, nle3, nle4, nle5, nle6, nle7, nle8, nle9);
+}
+
+void *sieve_new(t_floatarg f)
+{
+ t_sieve *x = (t_sieve *)pd_new(sieve_class);
+ x->mode = f;
+ x->max = 0;
+ x->outmap = 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.nomap+i, 1);
+ }
+ x->mapped = outlet_new(&x->x_obj, &s_float);
+ x->value = outlet_new(&x->x_obj, &s_float);
+ x->mapout = outlet_new(&x->x_obj, &s_list);
+ x->inst = outlet_new(&x->x_obj, &s_bang);
+ return (void *)x;
+}
+
+void sieve_setup(void)
+{
+
+ sieve_class = class_new(gensym("sieve"),
+ (t_newmethod)sieve_new,
+ 0, sizeof(t_sieve),
+ 0, A_DEFFLOAT, 0);
+ post("|^^^^^^^^^^^^^sieve^^^^^^^^^^^^^|");
+ post("|->^^^integer map to floats^^^<-|");
+ post("|^^^^^^^Edward Kelly 2006^^^^^^^|");
+ class_sethelpsymbol(sieve_class, gensym("help-sieve"));
+ class_addfloat(sieve_class, sieve_float);
+ class_addmethod(sieve_class, (t_method)sieve_set, gensym("set"), A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(sieve_class, (t_method)sieve_map, gensym("map"), A_GIMME, 0);
+ class_addmethod(sieve_class, (t_method)sieve_clear, gensym("clear"), A_DEFFLOAT, 0);
+ class_addmethod(sieve_class, (t_method)sieve_get, gensym("get"), A_DEFFLOAT, 0);
+ class_addmethod(sieve_class, (t_method)sieve_mode, gensym("mode"), A_DEFFLOAT, 0);
+ class_addmethod(sieve_class, (t_method)sieve_debug, gensym("debug"), A_DEFFLOAT, 0);
+}