aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filterbank~/CHANGES.LOG2
-rw-r--r--filterbank~/INSTALL15
-rw-r--r--filterbank~/Makefile113
-rw-r--r--filterbank~/README20
-rw-r--r--filterbank~/analyze-100.pd41
-rw-r--r--filterbank~/filterbank~.c661
-rw-r--r--filterbank~/filterbank~.h84
-rw-r--r--filterbank~/filterbank~.tk77
-rw-r--r--filterbank~/help-filterbank~.pd199
-rw-r--r--filterbank~/resynth-64.pd285
-rw-r--r--filterbank~/setosc.pd21
11 files changed, 1518 insertions, 0 deletions
diff --git a/filterbank~/CHANGES.LOG b/filterbank~/CHANGES.LOG
new file mode 100644
index 0000000..63318c7
--- /dev/null
+++ b/filterbank~/CHANGES.LOG
@@ -0,0 +1,2 @@
+0.1
+ First filterbank~ implementation
diff --git a/filterbank~/INSTALL b/filterbank~/INSTALL
new file mode 100644
index 0000000..a8b614e
--- /dev/null
+++ b/filterbank~/INSTALL
@@ -0,0 +1,15 @@
+untar in /my/pd/dir/externs
+
+cd /my/pd/dir/externs/filterbank~
+
+make clean
+
+make
+
+make install
+
+open help-filterbank~.pd
+
+Thanx for getting here.
+Yves/
+comments and bugs @ ydegoyon@free.fr
diff --git a/filterbank~/Makefile b/filterbank~/Makefile
new file mode 100644
index 0000000..1052ae7
--- /dev/null
+++ b/filterbank~/Makefile
@@ -0,0 +1,113 @@
+NAME=filterbank~
+CSYM=filterbank~
+
+current: pd_linux
+
+# ----------------------- NT -----------------------
+
+pd_nt: $(NAME).dll
+
+.SUFFIXES: .dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+VC="C:\Program Files\Microsoft Visual Studio\Vc98"
+
+PDNTINCLUDE = /I. /I\tcl\include /I\ftp\pd\src /I$(VC)\include
+
+PDNTLDIR = $(VC)\lib
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ \ftp\pd\bin\pd.lib
+
+.c.ont:
+ cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+
+.c.dll:
+ cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+ link /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB)
+
+# ----------------------- IRIX 5.x -----------------------
+
+pd_irix5: $(NAME).pd_irix5
+
+.SUFFIXES: .pd_irix5
+
+SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2
+
+SGIINCLUDE = -I../../src
+
+.c.oi5:
+ cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c
+
+.c.pd_irix5:
+ cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c
+ ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o
+ rm $*.o
+
+# ----------------------- IRIX 6.x -----------------------
+
+pd_irix6: $(NAME).pd_irix6
+
+.SUFFIXES: .pd_irix6
+
+SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \
+ -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \
+ -Ofast=ip32
+
+.c.oi6:
+ cc $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c
+
+.c.pd_irix6:
+ cc $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c
+ ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o
+ rm $*.o
+
+# ----------------------- LINUX i386 -----------------------
+
+pd_linux: $(NAME).pd_linux
+
+.SUFFIXES: .pd_linux
+
+LINUXCFLAGS = -DPD -DUNIX -DICECAST -O2 -funroll-loops -fomit-frame-pointer \
+ -Wall -W -Wno-shadow -Wstrict-prototypes -g \
+ -Wno-unused -Wno-parentheses -Wno-switch -Werror
+
+LINUXINCLUDE = -I../../src
+
+.c.o:
+ cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
+
+.c.pd_linux:
+ ../tk2c.bash < $*.tk > $*.tk2c
+ cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
+ ld -export_dynamic -shared -o $*.pd_linux $*.o -lc -lm
+ strip --strip-unneeded $*.pd_linux
+ rm -f $*.o ../$*.pd_linux
+ ln -s $*/$*.pd_linux ..
+
+# ----------------------- Mac OSX -----------------------
+
+pd_darwin: $(NAME).pd_darwin
+
+.SUFFIXES: .pd_darwin
+
+DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \
+ -Wno-unused -Wno-parentheses -Wno-switch
+
+.c.osx:
+ cc $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
+
+.c.pd_darwin:
+ cc $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
+ cc -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o
+ rm -f $*.o ../$*.pd_darwin
+ ln -s $*/$*.pd_darwin ..
+
+# ----------------------------------------------------------
+
+install:
+ cp help-*.pd ../../doc/5.reference
+
+clean:
+ rm -f *.o *.pd_* *.tk2c core
diff --git a/filterbank~/README b/filterbank~/README
new file mode 100644
index 0000000..e43ec35
--- /dev/null
+++ b/filterbank~/README
@@ -0,0 +1,20 @@
+*****************************************************************************
+Version 0.1
+copyleft 2002 Yves Degoyon
+tarballs and updates available @ http://ydegoyon.free.fr
+
+filterbank~ : filterbank outputs frequency response for a range of filters
+
+To install filterbank~, follow the steps from INSTALL
+
+This software is published under GPL terms.
+
+This is software with ABSOLUTELY NO WARRANTY.
+Use it at your OWN RISK. It's possible to damage e.g. hardware or your hearing
+due to a bug or for other reasons.
+We do not warrant that the program is free of infringement of any third-party
+patents.
+
+*****************************************************************************
+
+
diff --git a/filterbank~/analyze-100.pd b/filterbank~/analyze-100.pd
new file mode 100644
index 0000000..132876b
--- /dev/null
+++ b/filterbank~/analyze-100.pd
@@ -0,0 +1,41 @@
+#N canvas 112 -6 970 685 10;
+#X obj 236 283 filterbank~ 0 2000 100;
+#X obj 31 62 t s b;
+#X obj 80 68 float \$0;
+#X text 31 1 Step 1 : Load a sound file;
+#X obj 31 83 route float;
+#X msg 336 250 bang;
+#X obj 125 250 tabplay~ \$0-filterbank-sample;
+#X obj 31 104 makefilename %d-filterbank-sample;
+#X obj 32 137 pack s s;
+#X msg 32 158 read -resize \$1 \$2;
+#X msg 239 220 bang;
+#X obj 28 220 tabplay~ \$0-filterbank-sample;
+#X obj 365 149 table \$0-filterbank-sample;
+#X msg 440 223 randomize 1;
+#X msg 442 246 randomize 0;
+#X obj 32 180 soundfiler;
+#X obj 719 55 playlist all 200 200;
+#X msg 484 52 location /Samples;
+#X obj 484 25 loadbang;
+#X obj 391 369 dac~;
+#X connect 0 8 19 0;
+#X connect 0 15 19 1;
+#X connect 0 28 19 1;
+#X connect 1 0 8 0;
+#X connect 1 1 2 0;
+#X connect 2 0 4 0;
+#X connect 4 0 7 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 7 0 8 1;
+#X connect 8 0 9 0;
+#X connect 9 0 15 0;
+#X connect 10 0 11 0;
+#X connect 11 0 19 1;
+#X connect 11 0 19 0;
+#X connect 13 0 0 0;
+#X connect 14 0 0 0;
+#X connect 16 0 1 0;
+#X connect 17 0 16 0;
+#X connect 18 0 17 0;
diff --git a/filterbank~/filterbank~.c b/filterbank~/filterbank~.c
new file mode 100644
index 0000000..19bc773
--- /dev/null
+++ b/filterbank~/filterbank~.c
@@ -0,0 +1,661 @@
+/* ---------------------------------------------------------------------------- */
+/* Copyright (c) 2002 Yves Degoyon. */
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL */
+/* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+/* */
+/* filterbank.c written by Yves Degoyon 2002 */
+/* outputs frequency responses against a bank of filters */
+/* */
+/* 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. */
+/* */
+/* See file LICENSE for further informations on licensing terms. */
+/* */
+/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* Made while listening to : */
+/* */
+/* The Three Johns -- Teenage Nightingales In Wax */
+/* Kk Null & Jim O Rourke - Neuro Politics */
+/* ---------------------------------------------------------------------------- */
+
+
+#include "filterbank~.h"
+
+#ifdef NT
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#define DEFAULT_FILTERBANK_LOWFREQ 0
+#define DEFAULT_FILTERBANK_HIGHFREQ 1600
+#define DEFAULT_FILTERBANK_NBFILTERS 10
+#define FILTERBANK_OUTLET_WIDTH 5
+#define FILTERBANK_HEIGHT 16
+
+static char *filterbank_version = "filterbank : responses from a set of band-pass filters, version 0.1 (ydegoyon@free.fr)";
+
+t_widgetbehavior filterbank_widgetbehavior;
+static t_class *filterbank_class_tilde;
+
+static int guidebug=0;
+
+#define SYS_VGUI2(a,b) if (guidebug) \
+ post(a,b);\
+ sys_vgui(a,b)
+
+#define SYS_VGUI3(a,b,c) if (guidebug) \
+ post(a,b,c);\
+ sys_vgui(a,b,c)
+
+#define SYS_VGUI4(a,b,c,d) if (guidebug) \
+ post(a,b,c,d);\
+ sys_vgui(a,b,c,d)
+
+#define SYS_VGUI5(a,b,c,d,e) if (guidebug) \
+ post(a,b,c,d,e);\
+ sys_vgui(a,b,c,d,e)
+
+#define SYS_VGUI6(a,b,c,d,e,f) if (guidebug) \
+ post(a,b,c,d,e,f);\
+ sys_vgui(a,b,c,d,e,f)
+
+#define SYS_VGUI7(a,b,c,d,e,f,g) if (guidebug) \
+ post(a,b,c,d,e,f,g);\
+ sys_vgui(a,b,c,d,e,f,g)
+
+#define SYS_VGUI8(a,b,c,d,e,f,g,h) if (guidebug) \
+ post(a,b,c,d,e,f,g,h);\
+ sys_vgui(a,b,c,d,e,f,g,h)
+
+#define SYS_VGUI9(a,b,c,d,e,f,g,h,i) if (guidebug) \
+ post(a,b,c,d,e,f,g,h,i);\
+ sys_vgui(a,b,c,d,e,f,g,h,i)
+
+#define SYS_VGUI10(a,b,c,d,e,f,g,h,i,j) if (guidebug) \
+ post(a,b,c,d,e,f,g,h,i,j);\
+ sys_vgui(a,b,c,d,e,f,g,h,i,j)
+
+#define SYS_VGUI11(a,b,c,d,e,f,g,h,i,j,k) if (guidebug) \
+ post(a,b,c,d,e,f,g,h,i,j,k);\
+ sys_vgui(a,b,c,d,e,f,g,h,i,j,k)
+
+/* this code is borrowed from pd's internal object : bp~ */
+
+static float miller_sigbp_qcos(float f)
+{
+ if (f >= -(0.5f*M_PI) && f <= 0.5f*M_PI)
+ {
+ float g = f*f;
+ return (((g*g*g * (-1.0f/720.0f) + g*g*(1.0f/24.0f)) - g*0.5) + 1);
+ }
+ else return (0);
+}
+
+static void miller_sigbp_docoef(t_filterbank_tilde *x, t_int index, t_floatarg f, t_floatarg q)
+{
+ float r, oneminusr, omega;
+ if (f < 0.001) f = 10;
+ if (q < 0) q = 0;
+ x->x_freq[index] = f;
+ x->x_q[index] = q;
+ omega = f * (2.0f * 3.14159f) / x->x_sr;
+ if (q < 0.001) oneminusr = 1.0f;
+ else oneminusr = omega/q;
+ if (oneminusr > 1.0f) oneminusr = 1.0f;
+ r = 1.0f - oneminusr;
+ x->x_ctl[index]->c_coef1 = 2.0f * miller_sigbp_qcos(omega) * r;
+ x->x_ctl[index]->c_coef2 = - r * r;
+ x->x_ctl[index]->c_gain = 2 * oneminusr * (oneminusr + r * omega);
+}
+
+static void filterbank_draw_new(t_filterbank_tilde *x, t_glist *glist)
+{
+ t_canvas *canvas=glist_getcanvas(glist);
+ int fi;
+
+ // draw the square
+ {
+
+ SYS_VGUI7(".x%x.c create rectangle %d %d %d %d -fill #FFFFFF -tags %xFILTERBANK\n",
+ canvas,
+ x->x_obj.te_xpix,
+ x->x_obj.te_ypix,
+ x->x_obj.te_xpix + x->x_width,
+ x->x_obj.te_ypix + x->x_height,
+ x);
+
+ SYS_VGUI7(".x%x.c create rectangle %d %d %d %d -fill #000000 -tags %xSIN\n",
+ canvas,
+ x->x_obj.te_xpix,
+ x->x_obj.te_ypix-1,
+ x->x_obj.te_xpix+7,
+ x->x_obj.te_ypix,
+ x);
+
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ char color[8];
+
+ sprintf( color, "#%.2x%.2x%.2x", random() % 256, random() % 256, random() % 256 );
+
+ SYS_VGUI11(".x%x.c create polygon %d %d %d %d %d %d -outline #000000 -fill %s -tags %xFILTER%d\n",
+ canvas,
+ x->x_obj.te_xpix + fi*x->x_width/x->x_nbfilters,
+ x->x_obj.te_ypix,
+ x->x_obj.te_xpix + fi*x->x_width/x->x_nbfilters + x->x_width/(2*x->x_nbfilters),
+ x->x_obj.te_ypix + x->x_height,
+ x->x_obj.te_xpix + (fi+1)*x->x_width/x->x_nbfilters,
+ x->x_obj.te_ypix,
+ color, x, fi);
+ }
+ }
+
+ canvas_fixlinesfor( canvas, (t_text*)x );
+}
+
+static void filterbank_draw_move(t_filterbank_tilde *x, t_glist *glist)
+{
+ t_canvas *canvas=glist_getcanvas(glist);
+ t_int fi;
+
+ SYS_VGUI7(".x%x.c coords %xFILTERBANK %d %d %d %d\n",
+ canvas, x,
+ x->x_obj.te_xpix,
+ x->x_obj.te_ypix,
+ x->x_obj.te_xpix + x->x_width,
+ x->x_obj.te_ypix + x->x_height
+ );
+
+ SYS_VGUI7(".x%x.c coords %xSIN %d %d %d %d\n",
+ canvas, x,
+ x->x_obj.te_xpix,
+ x->x_obj.te_ypix-1,
+ x->x_obj.te_xpix+7,
+ x->x_obj.te_ypix
+ );
+
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ SYS_VGUI10(".x%x.c coords %xFILTER%d %d %d %d %d %d %d\n",
+ canvas, x, fi,
+ x->x_obj.te_xpix + fi*x->x_width/x->x_nbfilters,
+ x->x_obj.te_ypix,
+ x->x_obj.te_xpix + fi*x->x_width/x->x_nbfilters + x->x_width/(2*x->x_nbfilters),
+ x->x_obj.te_ypix + x->x_height,
+ x->x_obj.te_xpix + (fi+1)*x->x_width/x->x_nbfilters,
+ x->x_obj.te_ypix
+ );
+ }
+
+ canvas_fixlinesfor( canvas, (t_text*)x );
+}
+
+static void filterbank_draw_erase(t_filterbank_tilde* x,t_glist* glist)
+{
+ t_canvas *canvas=glist_getcanvas(glist);
+ int fi;
+
+ SYS_VGUI3(".x%x.c delete %xFILTERBANK\n", canvas, x );
+ SYS_VGUI3(".x%x.c delete %xSIN\n", canvas, x );
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ SYS_VGUI4(".x%x.c delete %xFILTER%d\n", canvas, x, fi );
+ }
+
+}
+
+static void filterbank_draw_select(t_filterbank_tilde* x,t_glist* glist)
+{
+ t_canvas *canvas=glist_getcanvas(glist);
+
+ if(x->x_selected)
+ {
+ /* sets the item in blue */
+ SYS_VGUI3(".x%x.c itemconfigure %xFILTERBANK -outline #0000FF\n", canvas, x);
+ }
+ else
+ {
+ SYS_VGUI3(".x%x.c itemconfigure %xFILTERBANK -outline #000000\n", canvas, x);
+ }
+}
+
+/* ------------------------ filterbank widgetbehaviour----------------------------- */
+
+
+static void filterbank_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ t_filterbank_tilde* x = (t_filterbank_tilde*)z;
+
+ *xp1 = x->x_obj.te_xpix;
+ *yp1 = x->x_obj.te_ypix;
+ *xp2 = x->x_obj.te_xpix+x->x_width;
+ *yp2 = x->x_obj.te_ypix+x->x_height;
+}
+
+static void filterbank_save(t_gobj *z, t_binbuf *b)
+{
+ t_filterbank_tilde *x = (t_filterbank_tilde *)z;
+ t_int ii;
+
+ binbuf_addv(b, "ssiisiii", gensym("#X"),gensym("obj"),
+ (t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
+ gensym("filterbank~"), x->x_lowfreq, x->x_highfreq,
+ x->x_nbfilters );
+ binbuf_addv(b, ";");
+}
+
+static void filterbank_properties(t_gobj *z, t_glist *owner)
+{
+ char buf[800];
+ t_filterbank_tilde *x=(t_filterbank_tilde *)z;
+
+ sprintf(buf, "pdtk_filterbank_dialog %%s %d %d\n",
+ x->x_lowfreq, x->x_highfreq );
+ gfxstub_new(&x->x_obj.ob_pd, x, buf);
+}
+
+static void filterbank_select(t_gobj *z, t_glist *glist, int selected)
+{
+ t_filterbank_tilde *x = (t_filterbank_tilde *)z;
+
+ x->x_selected = selected;
+ filterbank_draw_select( x, glist );
+}
+
+static void filterbank_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_filterbank_tilde *x = (t_filterbank_tilde *)z;
+
+ // post( "filterbank~ : vis : %d", vis );
+ if (vis)
+ {
+ filterbank_draw_new( x, glist );
+ }
+ else
+ {
+ filterbank_draw_erase( x, glist );
+ }
+}
+
+static void filterbank_dialog(t_filterbank_tilde *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_int olowfreq = x->x_lowfreq;
+ t_int ohighfreq = x->x_highfreq;
+ t_int fi, ei;
+ t_int dspstate;
+ t_float Q;
+ t_float afreq, abandwidth;
+ t_canvas *canvas=glist_getcanvas(x->x_glist);
+
+ // !!paranoid
+ if ( !x ) {
+ post( "filterbank~ : error :tried to set properties on an unexisting object" );
+ }
+ if ( argc != 2 )
+ {
+ post( "filterbank : error in the number of arguments ( %d instead of 2 )", argc );
+ return;
+ }
+ if ( argv[0].a_type != A_FLOAT || argv[1].a_type != A_FLOAT ) {
+ post( "filterbank~ : wrong arguments" );
+ return;
+ }
+
+ x->x_allocate = 1;
+ x->x_lowfreq = (int)argv[0].a_w.w_float;
+ if ( x->x_lowfreq < 0 ) x->x_lowfreq = 0;
+ x->x_highfreq = (int)argv[1].a_w.w_float;
+ if ( x->x_highfreq < x->x_lowfreq ) x->x_highfreq = x->x_lowfreq + 100;
+
+ // recalculate filters if needed
+ if ( ( olowfreq != x->x_lowfreq ) || ( ohighfreq != x->x_highfreq ) )
+ {
+ // free filters
+ if ( x->x_freq )
+ {
+ freebytes( x->x_freq, x->x_nbfilters*sizeof(t_float) );
+ }
+ if ( x->x_q )
+ {
+ freebytes( x->x_q, x->x_nbfilters*sizeof(t_float) );
+ }
+ if ( x->x_cspace )
+ {
+ freebytes( x->x_cspace, x->x_nbfilters*sizeof(t_bpctl) );
+ }
+ if ( x->x_ctl )
+ {
+ freebytes( x->x_ctl, x->x_nbfilters*sizeof(t_bpctl*) );
+ }
+ // create filters
+ x->x_freq = (t_float *) getbytes( x->x_nbfilters*sizeof(t_float) );
+ x->x_q = (t_float *) getbytes( x->x_nbfilters*sizeof(t_float) );
+ x->x_cspace = (t_bpctl *) getbytes( x->x_nbfilters*sizeof(t_bpctl) );
+ x->x_ctl = (t_bpctl **) getbytes( x->x_nbfilters*sizeof(t_bpctl*) );
+ if ( !x->x_freq || !x->x_q || !x->x_cspace || !x->x_ctl )
+ {
+ post( "filterbank~ : could not allocate filters" );
+ return;
+ }
+ abandwidth = ( x->x_highfreq - x->x_lowfreq ) / x->x_nbfilters;
+ afreq = x->x_lowfreq + ( abandwidth / 2 );
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ x->x_ctl[fi] = &x->x_cspace[fi];
+ x->x_cspace[fi].c_x1 = 0;
+ x->x_cspace[fi].c_x2 = 0;
+ Q = ( (t_float) afreq )/ ( (t_float) abandwidth );
+ miller_sigbp_docoef( x, fi, afreq, Q );
+ afreq += abandwidth;
+ }
+ }
+
+ x->x_allocate = 0;
+}
+
+static void filterbank_delete(t_gobj *z, t_glist *glist)
+{
+ t_filterbank_tilde *x = (t_filterbank_tilde *)z;
+
+ // post( "filterbank~ : delete" );
+ filterbank_draw_erase( x, glist );
+ canvas_deletelinesfor( glist_getcanvas(glist), (t_text *)z);
+}
+
+static void filterbank_displace(t_gobj *z, t_glist *glist, int dx, int dy)
+{
+ t_filterbank_tilde *x = (t_filterbank_tilde *)z;
+ int xold = x->x_obj.te_xpix;
+ int yold = x->x_obj.te_ypix;
+
+ // post( "filterbank_displace dx=%d dy=%d", dx, dy );
+
+ x->x_obj.te_xpix += dx;
+ x->x_obj.te_ypix += dy;
+ if(xold != x->x_obj.te_xpix || yold != x->x_obj.te_ypix)
+ {
+ filterbank_draw_move(x, x->x_glist);
+ }
+}
+
+
+static void filterbank_randomize(t_filterbank_tilde *x, t_floatarg fflag )
+{
+ t_int shind, tmpi, fi;
+
+ if ( fflag != 0.0 && fflag != 1.0 ) {
+ post( "filterbank~ : wrong argument in randomize message : should be 0 or 1" );
+ return;
+ } else if ( fflag == 1 ) {
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ shind = rand() % x->x_nbfilters;
+ tmpi = x->x_outmapping[ shind ];
+ x->x_outmapping[ shind ] = x->x_outmapping[ fi ];
+ x->x_outmapping[ fi ] = tmpi;
+ }
+ } else {
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ x->x_outmapping[ fi ] = fi;
+ }
+ }
+}
+
+static t_filterbank_tilde *filterbank_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_int fi, ei;
+ t_filterbank_tilde *x;
+ char *str;
+ t_float Q;
+ t_float afreq, abandwidth;
+
+ x = (t_filterbank_tilde *)pd_new(filterbank_class_tilde);
+
+ x->x_samplerate = (int)sys_getsr();
+ x->x_sr = 44100;
+
+ // new filterbank created from the gui
+ if ( argc != 0 )
+ {
+ if ( argc != 3 )
+ {
+ post( "filterbank~ : error in the number of arguments ( %d )", argc );
+ return NULL;
+ }
+ if ( argv[0].a_type != A_FLOAT || argv[1].a_type != A_FLOAT ||
+ argv[2].a_type != A_FLOAT ) {
+ post( "filterbank~ : wrong arguments" );
+ return NULL;
+ }
+
+ x->x_lowfreq = (int)argv[0].a_w.w_float;
+ if ( x->x_lowfreq < 0 ) x->x_lowfreq = 0;
+ x->x_highfreq = (int)argv[1].a_w.w_float;
+ if ( x->x_highfreq < x->x_lowfreq ) x->x_highfreq = x->x_lowfreq + 100;
+ x->x_nbfilters = (int)argv[2].a_w.w_float;
+ if ( x->x_nbfilters < 1 ) x->x_nbfilters = 1;
+ }
+ else
+ {
+ x->x_lowfreq = DEFAULT_FILTERBANK_LOWFREQ;
+ x->x_highfreq = DEFAULT_FILTERBANK_HIGHFREQ;
+ x->x_nbfilters = DEFAULT_FILTERBANK_NBFILTERS;
+ }
+
+ // post( "filterbank~ : new [ %d,%d ] with %d filters", x->x_lowfreq, x->x_highfreq, x->x_nbfilters );
+
+ // create outlets
+ x->x_outputs = (t_outlet **) getbytes( x->x_nbfilters*sizeof(t_outlet *) );
+ if ( !x->x_outputs )
+ {
+ post( "filterbank~ : could not allocate outputs" );
+ return NULL;
+ }
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ x->x_outputs[fi] = outlet_new( &x->x_obj, &s_signal );
+ }
+
+ // create filters
+ x->x_freq = (t_float *) getbytes( x->x_nbfilters*sizeof(t_float) );
+ x->x_q = (t_float *) getbytes( x->x_nbfilters*sizeof(t_float) );
+ x->x_cspace = (t_bpctl *) getbytes( x->x_nbfilters*sizeof(t_bpctl) );
+ x->x_ctl = (t_bpctl **) getbytes( x->x_nbfilters*sizeof(t_bpctl*) );
+ if ( !x->x_freq || !x->x_q || !x->x_cspace || !x->x_ctl )
+ {
+ post( "filterbank~ : could not allocate filters" );
+ return NULL;
+ }
+ abandwidth = ( x->x_highfreq - x->x_lowfreq ) / x->x_nbfilters;
+ afreq = x->x_lowfreq + ( abandwidth / 2 );
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ x->x_ctl[fi] = &x->x_cspace[fi];
+ x->x_cspace[fi].c_x1 = 0;
+ x->x_cspace[fi].c_x2 = 0;
+ Q = ( (t_float) afreq ) / ( (t_float) abandwidth );
+ miller_sigbp_docoef( x, fi, afreq, Q );
+ afreq += abandwidth;
+ }
+
+ x->x_width = x->x_nbfilters*FILTERBANK_OUTLET_WIDTH*2;
+ x->x_height = FILTERBANK_HEIGHT;
+
+ x->x_glist = (t_glist *) canvas_getcurrent();
+ x->x_f = 0;
+
+ x->x_outmapping = (t_int*) getbytes( x->x_nbfilters*sizeof( t_int ) );
+ if ( !x->x_outmapping )
+ {
+ post( "filterbank~ : cannot allocate mapping array" );
+ return NULL; // otherwise, pd schrieks
+ }
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ x->x_outmapping[fi] = fi;
+ }
+ return (x);
+}
+
+static void filterbank_free(t_filterbank_tilde *x)
+{
+ t_int ei, fi;
+
+ if ( x->x_outputs )
+ {
+ for ( ei=0; ei<x->x_nbfilters; ei++ )
+ {
+ outlet_free( x->x_outputs[ei] );
+ }
+ freebytes( x->x_outputs, x->x_nbfilters*sizeof(t_outlet*) );
+ }
+ if ( x->x_freq )
+ {
+ freebytes( x->x_freq, x->x_nbfilters*sizeof(t_float) );
+ }
+ if ( x->x_q )
+ {
+ freebytes( x->x_q, x->x_nbfilters*sizeof(t_float) );
+ }
+ if ( x->x_cspace )
+ {
+ freebytes( x->x_cspace, x->x_nbfilters*sizeof(t_bpctl) );
+ }
+ if ( x->x_ctl )
+ {
+ freebytes( x->x_ctl, x->x_nbfilters*sizeof(t_bpctl*) );
+ }
+ if ( x->x_outmapping )
+ {
+ freebytes( x->x_outmapping, x->x_nbfilters*sizeof(t_int) );
+ }
+}
+
+static t_int *filterbank_perform(t_int *w)
+{
+ t_int fi, si;
+ t_filterbank_tilde *x = (t_filterbank_tilde*)(w[1]);
+ t_int n = w[2];
+ t_float *in, *out;
+ int i;
+ t_float last, prev, coef1, coef2, gain;
+ t_float *acopy;
+ t_int noneedtofilter = 1;
+
+ in = (t_float*)w[3];
+
+ // copy input audio block
+ acopy = (t_float*) getbytes( n*sizeof( t_float ) );
+ if ( !acopy )
+ {
+ post( "filterbank~ : cannot allocate audio copy block" );
+ return 0; // otherwise, pd schrieks
+ }
+ memcpy( acopy, in, n*sizeof(t_float) );
+
+ for ( i=0; i<n; i++ )
+ {
+ if ( *(acopy+i) != 0.0 ) noneedtofilter = 0;
+ }
+
+ if ( !noneedtofilter )
+ {
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ out = (t_float *)(w[x->x_outmapping[fi]+4]);
+
+ last = x->x_ctl[fi]->c_x1;
+ prev = x->x_ctl[fi]->c_x2;
+ coef1 = x->x_ctl[fi]->c_coef1;
+ coef2 = x->x_ctl[fi]->c_coef2;
+ gain = x->x_ctl[fi]->c_gain;
+ for (i=0; i < n; i++)
+ {
+ float output = *(acopy+i) + coef1 * last + coef2 * prev;
+ *out++ = gain * output;
+ prev = last;
+ last = output;
+ }
+ /* NAN protect */
+ if (!((last <= 0) || (last >= 0)))
+ last = 0;
+ if (!((prev <= 0) || (prev >= 0)))
+ prev = 0;
+ x->x_ctl[fi]->c_x1 = last;
+ x->x_ctl[fi]->c_x2 = prev;
+ }
+ } else {
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ out = (t_float *)(w[x->x_outmapping[fi]+4]);
+ for (i=0; i < n; i++)
+ {
+ *out++ = 0.0;
+ }
+ }
+ }
+
+ if ( acopy ) freebytes( acopy, n*sizeof(t_float) );
+
+ return (w+x->x_nbfilters+4);
+}
+
+static void filterbank_dsp(t_filterbank_tilde *x, t_signal **sp)
+{
+ t_int *dspargs, fi, nbargs;
+
+ dspargs = (t_int*) getbytes( (x->x_nbfilters+3)*sizeof(t_int) );
+
+ dspargs[0] = (t_int)x;
+ dspargs[1] = (t_int)sp[0]->s_n;
+ dspargs[2] = (t_int)sp[0]->s_vec;
+
+ nbargs = 3;
+ for ( fi=0; fi<x->x_nbfilters; fi++ )
+ {
+ dspargs[3+fi] = (t_int)sp[fi+1]->s_vec;
+ nbargs++;
+ }
+
+ dsp_addv(filterbank_perform, nbargs, dspargs );
+
+ if ( dspargs ) freebytes( dspargs, (x->x_nbfilters+3)*sizeof(t_int) );
+}
+
+void filterbank_tilde_setup(void)
+{
+ post( filterbank_version );
+#include "filterbank~.tk2c"
+ filterbank_class_tilde = class_new(gensym("filterbank~"), (t_newmethod)filterbank_new,
+ (t_method)filterbank_free, sizeof(t_filterbank_tilde), 0, A_GIMME, 0);
+ CLASS_MAINSIGNALIN( filterbank_class_tilde, t_filterbank_tilde, x_f );
+ class_addmethod(filterbank_class_tilde, (t_method)filterbank_dsp, gensym("dsp"), 0);
+ class_addmethod(filterbank_class_tilde, (t_method)filterbank_dialog, gensym("dialog"), A_GIMME, 0);
+ class_addmethod(filterbank_class_tilde, (t_method)filterbank_randomize, gensym("randomize"), A_DEFFLOAT, 0);
+ filterbank_widgetbehavior.w_getrectfn = filterbank_getrect;
+ filterbank_widgetbehavior.w_displacefn = filterbank_displace;
+ filterbank_widgetbehavior.w_selectfn = filterbank_select;
+ filterbank_widgetbehavior.w_activatefn = NULL;
+ filterbank_widgetbehavior.w_deletefn = filterbank_delete;
+ filterbank_widgetbehavior.w_visfn = filterbank_vis;
+ filterbank_widgetbehavior.w_clickfn = NULL;
+ filterbank_widgetbehavior.w_propertiesfn = filterbank_properties;
+ filterbank_widgetbehavior.w_savefn = filterbank_save;
+ class_setwidget(filterbank_class_tilde, &filterbank_widgetbehavior);
+ class_sethelpsymbol(filterbank_class_tilde, gensym("help-filterbank~.pd"));
+}
diff --git a/filterbank~/filterbank~.h b/filterbank~/filterbank~.h
new file mode 100644
index 0000000..70e35ab
--- /dev/null
+++ b/filterbank~/filterbank~.h
@@ -0,0 +1,84 @@
+/* Copyright (c) 2002 Yves Degoyon. */
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL */
+/* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+/* */
+/* a header for filterbank~ which outputs frequency response */
+/* for a range of filters */
+/* */
+/* The filter code is taken from Speech Filing System */
+/* from Mark Huckvale, University College London */
+/* */
+/* 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. */
+/* */
+/* See file LICENSE for further informations on licensing terms. */
+/* */
+/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* Made while listening to : */
+/* */
+/* Twine -- Instrumentals */
+/* Andy T -- Poetry */
+/* ---------------------------------------------------------------------------- */
+
+#ifndef __FILTERBANK_H
+#define __FILTERBANK_H
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <ctype.h>
+#include "m_imp.h"
+#include "g_canvas.h"
+#include "t_tk.h"
+
+/* this code is borrowed from pd's object : bp~ */
+
+typedef struct bpctl
+{
+ float c_x1;
+ float c_x2;
+ float c_coef1;
+ float c_coef2;
+ float c_gain;
+} t_bpctl;
+
+typedef struct _filterbank_tilde
+{
+ t_object x_obj;
+ t_glist *x_glist;
+ t_int x_samplerate; /* system sample rate */
+ t_int x_lowfreq; /* lower frequency of all filters */
+ t_int x_highfreq; /* higher frequency of all filters */
+ t_int x_nbfilters; /* number of filters */
+ t_outlet **x_outputs; /* outputs for frequency responses */
+ t_int x_nselected; /* index of item selected */
+ t_int x_width; /* graphical x size ( not setable ) */
+ t_int x_height; /* graphical y size ( not setable ) */
+ t_int x_selected; /* selection flag */
+ t_int x_allocate; /* allocation flag */
+ t_int *x_outmapping; /* output mapping array */
+
+ // bp~ section : borrowed from pd's d_filter.c
+ float x_sr;
+ float *x_freq;
+ float *x_q;
+ t_bpctl *x_cspace;
+ t_bpctl **x_ctl;
+
+ t_float x_f; /* classical float for signal input */
+} t_filterbank_tilde;
+
+#endif
diff --git a/filterbank~/filterbank~.tk b/filterbank~/filterbank~.tk
new file mode 100644
index 0000000..4143802
--- /dev/null
+++ b/filterbank~/filterbank~.tk
@@ -0,0 +1,77 @@
+############ filterbank procedures -- ydegoyon@free.fr #########
+
+proc filterbank_apply {id} {
+# strip "." from the TK id to make a variable name suffix
+ set vid [string trimleft $id .]
+# for each variable, make a local variable to hold its name...
+ set var_graph_lowfreq [concat graph_lowfreq_$vid]
+ global $var_graph_lowfreq
+ set var_graph_highfreq [concat graph_highfreq_$vid]
+ global $var_graph_highfreq
+
+ set cmd [concat $id dialog \
+ [eval concat $$var_graph_lowfreq] \
+ [eval concat $$var_graph_highfreq] \
+ \;]
+ #puts stderr $cmd
+ pd $cmd
+}
+
+proc filterbank_cancel {id} {
+ set cmd [concat $id cancel \;]
+ #puts stderr $cmd
+ pd $cmd
+}
+
+proc filterbank_ok {id} {
+ filterbank_apply $id
+ filterbank_cancel $id
+}
+
+proc pdtk_filterbank_dialog {id lowfreq highfreq} {
+ set vid [string trimleft $id .]
+ set var_graph_lowfreq [concat graph_lowfreq_$vid]
+ global $var_graph_lowfreq
+ set var_graph_highfreq [concat graph_highfreq_$vid]
+ global $var_graph_highfreq
+
+ set $var_graph_lowfreq $lowfreq
+ set $var_graph_highfreq $highfreq
+
+ toplevel $id
+ wm title $id {filterbank}
+ wm protocol $id WM_DELETE_WINDOW [concat filterbank_cancel $id]
+
+ label $id.label -text {FILTERBANK PROPERTIES}
+ pack $id.label -side top
+
+ frame $id.buttonframe
+ pack $id.buttonframe -side bottom -fill x -pady 2m
+ button $id.buttonframe.cancel -text {Cancel}\
+ -command "filterbank_cancel $id"
+ button $id.buttonframe.apply -text {Apply}\
+ -command "filterbank_apply $id"
+ button $id.buttonframe.ok -text {OK}\
+ -command "filterbank_ok $id"
+ pack $id.buttonframe.cancel -side left -expand 1
+ pack $id.buttonframe.apply -side left -expand 1
+ pack $id.buttonframe.ok -side left -expand 1
+
+ frame $id.1rangef
+ pack $id.1rangef -side top
+ label $id.1rangef.llowfreq -text "Lower Frequency :"
+ entry $id.1rangef.lowfreq -textvariable $var_graph_lowfreq -width 7
+ pack $id.1rangef.llowfreq $id.1rangef.lowfreq -side left
+
+ frame $id.2rangef
+ pack $id.2rangef -side top
+ label $id.2rangef.lhighfreq -text "Higher Frequency :"
+ entry $id.2rangef.highfreq -textvariable $var_graph_highfreq -width 7
+ pack $id.2rangef.lhighfreq $id.2rangef.highfreq -side left
+
+ bind $id.1rangef.lowfreq <KeyPress-Return> [concat filterbank_ok $id]
+ bind $id.2rangef.highfreq <KeyPress-Return> [concat filterbank_ok $id]
+ focus $id.1rangef.lowfreq
+}
+
+############ filterbank procedures END -- ydegoyon@free.fr #########
diff --git a/filterbank~/help-filterbank~.pd b/filterbank~/help-filterbank~.pd
new file mode 100644
index 0000000..855e833
--- /dev/null
+++ b/filterbank~/help-filterbank~.pd
@@ -0,0 +1,199 @@
+#N canvas 122 3 868 640 10;
+#X text 387 606 bugs and comments @ ydegoyon@free.fr [-_-];
+#X text 256 524 (invoke with <right mouse>Properties );
+#X text 256 506 You can set the following properties :;
+#X text 321 108 Constructor : filterbank~ <lower freq> <higher freq>
+<nbfilters> | filterbank~;
+#X text 264 543 * Lower Frequency : lower frequency of all filters
+;
+#X text 264 556 * Higher Frequency : higher frequency of all filters
+;
+#X text 321 77 filterbank~ outputs the frequency response against a
+set of band-pass filters;
+#X obj 127 279 filterbank~ 0 2000 30;
+#X text 387 588 part of unauthorized PD ( http://ydegoyon.free.fr )
+;
+#X msg 31 20 bang;
+#X obj 31 41 openpanel;
+#X obj 31 62 t s b;
+#X obj 77 62 float \$0;
+#X text 31 1 Step 1 : Load a sound file;
+#X obj 31 83 route float;
+#X msg 336 250 bang;
+#X obj 32 179 soundfiler;
+#X obj 125 250 tabplay~ \$0-filterbank-sample;
+#X obj 31 104 makefilename %d-filterbank-sample;
+#X obj 32 137 pack s s;
+#X msg 32 158 read -resize \$1 \$2;
+#X obj 72 599 table \$0-filterbank-sample;
+#X text 321 139 Example : filterbank~ 0 3000 30;
+#X obj 86 330 env~;
+#X obj 122 307 env~;
+#X obj 121 329 env~;
+#X obj 87 306 env~;
+#X obj 101 359 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 113 359 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 125 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 138 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 91 250 dac~;
+#X obj 156 331 env~;
+#X obj 191 307 env~;
+#X obj 191 330 env~;
+#X obj 158 307 env~;
+#X obj 171 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 183 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 195 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 208 361 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 227 331 env~;
+#X obj 262 307 env~;
+#X obj 262 330 env~;
+#X obj 228 307 env~;
+#X obj 242 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 254 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 266 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 279 361 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 297 331 env~;
+#X obj 332 307 env~;
+#X obj 332 330 env~;
+#X obj 298 307 env~;
+#X obj 312 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 324 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 336 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 349 361 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 367 331 env~;
+#X obj 403 308 env~;
+#X obj 402 330 env~;
+#X obj 368 307 env~;
+#X obj 382 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 394 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 406 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 419 361 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 438 330 env~;
+#X obj 473 306 env~;
+#X obj 473 329 env~;
+#X obj 439 306 env~;
+#X obj 453 359 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 465 359 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 477 359 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 490 360 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 513 328 env~;
+#X obj 548 304 env~;
+#X obj 548 327 env~;
+#X obj 514 304 env~;
+#X obj 528 357 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 540 357 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 552 357 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 565 358 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 580 328 env~;
+#X obj 581 304 env~;
+#X obj 595 357 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X obj 607 357 vsl 8 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X text 203 228 Step 2 : See the filterbank~ output;
+#X text 451 252 Step 3 : shift all the outputs randomly;
+#X msg 458 274 randomize 1;
+#X msg 547 274 randomize 0;
+#X connect 7 0 26 0;
+#X connect 7 1 23 0;
+#X connect 7 2 24 0;
+#X connect 7 3 25 0;
+#X connect 7 4 35 0;
+#X connect 7 5 32 0;
+#X connect 7 6 33 0;
+#X connect 7 7 34 0;
+#X connect 7 8 43 0;
+#X connect 7 9 40 0;
+#X connect 7 10 41 0;
+#X connect 7 11 42 0;
+#X connect 7 12 51 0;
+#X connect 7 13 48 0;
+#X connect 7 14 49 0;
+#X connect 7 15 50 0;
+#X connect 7 16 59 0;
+#X connect 7 17 56 0;
+#X connect 7 18 57 0;
+#X connect 7 18 58 0;
+#X connect 7 20 67 0;
+#X connect 7 21 64 0;
+#X connect 7 22 65 0;
+#X connect 7 23 66 0;
+#X connect 7 24 75 0;
+#X connect 7 25 72 0;
+#X connect 7 26 73 0;
+#X connect 7 27 74 0;
+#X connect 7 28 81 0;
+#X connect 7 29 80 0;
+#X connect 9 0 10 0;
+#X connect 10 0 11 0;
+#X connect 11 0 19 0;
+#X connect 11 1 12 0;
+#X connect 12 0 14 0;
+#X connect 14 0 18 0;
+#X connect 15 0 17 0;
+#X connect 17 0 31 0;
+#X connect 17 0 7 0;
+#X connect 17 0 31 1;
+#X connect 18 0 19 1;
+#X connect 19 0 20 0;
+#X connect 20 0 16 0;
+#X connect 23 0 28 0;
+#X connect 24 0 29 0;
+#X connect 25 0 30 0;
+#X connect 26 0 27 0;
+#X connect 32 0 37 0;
+#X connect 33 0 38 0;
+#X connect 34 0 39 0;
+#X connect 35 0 36 0;
+#X connect 40 0 45 0;
+#X connect 41 0 46 0;
+#X connect 42 0 47 0;
+#X connect 43 0 44 0;
+#X connect 48 0 53 0;
+#X connect 49 0 54 0;
+#X connect 50 0 55 0;
+#X connect 51 0 52 0;
+#X connect 56 0 61 0;
+#X connect 57 0 62 0;
+#X connect 58 0 63 0;
+#X connect 59 0 60 0;
+#X connect 64 0 69 0;
+#X connect 65 0 70 0;
+#X connect 66 0 71 0;
+#X connect 67 0 68 0;
+#X connect 72 0 77 0;
+#X connect 73 0 78 0;
+#X connect 74 0 79 0;
+#X connect 75 0 76 0;
+#X connect 80 0 83 0;
+#X connect 81 0 82 0;
+#X connect 86 0 7 0;
+#X connect 87 0 7 0;
diff --git a/filterbank~/resynth-64.pd b/filterbank~/resynth-64.pd
new file mode 100644
index 0000000..bb5a93d
--- /dev/null
+++ b/filterbank~/resynth-64.pd
@@ -0,0 +1,285 @@
+#N canvas 36 14 971 657 10;
+#X obj 56 522 *~ 1;
+#X obj 103 522 / 100;
+#X floatatom 147 522 5 0 0;
+#X obj 272 280 filterbank~ 0 1920 64;
+#X obj 31 62 t s b;
+#X obj 80 68 float \$0;
+#X obj 31 85 route float;
+#X msg 336 250 bang;
+#X obj 31 177 soundfiler;
+#X obj 125 250 tabplay~ \$0-filterbank-sample;
+#X obj 31 108 makefilename %d-filterbank-sample;
+#X obj 31 131 pack s s;
+#X msg 31 154 read -resize \$1 \$2;
+#X msg 239 220 bang;
+#X obj 28 220 tabplay~ \$0-filterbank-sample;
+#X obj 72 599 table \$0-filterbank-sample;
+#X msg 430 250 randomize 1;
+#X obj 486 42 playlist all 200 200;
+#X msg 359 35 location /Samples;
+#X obj 359 12 loadbang;
+#X obj 374 569 volpan;
+#X msg 518 250 randomize 0;
+#X obj 354 123 s fbstep;
+#X floatatom 354 100 5 0 0;
+#X msg 306 91 30;
+#X obj 306 68 loadbang;
+#X floatatom 229 42 5 0 0;
+#X obj 210 68 s firstfreq;
+#X msg 181 35 15;
+#X obj 181 12 loadbang;
+#X obj 107 314 setosc 0;
+#X obj 107 337 setosc 1;
+#X obj 107 360 setosc 2;
+#X obj 107 383 setosc 3;
+#X obj 107 406 setosc 4;
+#X obj 107 429 setosc 5;
+#X obj 107 452 setosc 6;
+#X obj 108 476 setosc 7;
+#X obj 199 521 *~ 1;
+#X obj 246 521 / 100;
+#X floatatom 290 521 5 0 0;
+#X obj 250 313 setosc 8;
+#X obj 250 336 setosc 9;
+#X obj 250 359 setosc 10;
+#X obj 250 382 setosc 11;
+#X obj 250 405 setosc 12;
+#X obj 250 428 setosc 13;
+#X obj 250 451 setosc 14;
+#X obj 251 475 setosc 15;
+#X obj 339 519 *~ 1;
+#X obj 386 519 / 100;
+#X floatatom 430 519 5 0 0;
+#X obj 390 311 setosc 16;
+#X obj 390 334 setosc 17;
+#X obj 390 357 setosc 18;
+#X obj 390 380 setosc 19;
+#X obj 390 403 setosc 20;
+#X obj 390 426 setosc 21;
+#X obj 390 449 setosc 22;
+#X obj 391 473 setosc 23;
+#X obj 479 519 *~ 1;
+#X obj 526 519 / 100;
+#X floatatom 570 519 5 0 0;
+#X obj 530 311 setosc 24;
+#X obj 530 334 setosc 25;
+#X obj 530 357 setosc 26;
+#X obj 530 380 setosc 27;
+#X obj 530 403 setosc 28;
+#X obj 530 426 setosc 29;
+#X obj 530 449 setosc 30;
+#X obj 531 473 setosc 31;
+#X obj 621 518 *~ 1;
+#X obj 668 518 / 100;
+#X floatatom 712 518 5 0 0;
+#X obj 672 310 setosc 32;
+#X obj 672 333 setosc 33;
+#X obj 672 356 setosc 34;
+#X obj 672 379 setosc 35;
+#X obj 672 402 setosc 36;
+#X obj 672 425 setosc 37;
+#X obj 672 448 setosc 38;
+#X obj 673 472 setosc 39;
+#X obj 762 519 *~ 1;
+#X obj 809 519 / 100;
+#X floatatom 853 519 5 0 0;
+#X obj 813 311 setosc 40;
+#X obj 813 334 setosc 41;
+#X obj 813 357 setosc 42;
+#X obj 813 380 setosc 43;
+#X obj 813 403 setosc 44;
+#X obj 813 426 setosc 45;
+#X obj 813 449 setosc 46;
+#X obj 814 473 setosc 47;
+#X obj 903 519 *~ 1;
+#X obj 950 519 / 100;
+#X floatatom 994 519 5 0 0;
+#X obj 954 311 setosc 48;
+#X obj 954 334 setosc 49;
+#X obj 954 357 setosc 50;
+#X obj 954 380 setosc 51;
+#X obj 954 403 setosc 52;
+#X obj 954 426 setosc 53;
+#X obj 954 449 setosc 54;
+#X obj 955 473 setosc 55;
+#X obj 1041 518 *~ 1;
+#X obj 1088 518 / 100;
+#X floatatom 1132 518 5 0 0;
+#X obj 1092 310 setosc 56;
+#X obj 1092 333 setosc 57;
+#X obj 1092 356 setosc 58;
+#X obj 1092 379 setosc 59;
+#X obj 1092 402 setosc 60;
+#X obj 1092 425 setosc 61;
+#X obj 1092 448 setosc 62;
+#X obj 1093 472 setosc 63;
+#X connect 0 0 20 0;
+#X connect 1 0 0 1;
+#X connect 2 0 1 0;
+#X connect 3 0 30 0;
+#X connect 3 1 31 0;
+#X connect 3 2 32 0;
+#X connect 3 3 33 0;
+#X connect 3 4 34 0;
+#X connect 3 5 35 0;
+#X connect 3 6 36 0;
+#X connect 3 7 37 0;
+#X connect 3 8 41 0;
+#X connect 3 9 42 0;
+#X connect 3 10 43 0;
+#X connect 3 11 44 0;
+#X connect 3 12 45 0;
+#X connect 3 13 46 0;
+#X connect 3 14 47 0;
+#X connect 3 15 48 0;
+#X connect 3 16 52 0;
+#X connect 3 17 53 0;
+#X connect 3 18 54 0;
+#X connect 3 19 55 0;
+#X connect 3 20 56 0;
+#X connect 3 21 57 0;
+#X connect 3 22 58 0;
+#X connect 3 23 59 0;
+#X connect 3 24 63 0;
+#X connect 3 25 64 0;
+#X connect 3 26 65 0;
+#X connect 3 27 66 0;
+#X connect 3 28 67 0;
+#X connect 3 29 68 0;
+#X connect 3 30 69 0;
+#X connect 3 31 70 0;
+#X connect 3 32 74 0;
+#X connect 3 33 75 0;
+#X connect 3 34 76 0;
+#X connect 3 35 77 0;
+#X connect 3 36 78 0;
+#X connect 3 37 79 0;
+#X connect 3 38 80 0;
+#X connect 3 39 81 0;
+#X connect 3 40 85 0;
+#X connect 3 41 86 0;
+#X connect 3 42 87 0;
+#X connect 3 43 88 0;
+#X connect 3 44 89 0;
+#X connect 3 45 90 0;
+#X connect 3 46 91 0;
+#X connect 3 47 92 0;
+#X connect 3 48 96 0;
+#X connect 3 49 97 0;
+#X connect 3 50 98 0;
+#X connect 3 51 99 0;
+#X connect 3 52 100 0;
+#X connect 3 53 101 0;
+#X connect 3 54 102 0;
+#X connect 3 55 103 0;
+#X connect 3 56 107 0;
+#X connect 3 57 108 0;
+#X connect 3 58 109 0;
+#X connect 3 59 110 0;
+#X connect 3 60 111 0;
+#X connect 3 61 112 0;
+#X connect 3 62 113 0;
+#X connect 3 63 114 0;
+#X connect 4 0 11 0;
+#X connect 4 1 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 10 0;
+#X connect 7 0 9 0;
+#X connect 9 0 3 0;
+#X connect 10 0 11 1;
+#X connect 11 0 12 0;
+#X connect 12 0 8 0;
+#X connect 13 0 14 0;
+#X connect 14 0 0 0;
+#X connect 16 0 3 0;
+#X connect 17 0 4 0;
+#X connect 18 0 17 0;
+#X connect 19 0 18 0;
+#X connect 21 0 3 0;
+#X connect 23 0 22 0;
+#X connect 24 0 22 0;
+#X connect 25 0 24 0;
+#X connect 26 0 27 0;
+#X connect 28 0 27 0;
+#X connect 29 0 28 0;
+#X connect 30 0 0 0;
+#X connect 31 0 0 0;
+#X connect 32 0 0 0;
+#X connect 33 0 0 0;
+#X connect 34 0 0 0;
+#X connect 35 0 0 0;
+#X connect 36 0 0 0;
+#X connect 37 0 0 0;
+#X connect 38 0 20 0;
+#X connect 39 0 38 1;
+#X connect 40 0 39 0;
+#X connect 41 0 38 0;
+#X connect 42 0 38 0;
+#X connect 43 0 38 0;
+#X connect 44 0 38 0;
+#X connect 45 0 38 0;
+#X connect 46 0 38 0;
+#X connect 47 0 38 0;
+#X connect 48 0 38 0;
+#X connect 49 0 20 0;
+#X connect 50 0 49 1;
+#X connect 51 0 50 0;
+#X connect 52 0 49 0;
+#X connect 53 0 49 0;
+#X connect 54 0 49 0;
+#X connect 55 0 49 0;
+#X connect 56 0 49 0;
+#X connect 57 0 49 0;
+#X connect 58 0 49 0;
+#X connect 59 0 49 0;
+#X connect 61 0 60 1;
+#X connect 62 0 61 0;
+#X connect 63 0 60 0;
+#X connect 64 0 60 0;
+#X connect 65 0 60 0;
+#X connect 66 0 60 0;
+#X connect 67 0 60 0;
+#X connect 68 0 60 0;
+#X connect 69 0 60 0;
+#X connect 70 0 60 0;
+#X connect 72 0 71 1;
+#X connect 73 0 72 0;
+#X connect 74 0 71 0;
+#X connect 75 0 71 0;
+#X connect 76 0 71 0;
+#X connect 77 0 71 0;
+#X connect 78 0 71 0;
+#X connect 79 0 71 0;
+#X connect 80 0 71 0;
+#X connect 81 0 71 0;
+#X connect 83 0 82 1;
+#X connect 84 0 83 0;
+#X connect 85 0 82 0;
+#X connect 86 0 82 0;
+#X connect 87 0 82 0;
+#X connect 88 0 82 0;
+#X connect 89 0 82 0;
+#X connect 90 0 82 0;
+#X connect 91 0 82 0;
+#X connect 92 0 82 0;
+#X connect 94 0 93 1;
+#X connect 95 0 94 0;
+#X connect 96 0 93 0;
+#X connect 97 0 93 0;
+#X connect 98 0 93 0;
+#X connect 99 0 93 0;
+#X connect 100 0 93 0;
+#X connect 101 0 93 0;
+#X connect 102 0 93 0;
+#X connect 103 0 93 0;
+#X connect 105 0 104 1;
+#X connect 106 0 105 0;
+#X connect 107 0 104 0;
+#X connect 108 0 104 0;
+#X connect 109 0 104 0;
+#X connect 110 0 104 0;
+#X connect 111 0 104 0;
+#X connect 112 0 104 0;
+#X connect 113 0 104 0;
+#X connect 114 0 104 0;
diff --git a/filterbank~/setosc.pd b/filterbank~/setosc.pd
new file mode 100644
index 0000000..6cb4ff0
--- /dev/null
+++ b/filterbank~/setosc.pd
@@ -0,0 +1,21 @@
+#N canvas 242 244 450 300 10;
+#X obj 191 209 osc~;
+#X obj 140 247 *~;
+#X obj 140 277 outlet~;
+#X obj 83 112 inlet~;
+#X floatatom 236 186 5 0 0;
+#X msg 274 87 bang;
+#X obj 335 64 r fbstep;
+#X obj 145 55 r firstfreq;
+#X obj 217 138 expr $f1 + $f2 * \$1;
+#X obj 341 100 t b f;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 3 0 1 1;
+#X connect 5 0 8 0;
+#X connect 6 0 9 0;
+#X connect 7 0 8 0;
+#X connect 8 0 4 0;
+#X connect 8 0 0 0;
+#X connect 9 0 8 0;
+#X connect 9 1 8 1;