aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--Makefile.config21
-rw-r--r--Makefile.config_darwin25
-rw-r--r--Makefile.pd_darwin27
-rw-r--r--README17
-rw-r--r--README.darwin8
-rw-r--r--abs/64k.pd38
-rw-r--r--abs/cadd~.pd12
-rw-r--r--abs/ccmap~.pd36
-rw-r--r--abs/cconj~.pd10
-rw-r--r--abs/cep~.pd18
-rw-r--r--abs/cinv~.pd27
-rw-r--r--abs/cmul~.pd28
-rw-r--r--abs/cosc~.pd22
-rw-r--r--abs/cstate+~.pd9
-rw-r--r--abs/cstate~.pd7
-rw-r--r--abs/csub~.pd16
-rw-r--r--abs/dsfosc~.pd73
-rw-r--r--abs/expmap~.pd38
-rw-r--r--abs/fblock.pd2
-rw-r--r--abs/fblock~.pd22
-rw-r--r--abs/fmod.pd25
-rw-r--r--abs/fmop~.pd20
-rw-r--r--abs/frequor~.pd26
-rw-r--r--abs/icep~.pd18
-rw-r--r--abs/idsfosc~.pd27
-rw-r--r--abs/lattice3.pd31
-rw-r--r--abs/lpifft~.pd61
-rw-r--r--abs/pulsor~.pd39
-rw-r--r--abs/sin~.pd8
-rw-r--r--abs/step_16.pd53
-rw-r--r--abs/step_16r.pd50
-rw-r--r--abs/step_4.pd36
-rw-r--r--abs/step_4r.pd26
-rw-r--r--abs/ti_hihat.pd195
-rw-r--r--abs/ti_snare.pd74
-rw-r--r--abs/ucmod~.pd27
-rw-r--r--abs/ucnorm~.pd27
-rw-r--r--configure.ac42
-rw-r--r--doc/bitsplit~.pd45
-rw-r--r--doc/blocknorm~.pd77
-rw-r--r--doc/blosc~.pd110
-rw-r--r--doc/bmatrix~.pd10
-rw-r--r--doc/bwin~.pd10
-rw-r--r--doc/clog~.pd8
-rw-r--r--doc/eadsr~.pd74
-rw-r--r--doc/ead~.pd47
-rw-r--r--doc/examples/formantdynwav.pd198
-rw-r--r--doc/lattice~.pd40
-rw-r--r--doc/reference.txt28
-rw-r--r--doc/resofilt~.pd79
-rw-r--r--doc/sbosc~.pd36
-rw-r--r--doc/scrollgrid1D~.pd111
-rw-r--r--include/dspi/DSPIcomplex.h2
-rw-r--r--include/extlib_util.h12
-rw-r--r--include/filters.h226
-rw-r--r--modules++/Makefile2
-rw-r--r--modules++/filterortho.cc26
-rw-r--r--modules/Makefile3
-rw-r--r--modules/bfft.c41
-rw-r--r--modules/bitsplit.c107
-rw-r--r--modules/blocknorm.c129
-rw-r--r--modules/cmath.c176
-rw-r--r--modules/dynwav.c2
-rw-r--r--modules/ead.c43
-rw-r--r--modules/eadsr.c47
-rw-r--r--modules/ear.c8
-rw-r--r--modules/eblosc.c599
-rw-r--r--modules/fdn.c4
-rw-r--r--modules/lattice.c11
-rw-r--r--modules/matrix.c4
-rw-r--r--modules/permut.c9
-rw-r--r--modules/ramp.c66
-rw-r--r--modules/resofilt.c397
-rw-r--r--modules/sbosc.c175
-rw-r--r--modules/scrollgrid1D.c220
-rw-r--r--modules/statwav.c8
-rw-r--r--system/setup.c19
78 files changed, 4153 insertions, 301 deletions
diff --git a/Makefile b/Makefile
index e24c31b..c14ac9f 100644
--- a/Makefile
+++ b/Makefile
@@ -22,3 +22,7 @@ tags:
tagsclean:
rm -f TAGS
+mrproper: clean tagsclean
+ rm -rf Makefile.config config.status config.log configure autom4te.cache
+
+
diff --git a/Makefile.config b/Makefile.config
deleted file mode 100644
index dbbe56b..0000000
--- a/Makefile.config
+++ /dev/null
@@ -1,21 +0,0 @@
-PD_DIR = /home/tom/pd/distro/pd/src
-CREB_DIR = /home/tom/pd/extlib
-CREB_VERSION = 0.8
-
-DEFS = -DPD -DCREB_VERSION=\"$(CREB_VERSION)\"
-#-DHAVE_ABS_TILDE
-
-LINUXCFLAGS = $(DEFS) -O2 -funroll-loops -fomit-frame-pointer \
- -Wall -W -Wstrict-prototypes -Werror \
- -Wno-unused -Wno-parentheses -Wno-switch # -Wshadow
-
-LINUXINCLUDE = -I$(PD_DIR) -I../include -I../include/dspi
-
-#CC = gcc
-#CXX = g++
-
-.c.o:
- $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
-.cc.o:
- $(CXX) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.cc
-
diff --git a/Makefile.config_darwin b/Makefile.config_darwin
deleted file mode 100644
index 705d134..0000000
--- a/Makefile.config_darwin
+++ /dev/null
@@ -1,25 +0,0 @@
-PD_DIR = /usr/local/pd/src
-PD_EXECUTABLE = /usr/local/pd/bin/pd
-
-CREB_VERSION = 0.8
-
-LIBNAME = creb.pd_darwin
-
-DEFS = -DPD -DCREB_VERSION=\"$(CREB_VERSION)\"
-
-CFLAGS = $(DEFS) -O2 -funroll-loops -fomit-frame-pointer \
- -Wall -W -Wstrict-prototypes -Werror \
- -Wno-unused -Wno-parentheses -Wno-switch # -Wshadow
-
-INCLUDE = -I$(PD_DIR) -I../include -I../include/dspi
-
-LIBFLAGS = -bundle -bundle_loader $(PD_EXECUTABLE)
-
-#CC = gcc
-#CXX = g++
-
-.c.o:
- $(CC) $(CFLAGS) $(INCLUDE) -o $*.o -c $*.c
-.cc.o:
- $(CXX) $(CFLAGS) $(INCLUDE) -o $*.o -c $*.cc
-
diff --git a/Makefile.pd_darwin b/Makefile.pd_darwin
deleted file mode 100644
index bcdaa83..0000000
--- a/Makefile.pd_darwin
+++ /dev/null
@@ -1,27 +0,0 @@
-CONFIGFILE = Makefile.config_darwin
-include $(CONFIGFILE)
-
-current:
- make -C system
- make -C modules
- make -C modules++
-
- rm -f $(LIBNAME)
- $(CXX) $(LIBFLAGS) -o $(LIBNAME) system/*.o modules/*.o modules++/*.o -lm
-# strip --strip-unneeded $(LIBNAME)
-
-clean:
- make -C include clean
- make -C modules clean
- make -C modules++ clean
- make -C system clean
- rm -f $(LIBNAME)
- rm -f *~
-
-tags:
- etags --language=auto include/*.h system/*.c modules/*.c modules++/*.cpp
-
-tagsclean:
- rm -f TAGS
-
-
diff --git a/README b/README
index 8f2bb32..b4c81c8 100644
--- a/README
+++ b/README
@@ -22,22 +22,21 @@ The GNU Public Licence can be found in the file COPYING
------------------------------------------------------------------
-This is a collection of pd externals. No fancy stuff, just my
-personal bag of (ahem) tricks...
+This is a collection of pd externals. My bag of tricks.
-Edit Makefile.config, type make.
+To build:
+./configure
+make
+To run:
add the library to the pd startup line, and specify the
path for the included abstractions (<crebdir>/abs)
-Documentation packages in doc/
+To figure out how it works:
+Documentation patches in doc/
See doc/reference.txt for a list of objects
-The package only includes linux + darwin makefiles. It is plain c/c++ so
-porting should be relatively simple.
-
-For compilation on OSX, see README.darwin (thanks to Adam Lindsay for
-the darwin makefiles)
+Should build on linux and darwin (OSX).
Enjoy,
diff --git a/README.darwin b/README.darwin
deleted file mode 100644
index 0edef42..0000000
--- a/README.darwin
+++ /dev/null
@@ -1,8 +0,0 @@
-Create a symbolic link to Makefile.config_darwin:
-
- ln -s Makefile.config_darwin Makefile.config
-
-Make the file using the pd_darwin file:
-
- make -f Makefile.pd_darwin
-
diff --git a/abs/64k.pd b/abs/64k.pd
index 7dc4933..9a919b1 100644
--- a/abs/64k.pd
+++ b/abs/64k.pd
@@ -1,19 +1,19 @@
-#N canvas 50 0 979 783 10;
+#N canvas 0 0 968 634 10;
#X obj 501 74 soundfiler;
#X obj 45 125 * 65536;
-#X obj 91 649 +~;
-#X obj 106 618 *~ 65536;
-#X obj 289 309 metro 62.5;
-#X obj 116 580 phasor~ 1;
-#X obj 279 460 sel 0;
-#X msg 279 527 0;
-#X obj 561 181 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144
--1 -1;
+#X obj 197 414 +~;
+#X obj 212 383 *~ 65536;
+#X obj 268 232 metro 62.5;
+#X obj 213 347 phasor~ 1;
+#X obj 272 271 sel 0;
+#X msg 270 296 0;
+#X obj 561 181 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
#X obj 45 35 +;
#X obj 45 10 *;
-#X obj 391 276 bpm;
-#X msg 286 254 reset;
-#X obj 202 164 count 32;
+#X obj 683 196 bpm;
+#X msg 265 177 reset;
+#X obj 189 133 count 32;
#X obj 478 -63 loadbang;
#X obj 265 55 mod 16;
#X obj 257 2 *;
@@ -32,7 +32,7 @@
#X text 151 -46 sample offset;
#X obj 377 -23 inlet;
#X text 357 -44 beat offset;
-#X obj 116 535 f;
+#X obj 601 278 f;
#X obj 681 144 inlet;
#X text 688 123 bpm;
#X msg 500 43 read -resize -raw 0 1 2 l \$1 \$2;
@@ -40,14 +40,14 @@
#X obj 571 -47 t b b;
#X obj 589 144 inlet;
#X text 589 123 reset;
-#X obj 91 704 outlet~;
+#X obj 193 477 outlet~;
#X obj 580 -17 symbol \$0-table;
#X obj 795 95 table \$0-table;
-#X obj 91 675 tabread4~ \$0-table;
-#X text 608 612 reset;
-#X obj 608 633 outlet;
-#X obj 387 644 outlet;
-#X text 387 623 counter;
+#X obj 201 441 tabread4~ \$0-table;
+#X text 433 459 reset;
+#X obj 433 480 outlet;
+#X obj 362 480 outlet;
+#X text 362 459 counter;
#X connect 0 0 24 0;
#X connect 1 0 2 0;
#X connect 2 0 43 0;
diff --git a/abs/cadd~.pd b/abs/cadd~.pd
new file mode 100644
index 0000000..47a31c0
--- /dev/null
+++ b/abs/cadd~.pd
@@ -0,0 +1,12 @@
+#N canvas 800 696 381 197 10;
+#X obj 58 49 inlet~;
+#X obj 58 159 outlet~;
+#X text 49 5 complex addition;
+#X obj 195 49 inlet~;
+#X obj 114 49 inlet~;
+#X obj 114 159 outlet~;
+#X obj 251 49 inlet~;
+#X connect 0 0 1 0;
+#X connect 3 0 1 0;
+#X connect 4 0 5 0;
+#X connect 6 0 5 0;
diff --git a/abs/ccmap~.pd b/abs/ccmap~.pd
new file mode 100644
index 0000000..8fbeb31
--- /dev/null
+++ b/abs/ccmap~.pd
@@ -0,0 +1,36 @@
+#N canvas 725 589 450 300 10;
+#X obj 39 85 inlet~;
+#X obj 139 254 outlet~;
+#X obj 210 86 inlet~;
+#X obj 98 85 inlet~;
+#X obj 198 254 outlet~;
+#X obj 269 86 inlet~;
+#X text 63 58 z;
+#X text 237 60 a;
+#X obj 159 206 cinv~;
+#X obj 138 230 cmul~;
+#X obj 211 117 cconj~;
+#X obj 159 167 -~ 1;
+#X obj 64 169 csub~;
+#X text 23 10 conformal self map of the unit disk (z-a)/(1-conj(a)z)
+;
+#X obj 182 142 cmul~;
+#X connect 0 0 12 2;
+#X connect 0 0 14 0;
+#X connect 2 0 10 0;
+#X connect 2 0 12 0;
+#X connect 3 0 12 3;
+#X connect 3 0 14 1;
+#X connect 5 0 10 1;
+#X connect 5 0 12 1;
+#X connect 8 0 9 2;
+#X connect 8 1 9 3;
+#X connect 9 0 1 0;
+#X connect 9 1 4 0;
+#X connect 10 0 14 2;
+#X connect 10 1 14 3;
+#X connect 11 0 8 0;
+#X connect 12 0 9 0;
+#X connect 12 1 9 1;
+#X connect 14 0 11 0;
+#X connect 14 1 8 1;
diff --git a/abs/cconj~.pd b/abs/cconj~.pd
new file mode 100644
index 0000000..dcf2f5f
--- /dev/null
+++ b/abs/cconj~.pd
@@ -0,0 +1,10 @@
+#N canvas 700 418 285 166 10;
+#X obj 58 49 inlet~;
+#X obj 57 105 outlet~;
+#X obj 195 49 inlet~;
+#X obj 194 105 outlet~;
+#X obj 194 75 *~ -1;
+#X text 49 5 complex conjugate;
+#X connect 0 0 1 0;
+#X connect 2 0 4 0;
+#X connect 4 0 3 0;
diff --git a/abs/cep~.pd b/abs/cep~.pd
new file mode 100644
index 0000000..cbebf0e
--- /dev/null
+++ b/abs/cep~.pd
@@ -0,0 +1,18 @@
+#N canvas 203 382 521 228 10;
+#X obj 70 42 inlet~;
+#X obj 124 42 inlet~;
+#X obj 94 66 nfft~;
+#X obj 94 95 clog~;
+#X obj 94 124 nifft~;
+#X obj 68 164 outlet~;
+#X obj 126 164 outlet~;
+#X text 229 45 forward cepstrum;
+#X text 229 64 using normalized fft/ifft objects;
+#X connect 0 0 2 0;
+#X connect 1 0 2 1;
+#X connect 2 0 3 0;
+#X connect 2 1 3 1;
+#X connect 3 0 4 0;
+#X connect 3 1 4 1;
+#X connect 4 0 5 0;
+#X connect 4 1 6 0;
diff --git a/abs/cinv~.pd b/abs/cinv~.pd
new file mode 100644
index 0000000..c7d4fa3
--- /dev/null
+++ b/abs/cinv~.pd
@@ -0,0 +1,27 @@
+#N canvas 808 178 381 297 10;
+#X obj 58 49 inlet~;
+#X obj 58 207 outlet~;
+#X obj 59 182 *~;
+#X obj 110 84 *~;
+#X obj 195 49 inlet~;
+#X obj 179 208 outlet~;
+#X obj 180 183 *~;
+#X obj 145 83 *~;
+#X obj 94 119 /~;
+#X obj 196 111 *~ -1;
+#X obj 73 85 +~ 1;
+#X text 49 5 complex inverse;
+#X connect 0 0 2 0;
+#X connect 0 0 3 0;
+#X connect 0 0 3 1;
+#X connect 2 0 1 0;
+#X connect 3 0 8 1;
+#X connect 4 0 7 0;
+#X connect 4 0 7 1;
+#X connect 4 0 9 0;
+#X connect 6 0 5 0;
+#X connect 7 0 8 1;
+#X connect 8 0 2 1;
+#X connect 8 0 6 0;
+#X connect 9 0 6 1;
+#X connect 10 0 8 0;
diff --git a/abs/cmul~.pd b/abs/cmul~.pd
new file mode 100644
index 0000000..f7e9b5a
--- /dev/null
+++ b/abs/cmul~.pd
@@ -0,0 +1,28 @@
+#N canvas 24 618 381 197 10;
+#X obj 58 49 inlet~;
+#X obj 58 159 outlet~;
+#X obj 177 154 outlet~;
+#X text 49 5 complex multiplication;
+#X obj 178 131 +~;
+#X obj 58 136 -~;
+#X obj 58 105 *~;
+#X obj 108 49 inlet~;
+#X obj 108 105 *~;
+#X obj 192 49 inlet~;
+#X obj 177 106 *~;
+#X obj 242 49 inlet~;
+#X obj 227 106 *~;
+#X connect 0 0 6 0;
+#X connect 0 0 12 0;
+#X connect 4 0 2 0;
+#X connect 5 0 1 0;
+#X connect 6 0 5 0;
+#X connect 7 0 8 0;
+#X connect 7 0 10 0;
+#X connect 8 0 5 1;
+#X connect 9 0 6 1;
+#X connect 9 0 10 1;
+#X connect 10 0 4 0;
+#X connect 11 0 8 1;
+#X connect 11 0 12 1;
+#X connect 12 0 4 1;
diff --git a/abs/cosc~.pd b/abs/cosc~.pd
new file mode 100644
index 0000000..b2762f4
--- /dev/null
+++ b/abs/cosc~.pd
@@ -0,0 +1,22 @@
+#N canvas 267 527 381 197 10;
+#X obj 57 52 inlet~;
+#X obj 58 78 phasor~;
+#X obj 151 51 inlet;
+#X text 48 25 frequency;
+#X text 154 25 phase;
+#X text 49 5 complex oscillator (unit norm exponential);
+#X obj 59 131 cos~;
+#X obj 118 132 sin~;
+#X obj 58 159 outlet~;
+#X obj 119 158 outlet~;
+#X obj 221 52 inlet;
+#X obj 59 105 *~ 1;
+#X text 211 24 phase synchronous harmonic;
+#X connect 0 0 1 0;
+#X connect 1 0 11 0;
+#X connect 2 0 1 1;
+#X connect 6 0 8 0;
+#X connect 7 0 9 0;
+#X connect 10 0 11 1;
+#X connect 11 0 7 0;
+#X connect 11 0 6 0;
diff --git a/abs/cstate+~.pd b/abs/cstate+~.pd
new file mode 100644
index 0000000..cfba48e
--- /dev/null
+++ b/abs/cstate+~.pd
@@ -0,0 +1,9 @@
+#N canvas 441 639 286 142 10;
+#X obj 23 12 table \$1-real \$2;
+#X obj 23 33 table \$1-imag \$2;
+#X obj 23 101 tabsend~ \$1-real;
+#X obj 143 101 tabsend~ \$1-imag;
+#X obj 22 70 inlet~;
+#X obj 143 69 inlet~;
+#X connect 4 0 2 0;
+#X connect 5 0 3 0;
diff --git a/abs/cstate~.pd b/abs/cstate~.pd
new file mode 100644
index 0000000..f437c84
--- /dev/null
+++ b/abs/cstate~.pd
@@ -0,0 +1,7 @@
+#N canvas 441 639 416 164 10;
+#X obj 18 23 tabreceive~ \$1-real;
+#X obj 17 52 outlet~;
+#X obj 164 53 outlet~;
+#X obj 165 24 tabreceive~ \$1-imag;
+#X connect 0 0 1 0;
+#X connect 3 0 2 0;
diff --git a/abs/csub~.pd b/abs/csub~.pd
new file mode 100644
index 0000000..eaf2b06
--- /dev/null
+++ b/abs/csub~.pd
@@ -0,0 +1,16 @@
+#N canvas 703 725 381 197 10;
+#X obj 58 49 inlet~;
+#X obj 58 159 outlet~;
+#X obj 195 49 inlet~;
+#X obj 59 101 -~;
+#X obj 116 49 inlet~;
+#X obj 116 159 outlet~;
+#X obj 253 49 inlet~;
+#X obj 117 101 -~;
+#X text 49 5 complex subtraction;
+#X connect 0 0 3 0;
+#X connect 2 0 3 1;
+#X connect 3 0 1 0;
+#X connect 4 0 7 0;
+#X connect 6 0 7 1;
+#X connect 7 0 5 0;
diff --git a/abs/dsfosc~.pd b/abs/dsfosc~.pd
new file mode 100644
index 0000000..2bb3675
--- /dev/null
+++ b/abs/dsfosc~.pd
@@ -0,0 +1,73 @@
+#N canvas 162 88 557 519 10;
+#X obj 201 473 outlet~;
+#X obj 258 473 outlet~;
+#X text 59 21 complex form of the discrete summation oscillator;
+#X text 62 38 (1-az^n)/(1-az) \, with z = e^(jw);
+#X obj 118 122 inlet~;
+#X text 93 100 frequency;
+#X obj 263 119 inlet;
+#X obj 118 284 cosc~;
+#X obj 233 258 *~ \$1;
+#X obj 118 350 *~;
+#X obj 149 350 *~;
+#X obj 233 283 cosc~;
+#X obj 232 340 *~;
+#X obj 263 340 *~;
+#X obj 118 378 +~ 1;
+#X obj 233 368 +~ 1;
+#X obj 119 404 cinv~;
+#X obj 213 446 cmul~;
+#X obj 354 122 inlet;
+#X obj 354 170 * -1;
+#X obj 166 327 lop~ 10;
+#X text 195 100 harmonics (N);
+#X text 317 102 modulation (r);
+#X obj 384 217 abs;
+#X obj 354 194 t f f;
+#X obj 354 278 *;
+#X obj 354 236 /;
+#X obj 384 256 pow \$1;
+#X floatatom 368 316 5 0 0 0 - - -;
+#X floatatom 192 270 5 0 0 0 - - -;
+#X obj 264 150 t b f;
+#X obj 354 148 f;
+#X obj 298 333 lop~ 10;
+#X connect 4 0 8 0;
+#X connect 4 0 7 0;
+#X connect 6 0 30 0;
+#X connect 7 0 9 0;
+#X connect 7 1 10 0;
+#X connect 8 0 11 0;
+#X connect 9 0 14 0;
+#X connect 10 0 16 1;
+#X connect 11 0 12 0;
+#X connect 11 1 13 0;
+#X connect 12 0 15 0;
+#X connect 13 0 17 3;
+#X connect 14 0 16 0;
+#X connect 15 0 17 2;
+#X connect 16 0 17 0;
+#X connect 16 1 17 1;
+#X connect 17 0 0 0;
+#X connect 17 1 1 0;
+#X connect 18 0 31 0;
+#X connect 19 0 24 0;
+#X connect 19 0 20 0;
+#X connect 20 0 10 1;
+#X connect 20 0 9 1;
+#X connect 23 0 26 1;
+#X connect 23 0 27 0;
+#X connect 24 0 26 0;
+#X connect 24 1 23 0;
+#X connect 25 0 32 0;
+#X connect 26 0 25 0;
+#X connect 27 0 25 1;
+#X connect 28 0 32 1;
+#X connect 28 0 29 0;
+#X connect 29 0 20 1;
+#X connect 30 0 31 0;
+#X connect 30 1 8 1;
+#X connect 30 1 27 1;
+#X connect 31 0 19 0;
+#X connect 32 0 13 1;
+#X connect 32 0 12 1;
diff --git a/abs/expmap~.pd b/abs/expmap~.pd
new file mode 100644
index 0000000..902b856
--- /dev/null
+++ b/abs/expmap~.pd
@@ -0,0 +1,38 @@
+#N canvas 754 478 456 394 10;
+#X obj 75 47 inlet~;
+#X obj 134 47 inlet;
+#X obj 186 47 inlet;
+#X obj 167 138 /;
+#X obj 167 160 log;
+#X text 138 29 min;
+#X text 193 30 max;
+#X text 80 9 exponential map from (-1 \, 1) to (min \, max);
+#X obj 75 244 *~;
+#X obj 75 302 *~;
+#X obj 74 335 outlet~;
+#X obj 214 114 f \$1;
+#X obj 167 114 f \$2;
+#X obj 75 268 exp~;
+#X obj 271 70 t b b;
+#X obj 271 49 loadbang;
+#X obj 134 71 t b f;
+#X obj 74 137 +~ 1;
+#X obj 74 162 *~ 0.5;
+#X connect 0 0 17 0;
+#X connect 1 0 16 0;
+#X connect 2 0 12 0;
+#X connect 3 0 4 0;
+#X connect 4 0 8 1;
+#X connect 8 0 13 0;
+#X connect 9 0 10 0;
+#X connect 11 0 3 1;
+#X connect 11 0 9 1;
+#X connect 12 0 3 0;
+#X connect 13 0 9 0;
+#X connect 14 0 12 0;
+#X connect 14 1 11 0;
+#X connect 15 0 14 0;
+#X connect 16 0 12 0;
+#X connect 16 1 11 0;
+#X connect 17 0 18 0;
+#X connect 18 0 8 0;
diff --git a/abs/fblock.pd b/abs/fblock.pd
index b75a8b2..a3d0828 100644
--- a/abs/fblock.pd
+++ b/abs/fblock.pd
@@ -7,12 +7,12 @@
#X obj 59 158 +;
#X obj 103 144 *;
#X obj 103 59 t b b f;
-#X text 200 35 fblock: compute block relative frequencies;
#X text 200 79 right inlet is also "active";
#X text 201 119 main usage is to compute block synchronous frequencies
;
#X text 200 134 for spectral domain processing;
#X text 201 49 out = left + right * (sys samplerate / blocksize);
+#X text 200 35 fblock: compute block relative frequencies;
#X connect 0 0 5 0;
#X connect 1 0 7 0;
#X connect 3 0 4 0;
diff --git a/abs/fblock~.pd b/abs/fblock~.pd
new file mode 100644
index 0000000..256c5c8
--- /dev/null
+++ b/abs/fblock~.pd
@@ -0,0 +1,22 @@
+#N canvas 64 291 617 246 10;
+#X text 201 77 main usage is to compute block synchronous frequencies
+;
+#X text 200 92 for spectral domain processing;
+#X text 201 49 out = left + right * (sys samplerate / blocksize);
+#X obj 36 36 inlet~;
+#X obj 37 198 outlet~;
+#X obj 102 110 samplerate~;
+#X text 200 35 fblock~: compute block relative frequencies;
+#X obj 102 83 loadbang;
+#X obj 57 165 *~;
+#X obj 101 35 inlet~;
+#X obj 102 138 / \$1;
+#X obj 171 86 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X connect 3 0 4 0;
+#X connect 5 0 10 0;
+#X connect 7 0 5 0;
+#X connect 8 0 4 0;
+#X connect 9 0 8 0;
+#X connect 10 0 8 1;
+#X connect 11 0 5 0;
diff --git a/abs/fmod.pd b/abs/fmod.pd
new file mode 100644
index 0000000..8cff45c
--- /dev/null
+++ b/abs/fmod.pd
@@ -0,0 +1,25 @@
+#N canvas 714 472 443 338 10;
+#X obj 52 36 inlet;
+#X obj 52 255 outlet;
+#X obj 110 36 inlet;
+#X obj 52 64 / \$1;
+#X obj 52 230 * \$1;
+#X obj 82 122 int;
+#X obj 52 96 t f f;
+#X obj 52 148 -;
+#X text 175 90 floating point version of;
+#X text 361 91 [mod];
+#X obj 52 175 moses 0;
+#X obj 52 203 + 1;
+#X connect 0 0 3 0;
+#X connect 2 0 3 1;
+#X connect 2 0 4 1;
+#X connect 3 0 6 0;
+#X connect 4 0 1 0;
+#X connect 5 0 7 1;
+#X connect 6 0 7 0;
+#X connect 6 1 5 0;
+#X connect 7 0 10 0;
+#X connect 10 0 11 0;
+#X connect 10 1 4 0;
+#X connect 11 0 4 0;
diff --git a/abs/fmop~.pd b/abs/fmop~.pd
new file mode 100644
index 0000000..e68f8e5
--- /dev/null
+++ b/abs/fmop~.pd
@@ -0,0 +1,20 @@
+#N canvas 662 414 450 300 10;
+#X obj 82 154 cos~;
+#X obj 82 89 phasor~;
+#X obj 160 96 osc~;
+#X obj 160 122 *~;
+#X obj 82 190 outlet~;
+#X obj 82 61 inlet~;
+#X obj 160 60 inlet~;
+#X obj 230 60 inlet~;
+#X text 76 12 fm operator;
+#X text 234 38 mod depth;
+#X text 157 40 mod freq;
+#X text 59 39 carrier freq;
+#X connect 0 0 4 0;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 3 0 0 0;
+#X connect 5 0 1 0;
+#X connect 6 0 2 0;
+#X connect 7 0 3 1;
diff --git a/abs/frequor~.pd b/abs/frequor~.pd
new file mode 100644
index 0000000..e12aace
--- /dev/null
+++ b/abs/frequor~.pd
@@ -0,0 +1,26 @@
+#N canvas 649 489 450 300 10;
+#X obj 133 212 *~ 2;
+#X obj 134 235 -~ 1;
+#X obj 230 141 + 0.5;
+#X obj 133 188 phasor~;
+#X msg 190 112 0;
+#X obj 190 90 loadbang;
+#X obj 135 258 outlet~;
+#X obj 133 165 fblock \$1;
+#X msg 190 141 1;
+#X obj 132 92 inlet;
+#X text 28 4 frequor~: frequency domain phasor~ (for traversing spectra)
+;
+#X text 98 75 nb windings;
+#X text 102 25 output: (0 \, N/2-1) -> (0 \, 1);
+#X text 152 41 (N/2 \, N-1) -> (-1 \, 0);
+#X connect 0 0 1 0;
+#X connect 1 0 6 0;
+#X connect 2 0 3 1;
+#X connect 3 0 0 0;
+#X connect 4 0 2 0;
+#X connect 4 0 8 0;
+#X connect 5 0 4 0;
+#X connect 7 0 3 0;
+#X connect 8 0 7 1;
+#X connect 9 0 7 1;
diff --git a/abs/icep~.pd b/abs/icep~.pd
new file mode 100644
index 0000000..ec05a93
--- /dev/null
+++ b/abs/icep~.pd
@@ -0,0 +1,18 @@
+#N canvas 318 596 521 228 10;
+#X obj 70 42 inlet~;
+#X obj 124 42 inlet~;
+#X obj 94 66 nfft~;
+#X obj 94 124 nifft~;
+#X obj 68 164 outlet~;
+#X obj 126 164 outlet~;
+#X text 229 45 backward cepstrum;
+#X obj 94 95 cexp~;
+#X text 229 64 using normalized fft/ifft objects;
+#X connect 0 0 2 0;
+#X connect 1 0 2 1;
+#X connect 2 0 7 0;
+#X connect 2 1 7 1;
+#X connect 3 0 4 0;
+#X connect 3 1 5 0;
+#X connect 7 0 3 0;
+#X connect 7 1 3 1;
diff --git a/abs/idsfosc~.pd b/abs/idsfosc~.pd
new file mode 100644
index 0000000..76db5bf
--- /dev/null
+++ b/abs/idsfosc~.pd
@@ -0,0 +1,27 @@
+#N canvas 414 255 527 400 10;
+#X obj 118 339 outlet~;
+#X obj 175 339 outlet~;
+#X obj 118 122 inlet~;
+#X text 93 100 frequency;
+#X obj 118 162 cosc~;
+#X obj 118 228 *~;
+#X obj 149 228 *~;
+#X obj 118 256 +~ 1;
+#X obj 119 282 cinv~;
+#X text 59 21 complex form of the (infinite) discrete summation oscillator
+;
+#X text 62 38 1/(1-az) \, with z = e^(jw);
+#X text 178 103 modulation (a);
+#X obj 215 123 inlet~;
+#X obj 214 192 *~ -1;
+#X connect 2 0 4 0;
+#X connect 4 0 5 0;
+#X connect 4 1 6 0;
+#X connect 5 0 7 0;
+#X connect 6 0 8 1;
+#X connect 7 0 8 0;
+#X connect 8 0 0 0;
+#X connect 8 1 1 0;
+#X connect 12 0 13 0;
+#X connect 13 0 6 1;
+#X connect 13 0 5 1;
diff --git a/abs/lattice3.pd b/abs/lattice3.pd
new file mode 100644
index 0000000..dadae9c
--- /dev/null
+++ b/abs/lattice3.pd
@@ -0,0 +1,31 @@
+#N canvas 178 387 450 300 10;
+#X obj 59 138 pow;
+#X msg 59 116 2;
+#X obj 106 139 pow;
+#X obj 159 136 pow;
+#X msg 106 117 1.5;
+#X msg 159 114 1.25;
+#X obj 106 166 *;
+#X obj 59 197 *;
+#X obj 130 47 unpack 0 0 0;
+#X obj 59 46 t b b b a;
+#X obj 59 226 outlet;
+#X obj 59 24 inlet;
+#X text 22 4 expand harmonic lattice vector in the (2 \, 3/2 \, 5/4)
+basis;
+#X connect 0 0 7 0;
+#X connect 1 0 0 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 1;
+#X connect 4 0 2 0;
+#X connect 5 0 3 0;
+#X connect 6 0 7 1;
+#X connect 7 0 10 0;
+#X connect 8 0 0 1;
+#X connect 8 1 2 1;
+#X connect 8 2 3 1;
+#X connect 9 0 1 0;
+#X connect 9 1 4 0;
+#X connect 9 2 5 0;
+#X connect 9 3 8 0;
+#X connect 11 0 9 0;
diff --git a/abs/lpifft~.pd b/abs/lpifft~.pd
new file mode 100644
index 0000000..60dde2d
--- /dev/null
+++ b/abs/lpifft~.pd
@@ -0,0 +1,61 @@
+#N canvas 261 505 536 346 10;
+#X obj 407 227 f;
+#X obj 351 251 * -1;
+#X obj 73 189 *~;
+#X obj 104 189 *~;
+#X obj 49 41 inlet~;
+#X obj 103 42 inlet~;
+#X obj 64 242 +~;
+#X obj 112 246 -~;
+#X obj 361 35 inlet;
+#X obj 377 59 fblock \$1;
+#X msg 434 38 1;
+#X obj 361 85 /;
+#X obj 392 299 +~;
+#X obj 361 109 moses 1;
+#X msg 361 131 1;
+#X obj 407 154 t b f;
+#X msg 407 176 0.5;
+#X obj 409 204 /;
+#X obj 407 275 pulsor~ \$1;
+#X obj 329 275 pulsor~ \$1;
+#X obj 446 15 loadbang;
+#X obj 48 315 outlet~;
+#X obj 123 312 outlet~;
+#X text 18 265 xform s.t. real spectrum = mono;
+#X text 18 7 ifft with rectangular lowpass for anti-aliased dynwav
+;
+#X text 9 18 creation arg = fft size \, right inlet = dynwav cutoff
+freq;
+#X obj 122 165 +~;
+#X obj 73 214 nifft~;
+#X connect 0 0 1 0;
+#X connect 0 0 18 0;
+#X connect 1 0 19 0;
+#X connect 2 0 27 0;
+#X connect 3 0 27 1;
+#X connect 4 0 2 0;
+#X connect 5 0 3 0;
+#X connect 6 0 21 0;
+#X connect 7 0 22 0;
+#X connect 8 0 11 0;
+#X connect 9 0 11 1;
+#X connect 10 0 9 1;
+#X connect 11 0 13 0;
+#X connect 12 0 26 0;
+#X connect 13 0 14 0;
+#X connect 13 1 15 0;
+#X connect 14 0 15 0;
+#X connect 15 0 16 0;
+#X connect 15 1 17 1;
+#X connect 16 0 17 0;
+#X connect 17 0 0 0;
+#X connect 18 0 12 1;
+#X connect 19 1 12 0;
+#X connect 20 0 10 0;
+#X connect 26 0 3 1;
+#X connect 26 0 2 1;
+#X connect 27 0 6 0;
+#X connect 27 0 7 0;
+#X connect 27 1 6 1;
+#X connect 27 1 7 1;
diff --git a/abs/pulsor~.pd b/abs/pulsor~.pd
new file mode 100644
index 0000000..7069986
--- /dev/null
+++ b/abs/pulsor~.pd
@@ -0,0 +1,39 @@
+#N canvas 641 469 535 446 10;
+#X obj 96 90 fblock \$1;
+#X obj 203 102 bang~;
+#X msg 203 126 0;
+#X obj 96 179 phasor~;
+#X obj 159 179 phasor~;
+#X obj 133 216 -~;
+#X msg 154 64 1;
+#X obj 154 37 loadbang;
+#X obj 203 151 +;
+#X obj 266 78 inlet;
+#X text 251 57 duty cycle;
+#X text 46 11 pulsor~: rectangular window w. duty cycle;
+#X obj 133 243 +~;
+#X obj 266 126 fmod 1;
+#X obj 132 273 onecomp~;
+#X obj 133 301 outlet~;
+#X text 115 332 pulse outlet;
+#X obj 266 104 * -1;
+#X obj 232 301 outlet~;
+#X text 228 331 complement;
+#X connect 0 0 4 0;
+#X connect 0 0 3 0;
+#X connect 1 0 2 0;
+#X connect 2 0 8 0;
+#X connect 2 0 3 1;
+#X connect 3 0 5 0;
+#X connect 4 0 5 1;
+#X connect 5 0 12 0;
+#X connect 6 0 0 1;
+#X connect 7 0 6 0;
+#X connect 8 0 4 1;
+#X connect 9 0 17 0;
+#X connect 12 0 14 0;
+#X connect 12 0 18 0;
+#X connect 13 0 8 1;
+#X connect 13 0 12 1;
+#X connect 14 0 15 0;
+#X connect 17 0 13 0;
diff --git a/abs/sin~.pd b/abs/sin~.pd
new file mode 100644
index 0000000..c9b09ba
--- /dev/null
+++ b/abs/sin~.pd
@@ -0,0 +1,8 @@
+#N canvas 843 64 157 187 10;
+#X obj 29 28 inlet~;
+#X obj 29 59 -~ 0.25;
+#X obj 29 90 cos~;
+#X obj 29 117 outlet~;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
diff --git a/abs/step_16.pd b/abs/step_16.pd
new file mode 100644
index 0000000..317bf6a
--- /dev/null
+++ b/abs/step_16.pd
@@ -0,0 +1,53 @@
+#N canvas 347 311 817 158 10;
+#X obj 42 62 inlet;
+#X obj 84 62 inlet;
+#X obj 125 62 inlet;
+#X obj 166 62 inlet;
+#X obj 209 62 inlet;
+#X obj 251 62 inlet;
+#X obj 292 62 inlet;
+#X obj 333 62 inlet;
+#X obj 374 62 inlet;
+#X obj 416 62 inlet;
+#X obj 457 62 inlet;
+#X obj 498 62 inlet;
+#X obj 541 62 inlet;
+#X obj 583 62 inlet;
+#X obj 624 62 inlet;
+#X obj 665 62 inlet;
+#X text 51 14 16 part step sequencer array input;
+#X obj 185 41 + 4;
+#X obj 42 110 step_4 \$1;
+#X obj 209 110 step_4 \$1;
+#X obj 374 41 + 4;
+#X obj 374 110 step_4 \$1;
+#X obj 541 110 step_4 \$1;
+#X obj 540 40 + 4;
+#X obj 737 40 inlet;
+#X obj 100 40 f 0;
+#X obj 341 15 loadbang;
+#X connect 0 0 18 0;
+#X connect 1 0 18 1;
+#X connect 2 0 18 2;
+#X connect 3 0 18 3;
+#X connect 4 0 19 0;
+#X connect 5 0 19 1;
+#X connect 6 0 19 2;
+#X connect 7 0 19 3;
+#X connect 8 0 21 0;
+#X connect 9 0 21 1;
+#X connect 10 0 21 2;
+#X connect 11 0 21 3;
+#X connect 12 0 22 0;
+#X connect 13 0 22 1;
+#X connect 14 0 22 2;
+#X connect 15 0 22 3;
+#X connect 17 0 19 4;
+#X connect 17 0 20 0;
+#X connect 20 0 21 4;
+#X connect 20 0 23 0;
+#X connect 23 0 22 4;
+#X connect 24 0 25 0;
+#X connect 25 0 17 0;
+#X connect 25 0 18 4;
+#X connect 26 0 25 0;
diff --git a/abs/step_16r.pd b/abs/step_16r.pd
new file mode 100644
index 0000000..aaa16a0
--- /dev/null
+++ b/abs/step_16r.pd
@@ -0,0 +1,50 @@
+#N canvas 602 279 442 438 10;
+#X obj 135 64 inlet;
+#X text 43 21 4 part building block (read) for a step sequencer array
+input;
+#X obj 135 148 + 4;
+#X obj 135 173 step_4r \$1;
+#X obj 200 203 outlet;
+#X obj 178 229 outlet;
+#X obj 156 252 outlet;
+#X obj 135 278 outlet;
+#X obj 21 176 step_4r \$1;
+#X obj 86 206 outlet;
+#X obj 64 232 outlet;
+#X obj 42 255 outlet;
+#X obj 21 281 outlet;
+#X obj 363 166 step_4r \$1;
+#X obj 428 196 outlet;
+#X obj 406 222 outlet;
+#X obj 384 245 outlet;
+#X obj 363 271 outlet;
+#X obj 249 169 step_4r \$1;
+#X obj 314 199 outlet;
+#X obj 292 225 outlet;
+#X obj 270 248 outlet;
+#X obj 249 274 outlet;
+#X obj 249 144 + 8;
+#X obj 363 141 + 12;
+#X connect 0 0 2 0;
+#X connect 0 0 8 0;
+#X connect 0 0 23 0;
+#X connect 0 0 24 0;
+#X connect 2 0 3 0;
+#X connect 3 0 7 0;
+#X connect 3 1 6 0;
+#X connect 3 2 5 0;
+#X connect 3 3 4 0;
+#X connect 8 0 12 0;
+#X connect 8 1 11 0;
+#X connect 8 2 10 0;
+#X connect 8 3 9 0;
+#X connect 13 0 17 0;
+#X connect 13 1 16 0;
+#X connect 13 2 15 0;
+#X connect 13 3 14 0;
+#X connect 18 0 22 0;
+#X connect 18 1 21 0;
+#X connect 18 2 20 0;
+#X connect 18 3 19 0;
+#X connect 23 0 18 0;
+#X connect 24 0 13 0;
diff --git a/abs/step_4.pd b/abs/step_4.pd
new file mode 100644
index 0000000..226173f
--- /dev/null
+++ b/abs/step_4.pd
@@ -0,0 +1,36 @@
+#N canvas 241 612 442 251 10;
+#X obj 59 51 inlet;
+#X obj 90 186 tabwrite \$1;
+#X obj 59 79 t f b;
+#X msg 89 104 0;
+#X obj 102 51 inlet;
+#X obj 102 79 t f b;
+#X obj 145 51 inlet;
+#X obj 145 79 t f b;
+#X obj 188 51 inlet;
+#X obj 188 79 t f b;
+#X msg 132 104 1;
+#X msg 175 104 2;
+#X msg 218 104 3;
+#X text 43 21 4 part building block for a step sequencer array input
+;
+#X obj 293 50 inlet;
+#X obj 162 157 +;
+#X connect 0 0 2 0;
+#X connect 2 0 1 0;
+#X connect 2 1 3 0;
+#X connect 3 0 15 0;
+#X connect 4 0 5 0;
+#X connect 5 0 1 0;
+#X connect 5 1 10 0;
+#X connect 6 0 7 0;
+#X connect 7 0 1 0;
+#X connect 7 1 11 0;
+#X connect 8 0 9 0;
+#X connect 9 0 1 0;
+#X connect 9 1 12 0;
+#X connect 10 0 15 0;
+#X connect 11 0 15 0;
+#X connect 12 0 15 0;
+#X connect 14 0 15 1;
+#X connect 15 0 1 1;
diff --git a/abs/step_4r.pd b/abs/step_4r.pd
new file mode 100644
index 0000000..6b5849b
--- /dev/null
+++ b/abs/step_4r.pd
@@ -0,0 +1,26 @@
+#N canvas 241 612 442 251 10;
+#X obj 59 173 tabread \$1;
+#X obj 59 199 outlet;
+#X obj 135 64 inlet;
+#X obj 135 173 tabread \$1;
+#X obj 135 199 outlet;
+#X obj 210 173 tabread \$1;
+#X obj 210 199 outlet;
+#X obj 288 173 tabread \$1;
+#X obj 288 199 outlet;
+#X obj 135 148 + 1;
+#X obj 210 148 + 2;
+#X obj 288 148 + 3;
+#X text 43 21 4 part building block (read) for a step sequencer array
+input;
+#X connect 0 0 1 0;
+#X connect 2 0 0 0;
+#X connect 2 0 9 0;
+#X connect 2 0 10 0;
+#X connect 2 0 11 0;
+#X connect 3 0 4 0;
+#X connect 5 0 6 0;
+#X connect 7 0 8 0;
+#X connect 9 0 3 0;
+#X connect 10 0 5 0;
+#X connect 11 0 7 0;
diff --git a/abs/ti_hihat.pd b/abs/ti_hihat.pd
new file mode 100644
index 0000000..a75619d
--- /dev/null
+++ b/abs/ti_hihat.pd
@@ -0,0 +1,195 @@
+#N canvas 512 35 209 79 10;
+#X obj 160 133 inlet;
+#X text 9 2 ti_hihat;
+#X obj 211 103 inlet;
+#X obj 151 214 ead~;
+#X obj 114 214 *~;
+#N canvas 413 387 659 494 hihat 0;
+#X obj 27 324 square~;
+#X obj 87 324 square~;
+#X obj 60 360 *~;
+#X obj 156 326 square~;
+#X obj 216 326 square~;
+#X obj 189 362 *~;
+#X obj 289 329 square~;
+#X obj 349 329 square~;
+#X obj 322 365 *~;
+#X obj 418 331 square~;
+#X obj 478 331 square~;
+#X obj 451 367 *~;
+#X obj 320 396 +~;
+#X obj 165 408 +~;
+#X obj 217 444 outlet~;
+#X obj 212 181 f;
+#X obj 251 183 + 1;
+#X obj 211 155 until;
+#X msg 210 131 8;
+#X msg 242 130 0;
+#X obj 210 108 t b b;
+#X obj 210 79 t b f;
+#X obj 277 212 random 20000;
+#X msg 309 128 seed \$1;
+#X obj 211 211 t f b;
+#X obj 212 256 pack 0 0;
+#X obj 212 278 route 0 1 2 3 4 5 6 7;
+#X obj 210 34 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10
+-262144 -1 -1 600.246 256;
+#X floatatom 28 304 5 0 0 0 - - -;
+#X floatatom 93 305 5 0 0 0 - - -;
+#X floatatom 161 305 5 0 0 0 - - -;
+#X floatatom 219 307 5 0 0 0 - - -;
+#X floatatom 292 307 5 0 0 0 - - -;
+#X floatatom 353 305 5 0 0 0 - - -;
+#X floatatom 421 307 5 0 0 0 - - -;
+#X floatatom 481 311 5 0 0 0 - - -;
+#X obj 279 237 + 0;
+#X text 193 16 magic number;
+#X obj 355 37 nbx 5 14 20 20000 1 1 empty empty empty 0 -6 0 10 -262144
+-1 -1 10752.2 256;
+#X text 344 18 freq range;
+#X obj 464 37 nbx 5 14 20 20000 1 1 empty empty empty 0 -6 0 10 -262144
+-1 -1 95.6572 256;
+#X text 433 16 bottom freq;
+#X obj 143 31 inlet;
+#X obj 307 38 inlet;
+#X obj 424 36 inlet;
+#X obj 143 62 * 1000;
+#X obj 210 55 f 0;
+#X obj 456 79 t b f;
+#X obj 354 59 t b f;
+#X connect 0 0 2 0;
+#X connect 1 0 2 1;
+#X connect 2 0 13 0;
+#X connect 3 0 5 0;
+#X connect 4 0 5 1;
+#X connect 5 0 13 1;
+#X connect 6 0 8 0;
+#X connect 7 0 8 1;
+#X connect 8 0 12 0;
+#X connect 9 0 11 0;
+#X connect 10 0 11 1;
+#X connect 11 0 12 1;
+#X connect 12 0 14 0;
+#X connect 13 0 14 0;
+#X connect 15 0 16 0;
+#X connect 15 0 24 0;
+#X connect 16 0 15 1;
+#X connect 17 0 15 0;
+#X connect 18 0 17 0;
+#X connect 19 0 15 1;
+#X connect 20 0 18 0;
+#X connect 20 1 19 0;
+#X connect 21 0 20 0;
+#X connect 21 1 23 0;
+#X connect 22 0 36 0;
+#X connect 23 0 22 0;
+#X connect 24 0 25 0;
+#X connect 24 1 22 0;
+#X connect 25 0 26 0;
+#X connect 26 0 28 0;
+#X connect 26 1 29 0;
+#X connect 26 2 30 0;
+#X connect 26 3 31 0;
+#X connect 26 4 32 0;
+#X connect 26 5 33 0;
+#X connect 26 6 34 0;
+#X connect 26 7 35 0;
+#X connect 27 0 46 0;
+#X connect 28 0 0 0;
+#X connect 29 0 1 0;
+#X connect 30 0 3 0;
+#X connect 31 0 4 0;
+#X connect 32 0 6 0;
+#X connect 33 0 7 0;
+#X connect 34 0 9 0;
+#X connect 35 0 10 0;
+#X connect 36 0 25 1;
+#X connect 38 0 48 0;
+#X connect 40 0 36 1;
+#X connect 40 0 47 0;
+#X connect 42 0 45 0;
+#X connect 43 0 38 0;
+#X connect 44 0 40 0;
+#X connect 45 0 27 0;
+#X connect 46 0 21 0;
+#X connect 47 0 46 0;
+#X connect 47 1 36 1;
+#X connect 48 0 46 0;
+#X connect 48 1 22 1;
+#X restore 114 184 pd hihat;
+#X obj 112 323 vol~;
+#X obj 140 53 nbx 3 14 -1e+37 1e+37 0 1 empty empty VOL -20 7 0 10
+-262144 -1 -1 111.47 256;
+#X obj 140 30 nbx 5 14 20 20000 1 1 empty empty HP -20 7 0 10 -24198
+-1 -1 6796.42 256;
+#X obj 113 283 bhip~ 1;
+#X obj 74 30 nbx 3 14 -1e+37 1e+37 0 1 empty empty A' -14 7 0 10 -225271
+-1 -1 -17 256;
+#X obj 43 106 +;
+#X obj 12 29 nbx 3 14 -1e+37 1e+37 0 1 empty empty A -10 7 0 10 -260818
+-1 -1 16 256;
+#X obj 44 172 +;
+#X obj 13 50 nbx 3 14 -1e+37 1e+37 0 1 empty empty D -10 7 0 10 -260818
+-1 -1 156 256;
+#X obj 43 83 *;
+#X obj 44 134 *;
+#X obj 101 347 outlet~;
+#X obj 80 4 tgl 15 1 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1;
+#X obj 178 172 spigot;
+#X obj 74 50 nbx 3 14 -1e+37 1e+37 0 1 empty empty D' -14 7 0 10 -225271
+-1 -1 -58 256;
+#X obj 174 152 t b b;
+#X obj 101 106 f;
+#X obj 315 10 inlet;
+#X obj 315 57 unpack 0 0 0 0 0 0;
+#X obj 315 123 symbol set;
+#X obj 315 146 pack s 0 0 0 0 0 0;
+#X obj 314 202 outlet;
+#X obj 315 28 route bang;
+#X msg 315 96 bang;
+#X msg 316 172 \$1 \$2 \$3 \$4 \$5 \$6 \$7;
+#X obj 176 4 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X connect 0 0 21 0;
+#X connect 2 0 22 0;
+#X connect 3 0 4 1;
+#X connect 4 0 9 0;
+#X connect 5 0 4 0;
+#X connect 6 0 17 0;
+#X connect 7 0 6 1;
+#X connect 7 0 26 6;
+#X connect 8 0 9 1;
+#X connect 8 0 26 5;
+#X connect 9 0 6 0;
+#X connect 10 0 15 1;
+#X connect 10 0 26 3;
+#X connect 11 0 3 1;
+#X connect 12 0 11 1;
+#X connect 12 0 26 1;
+#X connect 13 0 3 2;
+#X connect 14 0 13 1;
+#X connect 14 0 26 2;
+#X connect 15 0 11 0;
+#X connect 16 0 13 0;
+#X connect 18 0 19 1;
+#X connect 19 0 3 0;
+#X connect 20 0 16 1;
+#X connect 20 0 26 4;
+#X connect 21 0 19 0;
+#X connect 22 0 16 0;
+#X connect 22 0 15 0;
+#X connect 23 0 28 0;
+#X connect 24 0 12 0;
+#X connect 24 1 14 0;
+#X connect 24 2 10 0;
+#X connect 24 3 20 0;
+#X connect 24 4 8 0;
+#X connect 24 5 7 0;
+#X connect 25 0 26 0;
+#X connect 26 0 30 0;
+#X connect 28 0 29 0;
+#X connect 28 1 24 0;
+#X connect 29 0 25 0;
+#X connect 30 0 27 0;
+#X connect 31 0 29 0;
+#X coords 0 0 1 1 200 50 1;
diff --git a/abs/ti_snare.pd b/abs/ti_snare.pd
new file mode 100644
index 0000000..467a9b2
--- /dev/null
+++ b/abs/ti_snare.pd
@@ -0,0 +1,74 @@
+#N canvas 448 117 288 79 10;
+#X obj 143 84 inlet;
+#X obj 243 84 inlet;
+#X obj 112 323 vol~;
+#X obj 222 52 nbx 3 14 -1e+37 1e+37 0 1 empty empty VOL -20 7 0 10
+-262144 -1 -1 99.47 256;
+#X obj 140 30 nbx 5 14 20 20000 1 1 empty empty T1 -20 7 0 10 -24198
+-1 -1 552.632 256;
+#X obj 74 30 nbx 3 14 -1e+37 1e+37 0 1 empty empty A' -14 7 0 10 -225271
+-1 -1 0 256;
+#X obj 43 106 +;
+#X obj 12 29 nbx 3 14 -1e+37 1e+37 0 1 empty empty A -10 7 0 10 -260818
+-1 -1 -1 256;
+#X obj 44 172 +;
+#X obj 13 50 nbx 3 14 -1e+37 1e+37 0 1 empty empty D -10 7 0 10 -260818
+-1 -1 113 256;
+#X obj 43 83 *;
+#X obj 44 134 *;
+#X obj 101 347 outlet~;
+#X obj 80 4 tgl 15 1 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1;
+#X obj 178 153 spigot;
+#X obj 74 50 nbx 3 14 -1e+37 1e+37 0 1 empty empty D' -14 7 0 10 -225271
+-1 -1 45 256;
+#X obj 140 51 nbx 5 14 20 20000 1 1 empty empty T2 -20 7 0 10 -24198
+-1 -1 151.334 256;
+#X obj 222 30 nbx 5 14 20 20000 1 1 empty empty T3 -20 7 0 10 -24198
+-1 -1 9652.14 256;
+#X text 9 2 ti_snare;
+#X obj 186 209 ead~;
+#X obj 236 247 osc~;
+#X obj 122 172 osc~;
+#X obj 109 286 *~;
+#X obj 242 178 noise~;
+#X obj 240 210 lop~;
+#X obj 151 209 *~;
+#X obj 82 250 *~;
+#X obj 103 207 *~;
+#X obj 154 109 t b b;
+#X obj 116 110 f 0;
+#X connect 0 0 28 0;
+#X connect 1 0 29 0;
+#X connect 2 0 12 0;
+#X connect 3 0 2 1;
+#X connect 4 0 21 0;
+#X connect 5 0 10 1;
+#X connect 6 0 19 1;
+#X connect 7 0 6 1;
+#X connect 8 0 19 2;
+#X connect 9 0 8 1;
+#X connect 10 0 6 0;
+#X connect 11 0 8 0;
+#X connect 13 0 14 1;
+#X connect 14 0 19 0;
+#X connect 15 0 11 1;
+#X connect 16 0 20 0;
+#X connect 17 0 24 1;
+#X connect 19 0 22 1;
+#X connect 19 0 25 1;
+#X connect 19 0 26 1;
+#X connect 20 0 22 0;
+#X connect 21 0 25 0;
+#X connect 21 0 27 0;
+#X connect 22 0 2 0;
+#X connect 23 0 24 0;
+#X connect 24 0 22 0;
+#X connect 24 0 27 1;
+#X connect 25 0 22 0;
+#X connect 26 0 22 1;
+#X connect 27 0 26 0;
+#X connect 28 0 14 0;
+#X connect 28 1 29 0;
+#X connect 29 0 10 0;
+#X connect 29 0 11 0;
+#X coords 0 0 1 1 270 50 1;
diff --git a/abs/ucmod~.pd b/abs/ucmod~.pd
new file mode 100644
index 0000000..9257300
--- /dev/null
+++ b/abs/ucmod~.pd
@@ -0,0 +1,27 @@
+#N canvas 0 0 450 300 10;
+#X obj 74 72 inlet~;
+#X obj 121 72 inlet~;
+#X obj 150 147 *~ -1;
+#X obj 87 114 *~;
+#X obj 124 114 *~;
+#X obj 179 71 inlet~;
+#X obj 86 146 +~ 1;
+#X obj 88 236 cmul~;
+#X obj 135 193 cinv~;
+#X obj 87 266 outlet~;
+#X obj 144 267 outlet~;
+#X text 84 18 unit circle modulator. (1+r conj(z)/(1+rz);
+#X connect 0 0 3 0;
+#X connect 1 0 4 0;
+#X connect 2 0 8 1;
+#X connect 3 0 6 0;
+#X connect 4 0 7 1;
+#X connect 4 0 2 0;
+#X connect 5 0 4 1;
+#X connect 5 0 3 1;
+#X connect 6 0 7 0;
+#X connect 6 0 8 0;
+#X connect 7 0 9 0;
+#X connect 7 1 10 0;
+#X connect 8 0 7 2;
+#X connect 8 1 7 3;
diff --git a/abs/ucnorm~.pd b/abs/ucnorm~.pd
new file mode 100644
index 0000000..6a524f7
--- /dev/null
+++ b/abs/ucnorm~.pd
@@ -0,0 +1,27 @@
+#N canvas 0 0 450 300 10;
+#X text 59 21 normalize complex number to unit magnitude;
+#X obj 117 70 inlet~;
+#X obj 131 99 *~;
+#X obj 187 70 inlet~;
+#X obj 203 99 *~;
+#X obj 226 157 +~ 1;
+#X obj 226 185 /~;
+#X obj 226 213 sqrt~;
+#X obj 116 242 *~;
+#X obj 116 264 outlet~;
+#X obj 186 242 *~;
+#X obj 186 264 outlet~;
+#X connect 1 0 2 0;
+#X connect 1 0 2 1;
+#X connect 1 0 8 0;
+#X connect 2 0 6 1;
+#X connect 3 0 4 0;
+#X connect 3 0 4 1;
+#X connect 3 0 10 0;
+#X connect 4 0 6 1;
+#X connect 5 0 6 0;
+#X connect 6 0 7 0;
+#X connect 7 0 10 1;
+#X connect 7 0 8 1;
+#X connect 8 0 9 0;
+#X connect 10 0 11 0;
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..a5a1465
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,42 @@
+AC_INIT(system/setup.c)
+AC_PROG_CC
+AC_HEADER_STDC
+
+
+echo -n "checking architecture... "
+ARCH=`uname -s`
+if test $ARCH == Linux;
+then
+ PD_INCLUDE_DIR=$prefix/pd/src
+ LIBNAME=creb.pd_linux
+ LIBFLAGS="-export_dynamic -shared"
+ echo "Linux"
+
+elif test $ARCH == Darwin;
+then
+ PD_INCLUDE_DIR=$prefix/pd/src
+ LIBNAME=creb.pd_darwin
+ LIBFLAGS="-bundle -bundle_loader $prefix/pd/bin/pd"
+ echo "Darwin"
+
+else
+ echo WARNING: Architecture `uname -s` not supported.
+ exit;
+fi
+
+
+CPPFLAGS="$CPPFLAGS -I$prefix/pd/src"
+
+AC_CHECK_HEADER(m_pd.h,,
+ echo "WARNING: m_pd.h not found in the standard include path."
+ echo " If PD_DIR in Makefile.config.in is set correctly you can ignore this warning." )
+
+AC_CHECK_LIB(m,sin,,
+ echo "Math library not found. sorry..." || exit)
+
+
+AC_SUBST(PD_INCLUDE_DIR)
+AC_SUBST(LIBNAME)
+AC_SUBST(LIBFLAGS)
+AC_CONFIG_FILES(Makefile.config)
+AC_OUTPUT
diff --git a/doc/bitsplit~.pd b/doc/bitsplit~.pd
new file mode 100644
index 0000000..fffce2e
--- /dev/null
+++ b/doc/bitsplit~.pd
@@ -0,0 +1,45 @@
+#N canvas 180 482 616 243 10;
+#X obj 111 51 osc~;
+#X floatatom 111 29 5 0 0 0 - - -;
+#X obj 112 93 bitsplit~ 4;
+#X obj 81 177 dac~;
+#X obj 81 153 vol~;
+#X floatatom 110 136 5 0 0 0 - - -;
+#X obj 183 178 dac~;
+#X obj 183 154 vol~;
+#X floatatom 212 137 5 0 0 0 - - -;
+#X floatatom 178 50 5 0 0 0 - - -;
+#X obj 112 72 *~ 1;
+#X text 267 25 split a signal into a parallel binary word.;
+#X text 267 43 MSB = left \, LSB = right.;
+#X obj 339 127 *~;
+#X obj 367 127 / 2;
+#X obj 402 127 *~;
+#X obj 430 127 / 2;
+#N canvas 0 0 450 300 s 0;
+#X obj 152 123 *~;
+#X obj 152 89 inlet~;
+#X obj 206 90 inlet;
+#X obj 206 121 / 2;
+#X obj 152 150 outlet~;
+#X obj 206 151 outlet;
+#X connect 0 0 4 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 1;
+#X connect 2 0 3 0;
+#X connect 3 0 5 0;
+#X restore 383 178 pd s;
+#X connect 0 0 10 0;
+#X connect 1 0 0 0;
+#X connect 2 0 4 0;
+#X connect 2 3 7 0;
+#X connect 4 0 3 0;
+#X connect 4 0 3 1;
+#X connect 5 0 4 1;
+#X connect 7 0 6 0;
+#X connect 7 0 6 1;
+#X connect 8 0 7 1;
+#X connect 9 0 10 1;
+#X connect 10 0 2 0;
+#X connect 14 0 15 1;
+#X connect 14 0 16 0;
diff --git a/doc/blocknorm~.pd b/doc/blocknorm~.pd
new file mode 100644
index 0000000..3f25fc3
--- /dev/null
+++ b/doc/blocknorm~.pd
@@ -0,0 +1,77 @@
+#N canvas 623 54 632 460 10;
+#X text 62 14 blocknorm~: normalize a dsp block to RMS = 1;
+#X text 144 33 creation argument = nb channels;
+#X obj 96 349 lop~;
+#X obj 95 410 tabsend~ state;
+#X obj 95 384 blocknorm~ 1;
+#X obj 95 320 hip~;
+#X obj 134 298 hsl 128 15 100 10000 1 1 empty empty empty -2 -6 0 8
+-262144 -1 -1 3800 1;
+#X obj 93 131 tabreceive~ state;
+#X obj 138 222 fblock 64;
+#X obj 352 388 pdynwav~;
+#X obj 351 429 vol~;
+#X obj 350 458 dac~;
+#X floatatom 389 408 5 0 0 0 - - -;
+#X floatatom 406 365 5 0 0 0 - - -;
+#X obj 13 144 ead~ 0 20;
+#X obj 30 168 noise~;
+#X obj 14 191 *~;
+#X obj 13 121 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 237 134 1;
+#X floatatom 237 157 5 0 0 0 - - -;
+#X floatatom 138 202 5 0 0 0 - - -;
+#X text 11 64 example: a waveform folding oscillator: power is shifted
+up or down in frequency by contraction/dilatation \, and filtered \,
+but normalized to preserve total state energy.;
+#X obj 466 281 table state 64;
+#X obj 94 270 dynwav~;
+#X obj 138 245 phasor~;
+#X obj 310 181 bang~;
+#X msg 268 133 2;
+#X obj 310 205 f;
+#X floatatom 358 200 5 0 0 0 - - -;
+#X msg 357 179 0;
+#X msg 387 179 0.03;
+#X msg 425 179 0.17;
+#X obj 310 241 spigot;
+#X obj 348 223 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X text 403 201 phase offset;
+#X text 182 201 mod freq;
+#X text 366 222 phase sync;
+#X obj 134 326 hsl 128 15 100 10000 1 1 empty empty empty -2 -6 0 8
+-262144 -1 -1 8100 1;
+#X text 282 157 relative formant shift;
+#X connect 2 0 4 0;
+#X connect 2 0 9 0;
+#X connect 4 0 3 0;
+#X connect 5 0 2 0;
+#X connect 6 0 5 1;
+#X connect 7 0 23 0;
+#X connect 8 0 24 0;
+#X connect 9 0 10 0;
+#X connect 10 0 11 0;
+#X connect 10 0 11 1;
+#X connect 12 0 10 1;
+#X connect 13 0 9 1;
+#X connect 14 0 16 0;
+#X connect 15 0 16 1;
+#X connect 16 0 5 0;
+#X connect 17 0 14 0;
+#X connect 18 0 19 0;
+#X connect 19 0 8 1;
+#X connect 20 0 8 0;
+#X connect 23 0 5 0;
+#X connect 24 0 23 1;
+#X connect 25 0 27 0;
+#X connect 26 0 19 0;
+#X connect 27 0 32 0;
+#X connect 28 0 27 1;
+#X connect 29 0 28 0;
+#X connect 30 0 28 0;
+#X connect 31 0 28 0;
+#X connect 32 0 24 1;
+#X connect 33 0 32 1;
+#X connect 37 0 2 1;
diff --git a/doc/blosc~.pd b/doc/blosc~.pd
new file mode 100644
index 0000000..ce70940
--- /dev/null
+++ b/doc/blosc~.pd
@@ -0,0 +1,110 @@
+#N canvas 456 143 763 746 10;
+#X obj 80 243 dac~;
+#X obj 80 219 vol~;
+#X floatatom 103 195 5 0 0;
+#X obj 80 158 blosc~ pulse;
+#X floatatom 80 128 5 0 0;
+#X text 59 106 one-sided impulse;
+#X obj 255 243 dac~;
+#X obj 255 219 vol~;
+#X floatatom 278 195 5 0 0;
+#X floatatom 255 128 5 0 0;
+#X text 234 106 two-sided impulse;
+#X obj 255 158 blosc~ pulse2;
+#X obj 433 241 dac~;
+#X obj 433 217 vol~;
+#X floatatom 456 193 5 0 0;
+#X floatatom 433 126 5 0 0;
+#X text 442 105 sawtooth;
+#X obj 596 245 dac~;
+#X obj 596 221 vol~;
+#X floatatom 619 197 5 0 0;
+#X floatatom 596 130 5 0 0;
+#X text 571 106 hard synced sawtooth;
+#X text 53 18 blosc~ - some bandlimited oscillators based on minimal
+phase impulse and step functions. (inspired by Eli Brandt's paper "Hard
+Sync Without Aliasing".);
+#X obj 433 156 blosc~ saw;
+#X obj 596 160 blosc~ syncsaw;
+#X floatatom 642 130 5 0 0;
+#X obj 416 645 dac~;
+#X obj 416 610 vol~;
+#X floatatom 439 586 5 0 0;
+#X text 255 304 bandlimited comparator;
+#X obj 416 549 blosc~ comparator;
+#X obj 416 435 phasor~;
+#X obj 416 519 -~;
+#X floatatom 416 380 5 0 0;
+#X floatatom 416 355 5 0 0;
+#X obj 80 391 phasor~;
+#X floatatom 80 367 5 0 0;
+#X obj 80 448 blosc~ comparator;
+#X obj 80 538 dac~;
+#X obj 80 503 vol~;
+#X floatatom 103 479 5 0 0;
+#X obj 80 420 -~ 0.5;
+#X text 75 341 (square - pulse wave);
+#X floatatom 150 402 5 0 0;
+#X obj 153 384 hsl 50 15 0.01 0.99 0 0 empty empty empty -2 -6 0 8
+-262144 -1 -1 2050 1;
+#X msg 150 363 0.5;
+#X text 411 332 (pwm);
+#X obj 511 416 osc~;
+#X floatatom 511 383 5 0 0;
+#X obj 511 446 *~;
+#X floatatom 561 428 5 0 0;
+#X obj 564 406 hsl 50 15 0 0.99 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 2300 1;
+#X text 626 406 depth;
+#X obj 514 362 hsl 50 15 0.1 10 1 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 4300 1;
+#X text 578 362 mod freq;
+#X obj 416 460 *~ 2;
+#X obj 416 485 -~ 1;
+#X connect 1 0 0 0;
+#X connect 1 0 0 1;
+#X connect 2 0 1 1;
+#X connect 3 0 1 0;
+#X connect 4 0 3 0;
+#X connect 7 0 6 0;
+#X connect 7 0 6 1;
+#X connect 8 0 7 1;
+#X connect 9 0 11 0;
+#X connect 11 0 7 0;
+#X connect 13 0 12 0;
+#X connect 13 0 12 1;
+#X connect 14 0 13 1;
+#X connect 15 0 23 0;
+#X connect 18 0 17 0;
+#X connect 18 0 17 1;
+#X connect 19 0 18 1;
+#X connect 20 0 24 0;
+#X connect 23 0 13 0;
+#X connect 24 0 18 0;
+#X connect 25 0 24 1;
+#X connect 27 0 26 0;
+#X connect 27 0 26 1;
+#X connect 28 0 27 1;
+#X connect 30 0 27 0;
+#X connect 31 0 55 0;
+#X connect 32 0 30 0;
+#X connect 33 0 31 0;
+#X connect 34 0 33 0;
+#X connect 35 0 41 0;
+#X connect 36 0 35 0;
+#X connect 37 0 39 0;
+#X connect 39 0 38 0;
+#X connect 39 0 38 1;
+#X connect 40 0 39 1;
+#X connect 41 0 37 0;
+#X connect 43 0 41 1;
+#X connect 44 0 43 0;
+#X connect 45 0 44 0;
+#X connect 47 0 49 0;
+#X connect 48 0 47 0;
+#X connect 49 0 32 1;
+#X connect 50 0 49 1;
+#X connect 51 0 50 0;
+#X connect 53 0 48 0;
+#X connect 55 0 56 0;
+#X connect 56 0 32 0;
diff --git a/doc/bmatrix~.pd b/doc/bmatrix~.pd
new file mode 100644
index 0000000..5cb34a5
--- /dev/null
+++ b/doc/bmatrix~.pd
@@ -0,0 +1,10 @@
+#N canvas 523 376 560 300 10;
+#X msg 69 127 load matrix.bin;
+#X text 27 39 added for completeness. mainly intended for spectral
+transfos;
+#X text 26 73 the file format is binary floating point \, column encoded.
+;
+#X obj 46 174 bmatrix~;
+#X text 29 23 bmatrix multiplies a signal block with an arbitrary matrix
+;
+#X connect 0 0 3 0;
diff --git a/doc/bwin~.pd b/doc/bwin~.pd
index 7f630d8..42b4fd6 100644
--- a/doc/bwin~.pd
+++ b/doc/bwin~.pd
@@ -1,5 +1,5 @@
-#N canvas 62 558 450 300 10;
-#N canvas 409 279 692 500 windowing 1;
+#N canvas 95 391 450 300 10;
+#N canvas 274 117 692 500 windowing 1;
#X obj 62 441 outlet~;
#X obj 62 65 inlet~;
#X obj 62 142 bfft~;
@@ -25,8 +25,8 @@ bwin~ bfft~ bifft~ and dist~;
#X msg 344 207 type bfft_db/octave \$1;
#X floatatom 517 172 5 0 0;
#X msg 345 277 type bfft_db/octave \$1;
-#X obj 545 427 block~ 16384 2;
#X floatatom 519 244 5 0 0;
+#X obj 545 427 block~ 1024 2;
#X connect 1 0 19 0;
#X connect 2 0 5 0;
#X connect 3 0 18 0;
@@ -40,12 +40,12 @@ bwin~ bfft~ bifft~ and dist~;
#X connect 20 0 16 0;
#X connect 21 0 20 0;
#X connect 22 0 17 0;
-#X connect 24 0 22 0;
+#X connect 23 0 22 0;
#X restore 53 88 pd windowing;
#X obj 41 219 dac~;
#X obj 53 150 vol~;
#X floatatom 76 124 5 0 0;
-#X obj 53 41 adc~ 7;
+#X obj 53 41 adc~ 1;
#X connect 0 0 2 0;
#X connect 2 0 1 0;
#X connect 2 0 1 1;
diff --git a/doc/clog~.pd b/doc/clog~.pd
new file mode 100644
index 0000000..490c406
--- /dev/null
+++ b/doc/clog~.pd
@@ -0,0 +1,8 @@
+#N canvas 642 410 542 207 10;
+#X obj 85 82 clog~;
+#X obj 145 82 cexp~;
+#X text 235 81 complex log and exp.;
+#X text 237 105 see also;
+#X obj 309 104 cep~;
+#X text 351 103 and;
+#X obj 384 105 icep~;
diff --git a/doc/eadsr~.pd b/doc/eadsr~.pd
index 220ea54..f72bdaf 100644
--- a/doc/eadsr~.pd
+++ b/doc/eadsr~.pd
@@ -1,41 +1,57 @@
#N canvas 478 386 580 306 10;
#X obj 89 227 *~;
#X obj 105 40 metro;
-#X obj 105 12 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1
--1;
#X obj 26 203 osc~;
-#X floatatom 26 171 5 0 0;
-#X floatatom 135 12 5 0 0;
-#X floatatom 209 117 5 0 0;
-#X floatatom 208 139 5 0 0;
-#X obj 77 265 dac~;
+#X floatatom 26 171 5 0 0 0 - - -;
+#X floatatom 135 12 5 0 0 0 - - -;
+#X floatatom 209 117 5 0 0 0 - - -;
+#X floatatom 208 139 5 0 0 0 - - -;
+#X obj 81 277 dac~;
#X msg 58 12 stop;
#X msg 26 124 start;
#X msg 71 123 stop;
#X obj 105 77 del;
-#X floatatom 159 50 5 0 0;
+#X floatatom 159 50 5 0 0 0 - - -;
#X obj 105 197 eadsr~ 0 0;
#X text 191 81 exponential attack/decay/sustain/release envelope;
#X text 265 125 60db attack and decay time;
-#X text 265 182 60db attack and decay time;
-#X floatatom 209 160 5 0 0;
-#X floatatom 209 180 5 0 0;
+#X floatatom 209 160 5 0 0 0 - - -;
+#X floatatom 209 180 5 0 0 0 - - -;
#X text 264 159 sustain level;
-#X connect 0 0 8 0;
-#X connect 0 0 8 1;
-#X connect 1 0 10 0;
-#X connect 1 0 12 0;
-#X connect 2 0 1 0;
-#X connect 3 0 0 0;
-#X connect 4 0 3 0;
-#X connect 5 0 1 1;
-#X connect 6 0 14 1;
-#X connect 7 0 14 2;
-#X connect 9 0 1 0;
-#X connect 10 0 14 0;
-#X connect 11 0 14 0;
-#X connect 12 0 11 0;
-#X connect 13 0 12 1;
-#X connect 14 0 0 1;
-#X connect 18 0 14 3;
-#X connect 19 0 14 4;
+#X obj 88 253 vol~;
+#X floatatom 132 238 5 0 0 0 - - -;
+#X obj 343 228 table t 10000;
+#X obj 343 267 tabwrite~ t;
+#X obj 343 247 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 103 13 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj 262 276 del;
+#X floatatom 276 225 5 0 0 0 - - -;
+#X text 265 182 60db release time;
+#X connect 0 0 19 0;
+#X connect 1 0 9 0;
+#X connect 1 0 11 0;
+#X connect 2 0 0 0;
+#X connect 3 0 2 0;
+#X connect 4 0 1 1;
+#X connect 5 0 13 1;
+#X connect 6 0 13 2;
+#X connect 8 0 1 0;
+#X connect 9 0 13 0;
+#X connect 10 0 13 0;
+#X connect 11 0 10 0;
+#X connect 12 0 11 1;
+#X connect 13 0 0 1;
+#X connect 13 0 22 0;
+#X connect 16 0 13 3;
+#X connect 17 0 13 4;
+#X connect 19 0 7 1;
+#X connect 19 0 7 0;
+#X connect 20 0 19 1;
+#X connect 23 0 22 0;
+#X connect 23 0 25 0;
+#X connect 23 0 9 0;
+#X connect 24 0 1 0;
+#X connect 25 0 10 0;
+#X connect 26 0 25 1;
diff --git a/doc/ead~.pd b/doc/ead~.pd
index 9d9bc5f..835ba3d 100644
--- a/doc/ead~.pd
+++ b/doc/ead~.pd
@@ -2,28 +2,39 @@
#X obj 105 111 ead~ 0 0;
#X obj 89 179 *~;
#X obj 105 40 metro;
-#X obj 105 12 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1
--1;
#X obj 41 144 osc~;
-#X floatatom 41 112 5 0 0;
-#X floatatom 135 12 5 0 0;
-#X floatatom 130 64 5 0 0;
-#X floatatom 156 86 5 0 0;
-#X obj 77 217 dac~;
+#X floatatom 41 112 5 0 0 0 - - -;
+#X floatatom 135 12 5 0 0 0 - - -;
+#X floatatom 130 64 5 0 0 0 - - -;
+#X floatatom 156 86 5 0 0 0 - - -;
+#X obj 78 242 dac~;
#X text 202 71 60db attack and decay time;
-#X obj 70 76 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1
+#X obj 70 76 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#X msg 58 12 stop;
#X text 201 51 exponential attack/decay envelope;
+#X obj 89 212 vol~;
+#X floatatom 117 193 5 0 0 0 - - -;
+#X obj 265 119 table t 5000;
+#X obj 265 176 tabwrite~ t;
+#X obj 265 152 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 105 13 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
#X connect 0 0 1 1;
-#X connect 1 0 9 0;
-#X connect 1 0 9 1;
+#X connect 0 0 16 0;
+#X connect 1 0 13 0;
#X connect 2 0 0 0;
-#X connect 3 0 2 0;
-#X connect 4 0 1 0;
-#X connect 5 0 4 0;
-#X connect 6 0 2 1;
-#X connect 7 0 0 1;
-#X connect 8 0 0 2;
-#X connect 11 0 0 0;
-#X connect 12 0 2 0;
+#X connect 3 0 1 0;
+#X connect 4 0 3 0;
+#X connect 5 0 2 1;
+#X connect 6 0 0 1;
+#X connect 7 0 0 2;
+#X connect 10 0 0 0;
+#X connect 11 0 2 0;
+#X connect 13 0 8 0;
+#X connect 13 0 8 1;
+#X connect 14 0 13 1;
+#X connect 17 0 16 0;
+#X connect 17 0 0 0;
+#X connect 18 0 2 0;
diff --git a/doc/examples/formantdynwav.pd b/doc/examples/formantdynwav.pd
new file mode 100644
index 0000000..60afd11
--- /dev/null
+++ b/doc/examples/formantdynwav.pd
@@ -0,0 +1,198 @@
+#N canvas 131 302 276 242 10;
+#N canvas 342 154 748 636 stuff 1;
+#X obj 59 376 outlet~;
+#X obj 59 348 vol~;
+#X floatatom 176 317 5 0 0;
+#X obj 197 29 bang~;
+#X obj 59 290 pdynwav~;
+#X floatatom 189 221 5 0 0;
+#X obj 46 103 osc~;
+#X obj 91 103 osc~;
+#X obj 135 102 osc~;
+#X obj 104 223 *~;
+#X obj 345 87 phasor~;
+#X obj 277 185 *~;
+#X obj 346 136 *~;
+#X obj 346 108 onecomp~;
+#X obj 346 164 *~;
+#X text 38 33 formant frequencies;
+#N canvas 139 0 533 326 to_formant 0;
+#X obj 339 217 /;
+#X obj 391 149 t b f;
+#X obj 291 182 samplerate~;
+#X floatatom 335 243 5 0 0;
+#X obj 369 47 inlet;
+#X obj 405 126 * 1024;
+#X obj 30 158 *~;
+#X obj 88 159 *~;
+#X obj 150 156 *~;
+#X obj 30 192 outlet~;
+#X obj 88 193 outlet~;
+#X obj 150 190 outlet~;
+#X obj 150 100 inlet~;
+#X obj 88 103 inlet~;
+#X obj 30 102 inlet~;
+#X connect 0 0 3 0;
+#X connect 0 0 8 1;
+#X connect 0 0 7 1;
+#X connect 0 0 6 1;
+#X connect 1 0 2 0;
+#X connect 1 1 0 1;
+#X connect 2 0 0 0;
+#X connect 4 0 5 0;
+#X connect 5 0 1 0;
+#X connect 6 0 9 0;
+#X connect 7 0 10 0;
+#X connect 8 0 11 0;
+#X connect 12 0 8 0;
+#X connect 13 0 7 0;
+#X connect 14 0 6 0;
+#X restore 45 71 pd to_formant;
+#X obj 189 260 +;
+#X obj 227 261 -;
+#X obj 136 374 outlet~;
+#X obj 136 346 vol~;
+#X obj 127 290 pdynwav~;
+#X floatatom 244 210 5 0 0;
+#X obj 253 237 t b f;
+#X obj 520 332 block~ 1024;
+#X obj 277 28 fblock 1024;
+#X obj 469 163 random 120;
+#X obj 469 191 - 60;
+#X obj 466 139 metro 750;
+#X obj 470 111 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 43 -75 *~;
+#X floatatom 59 -99 5 0 0;
+#X obj 43 -121 osc~;
+#X floatatom 43 -151 5 0 0;
+#X obj 113 -75 *~;
+#X floatatom 129 -99 5 0 0;
+#X obj 113 -121 osc~;
+#X floatatom 113 -151 5 0 0;
+#X obj 180 -74 *~;
+#X floatatom 196 -98 5 0 0;
+#X obj 180 -120 osc~;
+#X floatatom 180 -150 5 0 0;
+#X floatatom 531 106 5 0 0;
+#X floatatom 84 128 5 0 0;
+#X obj 44 157 vol~;
+#X floatatom 125 128 5 0 0;
+#X obj 85 157 vol~;
+#X floatatom 173 129 5 0 0;
+#X obj 133 158 vol~;
+#X floatatom 304 -126 5 0 0;
+#X msg 349 6 1;
+#X obj 277 159 phasor~;
+#X obj 94 199 *~ 1;
+#X msg 389 58 0;
+#X msg 197 60 0.25;
+#X obj 346 189 *~;
+#X msg 194 92 100;
+#X obj 374 242 tabsend~ period;
+#X obj 494 213 table period 1024;
+#X floatatom 298 322 5 0 0;
+#X obj 343 -83 loadbang;
+#X floatatom 198 -52 5 0 0;
+#X obj 182 -28 +~;
+#X floatatom 125 -49 5 0 0;
+#X obj 109 -25 +~;
+#X floatatom 65 -45 5 0 0;
+#X obj 49 -21 +~;
+#X connect 1 0 0 0;
+#X connect 2 0 1 1;
+#X connect 2 0 20 1;
+#X connect 3 0 54 0;
+#X connect 3 0 53 0;
+#X connect 4 0 1 0;
+#X connect 5 0 16 3;
+#X connect 5 0 17 0;
+#X connect 5 0 18 0;
+#X connect 6 0 44 0;
+#X connect 7 0 46 0;
+#X connect 8 0 48 0;
+#X connect 9 0 4 0;
+#X connect 9 0 21 0;
+#X connect 9 0 57 0;
+#X connect 10 0 13 0;
+#X connect 11 0 9 1;
+#X connect 12 0 14 0;
+#X connect 12 0 14 1;
+#X connect 13 0 12 1;
+#X connect 13 0 12 0;
+#X connect 14 0 55 0;
+#X connect 14 0 55 1;
+#X connect 14 0 11 1;
+#X connect 16 0 6 0;
+#X connect 16 1 7 0;
+#X connect 16 2 8 0;
+#X connect 17 0 4 1;
+#X connect 18 0 21 1;
+#X connect 20 0 19 0;
+#X connect 21 0 20 0;
+#X connect 22 0 17 1;
+#X connect 22 0 23 0;
+#X connect 23 0 18 0;
+#X connect 23 0 17 0;
+#X connect 23 1 18 1;
+#X connect 23 1 17 1;
+#X connect 25 0 10 0;
+#X connect 25 0 51 0;
+#X connect 26 0 27 0;
+#X connect 27 0 5 0;
+#X connect 28 0 26 0;
+#X connect 29 0 28 0;
+#X connect 30 0 66 0;
+#X connect 31 0 30 1;
+#X connect 32 0 30 0;
+#X connect 33 0 32 0;
+#X connect 34 0 64 0;
+#X connect 35 0 34 1;
+#X connect 36 0 34 0;
+#X connect 37 0 36 0;
+#X connect 38 0 62 0;
+#X connect 39 0 38 1;
+#X connect 40 0 38 0;
+#X connect 41 0 40 0;
+#X connect 42 0 28 1;
+#X connect 43 0 44 1;
+#X connect 44 0 52 0;
+#X connect 45 0 46 1;
+#X connect 46 0 52 0;
+#X connect 47 0 48 1;
+#X connect 48 0 52 0;
+#X connect 50 0 25 1;
+#X connect 51 0 11 0;
+#X connect 52 0 9 0;
+#X connect 53 0 10 1;
+#X connect 54 0 8 1;
+#X connect 54 0 7 1;
+#X connect 54 0 6 1;
+#X connect 56 0 47 0;
+#X connect 56 0 45 0;
+#X connect 56 0 43 0;
+#X connect 60 0 50 0;
+#X connect 61 0 62 1;
+#X connect 62 0 16 2;
+#X connect 63 0 64 1;
+#X connect 64 0 16 1;
+#X connect 65 0 66 1;
+#X connect 66 0 16 0;
+#X restore 18 14 pd stuff;
+#X obj 19 75 dac~;
+#X obj 94 79 vols~;
+#X obj 96 54 fdn~;
+#X floatatom 140 53 5 0 0;
+#X floatatom 108 24 5 0 0;
+#X floatatom 154 24 5 0 0;
+#X connect 0 0 1 0;
+#X connect 0 0 3 0;
+#X connect 0 1 1 1;
+#X connect 0 1 3 0;
+#X connect 2 0 1 0;
+#X connect 2 1 1 1;
+#X connect 3 0 2 0;
+#X connect 3 1 2 1;
+#X connect 4 0 2 2;
+#X connect 5 0 3 1;
+#X connect 6 0 3 2;
diff --git a/doc/lattice~.pd b/doc/lattice~.pd
index 4545470..6f62e3e 100644
--- a/doc/lattice~.pd
+++ b/doc/lattice~.pd
@@ -1,21 +1,21 @@
#N canvas 338 162 527 557 10;
-#X obj 57 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144
--1 -1 12100 1;
+#X obj 57 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 0 8 -262144
+-1 -1 12500 1;
#X msg 57 223 rc 0 \$1;
-#X obj 88 -78 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144
--1 -1 7150 1;
-#X obj 119 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144
--1 -1 5150 1;
-#X obj 149 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144
--1 -1 8100 1;
-#X obj 179 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144
--1 -1 11850 1;
-#X obj 210 -78 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144
--1 -1 15850 1;
-#X obj 241 -78 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144
--1 -1 17550 1;
-#X obj 271 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144
--1 -1 15050 1;
+#X obj 88 -78 vsl 15 250 -1 1 0 1 empty empty empty 20 8 0 8 -262144
+-1 -1 6432 1;
+#X obj 119 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 0 8 -262144
+-1 -1 3732 1;
+#X obj 149 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 0 8 -262144
+-1 -1 4332 1;
+#X obj 179 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 0 8 -262144
+-1 -1 21232 1;
+#X obj 210 -78 vsl 15 250 -1 1 0 1 empty empty empty 20 8 0 8 -262144
+-1 -1 24900 1;
+#X obj 241 -78 vsl 15 250 -1 1 0 1 empty empty empty 20 8 0 8 -262144
+-1 -1 18232 1;
+#X obj 271 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 0 8 -262144
+-1 -1 16932 1;
#X msg 86 199 rc 1 \$1;
#X msg 118 224 rc 2 \$1;
#X msg 147 200 rc 3 \$1;
@@ -23,15 +23,16 @@
#X msg 208 199 rc 5 \$1;
#X msg 240 224 rc 6 \$1;
#X msg 269 200 rc 7 \$1;
-#X floatatom 154 -125 5 -1 1;
+#X floatatom 154 -125 5 -1 1 0 - - -;
#X obj 64 302 lattice~ 8;
#X obj 6 254 noise~;
#X obj 63 363 vol~;
#X obj 63 397 dac~;
-#X floatatom 85 333 5 0 0;
+#X floatatom 85 333 5 0 0 0 - - -;
#X text 159 298 lattice~ a lattice filter;
#X text 139 333 [rc <index> <val>] sets reflection coefficient;
#X text 159 311 creation argument sets order;
+#X obj 27 330 dist~ 1;
#X connect 0 0 1 0;
#X connect 1 0 17 0;
#X connect 2 0 9 0;
@@ -56,8 +57,9 @@
#X connect 16 0 6 0;
#X connect 16 0 7 0;
#X connect 16 0 8 0;
-#X connect 17 0 19 0;
+#X connect 17 0 25 0;
#X connect 18 0 17 0;
#X connect 19 0 20 1;
#X connect 19 0 20 0;
#X connect 21 0 19 1;
+#X connect 25 0 19 0;
diff --git a/doc/reference.txt b/doc/reference.txt
index 9518d84..ff314e0 100644
--- a/doc/reference.txt
+++ b/doc/reference.txt
@@ -5,14 +5,34 @@ bdft,bdfts set decay time (ms/sec) and osc frequency (for bdiag~)
bhip~ butterworth high pass filter
blop~ butterworth low pass filter
bpm convert bpm to metro time and phasor freq
+cadd~ complex add
+ccmap~ conformal self map of the unit disk
+cconj~ complex conjugate
+cep~/icep~ complex cepstrum and inverse
+cinv~ complex inverse
+cmul~ complex multiplication
count modulo counter
+cosc~ complex oscillator
+csub~ complex subtraction
+dsfosc~ (finite) discrete summation formula oscillator
eadh~ exponential attack decay (with hold == duration)
eadsrh~ exponential attack decay sustain release (..)
+expmap~ exponential map
fblock block relative frequency conversion
+fmod floating point modulo
+fmop~ fm operator
+frequor~ like phasor, but for block spectra
+idsfosc~ infinite discrete summation formula
inv inverse
+lattice3 expand a 3D harmonic lattice vector
+lpfft~ ifft + lowpass (for anti-aliased dynwav)
pdynwav~ phasor~ + dynwav~
scale7 arbitrary 7 tone scale
+ti_hihat hihat gop object
+ti_snare snare drum gop object
tblock block relative time conversion
+ucnorm~ normalize a complex signal to unit norm
+ucmod~ unit circle modulator
vols~ volume for a stereo signal
vol~ volume for a mono signal
@@ -28,9 +48,14 @@ tilde externs
abs~ absolute value
bdiag~ block diagonal state space system (spectral processor)
bfft~ reordered fft
+bitsplit~ convert signal to binary vector
bwin~ several windowing functions and spectral envelopes
biquadseries~ biquad second order sections (i.e. butterworth)
+bitsplit~ convert a signal to binary representation
+blocknorm~ normalize a (set of) dsp block(s) (i.e. for spectral processing)
+blosc~ several bandlimited oscillators
cheby~ chebyshev polynomial waveshaper
+clog~ complex log
diag~ diagonal state space system (spectral processor)
dist~ several distortions & waveshaping functions
dwt~ discrete wavelet transform
@@ -48,7 +73,10 @@ permut~ random permute a signal block
qmult~ multiply 2 quaternion signals
qnorm~ normalize a quaternion signal (or any 4 channel sig)
ramp~ generates an integer ramp
+resofilt~ a reso filter (4pole, 3pole)
+sbosc~ smallband oscillator (i.e. for formant synthesis)
statwav~ a tabread4~ clone with 8 point interpolation
+scrollgrid1D~ a stabilized scroll grid chaotic oscillator
tabreadmix~ a tabread~ clone with overlap add (for smooth time stretch)
xfm~ coupled frequency modulation
diff --git a/doc/resofilt~.pd b/doc/resofilt~.pd
new file mode 100644
index 0000000..5adad08
--- /dev/null
+++ b/doc/resofilt~.pd
@@ -0,0 +1,79 @@
+#N canvas 413 70 819 645 10;
+#X floatatom 50 203 5 0 0 0 - - -;
+#X obj 118 433 vol~;
+#X floatatom 157 409 5 0 0 0 - - -;
+#X obj 110 468 dac~;
+#X floatatom 291 252 5 0 0 0 - - -;
+#X floatatom 290 301 5 0 0 0 - - -;
+#X obj 119 341 vol~;
+#X floatatom 142 318 5 0 0 0 - - -;
+#X obj 295 232 hsl 128 15 20 20000 1 1 empty empty empty -2 -6 0 8
+-262144 -1 -1 7900 1;
+#X obj 294 282 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144
+-1 -1 5600 1;
+#X obj 242 225 ead~;
+#X obj 243 268 *~;
+#X obj 235 203 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 259 203 5 0 0 0 - - -;
+#X floatatom 305 202 5 0 0 0 - - -;
+#X obj 19 170 ead~;
+#X obj 20 273 *~;
+#X obj 19 102 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 35 147 5 0 0 0 - - -;
+#X floatatom 76 147 5 0 0 0 - - -;
+#X obj 86 71 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 87 44 metro 125;
+#X obj 88 20 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X floatatom 147 16 5 0 0 0 - - -;
+#X msg 34 126 10;
+#X msg 76 126 400;
+#X msg 268 180 20;
+#X obj 36 225 blosc~ saw;
+#X obj 37 248 -~;
+#X msg 141 297 70;
+#X text 281 96 all inputs are signal inlets. frequency and reso are
+interpolated from their average (rms) value.;
+#X msg 305 181 500;
+#X text 279 28 resofilt~: high-quality implementations of the moog
+4-pole and tb303 3-pole reso ladder filter. state-limited which means
+it distorts on high reso input \, and can go into self oscillation
+when reso > 1;
+#X msg 53 182 70;
+#X obj 119 377 resofilt~ 4;
+#X text 222 378 creation argument 4 = 4pole \, 3 = 3pole;
+#X connect 0 0 27 0;
+#X connect 1 0 3 0;
+#X connect 1 0 3 1;
+#X connect 2 0 1 1;
+#X connect 4 0 11 1;
+#X connect 6 0 34 0;
+#X connect 7 0 6 1;
+#X connect 8 0 4 0;
+#X connect 9 0 5 0;
+#X connect 10 0 11 0;
+#X connect 12 0 10 0;
+#X connect 13 0 10 1;
+#X connect 14 0 10 2;
+#X connect 15 0 16 0;
+#X connect 16 0 6 0;
+#X connect 17 0 15 0;
+#X connect 18 0 15 1;
+#X connect 19 0 15 2;
+#X connect 20 0 12 0;
+#X connect 20 0 17 0;
+#X connect 21 0 20 0;
+#X connect 22 0 21 0;
+#X connect 23 0 21 1;
+#X connect 24 0 18 0;
+#X connect 25 0 19 0;
+#X connect 26 0 13 0;
+#X connect 27 0 28 0;
+#X connect 28 0 16 1;
+#X connect 29 0 7 0;
+#X connect 31 0 14 0;
+#X connect 33 0 0 0;
+#X connect 34 0 1 0;
diff --git a/doc/sbosc~.pd b/doc/sbosc~.pd
new file mode 100644
index 0000000..804b30d
--- /dev/null
+++ b/doc/sbosc~.pd
@@ -0,0 +1,36 @@
+#N canvas 624 424 408 499 10;
+#X obj 70 158 sbosc~;
+#X floatatom 101 285 5 0 0 0 - - -;
+#X obj 70 308 vol~;
+#X obj 58 340 dac~;
+#X floatatom 70 68 5 0 0 0 - - -;
+#X floatatom 136 106 5 0 0 0 - - -;
+#X msg 129 139 0;
+#X text 171 139 phase;
+#X text 56 44 pitch;
+#X text 119 84 center freq;
+#X text 38 14 sbosc~: smallband periodic complex oscillator.;
+#X obj 134 53 hsl 128 15 20 20000 1 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 4163 1;
+#X obj 213 91 hsl 128 15 20 20000 1 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 7400 1;
+#X obj 85 228 idsfosc~;
+#X obj 70 256 *~;
+#X floatatom 136 206 5 0 0 0 - - -;
+#X obj 194 191 hsl 128 15 -0.99 0.99 0 0 empty empty empty -2 -6 0
+8 -262144 -1 -1 9100 1;
+#X text 136 188 bw;
+#X connect 0 0 14 0;
+#X connect 1 0 2 1;
+#X connect 2 0 3 0;
+#X connect 2 0 3 1;
+#X connect 4 0 0 0;
+#X connect 4 0 13 0;
+#X connect 5 0 0 1;
+#X connect 6 0 0 2;
+#X connect 11 0 4 0;
+#X connect 12 0 5 0;
+#X connect 13 0 14 1;
+#X connect 14 0 2 0;
+#X connect 15 0 13 1;
+#X connect 16 0 15 0;
diff --git a/doc/scrollgrid1D~.pd b/doc/scrollgrid1D~.pd
new file mode 100644
index 0000000..1649dfb
--- /dev/null
+++ b/doc/scrollgrid1D~.pd
@@ -0,0 +1,111 @@
+#N canvas 309 57 748 724 10;
+#X obj 116 116 scrollgrid1D~;
+#X msg 36 92 reset;
+#X floatatom 111 87 5 0 0;
+#X floatatom 187 87 5 0 0;
+#X floatatom 237 86 5 0 0;
+#X floatatom 290 85 5 0 0;
+#X obj 401 200 tabwrite~ t;
+#X obj 401 147 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144
+-1 -1;
+#X obj 504 206 table t 10000;
+#X obj 123 222 vol~;
+#X floatatom 146 196 5 0 0;
+#X text 103 47 frequency;
+#X text 197 45 T1;
+#X text 249 45 T2;
+#X text 301 46 N;
+#X msg 111 66 350;
+#X msg 235 66 1;
+#X msg 291 65 3;
+#X msg 188 65 12;
+#X obj 379 222 tabwrite~ t;
+#X obj 379 147 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144
+-1 -1;
+#X obj 353 243 tabwrite~ t;
+#X obj 353 148 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144
+-1 -1;
+#X text 233 292 parameters:;
+#X text 266 359 N = number of scrolls or unstable rotation centers
+in attractor;
+#X text 233 404 outputs:;
+#X text 230 468 some remarks;
+#X text 266 422 the first output is alongside the scoll centers \,
+the other two are orthogonal to this line.;
+#X text 368 130 X Y Z;
+#X obj 178 222 vol~;
+#X floatatom 201 196 5 0 0;
+#X obj 64 223 vol~;
+#X floatatom 87 197 5 0 0;
+#X obj 63 282 hip~ 10;
+#X floatatom 133 286 5 0 0;
+#X obj 63 305 blop~ 4;
+#X msg 132 263 500;
+#X msg 163 263 5000;
+#X text 265 325 T1 = unstable time constant in ms ("attack" time);
+#X text 265 342 T2 = stable time constant in ms ("release" time);
+#X text 265 660 the entire circuit is clipped \, which means that for
+some parameter values that would normally cause a blowup \, its behaviour
+is limited to that of an oscillator.;
+#X obj 4 283 hip~ 10;
+#X obj 4 306 blop~ 4;
+#X obj 34 340 dac~;
+#X floatatom 180 170 5 0 0;
+#X obj 4 402 tabwrite~ t;
+#X obj 21 380 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1
+-1;
+#X msg 142 66 5000;
+#X text 264 309 freq = spiral frequency in Hz;
+#X text 265 493 this chaotic system is a switched unstable linear system.
+it consists of N scrolls (outward spirals). when the amplitude of the
+spiral has reached a certain threshold \, it is switched to the nearest
+fixed point (a neighbour spiral). the freq parameter determines the
+frequency of the outward spiralling motion on a scroll. T1 is the outward
+spiralling time constant. T1 large means slow buildup or mild chaotic
+motion \, T1 small means fast buildup or turbulent chaotic motion.
+T2 is the time constant with which a trajectory is attracted to the
+plane of a scroll. T2 small means fast attraction \, T2 large means
+slow attraction.;
+#X text 45 11 stabilized scroll grid chaotic oscillator with scroll
+centers located on a line.;
+#X msg 204 262 17000;
+#X connect 0 0 21 0;
+#X connect 0 0 31 0;
+#X connect 0 1 9 0;
+#X connect 0 1 19 0;
+#X connect 0 2 6 0;
+#X connect 0 2 29 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 1;
+#X connect 4 0 0 2;
+#X connect 5 0 0 3;
+#X connect 7 0 6 0;
+#X connect 9 0 41 0;
+#X connect 10 0 9 1;
+#X connect 15 0 2 0;
+#X connect 16 0 4 0;
+#X connect 17 0 5 0;
+#X connect 18 0 3 0;
+#X connect 20 0 19 0;
+#X connect 22 0 21 0;
+#X connect 29 0 33 0;
+#X connect 30 0 29 1;
+#X connect 31 0 33 0;
+#X connect 31 0 41 0;
+#X connect 32 0 31 1;
+#X connect 33 0 35 0;
+#X connect 34 0 35 1;
+#X connect 34 0 42 1;
+#X connect 35 0 43 1;
+#X connect 35 0 45 0;
+#X connect 36 0 34 0;
+#X connect 37 0 34 0;
+#X connect 41 0 42 0;
+#X connect 42 0 43 0;
+#X connect 42 0 45 0;
+#X connect 44 0 10 0;
+#X connect 44 0 30 0;
+#X connect 46 0 45 0;
+#X connect 47 0 2 0;
+#X connect 51 0 34 0;
diff --git a/include/dspi/DSPIcomplex.h b/include/dspi/DSPIcomplex.h
index c0e2d63..ad3e041 100644
--- a/include/dspi/DSPIcomplex.h
+++ b/include/dspi/DSPIcomplex.h
@@ -22,7 +22,7 @@
#define DSPIcomplex_h
#include <math.h>
-#include <iostream.h>
+#include <iostream>
class DSPIcomplex
{
diff --git a/include/extlib_util.h b/include/extlib_util.h
index 6e4d94b..3f92ab0 100644
--- a/include/extlib_util.h
+++ b/include/extlib_util.h
@@ -30,5 +30,15 @@
/* convert milliseconds to 1-p, with p a real pole */
float milliseconds_2_one_minus_realpole(float time);
+
+typedef union
+{
+ unsigned int i;
+ float f;
+} t_flint;
+
/* check if floating point number is denormal */
-#define IS_DENORMAL(f) (((*(unsigned int *)&(f))&0x7f800000) == 0)
+
+//#define IS_DENORMAL(f) (((*(unsigned int *)&(f))&0x7f800000) == 0)
+
+#define IS_DENORMAL(f) (((((t_flint)(f)).i) & 0x7f800000) == 0)
diff --git a/include/filters.h b/include/filters.h
new file mode 100644
index 0000000..e0d1c49
--- /dev/null
+++ b/include/filters.h
@@ -0,0 +1,226 @@
+/* this file contains a 37th attempt to write a general purpose iir filter toolset */
+
+/* defined as inline functions with call by reference to enable compiler ref/deref optim */
+
+/* the typedef */
+#ifndef T
+#define T float
+#endif
+
+
+/* the prototype for a word */
+#define P static inline void
+#define PP static void
+
+
+/* the 'reference' arguments */
+#define A *a
+#define B *b
+#define C *c
+#define D *d
+#define X *x
+#define Y *y
+#define S *s
+
+
+/* the opcodes */
+
+/* add */
+P cadd (T X, T Y, T A, T B, T C, T D) { X = A + C; Y = B + D;}
+P cadd2 (T A, T B, T C, T D) { A += C; B += D;}
+P vcadd (T X, T A, T C) { cadd(x,x+1,a,a+1,c,c+1); }
+P vcadd2 (T A, T C) { cadd2(a,a+1,c,c+1); }
+
+
+/* mul */
+P cmul_r (T X, T A, T B, T C, T D) { X = A * C - B * D;}
+P cmul_i (T Y, T A, T B, T C, T D) { Y = A * D + B * C;}
+P cmul (T X, T Y, T A, T B, T C, T D)
+{
+ cmul_r (x, a, b, c, d);
+ cmul_i (y, a, b, c, d);
+}
+P cmul2 (T A, T B, T C, T D)
+{
+ T x = A;
+ T y = B;
+ cmul (&x, &y, a, b, c, d);
+ A = x;
+ B = y;
+}
+
+P vcmul (T X, T A, T C) { cmul(x,x+1,a,a+1,c,c+1); }
+P vcmul2 (T A, T C) { cmul2(a,a+1,c,c+1); }
+
+
+/* norm */
+static inline float vcnorm(T X) { return hypot(x[0], x[1]); }
+
+
+
+/* swap */
+P vcswap(T Y, T X)
+{
+ float t[2] = {x[0], x[1]};
+ x[0] = y[0];
+ x[1] = y[1];
+ y[0] = t[0];
+ y[1] = t[1];
+}
+
+
+/* inverse */
+P vcinv(T Y, T X)
+{
+ float scale = 1.0f / vcnorm(x);
+ y[0] = scale * x[0];
+ y[1] = scale * x[1];
+}
+
+P vcinv1(T X)
+{
+ float scale = 1.0f / vcnorm(x);
+ x[0] *= scale;
+ x[1] *= scale;
+}
+
+/* exp */
+
+/* X = exp(Y) */
+P vcexp2 (T Y, T X)
+{
+ T r = exp(x[0]);
+ y[0] = cos (x[1]);
+ y[1] = sin (x[1]);
+ y[0] *= r;
+ y[1] *= r;
+}
+
+P vcexp1 (T X)
+{
+ T y[2];
+ vcexp2(y,x);
+ x[0] = y[0];
+ x[1] = y[1];
+}
+
+/*
+ FILTERS
+
+ the transfer function is defined in terms of the "engineering"
+ bilateral z-transform of the discrete impulse response h[n].
+
+ H(z) = Sum{n = -inf -> inf} h[n] z^(-n)
+
+ a unit delay operating on a singnal S(z) is therefore
+ represented as z^(-1) S(z)
+
+*/
+
+
+
+
+
+
+
+/* biquads */
+
+/* biquad, orthogonal (poles & zeros), real in, out, state, pole, output */
+P biq_orth_r (T X, T Y, T S, T A, T C)
+{
+ Y = X + c[0] * s[0] - c[1] * s[1]; /* mind sign of c[1] */
+ vcmul2(s, a);
+ S += X;
+}
+
+
+/* biquad, orthogonal, complex one-pole, with scaling */
+
+/* complex one pole: (output = s[0] + is[1]): C / (1-A z^(-1)) */
+
+P one_pole_complex (T X, T Y, T S, T A, T C)
+{
+ vcmul(y, s, a);
+ vcadd2(y, x);
+ s[0] = y[0];
+ s[1] = y[1];
+ vcmul(y, s, c);
+}
+
+/* complex conj two pole: (output = s[0] : (Re(C) - Re(C*Conj(A))) / (1 - A z^(-1)) (1 - Conj(A) z^(-1)) */
+
+P two_pole_complex_conj (T X, T Y, T S, T A, T C)
+{
+ vcmul2(s, a);
+ s[0] += x[0];
+ y[0] = s[0] * c[0] - s[1] * c[1];
+}
+
+
+
+/* support functions for IIR filter design */
+
+/* evaluate pole and allzero TF in z^-1 given the complex zeros/poles:
+ p(z) (or p(z)^-1) = \product (1-z_i z^-1) */
+PP eval_zero_poly(float *val, float *arg, float *zeros, int nb_zeros)
+{
+ int i;
+ float a[2] = {arg[0], arg[1]};
+ vcinv1(a);
+ val[0] = 1.0f;
+ val[1] = 0.0f;
+ a[0] *= -1;
+ a[1] *= -1;
+ for (i=0; i<nb_zeros; i++){
+ float t[2];
+ vcmul(t, a, zeros + 2*i);
+ t[0] += 1.0f;
+ vcmul2(val, t);
+ }
+}
+
+PP eval_pole_poly(float *val, float *arg, float *poles, int nb_poles)
+{
+ eval_zero_poly(val, arg, poles, nb_poles);
+ vcinv1(val);
+}
+
+
+/* since it's more efficient to store half of the poles for a real impulse
+ response, these functions compute p(z) conj(p(conj(z))) */
+
+PP eval_conj_zero_poly(float *val, float *arg, float *zeros, int nb_zeros)
+{
+ float t[2];
+ float a[2] = {arg[0], arg[1]};
+ eval_zero_poly(t, a, zeros, nb_zeros);
+ a[1] *= -1;
+ eval_zero_poly(val, a, zeros, nb_zeros);
+ val[1] *= -1;
+ vcmul2(val, t);
+}
+
+PP eval_conj_pole_poly(float *val, float *arg, float *poles, int nb_poles)
+{
+ eval_conj_zero_poly(val, arg, poles, nb_poles);
+ vcinv1(val);
+}
+
+PP eval_conj_pole_zero_ratfunc(float *val, float *arg, float *poles, float *zeros, int nb_poles, int nb_zeros)
+{
+ float t[2];
+ eval_conj_zero_poly(t, arg, zeros, nb_zeros);
+ eval_conj_pole_poly(val, arg, poles, nb_zeros);
+ vcmul2(val, t);
+}
+
+
+
+/* bandlimited IIR impulse:
+
+ * design analog butterworth filter
+ * obtain the partial fraction expansion of the transfer function
+ * determine the state increment as a function of fractional delay of impulse location
+ (sample the impulse response)
+
+*/
diff --git a/modules++/Makefile b/modules++/Makefile
index 1329f4b..65ba97a 100644
--- a/modules++/Makefile
+++ b/modules++/Makefile
@@ -1,7 +1,7 @@
include ../Makefile.config
current: all
-all: biquadseries.o filterortho.o
+all: biquadseries.o filterortho.o blosc.o
clean:
diff --git a/modules++/filterortho.cc b/modules++/filterortho.cc
index 11c6aac..c80552b 100644
--- a/modules++/filterortho.cc
+++ b/modules++/filterortho.cc
@@ -30,7 +30,7 @@ typedef struct filterortho_struct
{
t_object x_obj;
t_float x_f;
- DSPIfilterOrtho filterortho;
+ DSPIfilterOrtho *filterortho;
} t_filterortho;
void filterortho_bang(t_filterortho *x)
@@ -68,11 +68,12 @@ static t_int *filterortho_perform(t_int *w)
static void filterortho_dsp(t_filterortho *x, t_signal **sp)
{
- dsp_add(filterortho_perform, 4, &(x->filterortho), sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec);
+ dsp_add(filterortho_perform, 4, x->filterortho, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec);
}
-void filterortho_free(void)
+void filterortho_free(t_filterortho *x)
{
+ delete x->filterortho;
}
@@ -80,21 +81,22 @@ t_class *filterortho_class;
-void setLP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho.setLP(f / sys_getsr(), Q);}
-void setHP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho.setHP(f / sys_getsr(), Q);}
-void setBP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho.setBP(f / sys_getsr(), Q);}
-void setBR(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho.setBR(f / sys_getsr(), Q);}
-void setAP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho.setAP(f / sys_getsr(), Q);}
+void setLP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho->setLP(f / sys_getsr(), Q);}
+void setHP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho->setHP(f / sys_getsr(), Q);}
+void setBP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho->setBP(f / sys_getsr(), Q);}
+void setBR(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho->setBR(f / sys_getsr(), Q);}
+void setAP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho->setAP(f / sys_getsr(), Q);}
-void setLS(t_filterortho *x, t_floatarg f, t_floatarg A) {x->filterortho.setLS(f / sys_getsr(), A);}
-void setHS(t_filterortho *x, t_floatarg f, t_floatarg A) {x->filterortho.setHS(f / sys_getsr(), A);}
+void setLS(t_filterortho *x, t_floatarg f, t_floatarg A) {x->filterortho->setLS(f / sys_getsr(), A);}
+void setHS(t_filterortho *x, t_floatarg f, t_floatarg A) {x->filterortho->setHS(f / sys_getsr(), A);}
-void setEQ(t_filterortho *x, t_floatarg f, t_floatarg Q, t_floatarg A) {x->filterortho.setEQ(f / sys_getsr(), Q, A);}
+void setEQ(t_filterortho *x, t_floatarg f, t_floatarg Q, t_floatarg A) {x->filterortho->setEQ(f / sys_getsr(), Q, A);}
void *filterortho_new()
{
t_filterortho *x = (t_filterortho *)pd_new(filterortho_class);
+ x->filterortho = new DSPIfilterOrtho();
outlet_new(&x->x_obj, gensym("signal"));
setLP(x, 10000, 2);
return (void *)x;
@@ -107,12 +109,12 @@ extern "C" {
void filterortho_tilde_setup(void)
{
//post("filterortho~ v0.1");
-
filterortho_class = class_new(gensym("filterortho~"), (t_newmethod)filterortho_new,
(t_method)filterortho_free, sizeof(t_filterortho), 0, A_NULL);
CLASS_MAINSIGNALIN(filterortho_class, t_filterortho, x_f);
+
class_addmethod(filterortho_class, (t_method)filterortho_bang, gensym("bang"), A_NULL);
class_addmethod(filterortho_class, (t_method)filterortho_dsp, gensym("dsp"), A_NULL);
diff --git a/modules/Makefile b/modules/Makefile
index b5e6093..f054566 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -3,7 +3,8 @@ include ../Makefile.config
current: ead.o ear.o eadsr.o dist.o tabreadmix.o xfm.o qmult.o qnorm.o \
cheby.o abs.o ramp.o dwt.o bfft.o dynwav.o statwav.o bdiag.o \
diag.o matrix.o permut.o lattice.o ratio.o ffpoly.o fwarp.o \
- junction.o fdn.o window.o
+ junction.o fdn.o window.o cmath.o eblosc.o bitsplit.o sbosc.o \
+ blocknorm.o resofilt.o scrollgrid1D.o
clean:
diff --git a/modules/bfft.c b/modules/bfft.c
index 76b0254..750f020 100644
--- a/modules/bfft.c
+++ b/modules/bfft.c
@@ -1,5 +1,5 @@
/*
- * bfft.c - code for fourrier transform
+ * bfft.c - code for some fourrier transform variants and utility functions
* data organization is in (real, imag) pairs
* the first 2 components are (DC, NY)
* Copyright (c) 2000-2003 by Tom Schouten
@@ -29,17 +29,19 @@
typedef struct bfftctl
{
- t_int c_levels;
- char c_name[16];
- t_int *c_clutter;
- t_int *c_unclutter;
+ t_int c_levels;
+ char c_name[16];
+ t_int *c_clutter;
+ t_int *c_unclutter;
+ t_int c_kill_DC;
+ t_int c_kill_NY;
} t_bfftctl;
typedef struct bfft
{
- t_object x_obj;
- t_float x_f;
- t_bfftctl x_ctl;
+ t_object x_obj;
+ t_float x_f;
+ t_bfftctl x_ctl;
} t_bfft;
t_class *bfft_class, *ibfft_class, *fht_class;
@@ -127,10 +129,16 @@ static t_int *ibfft_perform(t_int *w)
t_float scale = sqrt(1.0f / (float)(n));
+ if (ctl->c_kill_DC) {out[0] = 0.0f;}
+ if (ctl->c_kill_NY) {out[1] = 0.0f;}
+
bfft_perform_permutation(out, n, ctl->c_clutter);
mayer_fht(out, n);
+
+
while (n--) *out++ *= scale;
+
return (w+5);
}
@@ -240,13 +248,22 @@ static void *bfft_new(void)
}
-static void *ibfft_new(void)
+static void *ibfft_new(t_symbol *s)
{
t_bfft *x = (t_bfft *)pd_new(ibfft_class);
int i;
outlet_new(&x->x_obj, gensym("signal"));
+ if (s == gensym("killDCNY")){
+ x->x_ctl.c_kill_DC = 1;
+ x->x_ctl.c_kill_NY = 1;
+ post("ibfft: removing DC and NY components.");
+ }
+ else{
+ x->x_ctl.c_kill_DC = 0;
+ x->x_ctl.c_kill_NY = 0;
+ }
x->x_ctl.c_clutter = NULL;
x->x_ctl.c_unclutter = NULL;
@@ -286,7 +303,11 @@ void bfft_tilde_setup(void)
ibfft_class = class_new(gensym("ibfft~"), (t_newmethod)ibfft_new,
- (t_method)bfft_free, sizeof(t_bfft), 0, 0);
+ (t_method)bfft_free, sizeof(t_bfft), 0, A_DEFSYMBOL, A_NULL);
+
+ /* add the more logical bifft~ alias */
+ class_addcreator((t_newmethod)ibfft_new,
+ gensym("bifft~"), 0, A_DEFSYMBOL, A_NULL);
CLASS_MAINSIGNALIN(ibfft_class, t_bfft, x_f);
class_addmethod(ibfft_class, (t_method)ibfft_dsp, gensym("dsp"), 0);
diff --git a/modules/bitsplit.c b/modules/bitsplit.c
new file mode 100644
index 0000000..9239d0b
--- /dev/null
+++ b/modules/bitsplit.c
@@ -0,0 +1,107 @@
+/*
+ * bitsplit.c - convert a signal to a binary vector
+ * Copyright (c) 2000-2003 by Tom Schouten
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "m_pd.h"
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#define MAXCHANNELS 24
+
+typedef struct bitsplitctl
+{
+ t_int c_outputs;
+ t_float *c_input;
+ t_float **c_output;
+} t_bitsplitctl;
+
+typedef struct bitsplit
+{
+ t_object x_obj;
+ t_float x_f;
+ t_bitsplitctl x_ctl;
+} t_bitsplit;
+
+
+static t_int *bitsplit_perform(t_int *word)
+{
+
+ t_bitsplitctl *ctl = (t_bitsplitctl *)(word[1]);
+ t_int n = (t_int)(word[2]);
+ t_float *in = ctl->c_input;
+ t_int outputs = ctl->c_outputs;
+ t_float **out = ctl->c_output;
+ t_int i,j;
+
+ for (i=0;i<n;i++){
+ long word = (in[i] * (float)(0x7fffffff));
+ for (j=0; j<outputs; j++){
+ out[j][i] = (float)((word >> 31) & 1);
+ word <<= 1;
+ }
+ }
+
+ return (word+3);
+}
+
+
+
+static void bitsplit_dsp(t_bitsplit *x, t_signal **sp)
+{
+
+ int i;
+ x->x_ctl.c_input = sp[0]->s_vec;
+ for (i=0;i<x->x_ctl.c_outputs;i++){
+ x->x_ctl.c_output[i] = sp[i+1]->s_vec;
+ }
+ dsp_add(bitsplit_perform, 2, &x->x_ctl, sp[0]->s_n);
+}
+
+
+static void bitsplit_free(t_bitsplit *x)
+{
+ free (x->x_ctl.c_output);
+}
+
+t_class *bitsplit_class;
+
+static void *bitsplit_new(t_floatarg channels)
+{
+ int i = (int)channels;
+ t_bitsplit *x = (t_bitsplit *)pd_new(bitsplit_class);
+
+ if (i<1) i = 1;
+ if (i>MAXCHANNELS) i = MAXCHANNELS;
+ x->x_ctl.c_outputs = i;
+ x->x_ctl.c_output = malloc(sizeof(float)*i);
+
+ while (i--) outlet_new(&x->x_obj, gensym("signal"));
+
+ return (void *)x;
+}
+
+void bitsplit_tilde_setup(void)
+{
+ bitsplit_class = class_new(gensym("bitsplit~"), (t_newmethod)bitsplit_new,
+ (t_method)bitsplit_free, sizeof(t_bitsplit), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(bitsplit_class, t_bitsplit, x_f);
+ class_addmethod(bitsplit_class, (t_method)bitsplit_dsp, gensym("dsp"), 0);
+}
+
diff --git a/modules/blocknorm.c b/modules/blocknorm.c
new file mode 100644
index 0000000..bcf695a
--- /dev/null
+++ b/modules/blocknorm.c
@@ -0,0 +1,129 @@
+/*
+ * blocknorm.c - normalize an array of dsp blocks (for spectral processing)
+ * Copyright (c) 2000-2003 by Tom Schouten
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "m_pd.h"
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#define MAXCHANNELS 32
+
+typedef struct blocknormctl
+{
+ t_int c_channels;
+ t_float **c_input;
+ t_float **c_output;
+} t_blocknormctl;
+
+typedef struct blocknorm
+{
+ t_object x_obj;
+ t_float x_f;
+ t_blocknormctl x_ctl;
+} t_blocknorm;
+
+
+static t_int *blocknorm_perform(t_int *word)
+{
+
+ t_blocknormctl *ctl = (t_blocknormctl *)(word[1]);
+ t_int n = (t_int)(word[2]);
+ t_float **in = ctl->c_input;
+ t_float **out = ctl->c_output;
+ t_int c = ctl->c_channels;
+ t_int i,j;
+
+ t_float p = 0.0f;
+ t_float x, s;
+
+ /* get power */
+ for (j=0;j<c;j++){
+ for (i=0;i<n;i++){
+ x = in[j][i];
+ p += x*x;
+ }
+ }
+
+ /* compute normalization */
+ if (p == 0.0f) s = 1.0f;
+ else s =sqrt(((float)(c * n)) / p);
+
+ /* normalize */
+ for (j=0;j<c;j++){
+ for (i=0;i<n;i++){
+ out[j][i] *= s;
+ }
+ }
+
+
+
+ return (word+3);
+}
+
+
+
+static void blocknorm_dsp(t_blocknorm *x, t_signal **sp)
+{
+
+ int i;
+ int c = x->x_ctl.c_channels;
+ for (i=0;i<c;i++){
+ x->x_ctl.c_input[i] = sp[i]->s_vec;
+ x->x_ctl.c_output[i] = sp[c+i]->s_vec;
+ }
+ dsp_add(blocknorm_perform, 2, &x->x_ctl, sp[0]->s_n);
+}
+
+
+static void blocknorm_free(t_blocknorm *x)
+{
+ free (x->x_ctl.c_output);
+ free (x->x_ctl.c_input);
+}
+
+t_class *blocknorm_class;
+
+static void *blocknorm_new(t_floatarg channels)
+{
+ int i = (int)channels;
+ int j;
+ t_blocknorm *x = (t_blocknorm *)pd_new(blocknorm_class);
+
+ if (i<1) i = 1;
+ if (i>MAXCHANNELS) i = MAXCHANNELS;
+ x->x_ctl.c_channels = i;
+ x->x_ctl.c_input = malloc(sizeof(float)*i);
+ x->x_ctl.c_output = malloc(sizeof(float)*i);
+
+ j = i;
+ while (--j) inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+ while (i--) outlet_new(&x->x_obj, gensym("signal"));
+
+ return (void *)x;
+}
+
+void blocknorm_tilde_setup(void)
+{
+ blocknorm_class = class_new(gensym("blocknorm~"), (t_newmethod)blocknorm_new,
+ (t_method)blocknorm_free, sizeof(t_blocknorm), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(blocknorm_class, t_blocknorm, x_f);
+ class_addmethod(blocknorm_class, (t_method)blocknorm_dsp, gensym("dsp"), 0);
+}
+
diff --git a/modules/cmath.c b/modules/cmath.c
new file mode 100644
index 0000000..3bd63a9
--- /dev/null
+++ b/modules/cmath.c
@@ -0,0 +1,176 @@
+/*
+ * cmath.c - some complex math dsp objects
+ * Copyright (c) 2000-2003 by Tom Schouten
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "m_pd.h"
+#include <math.h>
+
+#define MINNORM 0.0000000001
+
+typedef struct cmath
+{
+ t_object x_obj;
+ t_float x_f;
+ t_perfroutine x_perf;
+} t_cmath;
+
+
+static t_int *cmath_perform_clog(t_int *w)
+{
+ t_float *inx = (float *)(w[2]);
+ t_float *iny = (float *)(w[3]);
+ t_float *outx = (float *)(w[4]);
+ t_float *outy = (float *)(w[5]);
+ t_int i;
+ t_int n = (t_int)(w[1]);
+ t_float x;
+
+ while (n--){
+ float x = *inx++;
+ float y = *iny++;
+ float norm = sqrt(x*x + y*y);
+ float arg = atan2(y, x);
+ if (norm < MINNORM){
+ norm = MINNORM;
+ }
+ *outx++ = log(norm);
+ *outy++ = arg;
+ }
+
+ return (w+6);
+}
+
+
+static t_int *cmath_perform_cexp(t_int *w)
+{
+ t_float *inx = (float *)(w[2]);
+ t_float *iny = (float *)(w[3]);
+ t_float *outx = (float *)(w[4]);
+ t_float *outy = (float *)(w[5]);
+ t_int i;
+ t_int n = (t_int)(w[1]);
+ t_float x;
+
+ while (n--){
+ float x = *inx++;
+ float y = *iny++;
+ float norm = exp(x);
+ *outx++ = norm * cos(y);
+ *outy++ = norm * sin(y);
+ }
+
+ return (w+6);
+}
+
+static t_int *cmath_perform_nfft(t_int *w)
+{
+ t_float *inx = (float *)(w[2]);
+ t_float *iny = (float *)(w[3]);
+ t_float *outx = (float *)(w[4]);
+ t_float *outy = (float *)(w[5]);
+ t_int i;
+ t_int n = (t_int)(w[1]);
+ t_float x;
+ t_float scale = 1.0f / (sqrt((float)n));
+
+ mayer_fft(n, inx, outx);
+
+ while (n--){
+ float x = *inx++;
+ float y = *iny++;
+ *outx++ = scale * x;
+ *outy++ = scale * y;
+ }
+
+ return (w+6);
+}
+
+static t_int *cmath_perform_nifft(t_int *w)
+{
+ t_float *inx = (float *)(w[2]);
+ t_float *iny = (float *)(w[3]);
+ t_float *outx = (float *)(w[4]);
+ t_float *outy = (float *)(w[5]);
+ t_int i;
+ t_int n = (t_int)(w[1]);
+ t_float x;
+ t_float scale = 1.0f / (sqrt((float)n));
+
+ mayer_ifft(n, inx, outx);
+
+ while (n--){
+ float x = *inx++;
+ float y = *iny++;
+ *outx++ = scale * x;
+ *outy++ = scale * y;
+ }
+
+ return (w+6);
+}
+
+static void cmath_dsp(t_cmath *x, t_signal **sp)
+{
+ dsp_add(x->x_perf, 5, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec);
+
+}
+void cmath_free(void)
+{
+
+}
+
+t_class *cmath_class;
+
+t_cmath *cmath_new_common(void)
+{
+ t_cmath *x = (t_cmath *)pd_new(cmath_class);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ return x;
+}
+
+#define DEFNEWCMATH(name, perfmethod) \
+void * name (void) \
+{ \
+ t_cmath *x = cmath_new_common(); \
+ x->x_perf = perfmethod ; \
+ return (void*)x; \
+}
+
+DEFNEWCMATH(cmath_new_clog, cmath_perform_clog)
+DEFNEWCMATH(cmath_new_cexp, cmath_perform_cexp)
+DEFNEWCMATH(cmath_new_nfft, cmath_perform_nfft)
+DEFNEWCMATH(cmath_new_nifft, cmath_perform_nifft)
+
+
+void cmath_tilde_setup(void)
+{
+ //post("cmath~ v0.1");
+ cmath_class = class_new(gensym("clog~"), (t_newmethod)cmath_new_clog,
+ (t_method)cmath_free, sizeof(t_cmath), 0, 0);
+
+ class_addcreator((t_newmethod)cmath_new_cexp, gensym("cexp~"), A_NULL);
+ class_addcreator((t_newmethod)cmath_new_nfft, gensym("nfft~"), A_NULL);
+ class_addcreator((t_newmethod)cmath_new_nifft, gensym("nifft~"), A_NULL);
+
+ CLASS_MAINSIGNALIN(cmath_class, t_cmath, x_f);
+
+ class_addmethod(cmath_class, (t_method)cmath_dsp, gensym("dsp"), 0);
+}
+
diff --git a/modules/dynwav.c b/modules/dynwav.c
index 0ff75f3..9157f12 100644
--- a/modules/dynwav.c
+++ b/modules/dynwav.c
@@ -1,5 +1,5 @@
/*
- * dynwav.c - dynamic wavetable oscillator
+ * blosc.c - bandlimited oscillators
* data organization is in (real, imag) pairs
* the first 2 components are (DC, NY)
* Copyright (c) 2000-2003 by Tom Schouten
diff --git a/modules/ead.c b/modules/ead.c
index 4d301b8..88fc6ec 100644
--- a/modules/ead.c
+++ b/modules/ead.c
@@ -29,7 +29,7 @@ typedef struct eadctl
t_float c_attack;
t_float c_decay;
t_float c_state;
- t_float c_target;
+ t_int c_target;
} t_eadctl;
@@ -54,7 +54,13 @@ static void ead_decay(t_ead *x, t_floatarg f)
static void ead_start(t_ead *x)
{
- x->x_ctl.c_target = 1;
+ /* reset state if necessary to prevent skipping */
+
+ // always reset, seems to be safest
+ //if (x->x_ctl.c_target == 1)
+
+ x->x_ctl.c_state = 0.0f;
+ x->x_ctl.c_target = 1;
}
@@ -68,7 +74,6 @@ static t_int *ead_perform(t_int *w)
t_float attack = ctl->c_attack;
t_float decay = ctl->c_decay;
t_float state = ctl->c_state;
- t_float target = ctl->c_target;
t_int n = (t_int)(w[2]);
t_int i;
@@ -76,29 +81,27 @@ static t_int *ead_perform(t_int *w)
/* A/D code */
- if (target == 1)
- /* attack phase */
- {
- for (i = 0; i < n; i++)
- {
+ for (i = 0; i < n; i++){
+ switch(ctl->c_target){
+ case 1:
+ /* attack phase */
*out++ = state;
state += attack*(1 - state);
- }
- if (state > ENVELOPE_MAX)
- ctl->c_target = 0;
- }
-
- else
- /* decay phase */
- for (i = 0; i < n; i++)
- {
- *out++ = state;
- state -= decay*state;
+ ctl->c_target = (state <= ENVELOPE_MAX);
+ break;
+ default:
+ /* decay phase */
+ *out++ = state;
+ state -= decay*state;
+ break;
}
+
+ }
+ /* save state */
ctl->c_state = IS_DENORMAL(state) ? 0 : state;
- return (w+4); /* pd quirk: pointer for sequencer */
+ return (w+4);
}
diff --git a/modules/eadsr.c b/modules/eadsr.c
index bba96cd..332ddf4 100644
--- a/modules/eadsr.c
+++ b/modules/eadsr.c
@@ -63,6 +63,7 @@ void eadsr_release(t_eadsr *x, t_floatarg f)
void eadsr_start(t_eadsr *x)
{
x->x_ctl.c_target = 1;
+ x->x_ctl.c_state = 0.0f;
}
@@ -72,6 +73,12 @@ void eadsr_stop(t_eadsr *x)
}
+void eadsr_float(t_eadsr *x, t_floatarg f)
+{
+ if (f == 0.0f) eadsr_stop(x);
+ else eadsr_start(x);
+}
+
static t_int *eadsr_perform(t_int *w)
{
t_float *out = (float *)(w[3]);
@@ -87,35 +94,28 @@ static t_int *eadsr_perform(t_int *w)
t_int i;
- if (target == 1)
- /* attack phase */
- {
- for (i = 0; i < n; i++)
- {
+ for (i = 0; i < n; i++){
+ if (target == 1.0f){
+ /* attack */
*out++ = state;
state += attack*(1 - state);
- }
- if (state > ENVELOPE_MAX)
- ctl->c_target = sustain;
- }
-
- else if (target == 0)
- /* release phase */
- for (i = 0; i < n; i++)
- {
- *out++ = state;
- state -= release*state;
+ target = (state > ENVELOPE_MAX) ? sustain : 1.0f;
}
-
- else
- /* decay phase */
- for (i = 0; i < n; i++)
- {
- *out++ = state;
- state -= decay*(state-sustain);
+ else if (target == 0.0f){
+ /* release */
+ *out++ = state;
+ state -= release*state;
+ }
+ else{
+ /* decay */
+ *out++ = state;
+ state -= decay*(state-sustain);
}
+ }
+ /* save state */
ctl->c_state = IS_DENORMAL(state) ? 0 : state;
+ ctl->c_target = target;
return (w+4);
}
@@ -157,6 +157,7 @@ void eadsr_tilde_setup(void)
//post("eadsr~ v0.1");
eadsr_class = class_new(gensym("eadsr~"), (t_newmethod)eadsr_new,
(t_method)eadsr_free, sizeof(t_eadsr), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(eadsr_class, (t_method)eadsr_float, gensym("float"), A_FLOAT, 0);
class_addmethod(eadsr_class, (t_method)eadsr_start, gensym("start"), 0);
class_addmethod(eadsr_class, (t_method)eadsr_start, gensym("bang"), 0);
class_addmethod(eadsr_class, (t_method)eadsr_stop, gensym("stop"), 0);
diff --git a/modules/ear.c b/modules/ear.c
index d842065..28fe097 100644
--- a/modules/ear.c
+++ b/modules/ear.c
@@ -47,6 +47,7 @@ void ear_release(t_ear *x, t_floatarg f)
void ear_start(t_ear *x)
{
x->x_ctl.c_target = 1;
+ x->x_ctl.c_state = 0.0f;
}
@@ -56,6 +57,12 @@ void ear_stop(t_ear *x)
}
+void ear_float(t_ear *x, t_floatarg f)
+{
+ if (f == 0.0f) ear_stop(x);
+ else ear_start(x);
+}
+
static t_int *ear_perform(t_int *w)
{
t_float *out = (float *)(w[3]);
@@ -120,6 +127,7 @@ void ear_tilde_setup(void)
//post("ear~ v0.1");
ear_class = class_new(gensym("ear~"), (t_newmethod)ear_new,
(t_method)ear_free, sizeof(t_ear), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(ear_class, (t_method)ear_float, gensym("float"), A_FLOAT, 0);
class_addmethod(ear_class, (t_method)ear_start, gensym("start"), 0);
class_addmethod(ear_class, (t_method)ear_start, gensym("bang"), 0);
class_addmethod(ear_class, (t_method)ear_stop, gensym("stop"), 0);
diff --git a/modules/eblosc.c b/modules/eblosc.c
new file mode 100644
index 0000000..df1b059
--- /dev/null
+++ b/modules/eblosc.c
@@ -0,0 +1,599 @@
+/*
+ * eblosc.c - bandlimited oscillators with infinite support discontinuities
+ * using minimum phase impulse, step & ramp
+ * Copyright (c) 2000-2003 by Tom Schouten
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "m_pd.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "filters.h"
+
+
+typedef unsigned long long u64;
+typedef unsigned long u32;
+
+
+
+#define LPHASOR (8*sizeof(u32)) // the phasor logsize
+#define VOICES 8 // the number of oscillators
+#define CUTOFF 0.8f // fraction of nyquist for impulse cutoff
+
+
+
+typedef struct ebloscctl
+{
+ t_float c_pole[VOICES*2]; // complex poles
+ t_float c_gain[VOICES*2]; // complex gains (waveform specific constants)
+ t_float c_state[VOICES*2]; // complex state
+
+ u32 c_phase; // phase of main oscillator
+ u32 c_phase2; // phase of secondairy oscillator
+ t_float c_prev_amp; // previous input of comparator
+ t_float c_phase_inc_scale;
+ t_float c_scale;
+ t_float c_scale_update;
+ t_symbol *c_waveform;
+
+} t_ebloscctl;
+
+typedef struct eblosc
+{
+ t_object x_obj;
+ t_float x_f;
+ t_ebloscctl x_ctl;
+} t_eblosc;
+
+
+/* phase converters */
+static inline float _phase_to_float(u32 p){return ((float)p) * (1.0f / 4294967296.0f);}
+static inline u32 _float_to_phase(float f){return (u32)(f * 4294967296.0f);}
+
+
+
+/* get one sample from the oscillator bank and perform time tick */
+static inline t_float _osc_tick(t_ebloscctl *ctl)
+{
+ float sum = 0.0f;
+ int i;
+ /* sum all voices */
+ for (i=0; i<VOICES*2; i+=2){
+ /* rotate state */
+ vcmul2(ctl->c_state+i, ctl->c_pole+i);
+
+ /* get real part and add to output */
+ sum += ctl->c_state[0];
+ }
+
+ return sum;
+}
+
+/* add shifted impulse */
+static inline void _add_impulse(t_ebloscctl *ctl, t_float t0)
+{
+ int i;
+ for (i=0; i<VOICES*2; i+=2){
+ /* contribution is a_i z_i^t_0 */
+
+ float real = 1.0f;
+ float imag = 0.0f;
+
+ ctl->c_state[0] += real;
+ ctl->c_state[1] += imag;
+ }
+}
+
+
+/* add step */
+static inline void _add_step(t_ebloscctl *ctl)
+{
+ int i;
+ for (i=0; i<VOICES*2; i+=2){
+ /* contribution is a_i (1 - z_i) */
+
+ float real = 1.0f;
+ float imag = 0.0f;
+
+ ctl->c_state[0] += real;
+ ctl->c_state[1] += imag;
+ }
+}
+
+
+/* add shifted step */
+static inline void _add_shifted_step(t_ebloscctl *ctl, t_float t0)
+{
+ int i;
+ for (i=0; i<VOICES*2; i+=2){
+ /* contribution is a_i (1 - z_i^t_0) */
+
+ float real = 1.0f;
+ float imag = 0.0f;
+
+ ctl->c_state[0] += real;
+ ctl->c_state[1] += imag;
+ }
+}
+
+
+#if 0
+/* update waveplayers on zero cross */
+static void _bang_comparator(t_ebloscctl *ctl, float prev, float curr)
+{
+
+ /* check for sign change */
+ if ((prev * curr) < 0.0f){
+
+ int voice;
+
+ /* determine the location of the discontinuity (in oversampled coordiates
+ using linear interpolation */
+
+ float f = (float)S * curr / (curr - prev);
+
+ /* get the offset in the oversample table */
+
+ u32 table_index = (u32)f;
+
+ /* determine the fractional part (in oversampled coordinates)
+ for linear interpolation */
+
+ float table_frac_index = f - (float)table_index;
+
+ /* set state (+ or -) */
+
+ ctl->c_state = (curr > 0.0f) ? 0.5f : -0.5f;
+
+ /* steal the oldest voice */
+
+ voice = ctl->c_next_voice++;
+ ctl->c_next_voice &= VOICES-1;
+
+ /* initialize the new voice index and interpolation fraction */
+
+ ctl->c_index[voice] = table_index;
+ ctl->c_frac[voice] = table_frac_index;
+ ctl->c_vscale[voice] = -ctl->c_scale * 2.0f * ctl->c_state;
+
+ }
+
+}
+
+/* advance phasor and update waveplayers on phase wrap */
+static void _bang_phasor(t_ebloscctl *ctl, float freq)
+{
+ u32 phase = ctl->c_phase;
+ u32 phase_inc;
+ u32 oldphase;
+ int voice;
+ float scale = ctl->c_scale;
+
+ /* get increment */
+ float inc = freq * ctl->c_phase_inc_scale;
+
+ /* calculate new phase
+ the increment (and the phase) should be a multiple of S */
+ if (inc < 0.0f) inc = -inc;
+ phase_inc = ((u32)inc) & ~(S-1);
+ oldphase = phase;
+ phase += phase_inc;
+
+
+ /* check for phase wrap */
+ if (phase < oldphase){
+ u32 phase_inc_decimated = phase_inc >> LOVERSAMPLE;
+ u32 table_index;
+ u32 table_phase;
+
+ /* steal the oldest voice if we have a phase wrap */
+
+ voice = ctl->c_next_voice++;
+ ctl->c_next_voice &= VOICES-1;
+
+ /* determine the location of the discontinuity (in oversampled coordinates)
+ which is S * (new phase) / (increment) */
+
+ table_index = phase / phase_inc_decimated;
+
+ /* determine the fractional part (in oversampled coordinates)
+ for linear interpolation */
+
+ table_phase = phase - (table_index * phase_inc_decimated);
+
+ /* use it to initialize the new voice index and interpolation fraction */
+
+ ctl->c_index[voice] = table_index;
+ ctl->c_frac[voice] = (float)table_phase / (float)phase_inc_decimated;
+ ctl->c_vscale[voice] = scale;
+ scale = scale * ctl->c_scale_update;
+
+ }
+
+ /* save state */
+ ctl->c_phase = phase;
+ ctl->c_scale = scale;
+}
+
+
+/* the 2 oscillator version:
+ the second osc can reset the first osc's phase (hence it determines the pitch)
+ the first osc determines the waveform */
+
+static void _bang_hardsync_phasor(t_ebloscctl *ctl, float freq, float freq2)
+{
+ u32 phase = ctl->c_phase;
+ u32 phase2 = ctl->c_phase2;
+ u32 phase_inc;
+ u32 phase_inc2;
+ u32 oldphase;
+ u32 oldphase2;
+ int voice;
+ float scale = ctl->c_scale;
+
+
+ /* get increment */
+ float inc = freq * ctl->c_phase_inc_scale;
+ float inc2 = freq2 * ctl->c_phase_inc_scale;
+
+ /* calculate new phases
+ the increment (and the phase) should be a multiple of S */
+
+ /* save previous phases */
+ oldphase = phase;
+ oldphase2 = phase2;
+
+ /* update second osc */
+ if (inc2 < 0.0f) inc2 = -inc2;
+ phase_inc2 = ((u32)inc2) & ~(S-1);
+ phase2 += phase_inc2;
+
+ /* update first osc (freq should be >= freq of sync osc */
+ if (inc < 0.0f) inc = -inc;
+ phase_inc = ((u32)inc) & ~(S-1);
+ if (phase_inc < phase_inc2) phase_inc = phase_inc2;
+ phase += phase_inc;
+
+
+ /* check for sync discontinuity (osc 2) */
+ if (phase2 < oldphase2) {
+
+ /* adjust phase depending on the location of the discontinuity in phase2:
+ phase/phase_inc == phase2/phase_inc2 */
+
+ u64 pi = phase_inc >> LOVERSAMPLE;
+ u64 pi2 = phase_inc2 >> LOVERSAMPLE;
+ u64 lphase = ((u64)phase2 * pi) / pi2;
+ phase = lphase & ~(S-1);
+ }
+
+
+ /* check for phase discontinuity (osc 1) */
+ if (phase < oldphase){
+ u32 phase_inc_decimated = phase_inc >> LOVERSAMPLE;
+ u32 table_index;
+ u32 table_phase;
+ float stepsize;
+
+ /* steal the oldest voice if we have a phase wrap */
+
+ voice = ctl->c_next_voice++;
+ ctl->c_next_voice &= VOICES-1;
+
+ /* determine the location of the discontinuity (in oversampled coordinates)
+ which is S * (new phase) / (increment) */
+
+ table_index = phase / phase_inc_decimated;
+
+ /* determine the fractional part (in oversampled coordinates)
+ for linear interpolation */
+
+ table_phase = phase - (table_index * phase_inc_decimated);
+
+ /* determine the step size
+ as opposed to saw/impulse waveforms, the step is not always equal to one. it is:
+ oldphase - phase + phase_inc
+ but for the unit step this will overflow to zero, so we
+ reduce the bit depth to prevent overflow */
+
+ stepsize = _phase_to_float(((oldphase-phase) >> LOVERSAMPLE)
+ + phase_inc_decimated) * (float)S;
+
+ /* use it to initialize the new voice index and interpolation fraction */
+
+ ctl->c_index[voice] = table_index;
+ ctl->c_frac[voice] = (float)table_phase / (float)phase_inc_decimated;
+ ctl->c_vscale[voice] = scale * stepsize;
+ scale = scale * ctl->c_scale_update;
+
+ }
+
+ /* save state */
+ ctl->c_phase = phase;
+ ctl->c_phase2 = phase2;
+ ctl->c_scale = scale;
+}
+
+
+static t_int *eblosc_perform_hardsync_saw(t_int *w)
+{
+ t_float *freq = (float *)(w[3]);
+ t_float *freq2 = (float *)(w[4]);
+ t_float *out = (float *)(w[5]);
+ t_ebloscctl *ctl = (t_ebloscctl *)(w[1]);
+ t_int n = (t_int)(w[2]);
+ t_int i;
+
+ /* set postfilter cutoff */
+ ctl->c_butter->setButterHP(0.85f * (*freq / sys_getsr()));
+
+ while (n--) {
+ float frequency = *freq++;
+ float frequency2 = *freq2++;
+
+ /* get the bandlimited discontinuity */
+ float sample = _get_bandlimited_discontinuity(ctl, bls);
+
+ /* add aliased sawtooth wave */
+ sample += _phase_to_float(ctl->c_phase) - 0.5f;
+
+ /* highpass filter output to remove DC offset and low frequency aliasing */
+ ctl->c_butter->BangSmooth(sample, sample, 0.05f);
+
+ /* send to output */
+ *out++ = sample;
+
+ /* advance phasor */
+ _bang_hardsync_phasor(ctl, frequency2, frequency);
+
+ }
+
+ return (w+6);
+}
+
+static t_int *eblosc_perform_saw(t_int *w)
+{
+ t_float *freq = (float *)(w[3]);
+ t_float *out = (float *)(w[4]);
+ t_ebloscctl *ctl = (t_ebloscctl *)(w[1]);
+ t_int n = (t_int)(w[2]);
+ t_int i;
+
+ while (n--) {
+ float frequency = *freq++;
+
+ /* get the bandlimited discontinuity */
+ float sample = _get_bandlimited_discontinuity(ctl, bls);
+
+ /* add aliased sawtooth wave */
+ sample += _phase_to_float(ctl->c_phase) - 0.5f;
+
+ /* send to output */
+ *out++ = sample;
+
+ /* advance phasor */
+ _bang_phasor(ctl, frequency);
+
+ }
+
+ return (w+5);
+}
+
+
+
+static t_int *eblosc_perform_pulse(t_int *w)
+{
+ t_float *freq = (float *)(w[3]);
+ t_float *out = (float *)(w[4]);
+ t_ebloscctl *ctl = (t_ebloscctl *)(w[1]);
+ t_int n = (t_int)(w[2]);
+ t_int i;
+
+
+ /* set postfilter cutoff */
+ ctl->c_butter->setButterHP(0.85f * (*freq / sys_getsr()));
+
+ while (n--) {
+ float frequency = *freq++;
+
+ /* get the bandlimited discontinuity */
+ float sample = _get_bandlimited_discontinuity(ctl, bli);
+
+ /* highpass filter output to remove DC offset and low frequency aliasing */
+ ctl->c_butter->BangSmooth(sample, sample, 0.05f);
+
+ /* send to output */
+ *out++ = sample;
+
+ /* advance phasor */
+ _bang_phasor(ctl, frequency);
+
+ }
+
+ return (w+5);
+}
+
+static t_int *eblosc_perform_comparator(t_int *w)
+{
+ t_float *amp = (float *)(w[3]);
+ t_float *out = (float *)(w[4]);
+ t_ebloscctl *ctl = (t_ebloscctl *)(w[1]);
+ t_int n = (t_int)(w[2]);
+ t_int i;
+ t_float prev_amp = ctl->c_prev_amp;
+
+ while (n--) {
+ float curr_amp = *amp++;
+
+ /* exact zero won't work for zero detection (sic) */
+ if (curr_amp == 0.0f) curr_amp = 0.0000001f;
+
+ /* get the bandlimited discontinuity */
+ float sample = _get_bandlimited_discontinuity(ctl, bls);
+
+ /* add the block wave state */
+ sample += ctl->c_state;
+
+ /* send to output */
+ *out++ = sample;
+
+ /* advance phasor */
+ _bang_comparator(ctl, prev_amp, curr_amp);
+
+ prev_amp = curr_amp;
+
+ }
+
+ ctl->c_prev_amp = prev_amp;
+
+ return (w+5);
+}
+
+static void eblosc_phase(t_eblosc *x, t_float f)
+{
+ x->x_ctl.c_phase = _float_to_phase(f);
+ x->x_ctl.c_phase2 = _float_to_phase(f);
+}
+
+static void eblosc_phase1(t_eblosc *x, t_float f)
+{
+ x->x_ctl.c_phase = _float_to_phase(f);
+}
+
+static void eblosc_phase2(t_eblosc *x, t_float f)
+{
+ x->x_ctl.c_phase2 = _float_to_phase(f);
+}
+
+static void eblosc_dsp(t_eblosc *x, t_signal **sp)
+{
+ int n = sp[0]->s_n;
+
+ /* set sampling rate scaling for phasors */
+ x->x_ctl.c_phase_inc_scale = 4.0f * (float)(1<<(LPHASOR-2)) / sys_getsr();
+
+
+ /* setup & register the correct process routine depending on the waveform */
+
+ /* 2 osc */
+ if (x->x_ctl.c_waveform == gensym("syncsaw")){
+ x->x_ctl.c_scale = 1.0f;
+ x->x_ctl.c_scale_update = 1.0f;
+ dsp_add(eblosc_perform_hardsync_saw, 5, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec);
+ }
+
+ /* 1 osc */
+ else if (x->x_ctl.c_waveform == gensym("pulse")){
+ x->x_ctl.c_scale = 1.0f;
+ x->x_ctl.c_scale_update = 1.0f;
+ dsp_add(eblosc_perform_pulse, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec);
+ }
+ else if (x->x_ctl.c_waveform == gensym("pulse2")){
+ x->x_ctl.c_phase_inc_scale *= 2;
+ x->x_ctl.c_scale = 1.0f;
+ x->x_ctl.c_scale_update = -1.0f;
+ dsp_add(eblosc_perform_pulse, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec);
+ }
+ else if (x->x_ctl.c_waveform == gensym("comparator")){
+ x->x_ctl.c_scale = 1.0f;
+ x->x_ctl.c_scale_update = 1.0f;
+ dsp_add(eblosc_perform_comparator, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec);
+ }
+ else{
+ x->x_ctl.c_scale = 1.0f;
+ x->x_ctl.c_scale_update = 1.0f;
+ dsp_add(eblosc_perform_saw, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec);
+ }
+
+
+
+}
+static void eblosc_free(t_eblosc *x)
+{
+ delete x->x_ctl.c_butter;
+}
+
+t_class *eblosc_class;
+
+static void *eblosc_new(t_symbol *s)
+{
+ t_eblosc *x = (t_eblosc *)pd_new(eblosc_class);
+ int i;
+
+ /* out 1 */
+ outlet_new(&x->x_obj, gensym("signal"));
+
+ /* optional signal inlets */
+ if (s == gensym("syncsaw")){
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+ }
+
+ /* optional phase inlet */
+ if (s != gensym("comparator")){
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("phase"));
+ }
+
+ /* create the postfilter */
+ x->x_ctl.c_butter = new DSPIfilterSeries(3);
+
+ /* init oscillators */
+ for (i=0; i<VOICES; i++) {
+ x->x_ctl.c_index[i] = N-2;
+ x->x_ctl.c_frac[i] = 0.0f;
+ }
+
+ /* init rest of state data */
+ eblosc_phase(x, 0);
+ eblosc_phase2(x, 0);
+ x->x_ctl.c_state = 0.0;
+ x->x_ctl.c_prev_amp = 0.0;
+ x->x_ctl.c_next_voice = 0;
+ x->x_ctl.c_scale = 1.0f;
+ x->x_ctl.c_scale_update = 1.0f;
+ x->x_ctl.c_waveform = s;
+
+ return (void *)x;
+}
+
+
+
+
+
+extern "C"
+{
+ void eblosc_tilde_setup(void)
+ {
+ //post("eblosc~ v0.1");
+
+ build_tables();
+
+ eblosc_class = class_new(gensym("eblosc~"), (t_newmethod)eblosc_new,
+ (t_method)eblosc_free, sizeof(t_eblosc), 0, A_DEFSYMBOL, A_NULL);
+ CLASS_MAINSIGNALIN(eblosc_class, t_eblosc, x_f);
+ class_addmethod(eblosc_class, (t_method)eblosc_dsp, gensym("dsp"), A_NULL);
+ class_addmethod(eblosc_class, (t_method)eblosc_phase, gensym("phase"), A_FLOAT, A_NULL);
+ class_addmethod(eblosc_class, (t_method)eblosc_phase2, gensym("phase2"), A_FLOAT, A_NULL);
+
+
+ }
+
+}
+
+#endif
diff --git a/modules/fdn.c b/modules/fdn.c
index 22fcc40..9fbfee7 100644
--- a/modules/fdn.c
+++ b/modules/fdn.c
@@ -311,11 +311,11 @@ static void fdn_updatedamping(t_fdn *x)
}
static void fdn_timelow(t_fdn *x, t_float f){
- x->x_ctl.c_timelow = f;
+ x->x_ctl.c_timelow = fabs(f);
fdn_updatedamping(x);
}
static void fdn_timehigh(t_fdn *x, t_float f){
- x->x_ctl.c_timehigh = f;
+ x->x_ctl.c_timehigh = fabs(f);
fdn_updatedamping(x);
}
diff --git a/modules/lattice.c b/modules/lattice.c
index 9403393..6f8e816 100644
--- a/modules/lattice.c
+++ b/modules/lattice.c
@@ -22,7 +22,8 @@
#include "m_pd.h"
#include <math.h>
-#define maxorder 1024
+#define MAXORDER 1024
+#define MAXREFCO 0.9999f
typedef struct latticesegment
{
@@ -32,7 +33,7 @@ typedef struct latticesegment
typedef struct latticectl
{
- t_latticesegment c_segment[maxorder]; // array of lattice segment data
+ t_latticesegment c_segment[MAXORDER]; // array of lattice segment data
t_int c_segments;
} t_latticectl;
@@ -98,8 +99,8 @@ static void lattice_rc(t_lattice *x, t_float segment, t_float refco)
{
t_int seg = (t_float)segment;
if ((seg >= 0) && (seg < x->x_ctl.c_segments)){
- if (refco > 1.0f) refco = 1.0f;
- if (refco < -1.0f) refco = -1.0f;
+ if (refco >= MAXREFCO) refco = MAXREFCO;
+ if (refco <= -MAXREFCO) refco = -MAXREFCO;
x->x_ctl.c_segment[seg].rc = refco;
}
}
@@ -120,7 +121,7 @@ static void *lattice_new(t_floatarg segments)
outlet_new(&x->x_obj, gensym("signal"));
if (seg < 1) seg = 1;
- if (seg > maxorder) seg = maxorder;
+ if (seg > MAXORDER) seg = MAXORDER;
x->x_ctl.c_segments = seg;
diff --git a/modules/matrix.c b/modules/matrix.c
index 6fd55b7..b59d4d6 100644
--- a/modules/matrix.c
+++ b/modules/matrix.c
@@ -140,10 +140,10 @@ static void *matrix_new(t_floatarg order)
return (void *)x;
}
-void matrix_tilde_setup(void)
+void bmatrix_tilde_setup(void)
{
//post("matrix~ v0.1");
- matrix_class = class_new(gensym("matrix~"), (t_newmethod)matrix_new,
+ matrix_class = class_new(gensym("bmatrix~"), (t_newmethod)matrix_new,
(t_method)matrix_free, sizeof(t_matrix), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(matrix_class, t_matrix, x_f);
class_addmethod(matrix_class, (t_method)matrix_dsp, gensym("dsp"), 0);
diff --git a/modules/permut.c b/modules/permut.c
index bc143d2..7738f84 100644
--- a/modules/permut.c
+++ b/modules/permut.c
@@ -20,9 +20,10 @@
*/
-#include "m_pd.h"
#include <math.h>
#include <stdlib.h>
+//#include "m_pd.h"
+#include "extlib_util.h"
@@ -64,7 +65,8 @@ static void permut_random(t_permut *x, t_floatarg seed)
int *p = x->x_ctl.c_permutationtable;
int r, last = 0;
- srand(* ((unsigned int *)(&seed)));
+ //srand(* ((unsigned int *)(&seed)));
+ srand (((t_flint)seed).i);
if(p)
{
@@ -91,7 +93,8 @@ static void permut_random(t_permut *x, t_floatarg seed)
static void permut_bang(t_permut *x)
{
unsigned int r = rand();
- permut_random(x, *((float *)(&r)));
+ //permut_random(x, *((float *)(&r)));
+ permut_random(x, ((t_flint)r).f);
}
static void permut_resize_table(t_permut *x, int size)
diff --git a/modules/ramp.c b/modules/ramp.c
index ad13582..526ec4e 100644
--- a/modules/ramp.c
+++ b/modules/ramp.c
@@ -24,64 +24,53 @@
typedef struct rampctl
{
- t_float c_offset;
- t_float c_looppoint;
+ t_float c_offset;
+ t_int c_blockscale;
} t_rampctl;
typedef struct ramp
{
- t_object x_obj;
- t_float x_f;
- t_rampctl x_ctl;
+ t_object x_obj;
+ t_float x_f;
+ t_rampctl x_ctl;
} t_ramp;
void ramp_offset(t_ramp *x, t_floatarg f)
{
-
- x->x_ctl.c_offset = f;
-
-}
-
-void ramp_looppoint(t_ramp *x, t_floatarg f)
-{
-
- x->x_ctl.c_looppoint = f;
-
+ x->x_ctl.c_offset = f;
}
void ramp_bang(t_ramp *x)
{
- ramp_offset(x, 0);
-
+ ramp_offset(x, 0);
}
static t_int *ramp_perform(t_int *w)
{
+ t_float *out = (float *)(w[3]);
+ t_rampctl *ctl = (t_rampctl *)(w[1]);
+ t_int i;
+ t_int n = (t_int)(w[2]);
+ t_float x;
-
- t_float *out = (float *)(w[3]);
- t_rampctl *ctl = (t_rampctl *)(w[1]);
- t_int i;
- t_int n = (t_int)(w[2]);
- t_float x;
-
+ t_float scale = ctl->c_blockscale ? 1.0f / (float)n : 1.0f;
- x = ctl->c_offset;
-
- for (i = 0; i < n; i++)
- {
- *out++ = (float)x++;
- }
+ x = ctl->c_offset;
+
+ for (i = 0; i < n; i++)
+ {
+ *out++ = ((float)x++) * scale;
+ }
- ctl->c_offset = x; /* save state */
+ ctl->c_offset = x; /* save state */
- return (w+4);
+ return (w+4);
}
static void ramp_dsp(t_ramp *x, t_signal **sp)
@@ -99,18 +88,27 @@ t_class *ramp_class;
void *ramp_new(void)
{
t_ramp *x = (t_ramp *)pd_new(ramp_class);
- /* inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("looppoint"));*/
outlet_new(&x->x_obj, gensym("signal"));
-
+ x->x_ctl.c_blockscale = 0;
ramp_bang(x);
return (void *)x;
}
+void *blockramp_new(void)
+{
+ t_ramp *x = (t_ramp *)ramp_new();
+ x->x_ctl.c_blockscale = 1;
+ return (void *)x;
+}
+
void ramp_tilde_setup(void)
{
//post("ramp~ v0.1");
ramp_class = class_new(gensym("ramp~"), (t_newmethod)ramp_new,
(t_method)ramp_free, sizeof(t_ramp), 0, 0);
+
+ class_addcreator((t_newmethod)blockramp_new, gensym("blockramp~"), A_NULL);
+
class_addmethod(ramp_class, (t_method)ramp_bang, gensym("bang"), 0);
class_addmethod(ramp_class, (t_method)ramp_dsp, gensym("dsp"), 0);
class_addfloat(ramp_class, (t_method)ramp_offset);
diff --git a/modules/resofilt.c b/modules/resofilt.c
new file mode 100644
index 0000000..ba74532
--- /dev/null
+++ b/modules/resofilt.c
@@ -0,0 +1,397 @@
+/*
+ * resofilt.c - some high quality time variant filters
+ * Copyright (c) 2000-2003 by Tom Schouten
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/* some (expensive) time variant iir filters,
+ i.e. moog 4-pole transfer function using the impulse
+ invariant transform with self osc and
+ signal freq and reso inputs */
+
+
+#include "m_pd.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "filters.h"
+
+
+typedef struct resofiltctl
+{
+ t_float c_state[4]; /* filter state */
+ t_float c_f_prev;
+ t_float c_r_prev;
+
+} t_resofiltctl;
+
+typedef struct resofilt
+{
+ t_object x_obj;
+ t_float x_f;
+ t_resofiltctl x_ctl;
+ t_perfroutine x_dsp;
+} t_resofilt;
+
+
+static inline void _sat_state(t_float *x)
+{
+ const float norm_squared_max = 1.0f;
+ float norm_squared = x[0] * x[0] + x[1] * x[1];
+
+ if (norm_squared > norm_squared_max){
+ float scale = 1.0f / sqrt(norm_squared);
+ x[0] *= scale;
+ x[1] *= scale;
+ }
+}
+
+
+/* the moog vcf discretized with an impulse invariant transform */
+
+static t_int *resofilt_perform_fourpole(t_int *w)
+{
+
+ t_resofiltctl *ctl = (t_resofiltctl *)(w[1]);
+ t_int n = (t_int)(w[2]);
+ t_float *in = (float *)(w[3]);
+ t_float *freq = (float *)(w[4]);
+ t_float *reso = (float *)(w[5]);
+ t_float *out = (float *)(w[6]);
+
+ int i;
+ t_float inv_n = 1.0f / ((float)n);
+ t_float inv_sr = 1.0f / sys_getsr();
+
+ t_float phasor[2], phasor_rot[2];
+ t_float radior[2], radior_rot[2];
+ t_float scalor, scalor_inc;
+
+ t_float f,r,freq_rms,reso_rms;
+ t_float f_prev = ctl->c_f_prev;
+ t_float r_prev = ctl->c_r_prev;
+
+ /* use rms of input to drive freq and reso
+ this is such that connecting a dsp signal to the inlets has a reasonable result,
+ even if the inputs are oscillatory. the rms values will be interpolated linearly
+ (that is, linearly in the "analog" domain, so exponentially in the z-domain) */
+
+ reso_rms = freq_rms = 0.0f;
+ for (i=0; i<n; i++){
+ t_float _freq = *freq++; /* first input is the reso frequency (absolute) */
+ t_float _reso = *reso++; /* second input is the resonnance (0->1), >1 == self osc */
+ freq_rms += _freq * _freq;
+ reso_rms += _reso * _reso;
+ }
+ freq_rms = sqrt(freq_rms * inv_n) * inv_sr;
+ reso_rms = sqrt(reso_rms * inv_n);
+ f = (freq_rms > 0.5f) ? 0.5f : freq_rms;
+ r = sqrt(sqrt(reso_rms));
+
+
+ /* calculate the new pole locations
+ we use an impulse invariant transform: the moog vcf poles are located at
+ s_p = (-1 +- r \sqrt{+- j}, with r = (k/4)^(1/4) \in [0,1]
+
+ the poles are always complex, so we can use an orthogonal implementation
+ both conj pole pairs have the same angle, so we can use one phasor and 2 radii
+ */
+
+ /* compute phasor, radius and update eqs
+ since these are at k-rate, the expense is justifyable */
+ phasor[0] = cos(2.0 * M_PI * r_prev * f_prev);
+ phasor[1] = sin(2.0 * M_PI * r_prev * f_prev);
+ phasor_rot[0] = cos(2.0 * M_PI * (r*f - r_prev*f_prev) * inv_n);
+ phasor_rot[1] = sin(2.0 * M_PI * (r*f - r_prev*f_prev) * inv_n);
+
+ radior[0] = exp(f_prev * (-1.0 + r_prev)); /* dominant radius */
+ radior[1] = exp(f_prev * (-1.0 - r_prev));
+ radior_rot[0] = exp((f*(-1.0f + r) - f_prev * (-1.0 + r_prev)) * inv_n);
+ radior_rot[1] = exp((f*(-1.0f - r) - f_prev * (-1.0 - r_prev)) * inv_n);
+
+ /* moog like scaling */
+ if (1){
+ float r2 = r_prev * r_prev;
+ float r4 = r2 * r2;
+ scalor = 1.0f + (1.0f + 4.0f * r4);
+ r2 = r * r;
+ r4 = r2 * r2;
+ scalor_inc = ((1.0f + (1.0f + 4.0f * r4)) - scalor) * inv_n;
+ }
+
+ /* no scaling */
+ else{
+ scalor = 1.0f;
+ scalor_inc = 0.0f;
+ }
+
+ ctl->c_f_prev = f;
+ ctl->c_r_prev = r;
+
+
+
+
+
+ /* perform filtering */
+ for (i=0; i<n; i++){
+ float poleA[2], poleB[2];
+ float *stateA = ctl->c_state;
+ float *stateB = ctl->c_state+2;
+
+ float x;
+
+ /* compute poles */
+ poleA[0] = radior[0] * phasor[0];
+ poleA[1] = radior[0] * phasor[1];
+ poleB[0] = radior[1] * phasor[0];
+ poleB[1] = radior[1] * phasor[1];
+
+
+ /* perform filtering: use 2 DC normalized complex one-poles:
+ y[k] = x[k] + a(y[k-1] - x[k]) or y(z) = (1-a)/(1-az^{-1}) x(z) */
+
+ x = *in++ * scalor;
+
+ /* nondominant pole first */
+ stateB[0] -= x;
+ vcmul2(stateB, poleB);
+ x = stateB[0] += x;
+
+ /* dominant pole second */
+ stateA[0] -= x;
+ vcmul2(stateA, poleA);
+ x = stateA[0] += x;
+
+ *out++ = x;
+
+ /* saturate (normalize if pow > 1) state to prevent explosion and to allow self-osc */
+ _sat_state(stateA);
+ _sat_state(stateB);
+
+ /* interpolate filter coefficients */
+ vcmul2(phasor, phasor_rot);
+ radior[0] *= radior_rot[0];
+ radior[1] *= radior_rot[1];
+ scalor += scalor_inc;
+
+ }
+
+ return (w+7);
+}
+
+
+
+
+
+/* 303-style modified moog vcf (3-pole) */
+
+static t_int *resofilt_perform_threepole(t_int *w)
+{
+
+ t_resofiltctl *ctl = (t_resofiltctl *)(w[1]);
+ t_int n = (t_int)(w[2]);
+ t_float *in = (float *)(w[3]);
+ t_float *freq = (float *)(w[4]);
+ t_float *reso = (float *)(w[5]);
+ t_float *out = (float *)(w[6]);
+
+ int i;
+ t_float inv_n = 1.0f / ((float)n);
+ t_float inv_sr = 1.0f / sys_getsr();
+
+ t_float phasor[2], phasor_rot[2];
+ t_float radior[2], radior_rot[2];
+ t_float scalor, scalor_inc;
+
+ t_float f,r,freq_rms,reso_rms;
+ t_float f_prev = ctl->c_f_prev;
+ t_float r_prev = ctl->c_r_prev;
+
+ t_float sqrt5 = sqrtf(5.0f);
+
+ /* use rms of input to drive freq and reso */
+ reso_rms = freq_rms = 0.0f;
+ for (i=0; i<n; i++){
+ t_float _freq = *freq++; /* first input is the reso frequency (absolute) */
+ t_float _reso = *reso++; /* second input is the resonnance (0->1), >1 == self osc */
+ freq_rms += _freq * _freq;
+ reso_rms += _reso * _reso;
+ }
+ freq_rms = sqrt(freq_rms * inv_n) * inv_sr;
+ reso_rms = sqrt(reso_rms * inv_n);
+ f = (freq_rms > 0.5f) ? 0.25f : freq_rms * 0.5f;
+ r = cbrt(reso_rms);
+
+
+ /* calculate the new pole locations
+ we use an impulse invariant transform: the 303 vcf poles are located at
+ s_p = omega(-1 + r sqrt(5) e^{pi/3(1+2p)})
+
+ real pole: omega * (-1 -r)
+ complex pole:
+ real = omega (-1 + r)
+ imag = omega (+- 2 r)
+
+
+ this is a strange beast. legend goes it was "invented" by taking the moog vcf
+ and moving one cap up, such that the not-so controllable 3-pole that emerged
+ would avoid the moog patent..
+
+ so, the sound is not so much the locations of the poles, but how the filter
+ reacts to time varying controls. i.e. the pole movement with constant reso,
+ used in the tb-303.
+
+ */
+
+ /* compute phasor, radius and update eqs */
+ phasor[0] = cos(2.0 * M_PI * r_prev * f_prev * 2.0f);
+ phasor[1] = sin(2.0 * M_PI * r_prev * f_prev * 2.0f);
+ phasor_rot[0] = cos(2.0 * M_PI * (r*f - r_prev*f_prev) * 2.0f * inv_n);
+ phasor_rot[1] = sin(2.0 * M_PI * (r*f - r_prev*f_prev) * 2.0f * inv_n);
+
+ radior[0] = exp(f_prev * (-1.0 + r_prev)); /* dominant radius */
+ radior[1] = exp(f_prev * (-1.0 - sqrt5 * r_prev));
+ radior_rot[0] = exp((f*(-1.0f + r) - f_prev * (-1.0 + r_prev)) * inv_n);
+ radior_rot[1] = exp((f*(-1.0f - r) - f_prev * (-1.0 - sqrt5 * r_prev)) * inv_n);
+
+ /* 303 like scaling */
+ if (1){
+ float r3 = r_prev * r_prev * r_prev;
+ scalor = 1.0f + (1.0f + 3.0f * r_prev);
+ r3 = r * r * r;
+ scalor_inc = ((1.0f + (1.0f + 3.0f * r3)) - scalor) * inv_n;
+ }
+
+ /* no scaling */
+ else{
+ scalor = 1.0f;
+ scalor_inc = 0.0f;
+ }
+
+ ctl->c_f_prev = f;
+ ctl->c_r_prev = r;
+
+
+ ctl->c_state[3] = 0.0f;
+ /* perform filtering */
+ for (i=0; i<n; i++){
+ float poleA[2], poleB[2];
+ float *stateA = ctl->c_state;
+ float *stateB = ctl->c_state+2;
+
+ float x;
+
+ /* compute poles */
+ poleA[0] = radior[0] * phasor[0];
+ poleA[1] = radior[0] * phasor[1];
+
+ poleB[0] = radior[1];
+
+
+ /* perform filtering: use (real part of) 2 DC normalized complex one-poles:
+ y[k] = x[k] + a(y[k-1] - x[k]) or y(z) = (1-a)/(1-az^{-1}) x(z) */
+
+ x = *in++ * scalor;
+
+ /* nondominant pole first */
+ stateB[0] -= x;
+ stateB[0] *= poleB[0];
+ x = stateB[0] += x;
+
+ /* dominant pole second */
+ stateA[0] -= x;
+ vcmul2(stateA, poleA);
+ x = stateA[0] += x;
+
+ *out++ = x;
+
+ /* saturate (normalize if pow > 1) state to prevent explosion and to allow self-osc */
+ _sat_state(stateA);
+ _sat_state(stateB);
+
+ /* interpolate filter coefficients */
+ vcmul2(phasor, phasor_rot);
+ radior[0] *= radior_rot[0];
+ radior[1] *= radior_rot[1];
+ scalor += scalor_inc;
+
+ }
+
+ return (w+7);
+}
+
+
+
+
+
+static void resofilt_dsp(t_resofilt *x, t_signal **sp)
+{
+ int n = sp[0]->s_n;
+
+ dsp_add(x->x_dsp,
+ 6,
+ &x->x_ctl,
+ sp[0]->s_n,
+ sp[0]->s_vec,
+ sp[1]->s_vec,
+ sp[2]->s_vec,
+ sp[3]->s_vec);
+
+}
+static void resofilt_free(t_resofilt *x)
+{
+
+
+}
+
+t_class *resofilt_class;
+
+static void *resofilt_new(t_floatarg algotype)
+{
+ t_resofilt *x = (t_resofilt *)pd_new(resofilt_class);
+
+ /* in */
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+
+ /* out */
+ outlet_new(&x->x_obj, gensym("signal"));
+
+
+ /* set algo type */
+ if (algotype == 3.0f){
+ post("resofilt~: 3-pole lowpass ladder vcf");
+ x->x_dsp = resofilt_perform_threepole;
+ }
+ else {
+ post("resofilt~: 4-pole lowpass ladder vcf");
+ x->x_dsp = resofilt_perform_fourpole;
+ }
+
+
+ return (void *)x;
+}
+
+void resofilt_tilde_setup(void)
+{
+ resofilt_class = class_new(gensym("resofilt~"), (t_newmethod)resofilt_new,
+ (t_method)resofilt_free, sizeof(t_resofilt), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(resofilt_class, t_resofilt, x_f);
+ class_addmethod(resofilt_class, (t_method)resofilt_dsp, gensym("dsp"), 0);
+}
+
diff --git a/modules/sbosc.c b/modules/sbosc.c
new file mode 100644
index 0000000..511c770
--- /dev/null
+++ b/modules/sbosc.c
@@ -0,0 +1,175 @@
+/*
+ * sbosc.c - smallband oscillator. periodic, linear interpolated frequency center.
+ * data organization is in (real, imag) pairs
+ * the first 2 components are (DC, NY)
+ * Copyright (c) 2000-2003 by Tom Schouten
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "m_pd.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define LOGTABSIZE 10
+#define TABSIZE (1<<LOGTABSIZE)
+#define MASKTABSIZE (TABSIZE-1)
+
+#define SHIFTTABSIZE ((sizeof(unsigned int) * 8) - LOGTABSIZE)
+#define FRACTABSIZE (1<<SHIFTTABSIZE)
+#define INVFRACTABSIZE (1.0f / (float)(FRACTABSIZE))
+#define MASKFRACTABSIZE (FRACTABSIZE-1)
+
+#define PITCHLIMIT 20.0f
+
+static float costable[TABSIZE];
+
+static inline void _exp_j2pi(unsigned int t, float *real, float *imag)
+{
+ unsigned int i1 = t >> SHIFTTABSIZE;
+ float f2 = (t & MASKFRACTABSIZE) * INVFRACTABSIZE;
+ unsigned int i2 = (i1+1) & MASKTABSIZE;
+ unsigned int i3 = (i1 - (TABSIZE>>2)) & MASKTABSIZE;
+ unsigned int i4 = (i2 + 1 - (TABSIZE>>2)) & MASKTABSIZE;
+ float f1 = 1.0f - f2;
+ float a1 = f1 * costable[i1];
+ float a2 = f2 * costable[i2];
+ float b1 = f1 * costable[i3];
+ float b2 = f2 * costable[i4];
+ *real = a1 + a2;
+ *imag = b1 + b2;
+}
+
+static t_class *sbosc_tilde_class;
+
+typedef struct _sbosc_tilde
+{
+ t_object x_obj;
+ float x_f;
+
+ /* state vars */
+ unsigned int x_phase; // phase of main pitch osc
+ unsigned int x_phase_inc; // frequency of main pitch osc
+ unsigned int x_harmonic; // first harmonic
+ float x_frac; // fraction of first harmonic
+
+
+} t_sbosc_tilde;
+
+static void *sbosc_tilde_new(void)
+{
+ t_sbosc_tilde *x = (t_sbosc_tilde *)pd_new(sbosc_tilde_class);
+ x->x_phase = 0;
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("phase"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_f = 0;
+ return (x);
+}
+
+
+static t_int *sbosc_tilde_perform(t_int *w)
+{
+ t_sbosc_tilde *x = (t_sbosc_tilde *)(w[1]);
+ t_float *pitch = (t_float *)(w[2]);
+ t_float *center= (t_float *)(w[3]);
+ t_float *out_real = (t_float *)(w[4]);
+ t_float *out_imag = (t_float *)(w[5]);
+ int n = (int)(w[6]);
+ int i;
+
+ t_float pitch_to_phase = 4294967295.0f / sys_getsr();
+
+ for (i = 0; i < n; i++)
+ {
+ float p = *pitch++;
+ float c = *center++;
+ float r1,r2,i1,i2;
+
+ /* compute harmonic mixture */
+ unsigned int h1 = x->x_phase * x->x_harmonic;
+ unsigned int h2 = h1 + x->x_phase;
+ _exp_j2pi(h1, &r1, &i1);
+ _exp_j2pi(h2, &r2, &i2);
+ r1 *= x->x_frac;
+ i1 *= x->x_frac;
+ r2 *= 1.0f - x->x_frac;
+ i2 *= 1.0f - x->x_frac;
+
+ *out_real++ = r1 + r2;
+ *out_imag++ = i1 + i2;
+
+
+ x->x_phase += x->x_phase_inc;
+
+ /* check for phase wrap & update osc */
+ if ((x->x_phase <= x->x_phase_inc))
+ {
+ float p_plus = (p < 0.0f) ? -p : p;
+ float p_limit = (p_plus < PITCHLIMIT) ? PITCHLIMIT : p_plus;
+ float c_plus = (c < 0.0f) ? -c : c;
+ float harmonic = c_plus/p_limit;
+ x->x_phase_inc = pitch_to_phase * p_limit;
+ x->x_harmonic = harmonic;
+ x->x_frac = 1.0f - (harmonic - x->x_harmonic);
+ }
+
+
+ }
+
+ return (w+7);
+}
+
+static void sbosc_tilde_dsp(t_sbosc_tilde *x, t_signal **sp)
+{
+ dsp_add(sbosc_tilde_perform, 6, x,
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n);
+
+}
+
+static void sbosc_tilde_free(t_sbosc_tilde *x)
+{
+}
+
+static void sbosc_tilde_phase(t_sbosc_tilde *x, t_floatarg f)
+{
+ x->x_phase = f * (1.0f / 4294967295.0f);
+}
+
+void sbosc_tilde_setup(void)
+{
+ int i;
+
+ // init tables
+ for (i=0; i<TABSIZE; i++)
+ costable[i] = cos(2.0 * M_PI * (double)i / (double)TABSIZE);
+
+
+
+ // class setup
+ sbosc_tilde_class = class_new(gensym("sbosc~"),
+ (t_newmethod)sbosc_tilde_new, (t_method)sbosc_tilde_free,
+ sizeof(t_sbosc_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(sbosc_tilde_class, t_sbosc_tilde, x_f);
+ class_addmethod(sbosc_tilde_class, (t_method)sbosc_tilde_dsp,
+ gensym("dsp"), 0);
+ class_addmethod(sbosc_tilde_class, (t_method)sbosc_tilde_phase,
+ gensym("phase"), A_FLOAT, 0);
+}
+
diff --git a/modules/scrollgrid1D.c b/modules/scrollgrid1D.c
new file mode 100644
index 0000000..bcac7fe
--- /dev/null
+++ b/modules/scrollgrid1D.c
@@ -0,0 +1,220 @@
+/*
+ * scrollgrid1D.c - 1D scroll grid attractor
+ * Copyright (c) 2000-2003 by Tom Schouten
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/* 1D scroll grid attractor
+ for more information see:
+
+ Yalcin M., Ozoguz S., Suykens J.A.K., Vandewalle J.,
+ ``Families of Scroll Grid Attractors'',
+ International Journal of Bifurcation and Chaos, vol. 12, no. 1, Jan. 2002, pp. 23-41.
+
+ this file implements a digital variant of the method introduced in the paper,
+ so that it can be used as a parametrizable, bounded chatotic oscillator.
+ in short it is a switched linear system, with some added hard limiting to
+ convert unstable oscillations into stable ones.
+
+*/
+
+#include "m_pd.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "filters.h"
+
+
+typedef struct scrollgrid1Dctl
+{
+ t_float c_x, c_y, c_z; /* state */
+
+} t_scrollgrid1Dctl;
+
+typedef struct scrollgrid1D
+{
+ t_object x_obj;
+ t_float x_f;
+ t_scrollgrid1Dctl x_ctl;
+} t_scrollgrid1D;
+
+
+static inline float _fixedpoint(float x, int n)
+{
+ int ix = (x + 0.5f);
+ if (ix < 0) ix = 0;
+ else if (ix >= n) ix = n-1;
+ return (float)ix;
+}
+
+static inline float _sat(float x, float upper)
+{
+ float lower = -1.0f;
+ if (x < lower) x = lower;
+ else if (x > upper) x = upper;
+ return x;
+}
+
+static t_int *scrollgrid1D_perform(t_int *w)
+{
+
+
+ t_float *freq = (float *)(w[3]);
+ t_float *t1 = (float *)(w[4]);
+ t_float *t2 = (float *)(w[5]);
+ t_float *order = (float *)(w[6]);
+ t_float *outx = (float *)(w[7]);
+ t_float *outy = (float *)(w[8]);
+ t_float *outz = (float *)(w[9]);
+ t_scrollgrid1Dctl *ctl = (t_scrollgrid1Dctl *)(w[1]);
+ t_int n = (t_int)(w[2]);
+
+ t_int i;
+ t_float inv_sr = 1.0f /sys_getsr();
+ t_float state[3] = {ctl->c_x, ctl->c_y, ctl->c_z};
+ t_float c,f;
+ t_float pole[2], r1, r2;
+ t_int o;
+ t_float x,y,z;
+
+
+ for (i=0; i<n; i++){
+
+ /* get params */
+ r1 = exp(1000.0f * inv_sr / (0.01f + fabs(*t1++)));
+ r2 = exp(-1000.0f * inv_sr / (0.01f + fabs(*t2++)));
+ f = *freq++;
+ o = (int)(*order++);
+ if (o < 2) o = 2;
+ pole[0] = r1 * cos(2.0f * M_PI * inv_sr * f);
+ pole[1] = r1 * sin(2.0f * M_PI * inv_sr * f);
+
+ /* debug */
+ //post("%f", r1);
+
+ /* base transform + clipping to prevent blowup */
+ x = _sat(0.5f * (state[0] - state[2]), (float)o); /* projection onto axis containing fixed */
+ y = _sat(0.5f * state[1], 1.0f); /* the "pure" oscillation axis */
+ z = _sat(0.5f * (state[0] + state[2]), 1.0f); /* orthogonal complement of x */
+
+ /* output */
+ *outx++ = x;
+ *outy++ = y;
+ *outz++ = z;
+
+
+ /* calculate fixed point location (c, 0, -c) */
+ c = _fixedpoint(x, o);
+
+ /* inverse base transform */
+ state[0] = x + z;
+ state[1] = 2.0f * y;
+ state[2] = -x + z;
+
+
+ /* update transformed linear system around unstable fixed point */
+ state[0] -= c;
+ state[2] += c;
+ vcmul2(state, pole);
+ state[2] *= r2;
+ state[0] += c;
+ state[2] -= c;
+
+ }
+
+
+
+ ctl->c_x = state[0];
+ ctl->c_y = state[1];
+ ctl->c_z = state[2];
+
+ return (w+10);
+}
+
+static void scrollgrid1D_dsp(t_scrollgrid1D *x, t_signal **sp)
+{
+ int n = sp[0]->s_n;
+ int k;
+
+
+ dsp_add(scrollgrid1D_perform,
+ 9,
+ &x->x_ctl,
+ sp[0]->s_n,
+ sp[0]->s_vec,
+ sp[1]->s_vec,
+ sp[2]->s_vec,
+ sp[3]->s_vec,
+ sp[4]->s_vec,
+ sp[5]->s_vec,
+ sp[6]->s_vec);
+
+
+}
+static void scrollgrid1D_free(t_scrollgrid1D *x)
+{
+
+
+}
+
+
+
+
+static void scrollgrid1D_reset(t_scrollgrid1D *x)
+{
+ x->x_ctl.c_x = 1;
+ x->x_ctl.c_y = 1;
+ x->x_ctl.c_z = 1;
+}
+
+
+t_class *scrollgrid1D_class;
+
+static void *scrollgrid1D_new(t_floatarg algotype)
+{
+ t_scrollgrid1D *x = (t_scrollgrid1D *)pd_new(scrollgrid1D_class);
+
+ /* ins */
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+
+ /* outs */
+ outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+
+
+ /* init data */
+ scrollgrid1D_reset(x);
+
+ return (void *)x;
+}
+
+void scrollgrid1D_tilde_setup(void)
+{
+ //post("scrollgrid1D~ v0.1");
+ scrollgrid1D_class = class_new(gensym("scrollgrid1D~"), (t_newmethod)scrollgrid1D_new,
+ (t_method)scrollgrid1D_free, sizeof(t_scrollgrid1D), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(scrollgrid1D_class, t_scrollgrid1D, x_f);
+ class_addmethod(scrollgrid1D_class, (t_method)scrollgrid1D_dsp, gensym("dsp"), 0);
+ class_addmethod(scrollgrid1D_class, (t_method)scrollgrid1D_reset, gensym("reset"), 0);
+
+
+}
+
diff --git a/modules/statwav.c b/modules/statwav.c
index 52c6a0b..13d9c9f 100644
--- a/modules/statwav.c
+++ b/modules/statwav.c
@@ -67,11 +67,15 @@ static t_int *statwav_tilde_perform(t_int *w)
{
float phase = *in++;
float modphase = phase - (int)phase;
- float findex = modphase * maxindex;
- int index = findex;
+ float findex;
+ int index;
int ia, ib, ic, id;
float frac, a, b, c, d, cminusb;
static int count;
+
+ if (modphase < 0.0f) modphase += 1.0f;
+ findex = modphase * maxindex;
+ index = findex;
frac = findex - index;
diff --git a/system/setup.c b/system/setup.c
index 396fcec..987db50 100644
--- a/system/setup.c
+++ b/system/setup.c
@@ -19,7 +19,7 @@ void dynwav_tilde_setup(void);
void statwav_tilde_setup(void);
void bdiag_tilde_setup(void);
void diag_tilde_setup(void);
-void matrix_tilde_setup(void);
+void bmatrix_tilde_setup(void);
void permut_tilde_setup(void);
void lattice_tilde_setup(void);
void ratio_setup(void);
@@ -28,6 +28,13 @@ void fwarp_setup(void);
void junction_tilde_setup(void);
void fdn_tilde_setup(void);
void window_tilde_setup(void);
+void blosc_tilde_setup(void);
+void cmath_tilde_setup(void);
+void bitsplit_tilde_setup(void);
+void sbosc_tilde_setup(void);
+void blocknorm_tilde_setup(void);
+void resofilt_tilde_setup(void);
+void scrollgrid1D_tilde_setup(void);
void creb_setup(void)
{
@@ -50,12 +57,20 @@ void creb_setup(void)
statwav_tilde_setup();
bdiag_tilde_setup();
diag_tilde_setup();
- matrix_tilde_setup();
+ bmatrix_tilde_setup();
permut_tilde_setup();
lattice_tilde_setup();
junction_tilde_setup();
fdn_tilde_setup();
window_tilde_setup();
+ blosc_tilde_setup();
+ cmath_tilde_setup();
+ bitsplit_tilde_setup();
+ sbosc_tilde_setup();
+ blocknorm_tilde_setup();
+ resofilt_tilde_setup();
+ scrollgrid1D_tilde_setup();
+
/* setup other objects */
ratio_setup();