aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nusmuk_utils/LICENSE.txt290
-rw-r--r--nusmuk_utils/Makefile303
-rw-r--r--nusmuk_utils/README.txt8
-rw-r--r--nusmuk_utils/between-help.pd14
-rw-r--r--nusmuk_utils/between.pd30
-rw-r--r--nusmuk_utils/common.h17
-rw-r--r--nusmuk_utils/examples/bushmeat.pbank19
-rw-r--r--nusmuk_utils/filtered_random-help.pd47
-rw-r--r--nusmuk_utils/filtered_random.pd63
-rw-r--r--nusmuk_utils/fmod-help.pd9
-rw-r--r--nusmuk_utils/fmod.pd23
-rw-r--r--nusmuk_utils/lb-help.pd19
-rwxr-xr-xnusmuk_utils/lb.pd10
-rw-r--r--nusmuk_utils/lfo-help.pd21
-rw-r--r--nusmuk_utils/lfo.pd61
-rw-r--r--nusmuk_utils/line3-help.pd61
-rw-r--r--nusmuk_utils/line3.c177
-rw-r--r--nusmuk_utils/line3.pd_linuxbin0 -> 15305 bytes
-rw-r--r--nusmuk_utils/many_bang-help.pd47
-rw-r--r--nusmuk_utils/many_bang.pd100
-rw-r--r--nusmuk_utils/nusmuk_utils-meta.pd7
-rw-r--r--nusmuk_utils/once-help.pd13
-rw-r--r--nusmuk_utils/once.pd15
-rw-r--r--nusmuk_utils/p-help.pd8
-rwxr-xr-xnusmuk_utils/p.pd4
-rwxr-xr-xnusmuk_utils/pbank-help.pd562
-rwxr-xr-xnusmuk_utils/pbank.c1368
-rw-r--r--nusmuk_utils/pbank.h14
-rw-r--r--nusmuk_utils/pbank.pd_linuxbin0 -> 54522 bytes
-rw-r--r--nusmuk_utils/pps-help.pd13
-rw-r--r--nusmuk_utils/pps.pd8
-rwxr-xr-xnusmuk_utils/rand_diff-help.pd18
-rw-r--r--nusmuk_utils/rand_diff.pd34
-rwxr-xr-xnusmuk_utils/randn-help.pd20
-rwxr-xr-xnusmuk_utils/randn.pd49
-rw-r--r--nusmuk_utils/rnd_flow-help.pd27
-rw-r--r--nusmuk_utils/rnd_flow.pd70
-rw-r--r--nusmuk_utils/rnd_metro-help.pd15
-rw-r--r--nusmuk_utils/rnd_metro.pd53
39 files changed, 3617 insertions, 0 deletions
diff --git a/nusmuk_utils/LICENSE.txt b/nusmuk_utils/LICENSE.txt
new file mode 100644
index 0000000..fa0bef4
--- /dev/null
+++ b/nusmuk_utils/LICENSE.txt
@@ -0,0 +1,290 @@
+GNU GENERAL PUBLIC LICENSE
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom
+to share and change it. By contrast, the GNU General Public License is
+intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This General
+Public License applies to most of the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+(Some other Free Software Foundation software is covered by the
+GNU Library General Public License instead.) You can apply it to your
+programs, too.
+
+When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone
+to deny you these rights or to ask you to surrender the rights. These
+restrictions translate to certain responsibilities for you if you distribute
+copies of the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis
+or for a fee, you must give the recipients all the rights that you have. You
+must make sure that they, too, receive or can get the source code. And
+you must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on,
+we want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+Finally, any free program is threatened constantly by software patents.
+We wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program
+proprietary. To prevent this, we have made it clear that any patent must
+be licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and
+modification follow.
+
+TERMS AND CONDITIONS FOR
+COPYING, DISTRIBUTION AND
+MODIFICATION
+
+0. This License applies to any program or other work which contains a
+notice placed by the copyright holder saying it may be distributed under
+the terms of this General Public License. The "Program", below, refers
+to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it, either
+verbatim or with modifications and/or translated into another language.
+(Hereinafter, translation is included without limitation in the term
+"modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of running
+the Program is not restricted, and the output from the Program is
+covered only if its contents constitute a work based on the Program
+(independent of having been made by running the Program). Whether
+that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the notices
+that refer to this License and to the absence of any warranty; and give
+any other recipients of the Program a copy of this License along with the
+Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide a
+ warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but does
+ not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program, and
+can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based on
+the Program, the distribution of the whole must be on the terms of this
+License, whose permissions for other licensees extend to the entire
+whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise the
+right to control the distribution of derivative or collective works based
+on the Program.
+
+In addition, mere aggregation of another work not based on the
+Program with the Program (or with a work based on the Program) on a
+volume of a storage or distribution medium does not bring the other
+work under the scope of this License.
+
+3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding
+ machine-readable source code, which must be distributed under
+ the terms of Sections 1 and 2 above on a medium customarily
+ used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your cost
+ of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a
+ medium customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with
+ such an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to control
+compilation and installation of the executable. However, as a special
+exception, the source code distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies the
+executable.
+
+If distribution of executable or object code is made by offering access to
+copy from a designated place, then offering equivalent access to copy
+the source code from the same place counts as distribution of the source
+code, even though third parties are not compelled to copy the source
+along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt otherwise
+to copy, modify, sublicense or distribute the Program is void, and will
+automatically terminate your rights under this License. However, parties
+who have received copies, or rights, from you under this License will not
+have their licenses terminated so long as such parties remain in full
+compliance.
+
+5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and all
+its terms and conditions for copying, distributing or modifying the
+Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these terms
+and conditions. You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein. You are not responsible
+for enforcing compliance by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot distribute
+so as to satisfy simultaneously your obligations under this License and
+any other pertinent obligations, then as a consequence you may not
+distribute the Program at all. For example, if a patent license would not
+permit royalty-free redistribution of the Program by all those who
+receive copies directly or indirectly through you, then the only way you
+could satisfy both it and this License would be to refrain entirely from
+distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system, which is implemented by public license
+practices. Many people have made generous contributions to the wide
+range of software distributed through that system in reliance on
+consistent application of that system; it is up to the author/donor to
+decide if he or she is willing to distribute software through any other
+system and a licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be
+a consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an
+explicit geographical distribution limitation excluding those countries, so
+that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new
+versions of the General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may differ in
+detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number
+of this License, you may choose any version ever published by the Free
+Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we
+sometimes make exceptions for this. Our decision will be guided by the
+two goals of preserving the free status of all derivatives of our free
+software and of promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF
+CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM,
+TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
+WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE
+PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,
+EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD
+THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE
+COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW
+OR AGREED TO IN WRITING WILL ANY COPYRIGHT
+HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED
+ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
+ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT
+LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE
+WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
+OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
diff --git a/nusmuk_utils/Makefile b/nusmuk_utils/Makefile
new file mode 100644
index 0000000..8834b02
--- /dev/null
+++ b/nusmuk_utils/Makefile
@@ -0,0 +1,303 @@
+## Pd library template version 1.0.5
+# For instructions on how to use this template, see:
+# http://puredata.info/docs/developer/MakefileTemplate
+LIBRARY_NAME = nusmuk_utils
+
+# add your .c source files, one object per file, to the SOURCES
+# variable, help files will be included automatically
+SOURCES = line3.c pbank.c
+
+# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
+# be included automatically
+PDOBJECTS = pps.pd between.pd many_bang.pd rand_diff.pd filtered_random.pd randn.pd fmod.pd once.pd rnd_flow.pd lb.pd p.pd rnd_metro.pd lfo.pd
+
+# example patches and related files, in the 'examples' subfolder
+EXAMPLES = bushmeat.pbank
+
+# manuals and related files, in the 'manual' subfolder
+MANUAL =
+
+# if you want to include any other files in the source and binary tarballs,
+# list them here. This can be anything from header files, test patches,
+# documentation, etc. README.txt and LICENSE.txt are required and therefore
+# automatically included
+EXTRA_DIST = common.h pbank.h
+
+
+
+#------------------------------------------------------------------------------#
+#
+# things you might need to edit if you are using other C libraries
+#
+#------------------------------------------------------------------------------#
+
+CFLAGS = -DPD -I"$(PD_INCLUDE)" -Wall -W -g
+LDFLAGS =
+LIBS =
+
+#------------------------------------------------------------------------------#
+#
+# you shouldn't need to edit anything below here, if we did it right :)
+#
+#------------------------------------------------------------------------------#
+
+# get library version from meta file
+LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd)
+
+CFLAGS += -DVERSION='"$(LIBRARY_VERSION)"'
+
+PD_INCLUDE = $(PD_PATH)/include
+# where to install the library, overridden below depending on platform
+prefix = /usr/local
+libdir = $(prefix)/lib
+pkglibdir = $(libdir)/pd-externals
+objectsdir = $(pkglibdir)
+
+INSTALL = install
+INSTALL_PROGRAM = $(INSTALL) -p -m 644
+INSTALL_DATA = $(INSTALL) -p -m 644
+INSTALL_DIR = $(INSTALL) -p -m 755 -d
+
+ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \
+ $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows)
+
+DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION)
+ORIGDIR=pd-$(LIBRARY_NAME:~=)_$(LIBRARY_VERSION)
+
+UNAME := $(shell uname -s)
+ifeq ($(UNAME),Darwin)
+ CPU := $(shell uname -p)
+ ifeq ($(CPU),arm) # iPhone/iPod Touch
+ SOURCES += $(SOURCES_iphoneos)
+ EXTENSION = pd_darwin
+ OS = iphoneos
+ PD_PATH = /Applications/Pd-extended.app/Contents/Resources
+ IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
+ CC=$(IPHONE_BASE)/gcc
+ CPP=$(IPHONE_BASE)/cpp
+ CXX=$(IPHONE_BASE)/g++
+ ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk
+ IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6
+ OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer
+ CFLAGS := $(IPHONE_CFLAGS) $(OPT_CFLAGS) $(CFLAGS)
+ LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT)
+ LIBS += -lc
+ STRIP = strip -x
+ DISTBINDIR=$(DISTDIR)-$(OS)
+ else # Mac OS X
+ SOURCES += $(SOURCES_macosx)
+ EXTENSION = pd_darwin
+ OS = macosx
+ PD_PATH = /Applications/Pd-extended.app/Contents/Resources
+ OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast
+# build universal 32-bit on 10.4 and 32/64 on newer
+ ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8)
+ FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4
+ else
+ FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
+ SOURCES += $(SOURCES_iphoneos)
+ endif
+ CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include
+ LDFLAGS += $(FAT_FLAGS) -bundle -undefined dynamic_lookup -L/sw/lib
+ # if the 'pd' binary exists, check the linking against it to aid with stripping
+ LDFLAGS += $(shell test -e $(PD_PATH)/bin/pd && echo -bundle_loader $(PD_PATH)/bin/pd)
+ LIBS += -lc
+ STRIP = strip -x
+ DISTBINDIR=$(DISTDIR)-$(OS)
+# install into ~/Library/Pd on Mac OS X since /usr/local isn't used much
+ pkglibdir=$(HOME)/Library/Pd
+ endif
+endif
+ifeq ($(UNAME),Linux)
+ CPU := $(shell uname -m)
+ SOURCES += $(SOURCES_linux)
+ EXTENSION = pd_linux
+ OS = linux
+ PD_PATH = /usr
+ OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+ CFLAGS += -fPIC
+ LDFLAGS += -Wl,--export-dynamic -shared -fPIC
+ LIBS += -lc
+ STRIP = strip --strip-unneeded -R .note -R .comment
+ DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
+endif
+ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME)))
+ CPU := $(shell uname -m)
+ SOURCES += $(SOURCES_cygwin)
+ EXTENSION = dll
+ OS = cygwin
+ PD_PATH = $(cygpath $(PROGRAMFILES))/pd
+ OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+ CFLAGS +=
+ LDFLAGS += -Wl,--export-dynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin"
+ LIBS += -lc -lpd
+ STRIP = strip --strip-unneeded -R .note -R .comment
+ DISTBINDIR=$(DISTDIR)-$(OS)
+endif
+ifeq (MINGW,$(findstring MINGW,$(UNAME)))
+ CPU := $(shell uname -m)
+ SOURCES += $(SOURCES_windows)
+ EXTENSION = dll
+ OS = windows
+ PD_PATH = $(shell cd "$(PROGRAMFILES)"/pd && pwd)
+ OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer
+ CFLAGS += -mms-bitfields
+ LDFLAGS += -s -shared -Wl,--enable-auto-import
+ LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" -lpd -lwsock32 -lkernel32 -luser32 -lgdi32
+ STRIP = strip --strip-unneeded -R .note -R .comment
+ DISTBINDIR=$(DISTDIR)-$(OS)
+endif
+
+# in case somebody manually set the HELPPATCHES above
+HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd)
+
+CFLAGS += $(OPT_CFLAGS)
+
+
+.PHONY = install libdir_install single_install install-doc install-exec install-examples install-manual clean dist etags $(LIBRARY_NAME)
+
+all: $(SOURCES:.c=.$(EXTENSION))
+
+%.o: %.c
+ $(CC) $(CFLAGS) -o "$*.o" -c "$*.c"
+
+%.$(EXTENSION): %.o
+ $(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(LIBS)
+ chmod a-x "$*.$(EXTENSION)"
+
+# this links everything into a single binary file
+$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o
+ $(CC) $(LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(LIBS)
+ chmod a-x $(LIBRARY_NAME).$(EXTENSION)
+
+install: libdir_install
+
+# The meta and help files are explicitly installed to make sure they are
+# actually there. Those files are not optional, then need to be there.
+libdir_install: $(SOURCES:.c=.$(EXTENSION)) install-doc install-examples install-manual
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \
+ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ test -z "$(strip $(SOURCES))" || (\
+ $(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \
+ $(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION))))
+ test -z "$(strip $(PDOBJECTS))" || \
+ $(INSTALL_DATA) $(PDOBJECTS) \
+ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+
+# install library linked as single binary
+single_install: $(LIBRARY_NAME) install-doc install-exec
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION)
+
+install-doc:
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ test -z "$(strip $(SOURCES) $(PDOBJECTS))" || \
+ $(INSTALL_DATA) $(HELPPATCHES) \
+ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(INSTALL_DATA) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt
+ $(INSTALL_DATA) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt
+
+install-examples:
+ test -z "$(strip $(EXAMPLES))" || \
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples && \
+ for file in $(EXAMPLES); do \
+ $(INSTALL_DATA) examples/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples; \
+ done
+
+install-manual:
+ test -z "$(strip $(MANUAL))" || \
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual && \
+ for file in $(MANUAL); do \
+ $(INSTALL_DATA) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \
+ done
+
+
+clean:
+ -rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o)
+ -rm -f -- $(SOURCES:.c=.$(EXTENSION))
+ -rm -f -- $(LIBRARY_NAME).o
+ -rm -f -- $(LIBRARY_NAME).$(EXTENSION)
+
+distclean: clean
+ -rm -f -- $(DISTBINDIR).tar.gz
+ -rm -rf -- $(DISTBINDIR)
+ -rm -f -- $(DISTDIR).tar.gz
+ -rm -rf -- $(DISTDIR)
+ -rm -f -- $(ORIGDIR).tar.gz
+ -rm -rf -- $(ORIGDIR)
+
+
+$(DISTBINDIR):
+ $(INSTALL_DIR) $(DISTBINDIR)
+
+libdir: all $(DISTBINDIR)
+ $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTBINDIR)
+ $(INSTALL_DATA) $(SOURCES) $(DISTBINDIR)
+ $(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR)
+ test -z "$(strip $(EXTRA_DIST))" || \
+ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTBINDIR)
+# tar --exclude-vcs -czpf $(DISTBINDIR).tar.gz $(DISTBINDIR)
+
+$(DISTDIR):
+ $(INSTALL_DIR) $(DISTDIR)
+
+$(ORIGDIR):
+ $(INSTALL_DIR) $(ORIGDIR)
+
+dist: $(DISTDIR)
+ $(INSTALL_DATA) Makefile $(DISTDIR)
+ $(INSTALL_DATA) README.txt $(DISTDIR)
+ $(INSTALL_DATA) LICENSE.txt $(DISTDIR)
+ $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTDIR)
+ test -z "$(strip $(ALLSOURCES))" || \
+ $(INSTALL_DATA) $(ALLSOURCES) $(DISTDIR)
+ test -z "$(strip $(PDOBJECTS))" || \
+ $(INSTALL_DATA) $(PDOBJECTS) $(DISTDIR)
+ test -z "$(strip $(HELPPATCHES))" || \
+ $(INSTALL_DATA) $(HELPPATCHES) $(DISTDIR)
+ test -z "$(strip $(EXTRA_DIST))" || \
+ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTDIR)
+ test -z "$(strip $(EXAMPLES))" || \
+ $(INSTALL_DIR) $(DISTDIR)/examples && \
+ for file in $(EXAMPLES); do \
+ $(INSTALL_DATA) examples/$$file $(DISTDIR)/examples; \
+ done
+ test -z "$(strip $(MANUAL))" || \
+ $(INSTALL_DIR) $(DISTDIR)/manual && \
+ for file in $(MANUAL); do \
+ $(INSTALL_DATA) manual/$$file $(DISTDIR)/manual; \
+ done
+ tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR)
+
+# make a Debian source package
+dpkg-source:
+ debclean
+ make distclean dist
+ mv $(DISTDIR) $(ORIGDIR)
+ tar --exclude-vcs -czpf ../$(ORIGDIR).orig.tar.gz $(ORIGDIR)
+ rm -f -- $(DISTDIR).tar.gz
+ rm -rf -- $(DISTDIR) $(ORIGDIR)
+ cd .. && dpkg-source -b $(LIBRARY_NAME)
+
+etags:
+ etags *.h $(SOURCES) ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h
+
+showsetup:
+ @echo "CFLAGS: $(CFLAGS)"
+ @echo "LDFLAGS: $(LDFLAGS)"
+ @echo "LIBS: $(LIBS)"
+ @echo "PD_INCLUDE: $(PD_INCLUDE)"
+ @echo "PD_PATH: $(PD_PATH)"
+ @echo "objectsdir: $(objectsdir)"
+ @echo "LIBRARY_NAME: $(LIBRARY_NAME)"
+ @echo "LIBRARY_VERSION: $(LIBRARY_VERSION)"
+ @echo "SOURCES: $(SOURCES)"
+ @echo "PDOBJECTS: $(PDOBJECTS)"
+ @echo "ALLSOURCES: $(ALLSOURCES)"
+ @echo "UNAME: $(UNAME)"
+ @echo "CPU: $(CPU)"
+ @echo "pkglibdir: $(pkglibdir)"
+ @echo "DISTDIR: $(DISTDIR)"
+ @echo "ORIGDIR: $(ORIGDIR)"
diff --git a/nusmuk_utils/README.txt b/nusmuk_utils/README.txt
new file mode 100644
index 0000000..34b4486
--- /dev/null
+++ b/nusmuk_utils/README.txt
@@ -0,0 +1,8 @@
+This are a collection of usefull abstraction and that can be usefull.
+
+This lib is made by Cyrille Henry (exept pbank for zack settel), you can contact him on his webpage :
+http://www.chnry.net/ch/?001-Cyrille-Henry
+
+This lib is realese under the GNU Public License.
+
+To build it, just type make.
diff --git a/nusmuk_utils/between-help.pd b/nusmuk_utils/between-help.pd
new file mode 100644
index 0000000..f8dd77a
--- /dev/null
+++ b/nusmuk_utils/between-help.pd
@@ -0,0 +1,14 @@
+#N canvas 0 0 450 300 10;
+#X obj 29 91 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 29 183 5 0 0 0 - - -;
+#X floatatom 68 131 5 0 0 0 - - -;
+#X floatatom 108 131 5 0 0 0 - - -;
+#X obj 29 156 between 2 15;
+#X text 164 129 input range;
+#X text 62 20 output a float that is between a min and a max;
+#X text 52 90 <-- bang;
+#X connect 0 0 4 0;
+#X connect 2 0 4 1;
+#X connect 3 0 4 2;
+#X connect 4 0 1 0;
diff --git a/nusmuk_utils/between.pd b/nusmuk_utils/between.pd
new file mode 100644
index 0000000..2ddfead
--- /dev/null
+++ b/nusmuk_utils/between.pd
@@ -0,0 +1,30 @@
+#N canvas 0 0 757 565 10;
+#X obj 61 29 inlet;
+#X obj 211 31 inlet;
+#X obj 350 33 inlet;
+#X obj 195 172 \$1;
+#X obj 225 352 / 100000;
+#X obj 225 281 i;
+#X obj 195 380 +;
+#X obj 195 206 t f f;
+#X obj 195 410 outlet;
+#X obj 225 230 - \$2;
+#X obj 225 304 t b f;
+#X obj 225 328 random 0;
+#X obj 225 256 * -100000;
+#X obj 61 67 t b;
+#X connect 0 0 13 0;
+#X connect 1 0 3 1;
+#X connect 2 0 9 1;
+#X connect 3 0 7 0;
+#X connect 4 0 6 1;
+#X connect 5 0 10 0;
+#X connect 6 0 8 0;
+#X connect 7 0 6 0;
+#X connect 7 1 9 0;
+#X connect 9 0 12 0;
+#X connect 10 0 11 0;
+#X connect 10 1 11 1;
+#X connect 11 0 4 0;
+#X connect 12 0 5 0;
+#X connect 13 0 3 0;
diff --git a/nusmuk_utils/common.h b/nusmuk_utils/common.h
new file mode 100644
index 0000000..3f4a1c8
--- /dev/null
+++ b/nusmuk_utils/common.h
@@ -0,0 +1,17 @@
+/* common.h -- those things we define often */
+
+#define InRange(v,lo,hi) ((v)<=(hi)&&(v)>=(lo))
+#define MAXIUM(a,b) ((a)>(b)?(a):(b))
+#define MINIUM(a,b) ((a)<(b)?(a):(b))
+
+#define RetKey 13
+#define EnterKey 3
+#define SpaceBar 32
+#define BackSpace 8
+#define BackSlash 0x5C
+#define VertBar 0x7C
+#define Grave 0x60
+#define Tilde 0x7E
+#define TabKey 9
+#define ClearKey 27
+#define OptionSpace 202
diff --git a/nusmuk_utils/examples/bushmeat.pbank b/nusmuk_utils/examples/bushmeat.pbank
new file mode 100644
index 0000000..1b83547
--- /dev/null
+++ b/nusmuk_utils/examples/bushmeat.pbank
@@ -0,0 +1,19 @@
+pbank 4 12,
+ 166 1.10236 236 94,
+ 874 0.629921 7086 85,
+ 2286
+0.629921 4251 85,
+ 285.433 1.43937 2792.13 71,
+ 585.61 1.48661
+2886.93 75,
+ 165.362 3.46457 7414.57 75,
+ 5935.83 0.209449 9764.96
+75,
+ 403 0.472441 9921 75,
+ 403 0.472441 6692 75,
+ 403 0.472441
+1811 75,
+ CarrierFQ ModulatorFQ FMindex Gain,
+ PARAM1 PARAM2 PARAM3
+PARAM4,
+ \ No newline at end of file
diff --git a/nusmuk_utils/filtered_random-help.pd b/nusmuk_utils/filtered_random-help.pd
new file mode 100644
index 0000000..19e726b
--- /dev/null
+++ b/nusmuk_utils/filtered_random-help.pd
@@ -0,0 +1,47 @@
+#N canvas 374 22 791 605 10;
+#X obj 84 102 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 240 1;
+#X obj 85 363 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 0 1;
+#X obj 111 362 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 12033 1;
+#X obj 187 362 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 5750 1;
+#X obj 214 362 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 6142 1;
+#X obj 283 362 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 126 1;
+#X obj 310 362 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 7655 1;
+#X obj 85 244 filtered_random 127 0 0.3 20 0;
+#X obj 84 79 filtered_random 127 0 0 20 0;
+#X obj 187 282 filtered_random 127 0 0 20 500;
+#X obj 310 339 filtered_random 127 0 0 20 100;
+#X obj 111 263 filtered_random 127 0 -0.3 20 0;
+#X obj 283 320 filtered_random 1000 0 0.5 20 100;
+#X floatatom 84 12 5 0 0 0 - - -;
+#X floatatom 220 12 5 0 0 0 - - -;
+#X floatatom 344 12 5 0 0 0 - - -;
+#X floatatom 470 12 5 0 0 0 - - -;
+#X floatatom 612 12 5 0 0 0 - - -;
+#X text 446 450 related to :;
+#X text 345 28 courbe (-1 1);
+#X text 470 26 metro (20 5000..);
+#X text 610 27 line (0 5000..);
+#X text 89 28 amplitude (0 1..);
+#X text 223 29 offset (0 1..);
+#X text 82 -36 generate stream of number \, based on random;
+#X obj 448 471 rnd_flow;
+#X obj 214 301 filtered_random 127 0 0 20 1500;
+#X connect 7 0 1 0;
+#X connect 8 0 0 0;
+#X connect 9 0 3 0;
+#X connect 10 0 6 0;
+#X connect 11 0 2 0;
+#X connect 12 0 5 0;
+#X connect 13 0 8 0;
+#X connect 14 0 8 1;
+#X connect 15 0 8 2;
+#X connect 16 0 8 3;
+#X connect 17 0 8 4;
+#X connect 26 0 4 0;
diff --git a/nusmuk_utils/filtered_random.pd b/nusmuk_utils/filtered_random.pd
new file mode 100644
index 0000000..028174d
--- /dev/null
+++ b/nusmuk_utils/filtered_random.pd
@@ -0,0 +1,63 @@
+#N canvas 144 268 750 421 10;
+#X obj 58 279 outlet;
+#X obj 58 259 line;
+#X obj 58 79 loadbang;
+#X msg 58 99 1;
+#X text 86 -52 amplitude (0-100);
+#X text 220 -51 offset (0-100);
+#X text 467 -54 metro (20-5000);
+#X obj 83 -71 inlet;
+#X obj 220 -71 inlet;
+#X obj 339 -71 inlet;
+#X obj 464 -71 inlet;
+#X obj 590 -71 inlet;
+#X obj 58 199 * \$1;
+#X obj 58 219 + \$2;
+#X obj 58 179 pow \$3;
+#X obj 58 239 pack f \$5;
+#X obj 464 19 moses 0;
+#X msg 464 40 20;
+#X obj 58 139 random 100000;
+#X obj 58 159 / 100000;
+#X obj 58 119 metro 20;
+#X obj 472 -21 loadbang;
+#X obj 464 -2 \$4;
+#X obj 339 112 exp;
+#X msg 371 55 2;
+#X obj 371 74 log;
+#X obj 339 93 *;
+#X obj 346 -21 loadbang;
+#X obj 339 36 t f b;
+#X obj 339 -2 \$3;
+#X text 342 -52 courbe (-1 1);
+#X text 587 -52 line (0-5000);
+#X obj 339 17 * 10;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 3 0 20 0;
+#X connect 7 0 12 1;
+#X connect 8 0 13 1;
+#X connect 9 0 29 0;
+#X connect 10 0 22 0;
+#X connect 11 0 15 1;
+#X connect 12 0 13 0;
+#X connect 13 0 15 0;
+#X connect 14 0 12 0;
+#X connect 15 0 1 0;
+#X connect 16 0 17 0;
+#X connect 16 1 20 1;
+#X connect 17 0 20 1;
+#X connect 18 0 19 0;
+#X connect 19 0 14 0;
+#X connect 20 0 18 0;
+#X connect 21 0 22 0;
+#X connect 22 0 16 0;
+#X connect 23 0 14 1;
+#X connect 24 0 25 0;
+#X connect 25 0 26 1;
+#X connect 26 0 23 0;
+#X connect 27 0 29 0;
+#X connect 28 0 26 0;
+#X connect 28 1 24 0;
+#X connect 29 0 32 0;
+#X connect 32 0 28 0;
diff --git a/nusmuk_utils/fmod-help.pd b/nusmuk_utils/fmod-help.pd
new file mode 100644
index 0000000..b1ebd3c
--- /dev/null
+++ b/nusmuk_utils/fmod-help.pd
@@ -0,0 +1,9 @@
+#N canvas 1 22 449 300 10;
+#X obj 58 100 fmod 2.34;
+#X text 97 13 float version for mod;
+#X floatatom 58 80 5 0 0 0 - - -;
+#X floatatom 109 81 5 0 0 0 - - -;
+#X floatatom 58 123 5 0 0 0 - - -;
+#X connect 0 0 4 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 1;
diff --git a/nusmuk_utils/fmod.pd b/nusmuk_utils/fmod.pd
new file mode 100644
index 0000000..b8b9dab
--- /dev/null
+++ b/nusmuk_utils/fmod.pd
@@ -0,0 +1,23 @@
+#N canvas 714 472 314 297 10;
+#X obj 52 36 inlet;
+#X obj 52 208 outlet;
+#X obj 110 36 inlet;
+#X obj 52 64 / \$1;
+#X obj 52 188 * \$1;
+#X obj 84 106 int;
+#X obj 52 84 t f f;
+#X obj 52 126 -;
+#X obj 52 146 moses 0;
+#X obj 52 167 + 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 8 0;
+#X connect 8 0 9 0;
+#X connect 8 1 4 0;
+#X connect 9 0 4 0;
diff --git a/nusmuk_utils/lb-help.pd b/nusmuk_utils/lb-help.pd
new file mode 100644
index 0000000..2469e6b
--- /dev/null
+++ b/nusmuk_utils/lb-help.pd
@@ -0,0 +1,19 @@
+#N canvas 198 102 450 300 10;
+#X obj 83 92 lb;
+#X obj 113 92 loadbang;
+#X obj 83 112 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 113 113 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 58 92 lb;
+#X obj 58 112 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 205 91 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 205 112 s lb;
+#X text 102 29 This is mostly a shortcut for loadbang;
+#X text 103 45 you can send bangs to lb;
+#X connect 0 0 2 0;
+#X connect 1 0 3 0;
+#X connect 4 0 5 0;
+#X connect 6 0 7 0;
diff --git a/nusmuk_utils/lb.pd b/nusmuk_utils/lb.pd
new file mode 100755
index 0000000..eb73036
--- /dev/null
+++ b/nusmuk_utils/lb.pd
@@ -0,0 +1,10 @@
+#N canvas 583 629 201 161 10;
+#X obj 36 86 loadbang;
+#X obj 18 17 inlet;
+#X obj 18 108 outlet;
+#X obj 33 41 r lb;
+#X obj 18 63 t b;
+#X connect 0 0 2 0;
+#X connect 1 0 4 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
diff --git a/nusmuk_utils/lfo-help.pd b/nusmuk_utils/lfo-help.pd
new file mode 100644
index 0000000..658695f
--- /dev/null
+++ b/nusmuk_utils/lfo-help.pd
@@ -0,0 +1,21 @@
+#N canvas 77 355 426 472 10;
+#X floatatom 54 63 5 0 0 0 - - -;
+#X obj 54 237 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 3302 1;
+#X obj 54 188 * 127;
+#X text 93 85 creation arguments:;
+#X text 125 125 2 time grain in milliseconds;
+#X text 123 105 1 period time (ms);
+#X text 152 25 Low Frequency Modulator;
+#X text 105 63 <- time (ms);
+#X obj 54 165 lfo 2000 20 ______;
+#X obj 177 238 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 12700 1;
+#X obj 177 209 * 64;
+#X obj 177 188 + 1;
+#X connect 0 0 8 0;
+#X connect 2 0 1 0;
+#X connect 8 0 2 0;
+#X connect 8 1 11 0;
+#X connect 10 0 9 0;
+#X connect 11 0 10 0;
diff --git a/nusmuk_utils/lfo.pd b/nusmuk_utils/lfo.pd
new file mode 100644
index 0000000..2bb7330
--- /dev/null
+++ b/nusmuk_utils/lfo.pd
@@ -0,0 +1,61 @@
+#N canvas 193 96 408 667 10;
+#X obj 32 44 inlet;
+#X obj 200 41 loadbang;
+#X msg 200 95 1;
+#X obj 200 213 metro;
+#X obj 230 97 \$2;
+#X obj 230 125 sel 0;
+#X msg 230 152 20;
+#X obj 200 67 t b b;
+#X obj 200 636 outlet;
+#X obj 230 185 f;
+#X obj 58 258 /;
+#X obj 271 40 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 58 284 t b f;
+#X msg 58 232 1 \$1;
+#X obj 32 339 *;
+#X obj 32 317 \$1;
+#X obj 200 555 -;
+#X obj 230 532 i;
+#X obj 32 383 /;
+#X msg 32 362 1 \$1;
+#X obj 200 508 t f f;
+#X obj 276 634 outlet;
+#X obj 276 589 * 3.14159;
+#X obj 276 613 sin;
+#X obj 276 568 * 2;
+#X obj 200 451 f;
+#X obj 200 480 +;
+#X connect 0 0 15 0;
+#X connect 1 0 7 0;
+#X connect 2 0 3 0;
+#X connect 3 0 25 0;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 5 1 9 0;
+#X connect 6 0 9 0;
+#X connect 7 0 2 0;
+#X connect 7 1 4 0;
+#X connect 9 0 3 1;
+#X connect 9 0 13 0;
+#X connect 10 0 12 0;
+#X connect 11 0 7 0;
+#X connect 12 0 15 0;
+#X connect 12 1 14 1;
+#X connect 13 0 10 0;
+#X connect 14 0 19 0;
+#X connect 15 0 14 0;
+#X connect 16 0 8 0;
+#X connect 16 0 24 0;
+#X connect 16 0 25 1;
+#X connect 17 0 16 1;
+#X connect 18 0 26 1;
+#X connect 19 0 18 0;
+#X connect 20 0 16 0;
+#X connect 20 1 17 0;
+#X connect 22 0 23 0;
+#X connect 23 0 21 0;
+#X connect 24 0 22 0;
+#X connect 25 0 26 0;
+#X connect 26 0 20 0;
diff --git a/nusmuk_utils/line3-help.pd b/nusmuk_utils/line3-help.pd
new file mode 100644
index 0000000..77a9a5d
--- /dev/null
+++ b/nusmuk_utils/line3-help.pd
@@ -0,0 +1,61 @@
+#N canvas 256 172 683 616 10;
+#X obj 33 279 line3;
+#X msg 32 44 0 1000;
+#X msg 43 66 127 1000;
+#N canvas 0 0 450 300 graph3 0;
+#X array line3 100 float 2;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 306 174 graph;
+#X obj 33 394 t f b;
+#X obj 63 440 + 1;
+#X obj 63 418 f;
+#X obj 63 466 % 100;
+#X obj 62 163 random 127;
+#X obj 62 114 metro 300;
+#X msg 62 186 \$1 1000;
+#X obj 62 91 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 149 279 line;
+#N canvas 0 0 450 300 graph1 0;
+#X array line 100 float 2;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 306 314 graph;
+#X obj 33 525 tabwrite line3;
+#X obj 149 526 tabwrite line;
+#X text 290 7 line3;
+#N canvas 0 0 450 300 nothing 0;
+#X obj 29 22 inlet;
+#X obj 29 52 outlet;
+#X connect 0 0 1 0;
+#X restore 33 218 pd nothing;
+#X obj 80 139 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 168 40 line3 is compatible with line \, but the transition
+is made with a 3d order polynome. coeficiant of this polynome are adjusted
+to have the continuity of the output variation speed.;
+#X obj 33 317 - 63.5;
+#X obj 149 318 - 63.5;
+#X obj 149 342 / 63.5;
+#X obj 33 340 / 63.5;
+#X connect 0 0 20 0;
+#X connect 1 0 17 0;
+#X connect 2 0 17 0;
+#X connect 4 0 14 0;
+#X connect 4 1 6 0;
+#X connect 5 0 7 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 7 0 14 1;
+#X connect 7 0 15 1;
+#X connect 8 0 10 0;
+#X connect 9 0 8 0;
+#X connect 10 0 17 0;
+#X connect 11 0 9 0;
+#X connect 12 0 21 0;
+#X connect 17 0 0 0;
+#X connect 17 0 12 0;
+#X connect 18 0 8 0;
+#X connect 20 0 23 0;
+#X connect 21 0 22 0;
+#X connect 22 0 15 0;
+#X connect 23 0 4 0;
diff --git a/nusmuk_utils/line3.c b/nusmuk_utils/line3.c
new file mode 100644
index 0000000..25dcd8e
--- /dev/null
+++ b/nusmuk_utils/line3.c
@@ -0,0 +1,177 @@
+// line3
+// based on miller puckette line object (so licence / copyright comes from pure data)
+// compatible with line, but with a 3d order polynome.
+// there is continuity of the variation speed
+
+/*
+This software is copyrighted by Miller Puckette and others. The following
+terms (the "Standard Improved BSD License") apply to all files associated with
+the software unless explicitly disclaimed in individual files:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+3. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// Cyrille Henry 01 2005
+
+
+#include "m_pd.h"
+
+static t_class *line3_class;
+
+typedef struct _line3
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ double x_targettime;
+ t_float x_targetval,setderiv, a, b;
+ double x_prevtime;
+ t_float x_setval;
+ int x_gotinlet;
+ t_float x_grain;
+ double x_1overtimediff;
+ double x_in1val;
+} t_line3;
+
+void line3_tick(t_line3 *x)
+{
+ double tmp, t;
+ double timenow = clock_getsystime();
+ double msectogo = - clock_gettimesince(x->x_targettime);
+ if (msectogo < 1E-9)
+ {
+ outlet_float(x->x_obj.ob_outlet, x->x_targetval);
+ }
+ else
+ {
+ t = (timenow - x->x_prevtime);
+
+ tmp = x->a * t * t * t + x->b * t * t + x->setderiv * t + x->x_setval;
+
+ outlet_float(x->x_obj.ob_outlet, tmp);
+ clock_delay(x->x_clock, (x->x_grain > msectogo ? msectogo : x->x_grain));
+ }
+}
+
+void line3_float(t_line3 *x, t_float f)
+{
+ double timenow = clock_getsystime();
+ if (x->x_gotinlet && x->x_in1val > 0)
+ {
+ if (timenow >= x->x_targettime)
+ {
+ x->x_setval = x->x_targetval;
+ x->setderiv = 0;
+ }
+ else
+ {
+ x->x_setval = x->a * (timenow - x->x_prevtime) * (timenow - x->x_prevtime) * (timenow - x->x_prevtime) + x->b * (timenow - x->x_prevtime) * (timenow - x->x_prevtime) + x->setderiv * (timenow - x->x_prevtime) + x->x_setval;
+
+ x->setderiv = 3 * x->a * (timenow - x->x_prevtime) * (timenow - x->x_prevtime) + 2 * x->b * (timenow - x->x_prevtime) + x->setderiv;
+
+ }
+ x->x_prevtime = timenow;
+ x->x_targettime = clock_getsystimeafter(x->x_in1val);
+ x->x_targetval = f;
+ x->x_1overtimediff = 1./ (x->x_targettime - timenow);
+
+ x->a = -2 * (x->x_targetval - x->x_setval) * x->x_1overtimediff;
+ x->a += x->setderiv;
+ x->a *= x->x_1overtimediff;
+ x->a *= x->x_1overtimediff;
+
+ x->b = 3 * (x->x_targetval - x->x_setval) * x->x_1overtimediff;
+ x->b -= 2 * x->setderiv;
+ x->b *= x->x_1overtimediff;
+
+ line3_tick(x);
+ x->x_gotinlet = 0;
+
+ clock_delay(x->x_clock, (x->x_grain > x->x_in1val ? x->x_in1val : x->x_grain));
+ }
+ else
+ {
+ clock_unset(x->x_clock);
+ x->x_targetval = x->x_setval = f;
+ x->x_targettime = timenow;
+ outlet_float(x->x_obj.ob_outlet, f);
+ }
+ x->x_gotinlet = 0;
+}
+
+void line3_ft1(t_line3 *x, t_floatarg g)
+{
+ x->x_in1val = g;
+ x->x_gotinlet = 1;
+}
+
+void line3_stop(t_line3 *x)
+{
+ x->x_targetval = x->x_setval;
+ clock_unset(x->x_clock);
+}
+
+void line3_set(t_line3 *x, t_floatarg f)
+{
+ clock_unset(x->x_clock);
+ x->x_targetval = x->x_setval = f;
+ x->setderiv = 0;
+}
+
+void line3_free(t_line3 *x)
+{
+ clock_free(x->x_clock);
+}
+
+void *line3_new(t_floatarg f, t_floatarg grain)
+{
+ t_line3 *x = (t_line3 *)pd_new(line3_class);
+ x->x_targetval = x->x_setval = f;
+ x->x_gotinlet = 0;
+ x->setderiv = 0;
+ x->x_1overtimediff = 1;
+ x->x_clock = clock_new(x, (t_method)line3_tick);
+ x->x_targettime = x->x_prevtime = clock_getsystime();
+ if (grain <= 0) grain = 20;
+ x->x_grain = grain;
+ outlet_new(&x->x_obj, gensym("float"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
+ return (x);
+}
+
+void line3_setup(void)
+{
+ line3_class = class_new(gensym("line3"), (t_newmethod)line3_new,
+ (t_method)line3_free, sizeof(t_line3), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(line3_class, (t_method)line3_ft1,
+ gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(line3_class, (t_method)line3_stop,
+ gensym("stop"), 0);
+ class_addmethod(line3_class, (t_method)line3_set,
+ gensym("set"), A_FLOAT, 0);
+ class_addfloat(line3_class, (t_method)line3_float);
+}
diff --git a/nusmuk_utils/line3.pd_linux b/nusmuk_utils/line3.pd_linux
new file mode 100644
index 0000000..5133bf1
--- /dev/null
+++ b/nusmuk_utils/line3.pd_linux
Binary files differ
diff --git a/nusmuk_utils/many_bang-help.pd b/nusmuk_utils/many_bang-help.pd
new file mode 100644
index 0000000..d296adb
--- /dev/null
+++ b/nusmuk_utils/many_bang-help.pd
@@ -0,0 +1,47 @@
+#N canvas 0 0 742 777 10;
+#X obj 40 91 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 112 155 print done;
+#X obj 40 155 print;
+#X msg 69 92 stop;
+#X obj 40 125 many_bang 5;
+#X text 163 126 output 5 bangs;
+#X obj 45 236 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 138 299 print done;
+#X obj 45 300 print;
+#X msg 74 237 stop;
+#X text 168 271 output between 2 and 15 bangs;
+#X obj 47 381 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 161 445 print done;
+#X obj 47 445 print;
+#X msg 76 382 stop;
+#X text 174 416 output between 2 and 3 bangs \, with 500ms delay between
+bangs;
+#X obj 48 497 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 204 561 print done;
+#X obj 48 561 print;
+#X msg 77 498 stop;
+#X text 231 532 50 to 1500ms delay between 10 bangs;
+#X text 288 6 many_bang;
+#X obj 47 415 many_bang 2 3 500;
+#X obj 48 531 many_bang 10 10 50 1500;
+#X obj 45 271 many_bang 2 15;
+#X connect 0 0 4 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
+#X connect 4 1 1 0;
+#X connect 6 0 24 0;
+#X connect 9 0 24 0;
+#X connect 11 0 22 0;
+#X connect 14 0 22 0;
+#X connect 16 0 23 0;
+#X connect 19 0 23 0;
+#X connect 22 0 13 0;
+#X connect 22 1 12 0;
+#X connect 23 0 18 0;
+#X connect 23 1 17 0;
+#X connect 24 0 8 0;
+#X connect 24 1 7 0;
diff --git a/nusmuk_utils/many_bang.pd b/nusmuk_utils/many_bang.pd
new file mode 100644
index 0000000..d2bf173
--- /dev/null
+++ b/nusmuk_utils/many_bang.pd
@@ -0,0 +1,100 @@
+#N canvas 444 320 434 452 10;
+#X obj 149 208 moses \$1;
+#X obj 149 136 f;
+#X obj 149 163 + 1;
+#X obj 162 290 delay \$3;
+#X obj 149 383 outlet;
+#X obj 200 383 outlet;
+#X obj 84 20 inlet;
+#X obj 149 75 t b b;
+#X msg 149 97 0;
+#X obj 200 323 t b b;
+#X obj 149 233 t b f b;
+#X obj 200 155 i;
+#X obj 200 127 + 0.5;
+#X obj 84 45 route stop;
+#X msg 84 74 stop;
+#N canvas 0 0 450 300 between 0;
+#X obj 61 29 inlet;
+#X obj 211 31 inlet;
+#X obj 350 33 inlet;
+#X obj 195 172 \$1;
+#X obj 225 352 / 100000;
+#X obj 225 281 i;
+#X obj 195 380 +;
+#X obj 195 206 t f f;
+#X obj 195 410 outlet;
+#X obj 225 230 - \$2;
+#X obj 225 304 t b f;
+#X obj 225 328 random 0;
+#X obj 225 256 * -100000;
+#X obj 61 67 t b;
+#X connect 0 0 13 0;
+#X connect 1 0 3 1;
+#X connect 2 0 9 1;
+#X connect 3 0 7 0;
+#X connect 4 0 6 1;
+#X connect 5 0 10 0;
+#X connect 6 0 8 0;
+#X connect 7 0 6 0;
+#X connect 7 1 9 0;
+#X connect 9 0 12 0;
+#X connect 10 0 11 0;
+#X connect 10 1 11 1;
+#X connect 11 0 4 0;
+#X connect 12 0 5 0;
+#X connect 13 0 3 0;
+#X restore 199 104 pd between;
+#N canvas 0 0 478 635 between 0;
+#X obj 61 29 inlet;
+#X obj 211 31 inlet;
+#X obj 350 33 inlet;
+#X obj 225 352 / 100000;
+#X obj 225 281 i;
+#X obj 195 380 +;
+#X obj 195 206 t f f;
+#X obj 195 410 outlet;
+#X obj 225 304 t b f;
+#X obj 225 328 random 0;
+#X obj 225 256 * -100000;
+#X obj 61 67 t b;
+#X obj 225 230 - \$4;
+#X obj 195 172 \$3;
+#X connect 0 0 11 0;
+#X connect 1 0 13 1;
+#X connect 2 0 12 1;
+#X connect 3 0 5 1;
+#X connect 4 0 8 0;
+#X connect 5 0 7 0;
+#X connect 6 0 5 0;
+#X connect 6 1 12 0;
+#X connect 8 0 9 0;
+#X connect 8 1 9 1;
+#X connect 9 0 3 0;
+#X connect 10 0 4 0;
+#X connect 11 0 13 0;
+#X connect 12 0 10 0;
+#X connect 13 0 6 0;
+#X restore 213 262 pd between;
+#X connect 0 0 10 0;
+#X connect 0 1 9 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 0;
+#X connect 3 0 1 0;
+#X connect 6 0 13 0;
+#X connect 7 0 8 0;
+#X connect 7 1 15 0;
+#X connect 8 0 1 0;
+#X connect 9 0 5 0;
+#X connect 9 1 4 0;
+#X connect 10 0 3 0;
+#X connect 10 0 4 0;
+#X connect 10 1 1 1;
+#X connect 10 2 16 0;
+#X connect 11 0 0 1;
+#X connect 12 0 11 0;
+#X connect 13 0 14 0;
+#X connect 13 1 7 0;
+#X connect 14 0 3 0;
+#X connect 15 0 12 0;
+#X connect 16 0 3 1;
diff --git a/nusmuk_utils/nusmuk_utils-meta.pd b/nusmuk_utils/nusmuk_utils-meta.pd
new file mode 100644
index 0000000..a4cb8ab
--- /dev/null
+++ b/nusmuk_utils/nusmuk_utils-meta.pd
@@ -0,0 +1,7 @@
+#N canvas 272 88 496 221 10;
+#X text 12 116 LICENSE GNU GPL;
+#X text 10 39 AUTHOR Cyrille Henry;
+#X text 10 19 NAME nusmuk_utils;
+#X text 11 136 VERSION 1;
+#X text 10 58 DESCRIPTION This objects' collection is based on abstractions
+and externals. they provide usfull stuff for pd.;
diff --git a/nusmuk_utils/once-help.pd b/nusmuk_utils/once-help.pd
new file mode 100644
index 0000000..8838878
--- /dev/null
+++ b/nusmuk_utils/once-help.pd
@@ -0,0 +1,13 @@
+#N canvas 153 103 450 300 10;
+#X obj 84 130 once;
+#X obj 84 61 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 109 100 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 84 166 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X text 129 100 reset;
+#X text 120 15 once pass only 1 bang;
+#X connect 0 0 3 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 1;
diff --git a/nusmuk_utils/once.pd b/nusmuk_utils/once.pd
new file mode 100644
index 0000000..7fe3c60
--- /dev/null
+++ b/nusmuk_utils/once.pd
@@ -0,0 +1,15 @@
+#N canvas 818 139 431 322 10;
+#X obj 24 26 inlet;
+#X obj 24 168 outlet;
+#X msg 92 49 1;
+#X msg 115 79 0;
+#X obj 24 86 spigot 1;
+#X obj 24 119 t a b;
+#X obj 92 26 inlet;
+#X connect 0 0 4 0;
+#X connect 2 0 4 1;
+#X connect 3 0 4 1;
+#X connect 4 0 5 0;
+#X connect 5 0 1 0;
+#X connect 5 1 3 0;
+#X connect 6 0 2 0;
diff --git a/nusmuk_utils/p-help.pd b/nusmuk_utils/p-help.pd
new file mode 100644
index 0000000..620f09e
--- /dev/null
+++ b/nusmuk_utils/p-help.pd
@@ -0,0 +1,8 @@
+#N canvas 0 0 450 300 10;
+#X obj 103 97 p;
+#X floatatom 103 76 5 0 0 0 - - -;
+#X floatatom 145 77 5 0 0 0 - - -;
+#X obj 145 98 p foo;
+#X text 100 20 p is a shortcut to print;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
diff --git a/nusmuk_utils/p.pd b/nusmuk_utils/p.pd
new file mode 100755
index 0000000..20b3fa9
--- /dev/null
+++ b/nusmuk_utils/p.pd
@@ -0,0 +1,4 @@
+#N canvas 0 0 108 111 12;
+#X obj 9 10 inlet;
+#X obj 9 38 print \$1;
+#X connect 0 0 1 0;
diff --git a/nusmuk_utils/pbank-help.pd b/nusmuk_utils/pbank-help.pd
new file mode 100755
index 0000000..21839ef
--- /dev/null
+++ b/nusmuk_utils/pbank-help.pd
@@ -0,0 +1,562 @@
+#N canvas 212 22 1013 667 10;
+#X msg 487 31 set 1 2 100 3.1415 shupsh;
+#X msg 500 59 0 1 1.234;
+#X text 573 59 write 1.234 to column 0 of row 1;
+#X text 672 31 set list of elements starting at column 1 in row 2;
+#X msg 513 87 0 1;
+#X text 542 87 read value at column 0 of row 1;
+#X msg 538 138 2 0 coptox;
+#X text 556 110 read value at column 2 of row 0;
+#X msg 526 110 2 0;
+#X msg 608 245 put 0 100 3.14159 shupsh;
+#X text 793 251 put list of elements starting at column 0 in edit buffer
+;
+#X text 41 -12 A 2-dimensional parameter bank for floats or symbols
+;
+#X text -19 42 args:;
+#X text -4 56 argument1 gives the number of columns (X axis): <int>
+\; argument2 gives the number of rows (Y axis): <int> \; argument3
+is the name of the pbank: <symbol>;
+#X text 66 95 The arg3 (pbank 'name') is used by pbank in two ways:
+when a patch using a pbank is loaded \, a pbank data file corresponding
+to arg3 will be searched for and loaded if found. The 'name' also allows
+other pbanks with the same name to share data -in the way that tables
+do. If these two features are not wanted \, Arg3 (the 'name') can be
+set to the empty string: "" (two quotes) - see example below-;
+#X text 616 138 write symbol "coptox" to column 2 of row 0;
+#X text 777 564 The left-hand outlet outputs lists of the form: columnNo
+<int> item <int \, float or symbol>;
+#X text 777 589 note: Do not forget that this outlet is only used by
+pbank if argument 4 undefined (omitted) -see arguments;
+#X text 40 0 note: The structure of pbank includes an additional row
+that serves as an edit buffer. - see Messages;
+#X msg 654 336 store 3;
+#X msg 625 273 recall 3;
+#X text -5 187 argument4;
+#X text 65 187 is the symbol that pbank uses when directing its output
+to receives based on this symbol: <optional symbol>;
+#X obj -7 315 pbank 4 12;
+#X text -8 330 Creates a parameter bank of 4 columns by 12 rows;
+#X text -10 378 Creates a parameter bank of 4 columns by 12 rows \,
+reading in the contents of the file name "bushmeat.pbank" \, and sharing
+data with any other pbanks with the same name;
+#X floatatom 776 777 5 0 0 0 - - -;
+#X floatatom 816 777 5 0 0 0 - - -;
+#X obj 883 742 print pbankOut;
+#X obj 776 742 route 0 1 2 3;
+#X floatatom 856 777 5 0 0 0 - - -;
+#X floatatom 896 777 5 0 0 0 - - -;
+#X obj 614 636 send toPbanks;
+#X obj 776 682 receive toPbanks;
+#X text 486 3 MESSAGES: read/write;
+#X text 587 221 MESSAGES: edit buffer;
+#X text 696 485 MESSAGES: file IO;
+#X obj 383 677 route 0 1 2 3;
+#X msg 383 707 set \$1;
+#X msg 384 768 untitled_10;
+#X msg 484 707 set \$1;
+#X msg 484 768 0;
+#X msg 577 707 set \$1;
+#X msg 577 768 0;
+#X msg 670 707 set \$1;
+#X msg 670 768 0;
+#X msg 419 623 recall 11;
+#X msg 420 602 recall 10;
+#X obj 510 388 vradio 18 1 0 10 empty empty empty 0 -6 0 8 -262144
+-1 -1 7;
+#X msg 510 574 recall \$1;
+#X obj -9 437 receive toPbanks;
+#X floatatom 397 752 5 0 0 0 - - -;
+#X floatatom 490 752 5 0 0 0 - - -;
+#X floatatom 583 752 5 0 0 0 - - -;
+#X floatatom 676 752 5 0 0 0 - - -;
+#X obj -9 573 pbank 4 12 "" wireless;
+#X obj 420 576 loadbang;
+#X obj 397 730 r wireless-0;
+#X obj 490 730 r wireless-1;
+#X obj 583 730 r wireless-2;
+#X obj 676 730 r wireless-3;
+#X text -11 592 Creates an unnamed parameter bank of 4 columns by 12
+rows \, whose output will be sent to 4 corresponding receives whose
+names are based on the symbol "wireless-n" \, where n is the corresponding
+column number. Note that the argument3 has been set to the empty string:
+"".;
+#N canvas 291 52 1062 794 An_EXAMPLE 0;
+#X obj 109 8 r synth-0;
+#X msg 87 32 set \$1;
+#X msg 109 79 set \$1;
+#X obj 109 174 vsl 15 128 50 15000 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X floatatom 87 336 7 0 0 1 hz - -;
+#X msg 87 357 put 0 \$1;
+#X obj 259 426 s toSynthPbank;
+#X obj 117 104 r name-0;
+#X msg 117 126 set \$1;
+#X msg 117 147 untitled_10;
+#N canvas 571 157 505 529 SYNTH 0;
+#X obj 80 43 inlet;
+#X obj 192 43 inlet;
+#X obj 300 43 inlet;
+#X obj 399 43 inlet;
+#X text 89 23 fq;
+#X text 178 24 modFQscaler;
+#X text 299 23 index;
+#X text 401 23 gain;
+#X floatatom 80 69 5 0 0 0 - - -;
+#X obj 123 110 float;
+#X obj 80 156 sig~;
+#X obj 192 71 t b f;
+#X obj 123 156 * 1;
+#X obj 123 178 sig~;
+#X obj 123 207 osc~;
+#X floatatom 222 110 5 0 0 0 - - -;
+#X obj 123 238 *~;
+#X obj 300 154 sig~;
+#X floatatom 300 110 5 0 0 0 - - -;
+#X obj 80 285 +~;
+#X obj 80 330 osc~;
+#X obj 399 72 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X obj 79 441 dac~;
+#X text 19 474 xjimmies lib. z. settel/jm dumas 2003-2007;
+#X obj 80 410 gain2~;
+#X obj 98 388 r \$0-gain;
+#X obj 80 364 gain1~;
+#X connect 0 0 8 0;
+#X connect 1 0 11 0;
+#X connect 2 0 18 0;
+#X connect 3 0 21 0;
+#X connect 8 0 10 0;
+#X connect 8 0 9 0;
+#X connect 9 0 12 0;
+#X connect 10 0 19 0;
+#X connect 11 0 9 0;
+#X connect 11 1 15 0;
+#X connect 12 0 13 0;
+#X connect 13 0 14 0;
+#X connect 14 0 16 0;
+#X connect 15 0 12 1;
+#X connect 16 0 19 1;
+#X connect 17 0 16 1;
+#X connect 18 0 17 0;
+#X connect 19 0 20 0;
+#X connect 20 0 26 0;
+#X connect 21 0 26 1;
+#X connect 24 0 22 0;
+#X connect 24 0 22 1;
+#X connect 25 0 24 1;
+#X connect 26 0 24 0;
+#X restore 623 425 pd SYNTH;
+#X msg 259 33 set \$1;
+#X msg 281 80 set \$1;
+#X obj 281 175 vsl 15 128 0 20 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X floatatom 259 337 7 0 0 1 hz - -;
+#X msg 289 127 set \$1;
+#X msg 289 148 0;
+#X msg 437 31 set \$1;
+#X msg 459 78 set \$1;
+#X obj 459 173 vsl 15 128 50 10000 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X floatatom 437 335 7 0 0 1 hz - -;
+#X msg 467 125 set \$1;
+#X msg 467 146 0;
+#X msg 608 34 set \$1;
+#X obj 630 176 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X floatatom 608 338 7 0 0 1 hz - -;
+#X msg 634 126 set \$1;
+#X msg 634 147 0;
+#X obj 281 9 r synth-1;
+#X obj 459 7 r synth-2;
+#X obj 608 7 r synth-3;
+#X obj 634 104 r name-3;
+#X obj 467 103 r name-2;
+#X obj 289 105 r name-1;
+#X msg 259 358 put 1 \$1;
+#X msg 437 356 put 2 \$1;
+#X msg 608 359 put 3 \$1;
+#X obj 721 530 r toSynthPbank;
+#X obj 447 554 s toSynthPbank;
+#X msg 447 526 recall \$1;
+#X msg 810 480 recall 11;
+#X msg 723 480 recall 10;
+#X obj 723 460 loadbang;
+#X obj 723 506 pbank 4 12 bushmeat.pbank name;
+#X obj 449 501 i;
+#X obj 366 486 bng 15 250 50 0 empty empty empty 0 -6 0 8 -18753 -1
+-1;
+#X text 381 487 recall;
+#X obj 366 604 s toSynthPbank;
+#X obj 366 550 i;
+#X obj 366 466 bng 15 250 50 0 empty empty empty 0 -6 0 8 -258049 -1
+-1;
+#X text 388 465 store;
+#X msg 366 576 store \$1;
+#X floatatom 476 479 5 0 0 0 - - -;
+#X text 517 479 select memory;
+#X floatatom 476 502 5 0 0 0 - - -;
+#X text 518 500 current memory;
+#X obj 748 333 r synth-0;
+#X obj 748 353 r synth-1;
+#X obj 748 374 r synth-2;
+#X obj 748 395 r synth-3;
+#X obj 763 124 vsl 15 128 -99 18 0 1 \$0-gain empty Output -15 -14
+0 14 -260097 -1 -1 9300 1;
+#X floatatom 763 260 5 0 0 1 _db - -;
+#X obj 106 657 s toSynthPbank;
+#X obj 116 471 vradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1
+-1 0;
+#X obj 475 433 hradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1
+-1 0;
+#X floatatom 106 607 5 0 0 0 - - -;
+#X obj 723 629 pbank 4 12 bushmeat.pbank;
+#X msg 723 603 dump;
+#X msg 762 603 dump 2;
+#N canvas 675 151 189 317 interpol 0;
+#X obj 11 26 inlet;
+#X obj 72 98 min 127;
+#X obj 72 121 max 0;
+#X obj 11 98 min 127;
+#X obj 11 121 max 0;
+#N canvas 0 22 355 236 position 0;
+#X obj 49 121 pack f f;
+#X obj 49 17 inlet;
+#X obj 236 15 inlet;
+#X obj 49 152 outlet;
+#X obj 236 62 / 127;
+#X obj 49 93 / 127;
+#X obj 237 90 t b f;
+#X connect 0 0 3 0;
+#X connect 1 0 5 0;
+#X connect 2 0 4 0;
+#X connect 4 0 6 0;
+#X connect 5 0 0 0;
+#X connect 6 0 0 0;
+#X connect 6 1 0 1;
+#X restore 11 171 pd position;
+#N canvas 300 173 814 597 distance 0;
+#X obj 35 27 inlet;
+#X obj 37 538 outlet;
+#X obj 194 539 outlet;
+#X obj 37 144 unpack f f;
+#X obj 206 143 unpack f f;
+#X obj 341 142 unpack f f;
+#X obj 495 142 unpack f f;
+#X obj 634 140 unpack f f;
+#X obj 37 168 +;
+#X msg 37 192 1 \$1;
+#X obj 37 214 -;
+#X obj 206 171 - 1;
+#X obj 206 195 * -1;
+#X obj 205 224 +;
+#X msg 205 248 1 \$1;
+#X obj 205 270 -;
+#X obj 340 230 +;
+#X msg 340 254 1 \$1;
+#X obj 340 276 -;
+#X obj 492 223 +;
+#X msg 492 247 1 \$1;
+#X obj 492 269 -;
+#X obj 395 172 - 1;
+#X obj 395 196 * -1;
+#X obj 494 172 - 1;
+#X obj 494 196 * -1;
+#X obj 547 175 - 1;
+#X obj 547 199 * -1;
+#X obj 37 239 max 0;
+#X obj 206 292 max 0;
+#X obj 338 301 max 0;
+#X obj 493 298 max 0;
+#X obj 35 49 t a a a a a;
+#X obj 628 224 +;
+#X msg 628 248 1 \$1;
+#X obj 628 270 -;
+#X obj 629 299 max 0;
+#X obj 632 173 - 0.5;
+#X obj 683 176 - 0.5;
+#X obj 683 200 abs;
+#X obj 630 197 abs;
+#X obj 509 322 +;
+#X obj 379 349 +;
+#X obj 257 378 +;
+#X obj 62 413 +;
+#X obj 37 513 /;
+#X obj 37 264 t f f;
+#X obj 193 493 f;
+#X obj 193 517 /;
+#X obj 70 437 t b f;
+#X obj 325 487 f;
+#X obj 325 511 /;
+#X obj 480 481 f;
+#X obj 480 505 /;
+#X obj 616 480 f;
+#X obj 616 504 /;
+#X obj 480 531 outlet;
+#X obj 325 537 outlet;
+#X obj 616 532 outlet;
+#X connect 0 0 32 0;
+#X connect 3 0 8 0;
+#X connect 3 1 8 1;
+#X connect 4 0 11 0;
+#X connect 4 1 13 1;
+#X connect 5 0 16 0;
+#X connect 5 1 22 0;
+#X connect 6 0 24 0;
+#X connect 6 1 26 0;
+#X connect 7 0 37 0;
+#X connect 7 1 38 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 28 0;
+#X connect 11 0 12 0;
+#X connect 12 0 13 0;
+#X connect 13 0 14 0;
+#X connect 14 0 15 0;
+#X connect 15 0 29 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 0;
+#X connect 18 0 30 0;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 31 0;
+#X connect 22 0 23 0;
+#X connect 23 0 16 1;
+#X connect 24 0 25 0;
+#X connect 25 0 19 0;
+#X connect 26 0 27 0;
+#X connect 27 0 19 1;
+#X connect 28 0 46 0;
+#X connect 29 0 43 0;
+#X connect 29 0 47 1;
+#X connect 30 0 42 0;
+#X connect 30 0 50 1;
+#X connect 31 0 41 0;
+#X connect 31 0 52 1;
+#X connect 32 0 3 0;
+#X connect 32 1 4 0;
+#X connect 32 2 5 0;
+#X connect 32 3 6 0;
+#X connect 32 4 7 0;
+#X connect 33 0 34 0;
+#X connect 34 0 35 0;
+#X connect 35 0 36 0;
+#X connect 36 0 41 1;
+#X connect 36 0 54 1;
+#X connect 37 0 40 0;
+#X connect 38 0 39 0;
+#X connect 39 0 33 1;
+#X connect 40 0 33 0;
+#X connect 41 0 42 1;
+#X connect 42 0 43 1;
+#X connect 43 0 44 1;
+#X connect 44 0 45 1;
+#X connect 44 0 49 0;
+#X connect 45 0 1 0;
+#X connect 46 0 45 0;
+#X connect 46 1 44 0;
+#X connect 47 0 48 0;
+#X connect 48 0 2 0;
+#X connect 49 0 47 0;
+#X connect 49 0 50 0;
+#X connect 49 0 52 0;
+#X connect 49 0 54 0;
+#X connect 49 1 48 1;
+#X connect 49 1 51 1;
+#X connect 49 1 53 1;
+#X connect 49 1 55 1;
+#X connect 50 0 51 0;
+#X connect 51 0 57 0;
+#X connect 52 0 53 0;
+#X connect 53 0 56 0;
+#X connect 54 0 55 0;
+#X connect 55 0 58 0;
+#X restore 11 194 pd distance;
+#X obj 11 217 pack f f f f f;
+#X obj 11 266 outlet;
+#X msg 11 242 interp \$1 \$2 \$3 \$4 \$5;
+#X obj 11 50 unpack f f;
+#X obj 11 73 / 2;
+#X obj 72 72 / 2;
+#X obj 11 144 change;
+#X obj 72 144 change;
+#X connect 0 0 10 0;
+#X connect 1 0 2 0;
+#X connect 2 0 14 0;
+#X connect 3 0 4 0;
+#X connect 4 0 13 0;
+#X connect 5 0 6 0;
+#X connect 6 0 7 0;
+#X connect 6 1 7 1;
+#X connect 6 2 7 2;
+#X connect 6 3 7 3;
+#X connect 6 4 7 4;
+#X connect 7 0 9 0;
+#X connect 9 0 8 0;
+#X connect 10 0 11 0;
+#X connect 10 1 12 0;
+#X connect 11 0 3 0;
+#X connect 12 0 1 0;
+#X connect 13 0 5 0;
+#X connect 14 0 5 1;
+#X restore 200 616 pd interpol;
+#X obj 96 474 vsl 15 115 7 0 0 1 empty empty empty 0 -8 0 8 -262144
+-1 -1 11400 1;
+#X obj 721 560 pbank 4 12 bushmeat.pbank synth;
+#X msg 106 627 recall \$1;
+#X text 47 455 interpolation beetween adjacent presets;
+#X text 171 563 complicated interpolation;
+#X obj 200 592 xy;
+#X text 229 590 <- click here;
+#X connect 0 0 1 0;
+#X connect 0 0 2 0;
+#X connect 1 0 4 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 4 0 10 0;
+#X connect 5 0 6 0;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 11 0 14 0;
+#X connect 12 0 13 0;
+#X connect 13 0 14 0;
+#X connect 14 0 34 0;
+#X connect 14 0 10 1;
+#X connect 15 0 16 0;
+#X connect 17 0 20 0;
+#X connect 18 0 19 0;
+#X connect 19 0 20 0;
+#X connect 20 0 35 0;
+#X connect 20 0 10 2;
+#X connect 21 0 22 0;
+#X connect 23 0 25 0;
+#X connect 23 0 24 0;
+#X connect 24 0 25 0;
+#X connect 25 0 36 0;
+#X connect 25 0 10 3;
+#X connect 26 0 27 0;
+#X connect 28 0 11 0;
+#X connect 28 0 12 0;
+#X connect 29 0 17 0;
+#X connect 29 0 18 0;
+#X connect 30 0 23 0;
+#X connect 31 0 26 0;
+#X connect 32 0 21 0;
+#X connect 33 0 15 0;
+#X connect 34 0 6 0;
+#X connect 35 0 6 0;
+#X connect 36 0 6 0;
+#X connect 37 0 71 0;
+#X connect 39 0 38 0;
+#X connect 40 0 43 0;
+#X connect 41 0 43 0;
+#X connect 42 0 41 0;
+#X connect 44 0 39 0;
+#X connect 44 0 54 0;
+#X connect 45 0 44 0;
+#X connect 48 0 51 0;
+#X connect 48 0 54 0;
+#X connect 49 0 48 0;
+#X connect 51 0 47 0;
+#X connect 56 0 10 0;
+#X connect 57 0 10 1;
+#X connect 58 0 10 2;
+#X connect 59 0 10 3;
+#X connect 60 0 61 0;
+#X connect 63 0 65 0;
+#X connect 64 0 44 1;
+#X connect 64 0 52 0;
+#X connect 64 0 48 1;
+#X connect 65 0 72 0;
+#X connect 67 0 66 0;
+#X connect 68 0 66 0;
+#X connect 69 0 62 0;
+#X connect 70 0 65 0;
+#X connect 72 0 62 0;
+#X connect 75 0 69 0;
+#X restore 1076 740 pd An_EXAMPLE;
+#X text -18 -12 pbank :;
+#X text 776 545 OUTLETS;
+#X text -15 691 "pdjimmies" lib. z. settel 2004;
+#X text 65 216 Arg4 is optional. If it is not specified \, Pbank's
+output will be sent out of its outlet. If arg4 is specified \, pbank's
+outlet will be inactive and output will be directed to a number of
+receive objects whose names are based on arg4 (receive symbol). For
+each column \, there is a corresponding receive whose name shitfuck
+includes the column number -see example below.;
+#X text 723 363 output edit buffer (share beetween diferents object
+with same pbank file);
+#X msg 705 429 interp 0 0.2 0.6 0.2;
+#X text 620 157 output row 2 (same as recall \, but does not compy
+to the edit buffer);
+#X text 712 336 copy edit buffer to row 3;
+#X text 692 273 recall (output) row 3 and copy it into edit buffer
+;
+#X text 746 401 read value from edit buffer (-1) at column 2;
+#X msg 696 399 2 -1;
+#X msg 640 299 recall 2.5;
+#X text 714 450 interpolation between presets : output = 0 * preset1
++ 0.2 * preset2 + 0.6* preset3 + 0.2 * preset4;
+#X text 721 299 recalls interpolated values between adjacent rows:
+;
+#X text 725 312 output = (row 2 + row 3) * 0.5;
+#X text -14 708 "interp" method contributed by Cyrille Henry;
+#X text 1079 722 LOOK IN HERE;
+#X obj 383 652 pbank 4 12 glen;
+#X text -10 481 Creates a named pbank whose output is sent to receives
+based on the symbol "wireless". Since there are 4 columns \, pbank
+will be sending its output to 4 receives each one corresponding to
+the column number included in its name. This provides an alterative
+(and faster) way of getting data from a pbank.;
+#X msg 680 363 dump;
+#X msg 555 166 dump 2;
+#X msg 572 191 dump 2;
+#X text 625 190 same as above but outputs row as list thru outlet;
+#X obj -8 361 pbank 4 12 examples/bushmeat.pbank;
+#X obj -9 461 pbank 4 12 examples/bushmeat.pbank wireless;
+#X msg 697 505 read examples/bushmeat.pbank;
+#X msg 697 529 write examples/bushmeat.pbank;
+#X obj 776 706 pbank 4 12 examples/bushmeat.pbank;
+#X connect 0 0 32 0;
+#X connect 1 0 32 0;
+#X connect 4 0 32 0;
+#X connect 6 0 32 0;
+#X connect 8 0 32 0;
+#X connect 9 0 32 0;
+#X connect 19 0 32 0;
+#X connect 20 0 32 0;
+#X connect 29 0 26 0;
+#X connect 29 1 27 0;
+#X connect 29 2 30 0;
+#X connect 29 3 31 0;
+#X connect 33 0 90 0;
+#X connect 37 0 38 0;
+#X connect 37 1 40 0;
+#X connect 37 2 42 0;
+#X connect 37 3 44 0;
+#X connect 38 0 39 0;
+#X connect 40 0 41 0;
+#X connect 42 0 43 0;
+#X connect 44 0 45 0;
+#X connect 46 0 80 0;
+#X connect 47 0 80 0;
+#X connect 48 0 49 0;
+#X connect 49 0 32 0;
+#X connect 50 0 87 0;
+#X connect 56 0 47 0;
+#X connect 57 0 51 0;
+#X connect 58 0 52 0;
+#X connect 59 0 53 0;
+#X connect 60 0 54 0;
+#X connect 68 0 32 0;
+#X connect 73 0 32 0;
+#X connect 74 0 32 0;
+#X connect 80 0 37 0;
+#X connect 82 0 32 0;
+#X connect 83 0 32 0;
+#X connect 84 0 32 0;
+#X connect 88 0 32 0;
+#X connect 89 0 32 0;
+#X connect 90 0 28 0;
+#X connect 90 0 29 0;
diff --git a/nusmuk_utils/pbank.c b/nusmuk_utils/pbank.c
new file mode 100755
index 0000000..d391a66
--- /dev/null
+++ b/nusmuk_utils/pbank.c
@@ -0,0 +1,1368 @@
+/* pbank - zack settel 1994 */
+// ported to PD - Zack Settel 2004 using the ISPW sources
+// note that the generated message receivers are of the format: "name-n" and not "n-name"(the way it was on the ISPW)
+/* features class-independent data structure see pbank.h */
+
+
+// Source code for this object derived from the original sources in the IRCAM Jimmies release (1994), with the authorization of IRCAM. This object is part of the nSLAM release, developed by La SAT. nSLAM is also available on the IRCAM Forum site (http://forum.ircam.fr), as an incentive to PD users to join and contribute to Forum IRCAM"
+
+
+// multi row interpolation method provided by cyrille.henry@la-kitchen.fr
+
+/*
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; 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.
+*/
+
+// Zack Maintenance: march 06
+// fixed recallf method: index bounded now.
+// fixed pbank_saveto: fixed bug when full path is specified.
+
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <string.h>
+
+
+#include "pbank.h"
+#include "common.h"
+
+#define VERSION "pbank/pd v1.11 z.s. 2006"
+#define NIL 0L
+#define MAX_COLUMNS 2048
+#define DEFAULT_COLUMNS 10
+#define DEFAULT_ROWS 32
+#define MAX_ROWS 256 - EDBUFF
+#define PBANK_ID_STRING "theFucKinGPbanKIdeNtifacATioNStrinGGGG"
+
+#define EDBUFF 1 /* edbuffer at rows + 1 */
+#define DIRTFLAG 1 /* dirty flag kept at rows + 2 */
+
+#define GETROW(X,R)(((X)->p_data[(R)]))
+#define GET_EDBUFF(X)(((X)->p_data[((X)->p_rows)]))
+#define CR 13
+#define TAB 9
+
+
+
+typedef struct pbank
+{
+ t_object p_ob;
+ t_atom **p_data; /* param matrix : data[PATCH_COUNT] X *data+PARAMCOUNT */
+ t_symbol **p_receives; /* used for back door messaging */
+ t_symbol *p_name; /* pbank data/file name <optional> */
+ t_atom **p_dirty; /* points to extra cell in matrix used for dirty flag */
+ t_symbol *p_vol; /* default volume */
+ int p_curpatch;
+ int p_columns;
+ int p_rows;
+ t_canvas *x_canvas;
+
+} t_pbank;
+
+t_atom pbank_outlist[3]; /* used by list method for output */
+
+void *pbank_new(t_symbol *s, int argc, t_atom *argv);
+void pbank_bang(t_pbank *x);
+void pbank_dispose(t_pbank *x);
+void pbank_list(t_pbank *x, t_symbol *s, int argc, t_atom *argv);
+void pbank_recall(t_pbank *x,t_float row);
+void pbank_recallf(t_pbank *x,t_float row);
+void pbank_dump(t_pbank *x, t_symbol *s, int argc, t_atom *argv);
+void pbank_store(t_pbank *x,t_float row);
+void pbank_set(t_pbank *x, t_symbol *s, int argc, t_atom *argv);
+void pbank_put(t_pbank *x, t_symbol *s, int argc, t_atom *argv);
+void pbank_interp(t_pbank *x, t_symbol *s, int argc, t_atom *argv);
+void pbank_write(t_pbank *x, t_symbol *name);
+void pbank_tobinbuf(t_pbank *x,void *b);
+void pbank_read(t_pbank *x, t_symbol *fname);
+void pbank_saveto(t_pbank *x,char *fn);
+void pbank_db(t_pbank *x,t_float c,t_float r);
+void pbank_setup(void);
+int pbank_fromtext(t_pbank *x,void *b);
+
+t_atom **pbank_getmem(t_symbol *name,int columns,int rows);
+
+t_symbol *z_list, *z_float, *z_symbol, *z_receive; // *z_int,
+
+#define EMPTYSTRING ""
+
+/* class variables */
+
+t_shared *pbank_banks = NIL; /* linked list of shared data-matrixs */
+t_symbol *pbank_ID;
+
+t_atom *pbank_clipboard; /* NOT IMPLEMENTED points to edbuff of "copied" pbank */
+/* clipboard needed ???? */
+
+/* ************************************************************ */
+
+
+void pbank_db(t_pbank *x, t_float c_float, t_float r_float)
+{
+ t_atom *a;
+ long c = (long) c_float;
+ long r = (long) r_float;
+
+ *x->p_dirty = (c) ? (t_atom *)1:NIL;
+
+
+ post("p_dirty at %lx",x->p_dirty);
+ post("plus %ld addr = %lx",r,x->p_data+r);
+
+ a = GETROW(x,r);
+}
+
+
+
+void pbank_bang(t_pbank *x)
+{
+
+ t_shared *piss = NIL;
+
+ post(":DIRTY FLAS = %ld at %lx",*x->p_dirty,x->p_dirty);
+ return;
+
+ piss = pbank_banks; /* maintain list of instance memories */
+ while(piss)
+ {
+ post("->%s at %lx",piss->s_sym->s_name,piss);
+ post(" next->%lx",piss->s_next);
+ piss = piss->s_next;
+ }
+}
+ /* write item to matrix at given column,row address */
+ /* message: column row thing1......thingN */
+void pbank_set(t_pbank *x, t_symbol *s, int ac, t_atom *argv)
+{
+ t_atom *shit;
+ int column,row;
+
+ if (ac < 3)
+ {
+ post("ac=%d",ac);
+ error("pbank_set: takes at least 3 arguments: column row item(s)");
+ return;
+ }
+ if ((argv)->a_type != A_FLOAT || (argv+1)->a_type != A_FLOAT)
+ {
+ error("pbank_set: first arguments must of type float (columnNo. or rowNo.)");
+ return;
+ }
+
+ if ((column = (int)(argv)->a_w.w_float) < 0) column = 0;
+ else if (column >= x->p_columns) column = x->p_columns-1;
+
+ if ((row = (int)(argv+1)->a_w.w_float) < 0) row = 0;
+ else if (row >= x->p_rows) row = x->p_rows-1;
+
+ shit = GETROW(x,row);
+
+ ac -=2; /* get data */
+ argv +=2;
+ while (ac-- && (column < x->p_columns))
+ {
+ if ((argv)->a_type != A_FLOAT && (argv)->a_type != A_SYMBOL && (argv)->a_type != A_FLOAT)
+ {
+ error("pbank_set: argument no %d must be afloat or symbol",ac+1);
+ return;
+ }
+ *(shit+column++) = *argv++;
+ }
+ *x->p_dirty = (t_atom *)1; /* set dirty flag */
+
+}
+
+ /* same as set but writes to the edirt buffer: 'put' column thing1......thingN */
+void pbank_put(t_pbank *x, t_symbol *s, int ac, t_atom *argv)
+{
+ t_atom *shit;
+ int column;
+
+ if (ac < 2)
+ {
+ post("ac=%d",ac);
+ error("pbank_put: takes at least 2 arguments: column item(s)");
+ return;
+ }
+ if ((argv)->a_type != A_FLOAT)
+ {
+ error("pbank_put: first argument must a number (columnNo.)");
+ return;
+ }
+ if ((column = (int)(argv)->a_w.w_float) < 0) column = 0;
+ else if (column >= x->p_columns) column = x->p_columns-1;
+
+ shit = GET_EDBUFF(x);
+
+ ac --; /* get data */
+ argv ++;
+ while (ac-- && (column < x->p_columns))
+ {
+ if ((argv)->a_type != A_FLOAT && (argv)->a_type != A_SYMBOL && (argv)->a_type != A_FLOAT)
+ {
+ error("pbank_put: argument no %d must be a float or symbol",ac);
+ return;
+ }
+ *(shit+column++) = *argv++;
+ }
+}
+
+
+
+void pbank_recall(t_pbank *x, t_float row_float) /* dumps (outputs) and copies row to edbuffer */
+{
+
+ int z,ac;
+ t_atom *av,*ebuff;
+ long row = (long) row_float;
+ float indexf = (float) row_float;
+
+ if (row < 0) row = 0L;
+ else if (row > x->p_rows-1) row = (long)x->p_rows-1;
+
+ if (indexf < 0) indexf = 0L;
+ else if (indexf > x->p_rows-1) indexf = (float)x->p_rows-1;
+
+
+ if (indexf - row)
+ {
+ pbank_recallf(x, (t_float) indexf);
+ return;
+ }
+
+ av = GETROW(x,row);
+ ebuff = GET_EDBUFF(x);
+
+ if (x->p_receives) /* back-door sending??? */
+ {
+ t_symbol *type;
+ ebuff += x->p_columns-1;
+ av += x->p_columns-1;
+
+ for (z=x->p_columns-1;z>-1;z--,ebuff--,av--)
+ {
+ *ebuff = *av;
+ if (x->p_receives[z]->s_thing)
+ {
+ ac=1;
+ if (ebuff->a_type == A_FLOAT) type = z_float;
+ // else if (ebuff->a_type == A_LONG) type = z_int;
+ else if (ebuff->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[z]->s_thing, type,ac, ebuff);
+ }
+ }
+ }
+ else /* otherwise use outlet */
+ for (z=0;z<x->p_columns;z++,av++,ebuff++)
+ {
+ *ebuff = *av;
+ pbank_outlist->a_w.w_float = (float)z;
+ (pbank_outlist+1)->a_type = ebuff->a_type;
+ if (ebuff->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+ }
+exit:
+ return;
+}
+
+
+void pbank_recallf(t_pbank *x, t_float row_float) /* interpol, dumps (outputs) and copies row to edbuffer */
+{
+ int u, v, z, ac;
+ t_atom *av,*avplus1, *ebuff;
+
+
+ // no need to range check, since that's done by caller method
+
+ // float indexf = (float) row_float;
+ float interpfac;
+
+ u=(int)row_float;
+
+ interpfac = (float) (row_float - u);
+
+ av = GETROW(x,u);
+ av += x->p_columns-1;
+
+ avplus1 = GETROW(x,u+1);
+ avplus1 += x->p_columns-1;
+
+
+
+ ebuff = GET_EDBUFF(x);
+
+ ebuff += x->p_columns-1;
+
+
+ // for (v=x->p_columns-1;v>-1;v--,ebuff--)
+ // {
+ // SETFLOAT(ebuff, 0); //clear edit buffer
+ //}
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (v=x->p_columns-1;v>-1;v--,ebuff--,av--,avplus1--)
+ {
+ if (ebuff->a_type == A_FLOAT && av->a_type == A_FLOAT && avplus1->a_type == A_FLOAT)
+ SETFLOAT(ebuff, (t_float)(av->a_w.w_float * (1 - interpfac) + avplus1->a_w.w_float * interpfac));
+ else if (ebuff->a_type == A_SYMBOL)
+ {
+ if (interpfac <.5) SETSYMBOL(ebuff, av->a_w.w_symbol);
+ else SETSYMBOL(ebuff, avplus1->a_w.w_symbol);
+ }
+ else error("pbank: bug found in recallf method");
+ }
+
+#ifdef why_is_this_here_sheefa
+
+ if ((int)indexf!=indexf)
+ {
+ u++;
+
+ av = GETROW(x,u);
+ av += x->p_columns-1;
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (v=x->p_columns-1;v>-1;v--,ebuff--,av--)
+ {
+ if (ebuff->a_type == A_FLOAT && av->a_type == A_FLOAT)
+ SETFLOAT(ebuff, ebuff->a_w.w_float + av->a_w.w_float * (indexf - u +1)); else if (ebuff->a_type == A_SYMBOL)
+ SETSYMBOL(ebuff, av->a_w.w_symbol);
+ else error("pbank: bug found in recallf method");
+ }
+ }
+
+#endif
+
+ if (x->p_receives) /* back-door sending??? */
+ {
+ t_symbol *type;
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (z=x->p_columns-1;z>-1;z--,ebuff--,av--)
+ {
+
+ if (x->p_receives[z]->s_thing)
+ {
+ ac=1;
+ if (ebuff->a_type == A_FLOAT) type = z_float;
+ // else if (ebuff->a_type == A_LONG) type = z_int;
+ else
+ if (ebuff->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[z]->s_thing, type,ac, ebuff);
+ }
+ }
+ }
+ else /* otherwise use outlet */
+ {
+ ebuff = GET_EDBUFF(x);
+
+ for (z=0;z<x->p_columns;z++,ebuff++)
+ {
+ pbank_outlist->a_w.w_float = (float)z;
+ (pbank_outlist+1)->a_type = ebuff->a_type;
+ if (ebuff->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+ }
+ }
+exit:
+ return;
+
+}
+
+
+void pbank_interp(t_pbank *x, t_symbol *s, int argc, t_atom *argv)
+/* interpol, dumps (outputs) and copies row to edbuffer */
+{
+
+ int u, v, z, ac;
+ t_atom *av,*ebuff;
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (v=x->p_columns-1;v>-1;v--,ebuff--)
+ {
+ SETFLOAT(ebuff, 0); //clear edit buffer
+ }
+ for (u=argc-1;u>-1;u--)
+ {
+ av = GETROW(x,u);
+ av += x->p_columns-1;
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (v=x->p_columns-1;v>-1;v--,ebuff--,av--)
+ {
+ if (ebuff->a_type == A_FLOAT && av->a_type == A_FLOAT)
+ SETFLOAT(ebuff, ebuff->a_w.w_float + av->a_w.w_float * atom_getfloatarg(u, argc, argv) ); //add value of each columns and row
+ else
+ SETSYMBOL(ebuff, gensym("null"));
+ }
+ }
+
+ if (x->p_receives) /* back-door sending??? */
+ {
+ t_symbol *type;
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (z=x->p_columns-1;z>-1;z--,ebuff--,av--)
+ {
+
+ if (x->p_receives[z]->s_thing)
+ {
+ ac=1;
+ if (ebuff->a_type == A_FLOAT) type = z_float;
+ // else if (ebuff->a_type == A_LONG) type = z_int;
+ else
+ if (ebuff->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[z]->s_thing, type,ac, ebuff);
+ }
+ }
+ }
+ else /* otherwise use outlet */
+ {
+ ebuff = GET_EDBUFF(x);
+
+ for (z=0;z<x->p_columns;z++,ebuff++)
+
+ {
+ pbank_outlist->a_w.w_float = (float)z;
+ (pbank_outlist+1)->a_type = ebuff->a_type;
+ if (ebuff->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+
+ }
+ }
+
+exit:
+ return;
+}
+
+// 'dump' dumps edit buff, 'dump n' dumps memory n, 'dump n l' dumps row n as one single list
+void pbank_dump(t_pbank *x, t_symbol *s, int argc, t_atom *argv) /* dumps (outputs) ediuffer or row */
+{
+
+ int z,ac, row;
+ t_atom *ebuff;
+
+ if (argc==0)
+ {
+ ebuff = GET_EDBUFF(x);
+ if (x->p_receives) /* back-door sending??? */
+ {
+ t_symbol *type;
+ ebuff += x->p_columns-1;
+
+ for (z=x->p_columns-1;z>-1;z--,ebuff--)
+ {
+ if (x->p_receives[z]->s_thing)
+ {
+ ac=1;
+ if (ebuff->a_type == A_FLOAT) type = z_float;
+ // else if (ebuff->a_type == A_LONG) type = z_int;
+ else if (ebuff->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[z]->s_thing, type,ac, ebuff);
+ }
+ }
+ }
+ else /* otherwise use outlet */
+ for (z=0;z<x->p_columns;z++,ebuff++)
+ {
+ pbank_outlist->a_w.w_float = (float)z;
+ (pbank_outlist+1)->a_type = ebuff->a_type;
+ if (ebuff->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+ }
+ }
+
+ else
+ {
+ if ((row = (int)(argv)->a_w.w_float) < 0) row = 0;
+ else if (row >= x->p_rows) row = x->p_rows-1;
+
+ ebuff = GETROW(x, row);
+
+ if (x->p_receives) /* back-door sending??? */
+ {
+ t_symbol *type;
+ ebuff += x->p_columns-1;
+
+ for (z=x->p_columns-1;z>-1;z--,ebuff--)
+ {
+ if (x->p_receives[z]->s_thing)
+ {
+ ac=1;
+ if (ebuff->a_type == A_FLOAT) type = z_float;
+ // else if (ebuff->a_type == A_LONG) type = z_int;
+ else if (ebuff->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[z]->s_thing, type,ac, ebuff);
+ }
+ }
+ }
+ else /* otherwise use outlet */
+ {
+ if(argc>1) // dump as single list
+ outlet_list(x->p_ob.ob_outlet,0L,x->p_columns, ebuff);
+ else
+ {
+ for (z=0;z<x->p_columns;z++,ebuff++)
+ {
+ pbank_outlist->a_w.w_float = (float)z;
+ (pbank_outlist+1)->a_type = ebuff->a_type;
+ if (ebuff->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+ }
+ }
+ }
+ }
+exit:
+ return;
+}
+
+
+void pbank_store(t_pbank *x, t_float row_float) /* copies edbuffer to row */
+{
+ t_atom *av,*ebuff;
+ int z;
+ long row = (long) row_float;
+
+ if (row < 0) row = 0L;
+ else if (row >= x->p_rows) row = (long)x->p_rows-1;
+
+ av = GETROW(x,row);
+ ebuff = GET_EDBUFF(x);
+ for (z=0;z<x->p_columns;z++,av++,ebuff++)
+ {
+ *av = *ebuff;
+ }
+ *x->p_dirty = (t_atom *)1; /* set dirty flag */
+}
+
+
+/* eg 'list COLUMN ROW <optional> VALUE' - argc=2 is read, arg=3 is write */
+
+void pbank_list(t_pbank *x, t_symbol *s, int argc, t_atom *argv)
+{
+
+ t_atom *av;
+ int ac,column,row;
+
+ if ((argc != 2) && (argc != 3))
+ {
+ error("pbank_list: less than 2, or more than 3 elements in list");
+ goto exit;
+ }
+
+
+ if (((argv)->a_type != A_FLOAT) || ((argv+1)->a_type != A_FLOAT))
+ {
+ error("pbank_list: first two elements must be numbers");
+ goto exit;
+ }
+ if ((column = (int)(argv)->a_w.w_float) < 0) column = 0;
+ else if (column >= x->p_columns) column = x->p_columns-1;
+
+ if ((row = (int)(argv+1)->a_w.w_float) < -1) row = -1;
+ else if (row >= x->p_rows) row = x->p_rows-1;
+
+
+ if (row == -1)
+ {
+ av = GET_EDBUFF(x);
+ }
+ else
+ {
+ av = GETROW(x,row);
+ }
+
+ av += column;
+ ac = 1;
+
+ if (argc == 2) /* read */
+ {
+ if (x->p_receives)
+ {
+ if (x->p_receives[column]->s_thing)
+ {
+ t_symbol *type;
+ if (av->a_type == A_FLOAT) type = z_float;
+ // else if (av->a_type == A_LONG) type = z_int;
+ else if (av->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[column]->s_thing, type,ac, av);
+ }
+ }
+ else
+ {
+ pbank_outlist->a_w.w_float = (t_float)column;
+ (pbank_outlist+1)->a_type = av->a_type;
+ if (av->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = av->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = av->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+ }
+
+ }
+ else /* write */
+ {
+ switch ((argv+2)->a_type)
+ {
+
+ case A_FLOAT:
+ SETFLOAT(av,(argv+2)->a_w.w_float);
+ break;
+ /* case A_LONG:
+ SETLONG(av,(argv+2)->a_w.w_long);
+ break;
+ */
+ case A_SYMBOL:
+ SETSYMBOL(av,(argv+2)->a_w.w_symbol);
+ break;
+ default:
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ *x->p_dirty = (t_atom *)1; /* set dirty flag */
+ }
+exit:
+ return;
+
+}
+
+int pbank_fromtext(t_pbank *x,void *b)
+{
+ t_atom *av;
+ int z,atype;
+ int columnpos = 0,columns = 0;
+ int rowpos = 0, rows = 0;
+ long items = 0;
+ int argc = binbuf_getnatom(b),count = 0;
+
+ t_atom *ap = binbuf_getvec(b);
+
+
+ /* get pbank symbol */
+ if (ap->a_type != A_SYMBOL || ap->a_w.w_symbol != gensym("pbank"))
+ {
+ error("pbank_fromtext: bad file format: item one must be the symbol 'pbank");
+ goto error;
+ }
+
+ for (z=0;z<2;z++)
+ {
+ ap++, count++;
+
+ // binbuf_getatom(b,&p1,&p2,&at); /* get columns and rows */
+ if (ap->a_type != A_FLOAT)
+ {
+ error("pbank_fromtext: bad file format: item two and three must be COLUMNcount and ROWcount");
+ goto error;
+ }
+ if (z==0) columns = (int)ap->a_w.w_float;
+ else rows = (int)ap->a_w.w_float;
+ }
+
+ if (columns < 1 || rows < 1)
+ {
+ error("pbank_fromtext: bad value(s) for item two and/or three (COLUMNcount and/or ROWcount)");
+ goto error;
+ }
+ if (columns != x->p_columns)
+ {
+ error("pbank_fromtext: bad file format: wrong no. of columns (%d) in file", columns);
+ goto error;
+ }
+
+ /* get comma */
+ ap++, count++;
+ if (ap->a_type != A_COMMA)
+ {
+ error("pbank_fromtext: bad file format: comma expected after third item");
+ goto error;
+ }
+
+
+
+ av = GETROW(x,rowpos);
+
+ // post("pbank_fromtext: columns %d rows %d",columns,rows);
+
+ while (count < argc)
+ {
+
+
+ if (rowpos > x->p_rows) // safety check- remove later
+ {
+ bug("pbank_fromtext: rowpos=%d x->p_rows=%d items=%d argc=%d",rowpos,x->p_rows,count,argc);
+ error("pbank_fromtext: rowpos greater than x->p_rows: aborting");
+ goto error;
+ }
+
+
+
+ ap++, count++; // get next atom
+ atype = ap->a_type;
+
+ if (atype == A_NULL)
+ {
+ if (count == argc) goto done;
+ else
+ {
+ error("pbank_fromtext: unexpected A_NULL type read at position %d: aborting", count);
+ goto error;
+ }
+ }
+
+
+ if (columnpos >= x->p_columns) goto skipit;
+
+
+
+ if (atype==A_FLOAT || atype==A_SYMBOL)
+ {
+ av[columnpos] = *ap; /* write atom to matrix */
+ items++;
+ }
+
+ else if (atype==A_COMMA) /* new line */
+ {
+ if (columnpos)
+ post("pbank_fromtext: warning: unexpected comma found in column %d row %d", columnpos,rowpos);
+ goto skipit;
+ }
+ else
+ {
+ // post("ATYPE = %d", atype);
+ post("pbank_fromtext: warning: strange token found in at column %d, row %d of file", columnpos,rowpos);
+ goto ignore;
+ }
+skipit: /* ignore any data that lies outside of X's dimensions */
+ if (atype!=A_COMMA)
+ columnpos++;
+ if (columnpos == columns)
+ {
+ columnpos = 0;
+ rowpos++;
+ av = GETROW(x,rowpos);
+ }
+ignore:;
+ }
+done:
+ return(items);
+error:
+ return(0);
+}
+
+
+void pbank_fromfile(t_pbank *x,char *name, int type, int silentFlag) // filename with or without path
+{
+ void *b;
+ int errorf, itemcount;
+ char nilbuf[1];
+
+ nilbuf[0] = 0;
+
+
+ b = binbuf_new();
+ // errorf = binbuf_read(b, name, vol, type);
+
+ if (*name != '/' && *name != '~') // file name is not an absolute path
+ errorf = binbuf_read(b, name, canvas_getdir(x->x_canvas)->s_name, type);
+ else
+ errorf = binbuf_read(b, name, nilbuf, type);
+
+
+ if (errorf)
+ {
+ if (!silentFlag) post("warning: pbank_fromfile:%s not found",name); // not error, since filename may be used only as symbol for pbanks sharing memory
+ }
+ else
+ {
+ itemcount = pbank_fromtext(x,b);
+ post("pbank_fromfile: %d items read from file %s",itemcount, name);
+ *x->p_dirty = NIL;
+ }
+ binbuf_free(b);
+}
+
+
+#define TEXT 0
+#define BINARY 1
+
+void pbank_read(t_pbank *x, t_symbol *fname)
+{
+ /* if (!open_dialog(name, &vol, &type, types, 1)) */
+ pbank_fromfile(x,fname->s_name,TEXT,0);
+}
+
+
+ /* format for file <float type> <symbol *pname> <float p1 p2 p3 p4..p10> A_COMMA.... */
+void pbank_tobinbuf(t_pbank *x,void *b)
+{
+ t_atom at,*av;
+ t_symbol *s;
+ char shit[256];
+ int z,i;
+
+ sprintf(shit,"\n");
+ s = gensym("");
+
+ SETSYMBOL(&at,gensym("pbank")); /* write class name */
+ binbuf_add(b,1,&at);
+
+ SETFLOAT(&at,(t_float) x->p_columns); /* write column count */
+ binbuf_add(b,1,&at);
+
+ SETFLOAT(&at,(t_float) x->p_rows); /* write row count */
+ binbuf_add(b,1,&at);
+
+ SETCOMMA(&at); /* write comma */
+ binbuf_add(b,1,&at);
+
+ SETSYMBOL(&at,gensym(shit)); /* write CR */
+ binbuf_add(b,1,&at);
+
+
+ for (z=0;z<x->p_rows;z++) /* write params to binbuf */
+ {
+ av = GETROW(x,z);
+ for (i=0;i<x->p_columns;i++,av++)
+ {
+
+/* if (av->a_type == A_FLOAT)
+ {
+ post("A_FLOAT"); postfloat(av->a_w.w_float);
+ }
+
+ // else if (av->a_type == A_LONG) post("A_LONG %ld", av->a_w.w_long);
+
+ else if (av->a_type == A_SYMBOL) post("A_SYMBOL %s", av->a_w.w_symbol->s_name);
+*/
+ binbuf_add(b,1,av); /* write atom */
+ }
+ SETCOMMA(&at); /* rows seperated by comma */
+ binbuf_add(b,1,&at);
+ SETSYMBOL(&at,gensym(shit)); /* write CR */
+ binbuf_add(b,1,&at);
+
+ }
+}
+
+void pbank_write(t_pbank *x, t_symbol *name)
+{
+ char fn[256];
+
+ sprintf(fn,"%s", name->s_name);
+
+ /* def volume shit here */
+
+ pbank_saveto(x,fn);
+}
+
+void pbank_saveto(t_pbank *x,char *fn)
+{
+ int errorf = 0;
+ char nilbuf[1];
+ void *b = binbuf_new();
+
+
+ pbank_tobinbuf(x,b);
+
+ nilbuf[0]= 0; // nilbuf[1]= 0; bug fixed: zk-03/06
+
+ if (*fn != '/' && *fn != '~') // file name is not an absolute path
+ errorf = binbuf_write(b, fn, canvas_getdir(x->x_canvas)->s_name, TEXT); /* save as TEXT */
+ else
+ errorf = binbuf_write(b, fn, nilbuf, TEXT); /* save as TEXT */
+
+ binbuf_free(b);
+
+ if (errorf)
+ error("pbank_saveto: couldn't write %s", fn);
+ else
+ {
+ *x->p_dirty = NIL;
+ post("pbank_write:wrote file %s",fn);
+ }
+}
+
+void pbank_dispose(t_pbank *x)
+{
+ int z;
+
+ t_shared *prePiss = NIL;
+ t_shared *piss = NIL;
+
+ if (*x->p_dirty)
+ {
+ /* need a save dialog here */
+ post("unsaved data");
+ }
+
+ prePiss = piss = pbank_banks; /* maintain list of instance memories */
+ if (x->p_name)
+ {
+ while(piss)
+ {
+
+ /* post("->%s at %lx",piss->s_sym->s_name,piss);
+ post(" next->%lx",piss->s_next); */
+
+ if ((t_symbol *)piss->s_sym == x->p_name) break;
+
+ prePiss = piss;
+ piss = piss->s_next;
+ }
+ if (!piss)
+ {
+ error("pbank_dispose: bug found- can't find symbol");
+ goto skip;
+ }
+ /* post("found %s", piss->s_sym->s_name); */
+
+ piss->s_refcount--;
+ if (piss->s_refcount)
+ {
+ /* post("%s refcount = %d",piss->s_sym->s_name, piss->s_refcount); */
+ goto skip; /* things still pointing to data- don't dispose */
+ }
+
+ piss->s_sym->s_thing = (void *) 0L; /* clear symbol to no longer point to this class */
+
+ if (!piss->s_next) /* last element in list */
+ {
+ if (piss == pbank_banks) /* first element in list of only one element*/
+ {
+ /* post("°°°°°° unique element in list"); */
+ freebytes(piss, (int)sizeof(t_shared));
+ pbank_banks = NIL;
+ }
+ else /* last element in list - snip it */
+ {
+ if (!prePiss)
+ {
+ error("bug found in pbank_dispose (prePiss)");
+ goto skip;
+ }
+ /* post("°°°°°° last element in list"); */
+ prePiss->s_next = NIL;
+ freebytes(piss, (int)sizeof(t_shared));
+ }
+ }
+ else if (piss == pbank_banks) /* first element in list of at least two elements */
+ {
+ /* post("°°°°°° first element in list"); */
+ pbank_banks = piss->s_next;
+ freebytes(piss, (int)sizeof(t_shared));
+ }
+ else /* element with adjacent elements */
+ {
+ if (!prePiss)
+ {
+ error("bug found in pbank_dispose (prePiss)");
+ goto skip;
+ }
+ /* post("°°°°°° embedded element in list"); */
+ prePiss->s_next = piss->s_next;
+ freebytes(piss, (int)sizeof(t_shared));
+ }
+
+ }
+
+ for (z=0;z<x->p_rows+EDBUFF;z++)
+ {
+ freebytes((void *)x->p_data[z], (int)sizeof(t_atom)*x->p_columns);
+ }
+
+ freebytes((void *)x->p_data,(int)sizeof(t_atom *)*(x->p_rows+EDBUFF+DIRTFLAG));
+
+skip:
+ if (x->p_receives)
+ freebytes((void *)x->p_receives, (int)sizeof(t_symbol *)*x->p_columns);
+
+}
+
+
+
+t_class *pbank_class;
+
+void pbank_setup(void)
+{
+ pbank_class = class_new(gensym("pbank"), (t_newmethod) pbank_new, (t_method) pbank_dispose, sizeof(t_pbank), 0, A_GIMME,0);
+ class_addbang(pbank_class, (t_method) pbank_bang);
+ class_addlist(pbank_class, (t_method) pbank_list);
+ class_addmethod(pbank_class, (t_method) pbank_put, gensym("put"),A_GIMME,0);
+ class_addmethod(pbank_class, (t_method) pbank_db, gensym("db"), A_FLOAT,A_FLOAT, 0);
+ class_addmethod(pbank_class, (t_method) pbank_recall, gensym("recall"), A_FLOAT,0);
+ // class_addmethod(pbank_class, (t_method) pbank_recallf, gensym("recallf"), A_FLOAT,0);
+ class_addmethod(pbank_class, (t_method) pbank_dump, gensym("dump"),A_GIMME,0);
+ class_addmethod(pbank_class, (t_method) pbank_store, gensym("store"), A_FLOAT,0);
+ class_addmethod(pbank_class, (t_method) pbank_write, gensym("write"), A_SYMBOL,0);
+ class_addmethod(pbank_class, (t_method) pbank_read, gensym("read"), A_SYMBOL,0);
+ class_addmethod(pbank_class, (t_method) pbank_interp, gensym("interp"), A_GIMME,0);
+ class_addmethod(pbank_class, (t_method) pbank_set, gensym("set"),A_GIMME,0);
+
+
+ pbank_outlist->a_type = A_FLOAT;
+
+ z_list = gensym("list");
+ z_float = gensym("float");
+ // z_int = gensym("int");
+ z_symbol = gensym("symbol");
+ z_receive = gensym("receive");
+ pbank_ID = gensym(PBANK_ID_STRING);
+ pbank_ID->s_thing = (void *)pbank_ID;
+
+ post("%s", VERSION);
+}
+
+
+/* columns rows memory-name receiveName<optional> */
+/* note: memory-name is optional when no receiveName argument is specified */
+void *pbank_new(t_symbol *s, int argc, t_atom *argv)
+{
+ int z=0;
+ char *shit;
+ char piss[256];
+
+ t_pbank *x = (t_pbank *)pd_new(pbank_class);
+
+ x->p_name = NIL;
+ x->p_receives = NIL;
+ x->x_canvas = canvas_getcurrent();
+
+ // x->p_vol = getdefvolume();
+
+ if (!InRange(argc,2,4))
+ {
+ error("pbank_new: bad arg count - takes: colums rows fname <opt symbol> sendname");
+ goto err;
+ }
+
+
+
+
+ if (((argv)->a_type != A_FLOAT) || ((argv+1)->a_type != A_FLOAT))
+ {
+ error("pbank_new: first two elements must be numbers");
+ goto err;
+ }
+
+
+// if ((argv)->a_w.w_float < 1 || (argv+1)->a_w.w_float < 1)
+// {
+// error("pbank_new: first or second argument less than 1, can't continue");
+// goto err;
+// }
+
+ if (!InRange((argv)->a_w.w_float, 1,MAX_COLUMNS-1))
+ {
+ x->p_columns = DEFAULT_COLUMNS;
+ post("pbank_new: warning: columns argument out of range, setting to %d",x->p_columns);
+ }
+ else x->p_columns = (int)(argv)->a_w.w_float;
+
+ if (!InRange((argv+1)->a_w.w_float, 1,MAX_ROWS-1))
+ {
+ x->p_rows = DEFAULT_ROWS;
+ post("pbank_new: warning: rows argument out of range, setting to %d",x->p_rows);
+ }
+ else x->p_rows = (int)(argv+1)->a_w.w_float;
+
+
+
+ if (argc == 2) x->p_name = NIL;
+ else
+ {
+ if ((argv+2)->a_type != A_SYMBOL)
+ {
+ error("pbank_new: bad third arg: needs to be a symbol (or empty string %s)",gensym("")->s_name);
+ goto err;
+ }
+ shit = (argv+2)->a_w.w_symbol->s_name;
+ /* is it a crosshatch or un-defined ("") ? */
+ x->p_name = ((shit[0] == '#') || (shit[0] == '"' && shit[1] == '"')) ? NIL:gensym(shit);
+ }
+
+
+ if (argc == 4) /* argc == 4: establish output pointers to receive objects */
+ {
+ if ((argv+3)->a_type != A_SYMBOL)
+ {
+ if ((argv+3)->a_type == A_FLOAT)
+ {
+ post("pbank_new: warning: 4th arg not symbol: ignoring (%f)", (argv+3)->a_w.w_float);
+ goto nosyms;
+ }
+ else
+ {
+ error("pbank_new: optional fourth arg. needs to be a symbol");
+ goto err;
+ }
+ }
+
+
+ shit = (argv+3)->a_w.w_symbol->s_name;
+ if (shit[0] == '#' || (shit[0] == '"' && shit[1] == '"')) goto nosyms; /* crosshatch here */;
+
+ x->p_receives = (t_symbol **)getbytes((int)sizeof(t_symbol *)*x->p_columns);
+
+ for (z=0;z<x->p_columns;z++)
+ {
+ sprintf(piss,"%s-%d",shit,z); // generate symbol of form: "name-columnNo"
+ x->p_receives[z] = gensym(piss);
+
+ if (x->p_receives[z]->s_thing)
+ { /* sends or receive obj */
+
+ // post("found us a %s",class_getname(pd_class(x->p_receives[z]->s_thing)));
+
+ // if ((void *)pd_class(x->p_receives[z]->s_thing)->c_sym != gensym("through"))
+ /*
+ NO TESTING FOR SHARED SYMBOLS
+
+ if (strcmp(class_getname(pd_class(x->p_receives[z]->s_thing)), "send") &&
+ strcmp(class_getname(pd_class(x->p_receives[z]->s_thing)), "receive") &&
+ strcmp(class_getname(pd_class(x->p_receives[z]->s_thing)), "bindlist"))
+ {
+ error("pbank_new: symbol %s already being used, can't use it",shit);
+ post("z=%d found a %s",z,class_getname(pd_class(x->p_receives[z]->s_thing)));
+ goto err;
+ }
+ */
+
+ }
+ }
+ }
+
+nosyms:
+ if (NIL == (x->p_data = pbank_getmem(x->p_name, x->p_columns,x->p_rows))) goto err; /* can't allocate data matrix */
+ x->p_dirty = x->p_data+x->p_rows-1+EDBUFF+DIRTFLAG; /* points to extra cell in matrix used for dirty flag */
+
+
+ if (x->p_name)
+ {
+ pbank_fromfile(x,x->p_name->s_name, TEXT,1);
+ }
+
+ outlet_new((t_object *) x, gensym("list"));
+
+ return(x);
+err:
+ if (x->p_receives) freebytes((void *)x->p_receives, (int)sizeof(t_symbol *)*x->p_columns);
+ return(NIL);
+}
+
+
+
+
+
+
+/* NOTE: light error checking --- allocates memory and manages allocation list */
+/* returns NIL (on error) or pointer to existing or new data matrix */
+/* note memory size is columns*(rows+1) + 1 - where the extra row is for the edit buffer */
+/* and the extra cell is for the DIRTY flag */
+/* class independent allocation - needs class independent dispose method */
+
+t_atom **pbank_getmem(t_symbol *name,int columns,int rows)
+{
+ int z,i;
+ t_shared *piss = NIL;
+ t_atom **matrix,*av;
+ char crap[256];
+
+ if (!InRange(columns, 1,MAX_COLUMNS-1)) columns = DEFAULT_COLUMNS;
+ if (!InRange(rows, 1,MAX_ROWS-1)) rows = DEFAULT_ROWS;
+
+ if (name)
+ {
+ if (name->s_thing)
+ {
+ if (name->s_thing == pbank_ID->s_thing) /* memory already exists - increment refcount */
+ {
+ piss = pbank_banks; /* maintain list of instance memories */
+ while(piss)
+ {
+ if (piss->s_sym == name) /* pbank instances sharing memory */
+ {
+ if (piss->s_columns != columns || piss->s_rows != rows)
+ {
+ error("pbank_getmem: pbank %s's dimensions must be (%d x %d)",name->s_name,
+ piss->s_columns,piss->s_rows);
+ return(NIL);
+ }
+ piss->s_refcount++;
+ /* post("%s refcount=%d",piss->s_sym->s_name,piss->s_refcount); */
+ return(piss->s_data);
+ }
+ piss = piss->s_next;
+ }
+ error("pbank_getmem: bug: name %s not found",name->s_name);
+ return(NIL);
+ }
+ else /* bad symbol - already taken - can't do anything */
+ {
+ error("pbank_getmem: symbol %s already being used by another object",name->s_name);
+ return(NIL);
+ }
+ }
+ else /* allocate entry for given name in shared memory list */
+ {
+
+ name->s_thing = pbank_ID->s_thing; /* associate symbol with pbank class */
+ piss = getbytes(sizeof(t_shared)); /* allocate new entry */
+ piss->s_sym = name;
+ piss->s_refcount = 1;
+ piss->s_next = (pbank_banks) ? pbank_banks:NIL;
+ pbank_banks = piss; /* link it in at head of list */
+ /* post("PISS alloc %lx",piss); */
+ }
+ }
+
+ /* allocate memory for data matrix */
+ /* allocate "rows" + 1 (edbuff) + 1 (dirty flag) ROWS */
+ matrix = (t_atom **)getbytes((int)sizeof(t_atom *)*(rows+EDBUFF+DIRTFLAG));
+ for (z=0;z<rows+EDBUFF;z++)
+ matrix[z] = (t_atom *)getbytes(sizeof(t_atom)*columns);
+
+
+ for (z=0;z<rows+EDBUFF;z++) /* data matrix - all 0's */
+ {
+
+ sprintf(crap,"untitled_%d", z);
+ av = matrix[z];
+ SETSYMBOL(av,gensym(crap));
+ for (i=1;i<columns;i++)
+ SETFLOAT(av+i,0L);
+ }
+
+ matrix[rows-1+EDBUFF+DIRTFLAG] = NIL; /* set dirty flag cell to 0 */
+ if (piss)
+ {
+ piss->s_data = matrix; /* keep pointer to memory with shared */
+ piss->s_columns = columns;
+ piss->s_rows = rows;
+ }
+ return(matrix); /* no errors - return pointer to data matrix */
+}
+
+
+
+
+
+
+
+
+
diff --git a/nusmuk_utils/pbank.h b/nusmuk_utils/pbank.h
new file mode 100644
index 0000000..7bd1f44
--- /dev/null
+++ b/nusmuk_utils/pbank.h
@@ -0,0 +1,14 @@
+
+
+
+typedef struct shared
+{
+ t_symbol *s_sym; /* shared memory name */
+ t_atom **s_data; /* memory pointer */
+ int s_rows; /* memory dimension */
+ int s_columns; /* memory dimension */
+ int s_refcount; /* number of objects pointing to "s_data" */
+ struct shared *s_next;
+} t_shared;
+
+
diff --git a/nusmuk_utils/pbank.pd_linux b/nusmuk_utils/pbank.pd_linux
new file mode 100644
index 0000000..e6eb314
--- /dev/null
+++ b/nusmuk_utils/pbank.pd_linux
Binary files differ
diff --git a/nusmuk_utils/pps-help.pd b/nusmuk_utils/pps-help.pd
new file mode 100644
index 0000000..2702e65
--- /dev/null
+++ b/nusmuk_utils/pps-help.pd
@@ -0,0 +1,13 @@
+#N canvas 0 0 450 300 10;
+#X obj 40 28 pps;
+#X text 85 27 shortcut for :;
+#X obj 209 29 list prepend set;
+#X obj 209 50 list trim;
+#X obj 45 163 pps;
+#X msg 45 190 41 0;
+#X obj 45 137 pack f foo;
+#X floatatom 45 118 5 0 0 0 - - -;
+#X connect 2 0 3 0;
+#X connect 4 0 5 0;
+#X connect 6 0 4 0;
+#X connect 7 0 6 0;
diff --git a/nusmuk_utils/pps.pd b/nusmuk_utils/pps.pd
new file mode 100644
index 0000000..3e4c023
--- /dev/null
+++ b/nusmuk_utils/pps.pd
@@ -0,0 +1,8 @@
+#N canvas 0 0 450 300 10;
+#X obj 55 24 inlet;
+#X obj 55 43 list prepend set;
+#X obj 55 65 list trim;
+#X obj 55 87 outlet;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
diff --git a/nusmuk_utils/rand_diff-help.pd b/nusmuk_utils/rand_diff-help.pd
new file mode 100755
index 0000000..bbda493
--- /dev/null
+++ b/nusmuk_utils/rand_diff-help.pd
@@ -0,0 +1,18 @@
+#N canvas 93 73 450 300 10;
+#X msg 53 132 bang;
+#X floatatom 53 232 0 0 0 0 - - -;
+#X msg 63 156 seed 123;
+#X text 105 130 bang for output;
+#X text 145 156 message to set the seed;
+#X floatatom 134 183 0 0 0 0 - - -;
+#X text 164 183 inlet to reset the range;
+#X text 144 206 argument to initialize the range;
+#X text 125 77 \$1 : range;
+#X obj 53 206 rand_diff 10;
+#X text 45 31 rand-diff - random number with very few redondancy from
+precedent output;
+#X text 45 60 output are mostly growing;
+#X connect 0 0 9 0;
+#X connect 2 0 9 0;
+#X connect 5 0 9 1;
+#X connect 9 0 1 0;
diff --git a/nusmuk_utils/rand_diff.pd b/nusmuk_utils/rand_diff.pd
new file mode 100644
index 0000000..3682090
--- /dev/null
+++ b/nusmuk_utils/rand_diff.pd
@@ -0,0 +1,34 @@
+#N canvas 90 260 450 300 10;
+#X obj 51 169 random;
+#X obj 81 207 %;
+#X obj 51 207 +;
+#X obj 51 188 + 1;
+#X obj 174 100 sqrt;
+#X obj 174 138 i;
+#X obj 174 119 * 1.5;
+#X obj 174 11 inlet;
+#X obj 51 30 route bang seed;
+#X obj 51 11 inlet;
+#X obj 51 49 t b b;
+#X msg 102 81 seed \$1;
+#X obj 81 227 outlet;
+#X obj 174 81 \$1;
+#X obj 187 55 loadbang;
+#X connect 0 0 3 0;
+#X connect 1 0 2 1;
+#X connect 1 0 12 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X connect 4 0 6 0;
+#X connect 5 0 0 1;
+#X connect 6 0 5 0;
+#X connect 7 0 13 0;
+#X connect 8 0 10 0;
+#X connect 8 1 11 0;
+#X connect 9 0 8 0;
+#X connect 10 0 0 0;
+#X connect 10 1 13 0;
+#X connect 11 0 0 0;
+#X connect 13 0 1 1;
+#X connect 13 0 4 0;
+#X connect 14 0 13 0;
diff --git a/nusmuk_utils/randn-help.pd b/nusmuk_utils/randn-help.pd
new file mode 100755
index 0000000..b0787d9
--- /dev/null
+++ b/nusmuk_utils/randn-help.pd
@@ -0,0 +1,20 @@
+#N canvas 460 231 523 310 10;
+#X text 49 31 _randn - random numbers in gaussian distribution;
+#X text 111 67 \$2 : mean;
+#X text 111 49 \$1 : standard deviation;
+#X msg 73 112 bang;
+#X floatatom 103 161 0 0 0 0 - - -;
+#X floatatom 73 242 0 0 0 0 - - -;
+#X msg 83 136 seed 123;
+#X text 125 110 bang for output;
+#X text 165 136 message to set the seed;
+#X text 136 160 inlet to reset the std;
+#X text 149 216 argument to initialize the std and mean;
+#X floatatom 133 189 0 0 0 0 - - -;
+#X text 163 189 inlet to reset the mean;
+#X obj 73 217 randn 5 0;
+#X connect 3 0 13 0;
+#X connect 4 0 13 1;
+#X connect 6 0 13 0;
+#X connect 11 0 13 2;
+#X connect 13 0 5 0;
diff --git a/nusmuk_utils/randn.pd b/nusmuk_utils/randn.pd
new file mode 100755
index 0000000..c38ae79
--- /dev/null
+++ b/nusmuk_utils/randn.pd
@@ -0,0 +1,49 @@
+#N canvas 146 129 994 651 10;
+#X text 273 329 u1;
+#X obj 310 376 log;
+#X obj 310 401 * -2;
+#X obj 310 430 sqrt;
+#X obj 419 435 cos;
+#X obj 419 405 * 6.283;
+#X obj 310 463 *;
+#X text 521 339 u2;
+#X text 370 512 sigma;
+#X text 373 557 mean;
+#X obj 375 258 t b b;
+#X obj 310 214 route seed;
+#X obj 419 259 * 65636;
+#X obj 310 156 inlet;
+#X msg 419 311 seed \$1;
+#X msg 310 298 seed \$1;
+#X obj 310 592 outlet;
+#X obj 310 514 * \$1;
+#X obj 310 552 + \$2;
+#X obj 384 482 inlet;
+#X obj 471 483 inlet;
+#X obj 310 328 random 6.5e+06;
+#X obj 310 355 / 6.5e+06;
+#X obj 419 337 random 6.5e+06;
+#X obj 419 364 / 6.5e+06;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 3 0 6 0;
+#X connect 4 0 6 1;
+#X connect 5 0 4 0;
+#X connect 6 0 17 0;
+#X connect 10 0 21 0;
+#X connect 10 1 23 0;
+#X connect 11 0 12 0;
+#X connect 11 0 15 0;
+#X connect 11 1 10 0;
+#X connect 12 0 14 0;
+#X connect 13 0 11 0;
+#X connect 14 0 23 0;
+#X connect 15 0 21 0;
+#X connect 17 0 18 0;
+#X connect 18 0 16 0;
+#X connect 19 0 17 1;
+#X connect 20 0 18 1;
+#X connect 21 0 22 0;
+#X connect 22 0 1 0;
+#X connect 23 0 24 0;
+#X connect 24 0 5 0;
diff --git a/nusmuk_utils/rnd_flow-help.pd b/nusmuk_utils/rnd_flow-help.pd
new file mode 100644
index 0000000..05adb21
--- /dev/null
+++ b/nusmuk_utils/rnd_flow-help.pd
@@ -0,0 +1,27 @@
+#N canvas 579 67 428 392 10;
+#X obj 27 70 metro 20;
+#X obj 27 53 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1
+;
+#X floatatom 68 92 5 0 0 0 - - -;
+#X floatatom 109 108 5 0 0 0 - - -;
+#X floatatom 150 124 5 0 0 0 - - -;
+#X obj 27 211 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 6171 1;
+#X obj 27 171 + 1;
+#X obj 27 190 * 64;
+#X obj 27 33 loadbang;
+#X obj 242 308 filtered_random;
+#X text 241 287 related to :;
+#X text 113 90 amplitude max of each step;
+#X text 155 107 low pass filter of the output;
+#X text 195 124 high pass filter of the output;
+#X obj 27 152 rnd_flow 0.1 20 20;
+#X connect 0 0 14 0;
+#X connect 1 0 0 0;
+#X connect 2 0 14 1;
+#X connect 3 0 14 2;
+#X connect 4 0 14 3;
+#X connect 6 0 7 0;
+#X connect 7 0 5 0;
+#X connect 8 0 1 0;
+#X connect 14 0 6 0;
diff --git a/nusmuk_utils/rnd_flow.pd b/nusmuk_utils/rnd_flow.pd
new file mode 100644
index 0000000..70791e3
--- /dev/null
+++ b/nusmuk_utils/rnd_flow.pd
@@ -0,0 +1,70 @@
+#N canvas 596 195 579 445 10;
+#X obj 77 151 random 10001;
+#X obj 77 170 - 5000;
+#X obj 77 189 / 5000;
+#X obj 77 339 +;
+#X msg 131 74 0;
+#X obj 77 54 route bang reset;
+#X obj 77 246 +;
+#X obj 332 218 + 1;
+#X obj 332 181 1;
+#X obj 332 161 /;
+#X msg 332 141 1 \$1;
+#X obj 77 265 / 2;
+#X obj 77 227 * 1;
+#X obj 77 34 inlet;
+#X obj 77 365 outlet;
+#X obj 220 34 inlet;
+#X obj 332 34 inlet;
+#X obj 471 34 inlet;
+#X obj 77 208 * \$1;
+#X obj 109 338 * 1;
+#X obj 342 53 loadbang;
+#X obj 332 72 \$2;
+#X obj 332 91 max 0.0001;
+#X text 225 92 amplitude;
+#X text 342 109 filter (lop);
+#X text 345 124 0 .. 100;
+#X obj 471 91 / 1000;
+#X msg 471 110 1 \$1;
+#X obj 471 129 -;
+#X obj 480 53 loadbang;
+#X obj 471 72 \$3;
+#X text 474 153 filter (hip);
+#X text 476 168 0 .. 100;
+#X obj 230 53 loadbang;
+#X obj 220 72 \$1;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 18 0;
+#X connect 3 0 14 0;
+#X connect 3 0 19 0;
+#X connect 4 0 3 1;
+#X connect 4 0 6 1;
+#X connect 5 0 0 0;
+#X connect 5 1 4 0;
+#X connect 6 0 11 0;
+#X connect 7 0 11 1;
+#X connect 8 0 7 0;
+#X connect 8 0 12 1;
+#X connect 9 0 8 0;
+#X connect 10 0 9 0;
+#X connect 11 0 6 1;
+#X connect 11 0 3 0;
+#X connect 12 0 6 0;
+#X connect 13 0 5 0;
+#X connect 15 0 34 0;
+#X connect 16 0 21 0;
+#X connect 17 0 30 0;
+#X connect 18 0 12 0;
+#X connect 19 0 3 1;
+#X connect 20 0 21 0;
+#X connect 21 0 22 0;
+#X connect 22 0 10 0;
+#X connect 26 0 27 0;
+#X connect 27 0 28 0;
+#X connect 28 0 19 1;
+#X connect 29 0 30 0;
+#X connect 30 0 26 0;
+#X connect 33 0 34 0;
+#X connect 34 0 18 1;
diff --git a/nusmuk_utils/rnd_metro-help.pd b/nusmuk_utils/rnd_metro-help.pd
new file mode 100644
index 0000000..0d40928
--- /dev/null
+++ b/nusmuk_utils/rnd_metro-help.pd
@@ -0,0 +1,15 @@
+#N canvas 398 162 633 352 10;
+#X obj 27 112 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj 27 178 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 27 146 rnd_metro 100 2000;
+#X text 163 9 metronome with random delay between bang;
+#X text 162 197 2 : maximum time between 2 bang;
+#X text 127 175 args 1 : minimum time between 2 bang;
+#X floatatom 87 123 5 0 0 0 - - -;
+#X floatatom 148 123 5 0 0 0 - - -;
+#X connect 0 0 2 0;
+#X connect 2 0 1 0;
+#X connect 6 0 2 1;
+#X connect 7 0 2 2;
diff --git a/nusmuk_utils/rnd_metro.pd b/nusmuk_utils/rnd_metro.pd
new file mode 100644
index 0000000..d16905a
--- /dev/null
+++ b/nusmuk_utils/rnd_metro.pd
@@ -0,0 +1,53 @@
+#N canvas 0 0 450 300 10;
+#X obj 125 10 inlet;
+#X obj 104 177 spigot 0;
+#X obj 97 57 sel 1;
+#X obj 125 34 t f f;
+#X obj 95 146 delay;
+#X obj 238 14 inlet;
+#X obj 297 14 inlet;
+#X obj 95 85 t b b b;
+#X obj 139 263 outlet;
+#N canvas 0 0 450 300 between 0;
+#X obj 61 29 inlet;
+#X obj 211 31 inlet;
+#X obj 350 33 inlet;
+#X obj 195 172 \$1;
+#X obj 225 352 / 100000;
+#X obj 225 281 i;
+#X obj 195 380 +;
+#X obj 195 206 t f f;
+#X obj 195 410 outlet;
+#X obj 225 230 - \$2;
+#X obj 225 304 t b f;
+#X obj 225 328 random 0;
+#X obj 225 256 * -100000;
+#X obj 61 67 t b;
+#X connect 0 0 13 0;
+#X connect 1 0 3 1;
+#X connect 2 0 9 1;
+#X connect 3 0 7 0;
+#X connect 4 0 6 1;
+#X connect 5 0 10 0;
+#X connect 6 0 8 0;
+#X connect 7 0 6 0;
+#X connect 7 1 9 0;
+#X connect 9 0 12 0;
+#X connect 10 0 11 0;
+#X connect 10 1 11 1;
+#X connect 11 0 4 0;
+#X connect 12 0 5 0;
+#X connect 13 0 3 0;
+#X restore 117 113 pd between \$1 \$2;
+#X connect 0 0 3 0;
+#X connect 1 0 7 0;
+#X connect 2 0 7 0;
+#X connect 3 0 2 0;
+#X connect 3 1 1 1;
+#X connect 4 0 1 0;
+#X connect 5 0 9 1;
+#X connect 6 0 9 2;
+#X connect 7 0 4 0;
+#X connect 7 1 9 0;
+#X connect 7 2 8 0;
+#X connect 9 0 4 1;