aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Jurish <mukau@users.sourceforge.net>2006-02-02 12:49:19 +0000
committerBryan Jurish <mukau@users.sourceforge.net>2006-02-02 12:49:19 +0000
commit0727bfcaf2bd48bf501a7fa95515c400a1996902 (patch)
tree81a3774a9601ba1242482696344f3de3e08f8f22
parent6a4001a8538862ac02714a03fedd07c3b6f79366 (diff)
initial cvs import
svn path=/trunk/externals/moocow/; revision=4536
-rw-r--r--flite/COPYING290
-rw-r--r--flite/Makefile.am139
-rw-r--r--flite/README.cvs13
-rw-r--r--flite/README.pod89
-rwxr-xr-xflite/autogen.sh48
-rw-r--r--flite/config/Makefile.am66
-rw-r--r--flite/configure.in242
-rw-r--r--flite/flite-1.1-noaudio.patch20
-rw-r--r--flite/flite-help.pd54
-rw-r--r--flite/flite-numbers.pd48
-rw-r--r--flite/flite-test.pd70
-rw-r--r--flite/flite-test2.pd34
-rw-r--r--flite/flite.c264
-rw-r--r--gfsm/COPYING290
-rw-r--r--gfsm/Changes9
-rw-r--r--gfsm/Makefile.am98
-rw-r--r--gfsm/README.cvs13
-rw-r--r--gfsm/README.pod60
-rwxr-xr-xgfsm/autogen.sh48
-rw-r--r--gfsm/config/Makefile.am66
-rw-r--r--gfsm/configure.in233
-rw-r--r--gfsm/src/Makefile.am152
-rw-r--r--gfsm/src/atom_alphabet.c139
-rw-r--r--gfsm/src/atom_alphabet.h80
-rw-r--r--gfsm/src/gfsm-help.pd15
-rw-r--r--gfsm/src/gfsm-help.tfst3
-rw-r--r--gfsm/src/gfsm_alphabet-help.pd64
-rw-r--r--gfsm/src/gfsm_automaton-help.pd288
-rw-r--r--gfsm/src/gfsm_markov-help.pd68
-rw-r--r--gfsm/src/gfsm_markov.pd414
-rw-r--r--gfsm/src/gfsm_state-help.pd55
-rw-r--r--gfsm/src/lkpin.tfst4
-rw-r--r--gfsm/src/lkptest.tfst8
-rw-r--r--gfsm/src/pd_algebra.c299
-rw-r--r--gfsm/src/pd_alphabet.c494
-rw-r--r--gfsm/src/pd_alphabet.h78
-rw-r--r--gfsm/src/pd_automaton.c765
-rw-r--r--gfsm/src/pd_automaton.h85
-rw-r--r--gfsm/src/pd_gfsm.c93
-rw-r--r--gfsm/src/pd_gfsm.h54
-rw-r--r--gfsm/src/pd_io.c75
-rw-r--r--gfsm/src/pd_io.h47
-rw-r--r--gfsm/src/pd_state.c303
-rw-r--r--gfsm/src/pd_state.h58
-rw-r--r--gfsm/src/test-alphabet.pd3
-rw-r--r--gfsm/src/test-alphabet2.pd44
-rw-r--r--gfsm/src/test-automaton.pd260
-rw-r--r--gfsm/src/test-automaton2.pd196
-rw-r--r--gfsm/src/test-fsm.pd2
-rw-r--r--gfsm/src/test-markov.pd211
-rw-r--r--gfsm/src/test-state.pd427
-rw-r--r--gfsm/src/test-state2.pd415
-rw-r--r--gfsm/src/test.lab5
-rw-r--r--gfsm/src/test.tfst3
-rw-r--r--gfsm/src/test2.lab6
-rw-r--r--gfsm/src/test2.tfst4
-rw-r--r--gfsm/src/test3.tfst4
-rw-r--r--readdir/COPYING290
-rw-r--r--readdir/Changes7
-rw-r--r--readdir/Makefile.am98
-rw-r--r--readdir/README.cvs13
-rw-r--r--readdir/README.pod46
-rwxr-xr-xreaddir/autogen.sh48
-rw-r--r--readdir/config/Makefile.am66
-rw-r--r--readdir/configure.in197
-rw-r--r--readdir/src/Makefile.am135
-rw-r--r--readdir/src/readdir-help.pd41
-rw-r--r--readdir/src/readdir-test.pd28
-rw-r--r--readdir/src/readdir.c278
-rw-r--r--weightmap/COPYING290
-rw-r--r--weightmap/Changes7
-rw-r--r--weightmap/Makefile.am98
-rw-r--r--weightmap/README.cvs16
-rw-r--r--weightmap/README.pod40
-rwxr-xr-xweightmap/autogen.sh48
-rw-r--r--weightmap/config/Makefile.am66
-rw-r--r--weightmap/configure.in197
-rw-r--r--weightmap/src/Makefile.am135
-rw-r--r--weightmap/src/weightmap-help.pd74
-rw-r--r--weightmap/src/weightmap-test.pd135
-rw-r--r--weightmap/src/weightmap.c364
81 files changed, 10132 insertions, 0 deletions
diff --git a/flite/COPYING b/flite/COPYING
new file mode 100644
index 0000000..fa0bef4
--- /dev/null
+++ b/flite/COPYING
@@ -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/flite/Makefile.am b/flite/Makefile.am
new file mode 100644
index 0000000..84c306c
--- /dev/null
+++ b/flite/Makefile.am
@@ -0,0 +1,139 @@
+# File: ./Makefile.am
+# Package: flite
+# Description:
+# + top-level automake file
+#
+# Process this file with Automake to create Makefile.in.
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Options & Subdirectories
+#-----------------------------------------------------------------------
+
+## --- automake options
+#AUTOMAKE_OPTIONS = foreign dist-bzip2 dist-zip
+AUTOMAKE_OPTIONS = foreign
+
+## --- recursion subdirectories
+SUBDIRS = config
+
+## --- pseudo-deps for '.SUFFIXES'
+SUFFIXES = .pod .txt
+
+#-----------------------------------------------------------------------
+# Flags and variables
+#-----------------------------------------------------------------------
+PD_DIR = @PD_DIR@
+PD_INC = @PD_INC@
+PD_DOCDIR = @PD_DOC@
+PD_EXTDIR = @PD_EXTDIR@
+EXT = @EXT@
+
+#-----------------------------------------------------------------------
+# pd externals (hacked 'libexec_*')
+#-----------------------------------------------------------------------
+EXEEXT=.@EXT@
+libexecdir = @PD_EXTDIR@
+
+## --- externals
+libexec_PROGRAMS = flite
+
+## --- documentation
+datadir = @PD_DOCDIR@
+data_DATA = flite-help.pd
+
+#-----------------------------------------------------------------------
+# sources
+#-----------------------------------------------------------------------
+flite_SOURCES = flite.c
+
+#-----------------------------------------------------------------------
+# external compilation : flags
+#-----------------------------------------------------------------------
+DEFS = @DEFS@
+AFLAGS = @AFLAGS@
+DFLAGS = @DFLAGS@
+LFLAGS = @LFLAGS@
+WFLAGS = @WFLAGS@
+OFLAGS = @OFLAGS@
+
+AM_CPPFLAGS = $(DEFS) $(IFLAGS) $(DFLAGS)
+AM_CFLAGS = $(OFLAGS) $(WFLAGS) $(AFLAGS)
+
+flite_LDFLAGS = $(LFLAGS)
+flite_LDADD = $(FLITE_VOICELIBS) $(FLITE_LANGLIBS) $(FLITE_LEXLIBS) $(FLITE_LIBS)
+
+#-----------------------------------------------------------------------
+# Variables: cleanup
+#-----------------------------------------------------------------------
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+#CLEANFILES =
+
+## --- distclean: built by 'configure'
+DISTCLEANFILES = \
+ config.log \
+ config.cache \
+ config.status
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = *~ \
+ $(PODS:.pod=.txt) \
+ Makefile Makefile.in \
+ aclocal.m4 \
+ configure \
+ install-sh \
+ stamp-h.in \
+ config.h.in
+
+maintainer-clean-local:
+ rm -rf autom4te.cache
+
+#CVSCLEAN_SUBDIRS = $(SUBDIRS)
+
+#CVSCLEANFILES = Makefile.in Makefile
+
+
+#-----------------------------------------------------------------------
+# Additional Variables & Rules: PODS
+#-----------------------------------------------------------------------
+PODS = README.pod
+
+.pod.txt:
+ pod2text $< $@
+
+
+#-----------------------------------------------------------------------
+# Variables: distribution
+#-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = $(PODS:.pod=.txt) $(data_DATA) autogen.sh configure \
+ COPYING flite-1.1-noaudio.patch
+
+## --- recursion subdirectories for 'make dist'
+DIST_SUBDIRS = $(SUBDIRS)
+
+## --- dist-hook: when another 'Makefile.am' is overkill
+#DISTHOOK_DIRS = foo
+#DISTHOOK_FILES = foo/bar.txt foo/baz.txt
+#dist-hook:
+# for d in $(DISTHOOK_DIRS); do\
+# mkdir -p $(distdir)/$$d ;\
+# done
+# for f in $(DISTHOOK_FILES); do\
+# cp -p $(srcdir)/$$f $(distdir)/$$f ;\
+# done
+
+#dist-bz2: dist-bzip2 ;
+
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
+
diff --git a/flite/README.cvs b/flite/README.cvs
new file mode 100644
index 0000000..2a0ee0c
--- /dev/null
+++ b/flite/README.cvs
@@ -0,0 +1,13 @@
+To build from cvs, do the following:
+
+ ./autogen.sh
+ ./configure
+ make
+ make install
+
+NOTE: The README.txt file in the distribution
+is auto-generated from perl ".pod" format by
+the "pod2text" included in most perl distributions.
+
+marmosets,
+ Bryan
diff --git a/flite/README.pod b/flite/README.pod
new file mode 100644
index 0000000..12d4dc2
--- /dev/null
+++ b/flite/README.pod
@@ -0,0 +1,89 @@
+=pod
+
+README for PD external distribution 'pd-flite'
+
+Last updated for version 0.01
+
+=head1 DESCRIPTION
+
+The 'pd-flite' distribution contains a single PD external ("flite"),
+which provides a high-level text-to-speech interface for English based on
+the 'libflite' library by Alan W Black and Kevin A. Lenzo.
+
+Currently tested only under linux.
+
+
+=head1 REQUIREMENTS
+
+=over 4
+
+=item * libflite >= v1.1
+
+The 'libflite' library by Alan W Black and Keven A. Lenzo
+is required to build the PD 'flite' external.
+It is available from http://cmuflite.org.
+
+You may want to apply the patch 'libflite-noaudio.patch'
+which comes with this distribution to the 'libflite'
+sources before compiling them (the '--with-audio=none'
+configure flag did not work for me on its own).
+
+=back
+
+
+=head1 INSTALLATION
+
+First, build and install the libflite distribution.
+
+Then, issue the following commands to the shell:
+
+ cd PACKAGENAME-X.YY (or wherever you extracted this distribution)
+ ./configure
+ make
+ make install
+
+
+=head1 BUILD OPTIONS
+
+The 'configure' script supports the following options, among others:
+
+=over 4
+
+=item * --with-flite-dir=DIR
+
+Specify the base directory of the libflite distribution.
+
+=item * --with-pd-dir=DIR
+
+Specify PD base directory.
+
+=item * --enable-debug , --disable-debug
+
+Whether to enable verbose debugging messages.
+Default=no.
+
+=back
+
+See the output of './configure --help' for more options.
+
+
+=head1 ACKNOWLEDGEMENTS
+
+PD by Miller Puckette and others.
+
+Flite run-time speech synthesis library by Alan W Black
+and Kevin A. Lenzo.
+
+Ideas, black magic, and other nuggets of information drawn
+from code by Guenter Geiger, Larry Troxler, and iohannes m zmoelnig.
+
+=head1 KNOWN BUGS
+
+It gobbles memory, and also processor time on synthesis operations.
+
+No support for alternative voices or lexica, and no
+mid- or low-level interface to the libflite functions.
+
+=head1 AUTHOR
+
+Bryan Jurish E<lt>moocow@ling.uni-potsdam.deE<gt>
diff --git a/flite/autogen.sh b/flite/autogen.sh
new file mode 100755
index 0000000..845f276
--- /dev/null
+++ b/flite/autogen.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+#-----------------------------------------------------------------------
+# File: autogen.sh
+# Description:
+# + wrapper for m4 black-magic
+#-----------------------------------------------------------------------
+
+MY_ALDIRS="."
+MY_AHDIRS="."
+MY_AMDIRS="."
+MY_ACDIRS="."
+
+test -z "$ACLOCAL" && ACLOCAL=aclocal
+test -z "$AUTOHEADER" && AUTOHEADER=autoheader
+test -z "$AUTOMAKE" && AUTOMAKE=automake
+test -z "$AUTOCONF" && AUTOCONF=autoconf
+
+if test -n "$MY_ALDIRS"; then
+ for d in $MY_ALDIRS ; do
+ echo "(cd $d ; $ACLOCAL)"
+ (cd $d ; $ACLOCAL)
+ done
+fi
+
+if test -n "$MY_AHDIRS"; then
+ for d in $MY_AHDIRS ; do
+ echo "(cd $d ; $AUTOHEADER)"
+ (cd $d ; $AUTOHEADER)
+ done
+fi
+
+if test -n "$MY_AMDIRS"; then
+ for d in $MY_AMDIRS ; do
+ echo "(cd $d ; $AUTOMAKE -a)"
+ (cd $d ; $AUTOMAKE -a)
+ done
+fi
+
+if test -n "$MY_ACDIRS"; then
+ for d in $MY_ACDIRS ; do
+ echo "(cd $d ; $AUTOCONF)"
+ (cd $d ; $AUTOCONF)
+ done
+fi
+
+#echo "(./configure)"
+#./configure $*
diff --git a/flite/config/Makefile.am b/flite/config/Makefile.am
new file mode 100644
index 0000000..3e097e9
--- /dev/null
+++ b/flite/config/Makefile.am
@@ -0,0 +1,66 @@
+## File: config/Makefile.am
+## Package:
+## Description:
+## + automake file for 'config' package-subdir
+##
+## Process this file with Automake to create Makefile.in.
+##-----------------------------------------------------------------------
+
+##-----------------------------------------------------------------------
+## Variables: options
+##-----------------------------------------------------------------------
+
+##-----------------------------------------------------------------------
+## Variables: cleanup
+##-----------------------------------------------------------------------
+
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+#CLEANFILES =
+
+## --- distclean: built by 'configure'
+#DISTCLEANFILES =
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = \
+ *~ .*~ \
+ compile Makefile Makefile.in \
+ config.guess \
+ config.sub \
+ depcomp \
+ install-sh \
+ ltmain.sh \
+ missing \
+ mkinstalldirs \
+ texinfo.tex \
+ ylwrap
+
+
+##-----------------------------------------------------------------------
+## Variables: distribution
+##-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = \
+ Makefile.in \
+ depcomp \
+ install-sh \
+ mkinstalldirs \
+ missing
+
+# config.guess
+# config.sub
+# ltmain.sh
+# texinfo.tex
+
+## --- recursion subdirectories for 'make dist'
+#DIST_SUBDIRS = $(SUBDIRS)
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
diff --git a/flite/configure.in b/flite/configure.in
new file mode 100644
index 0000000..ded1a2e
--- /dev/null
+++ b/flite/configure.in
@@ -0,0 +1,242 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl -- adapted from 'configure.in' in ggee distribution by Guenter Geiger
+AC_PREREQ(2.5)
+AC_INIT(pd-flite, [0.01], [moocow@ling.uni-potsdam.de])
+
+dnl
+dnl source & aux
+dnl
+AC_CONFIG_AUX_DIR(config)
+
+dnl
+dnl use automake
+dnl
+AM_INIT_AUTOMAKE(pd-flite, [0.01])
+
+dnl
+dnl use autoheader
+dnl
+AM_CONFIG_HEADER(config.h)
+
+dnl
+dnl default prefix (== pd-dir)
+dnl
+AC_PREFIX_DEFAULT(/usr/local/lib/pd)
+
+dnl
+dnl Save user flags
+dnl
+UCFLAGS="$CFLAGS"
+ULDFLAGS="$LDFLAGS"
+ULIBS="$LIBS"
+
+dnl
+dnl Programs
+dnl
+AC_PROG_CC
+AC_PROG_INSTALL
+
+dnl
+dnl Substitutions
+dnl
+AC_SUBST(AFLAGS)
+AC_SUBST(DFLAGS)
+AC_SUBST(IFLAGS)
+AC_SUBST(LFLAGS)
+AC_SUBST(OFLAGS)
+AC_SUBST(WFLAGS)
+AC_SUBST(LD)
+AC_SUBST(EXT)
+
+dnl version stuff (automatically exported?)
+AC_SUBST(PACKAGE_VERSION)
+AC_SUBST(PACKAGE_NAME)
+AC_SUBST(BUGREPORT)
+
+
+dnl
+dnl pd-directory/ies
+dnl
+AC_ARG_WITH(pd-dir,
+ AC_HELP_STRING([--with-pd-dir=DIR], [PD base directory (default=/usr/local/pd)]),
+ [PD_DIR="$withval"],
+ [PD_DIR="/usr/local/pd"])
+AC_SUBST(PD_DIR)
+
+AC_ARG_WITH(pd-include,
+ AC_HELP_STRING([--with-pd-include=DIR], [PD include directory (default=${PD_DIR}/src)]),
+ [PD_INC="$withval"],
+ [PD_INC="${PD_DIR}/src"])
+IFLAGS="$IFLAGS -I${PD_INC}"
+AC_SUBST(PD_INC)
+
+AC_ARG_WITH(pd-externs,
+ AC_HELP_STRING([--with-pd-externs=DIR], [PD externals directory (default=${PD_DIR}/externs)]),
+ [PD_EXTDIR="$withval"],
+ [PD_EXTDIR="${PD_DIR}/externs"])
+AC_SUBST(PD_EXTDIR)
+
+
+AC_ARG_WITH(pd-doc,
+ AC_HELP_STRING([--with-pd-doc=DIR],
+ [PD documentation directory (default=${PD_DIR}/doc/5.reference)]),
+ [PD_DOCDIR="$withval"],
+ [PD_DOCDIR="${PD_DIR}/doc/5.reference"])
+AC_SUBST(PD_DOCDIR)
+
+
+dnl
+dnl flite-directory
+dnl
+AC_ARG_WITH(flite-dir,
+ AC_HELP_STRING([--with-flite-dir=DIR], [Flite base directory (default=/usr/local/lib/flite-1.1-release)]),
+ [FLITE_DIR="$withval"],
+ [FLITE_DIR="/usr/local/lib/flite-1.1-release"])
+AC_SUBST(FLITE_DIR)
+IFLAGS="$IFLAGS -I${FLITE_DIR}/include"
+LFLAGS="$LFLAGS -L${FLITE_DIR}/lib"
+
+dnl
+dnl Check for flite : headers
+dnl
+UCPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$UCPPFLAGS $IFLAGS"
+for h in flite.h ; do
+ AC_CHECK_HEADER($h,[pdflite_have_header="yes"],[pdflite_have_header="no"],[ ])
+ if test "$pdflite_have_header" = "no" ; then
+ AC_MSG_ERROR([required header 'flite.h' not found -- quitting],1)
+ fi
+done
+CPPFLAGS="$UCPPFLAGS"
+
+dnl
+dnl Check for flite : libs : flite
+dnl
+LDFLAGS="$ULDFLAGS $LFLAGS"
+LIBS="$LIBS -lm"
+AC_CHECK_LIB(flite,[flite_init],[],
+ [AC_MSG_ERROR([required library 'libflite.a' not found -- quitting],1)],
+ [-lm])
+LDFLAGS="$ULDFLAGS"
+FLITE_LIBS="-lflite -lm"
+AC_SUBST(FLITE_LIBS)
+
+dnl
+dnl Check for flite : libs : flite_cmulex
+dnl
+LDFLAGS="$ULDFLAGS $LFLAGS"
+AC_CHECK_LIB(flite_cmulex,[cmu_lex_init],[],
+ [AC_MSG_ERROR([required library 'libflite_cmulex.a' not found -- quitting],1)],
+ [-lflite -lm])
+FLITE_LEXLIBS="-lflite_cmulex"
+AC_SUBST(FLITE_LEXLIBS)
+
+dnl
+dnl Check for flite : libs : flite_usenglish
+dnl
+LDFLAGS="$ULDFLAGS $LFLAGS"
+AC_CHECK_LIB(flite_usenglish,[usenglish_init],[],
+ [AC_MSG_ERROR([required library 'libflite_usenglish.a' not found -- quitting],1)],
+ [-lflite_cmulex -lflite -lm])
+FLITE_LANGLIBS="-lflite_usenglish"
+AC_SUBST(FLITE_LANGLIBS)
+
+dnl Check for flite : libs : flite_cmu_us_kal16
+dnl
+LDFLAGS="$ULDFLAGS $LFLAGS"
+AC_CHECK_LIB(flite_cmu_us_kal16,[register_cmu_us_kal],[],
+ [AC_MSG_ERROR([required library 'libflite_cmu_us_kal16.a' not found -- quitting],1)],
+ [-lflite_usenglish -lflite_cmulex -lflite -lm])
+FLITE_VOICELIBS="-lflite_cmu_us_kal16"
+AC_SUBST(FLITE_VOICELIBS)
+
+AC_DEFINE([PDFLITE_REGISTER_VOICE],[register_cmu_us_kal],
+ [This is the function we will call to register the synth voice])
+
+
+
+dnl
+dnl debug version?
+dnl
+AC_MSG_CHECKING([whether we are building a debug version])
+AC_ARG_ENABLE([debug],
+ AC_HELP_STRING([--enable-debug],[build debug version (default=no)]))
+
+if test "$enable_debug" == "yes" ; then
+ AC_MSG_RESULT(yes)
+ DEBUG="yes"
+ DFLAGS="$DFLAGS -DPDFLITE_DEBUG"
+else
+ AC_MSG_RESULT(no)
+ DEBUG="no"
+fi
+AC_SUBST(DEBUG)
+
+dnl
+dnl compiler warnings
+dnl
+WFLAGS="-Wall"
+
+
+dnl
+dnl machine-dependent variables
+dnl
+LD=ld
+if test `uname -s` = Linux;
+then
+ LFLAGS="$LFLAGS -export_dynamic -shared"
+ if test "$DEBUG" == "no"; then
+ OFLAGS="-O6 -funroll-loops -fomit-frame-pointer"
+ else
+ OFLAGS="-g"
+ fi
+ EXT=pd_linux
+fi
+
+if test `uname -m` = alpha;
+then
+ AFLAGS="-mieee -mcpu=ev56";
+ OFLAGS="$CFLAGS"
+fi
+
+if test `uname -s` = IRIX64;
+then
+ LFLAGS="$LFLAGS -n32 -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \
+ -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \
+ -shared -rdata_shared"
+ OFLAGS="$CFLAGS"
+EXT=pd_irix6
+fi
+
+if test `uname -s` = IRIX32;
+then
+ LFLAGS="$LFLAGS -o32 -DUNIX -DIRIX -O2 -shared -rdata_shared"
+ OFLAGS="$CFLAGS"
+ EXT=pd_irix5
+fi
+
+dnl
+dnl Flags for MacOSX, borrowed from pd-0.35-test16
+dnl
+if test `uname -s` = Darwin;
+then
+ LD=cc
+ LFLAGS="$LFLAGS -bundle -undefined suppress -flat_namespace"
+ EXT=pd_darwin
+ DFLAGS="$DFLAGS -DMACOSX"
+
+ if test "$DEBUG" == "no"; then
+ OFLAGS="-O2"
+ else
+ OFLAGS="-g"
+ fi
+fi
+
+dnl
+dnl Restore user flags
+dnl
+LDFLAGS="$ULDFLAGS"
+CFLAGS="$UCFLAGS"
+LIBS="$ULIBS"
+
+AC_OUTPUT(config/Makefile Makefile)
diff --git a/flite/flite-1.1-noaudio.patch b/flite/flite-1.1-noaudio.patch
new file mode 100644
index 0000000..4c2ef0f
--- /dev/null
+++ b/flite/flite-1.1-noaudio.patch
@@ -0,0 +1,20 @@
+diff -uNr flite-1.1-release/src/audio/native_audio.h flite-1.1-release-noaudio/src/audio/native_audio.h
+--- flite-1.1-release/src/audio/native_audio.h Tue Dec 4 19:05:59 2001
++++ flite-1.1-release-noaudio/src/audio/native_audio.h Sun Nov 3 19:12:44 2002
+@@ -41,6 +41,16 @@
+ #ifndef _NATIVE_AUDIO_H__
+ #define _NATIVE_AUDIO_H__
+
++/* -- begin HACK: turn off all audio -- */
++#undef CST_AUDIO_COMMAND
++#undef CST_AUDIO_SUNOS
++#undef CST_AUDIO_LINUX
++#undef CST_AUDIO_ALSA
++#undef CST_AUDIO_FREEBSD
++#undef CST_AUDIO_WINCE
++#define CST_AUDIO_NONE
++/* -- end HACK -- */
++
+ #ifdef CST_AUDIO_COMMAND
+
+ #define AUDIO_OPEN_NATIVE audio_open_command
diff --git a/flite/flite-help.pd b/flite/flite-help.pd
new file mode 100644
index 0000000..eebdbee
--- /dev/null
+++ b/flite/flite-help.pd
@@ -0,0 +1,54 @@
+#N canvas 156 26 606 524 10;
+#X text 25 4 flite : text-to-speech synthesis with libflite;
+#N canvas 0 0 450 300 graph1 0;
+#X array words1 112963 float 0;
+#X coords 0 1 112962 -1 100 70 1;
+#X restore 265 245 graph;
+#N canvas 0 0 450 300 graph2 0;
+#X array words2 112963 float 0;
+#X coords 0 1 112962 -1 100 70 1;
+#X restore 426 248 graph;
+#X obj 22 298 print flite-synth-done;
+#X obj 23 279 flite words1;
+#X text 51 35 ARRAYNAME - initial array name;
+#X text 328 32 1 - control messages;
+#X text 321 59 1 - bang on completed synthesis;
+#X text 30 22 ARGUMENTS:;
+#X text 312 18 INLETS:;
+#X text 305 45 OUTLETS:;
+#X msg 27 81 set words1;
+#X msg 34 99 set words2;
+#X msg 64 167 synth;
+#X text 104 170 "synth" message synthesizes current text-buffer;
+#X text 157 145 "text" message sets input text-buffer;
+#X text 108 87 "set" message selects the output array;
+#X text 225 211 "list" messages set text and synthesize;
+#X obj 31 444 dac~;
+#X msg 262 358 \; pd dsp 1;
+#X msg 328 358 \; pd dsp 0;
+#X text 10 340 For playback \, you can use 'tabplay~':;
+#X msg 32 363 set words1;
+#X msg 37 383 set words2;
+#X obj 31 417 tabplay~ words1;
+#X msg 146 380 bang;
+#X msg 197 381 stop;
+#X msg 146 358 start;
+#X text 173 485 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X msg 58 145 text test 123;
+#X text 172 419 ACKNOWLEDGEMENTS:;
+#X text 190 434 Flite runtime speech synthesis library by Alan W Black
+and Kevin A. Lenzo.;
+#X msg 61 211 list bang bahda boobop;
+#X connect 4 0 3 0;
+#X connect 11 0 4 0;
+#X connect 12 0 4 0;
+#X connect 13 0 4 0;
+#X connect 22 0 24 0;
+#X connect 23 0 24 0;
+#X connect 24 0 18 0;
+#X connect 24 0 18 1;
+#X connect 25 0 24 0;
+#X connect 26 0 24 0;
+#X connect 27 0 25 0;
+#X connect 29 0 4 0;
+#X connect 32 0 4 0;
diff --git a/flite/flite-numbers.pd b/flite/flite-numbers.pd
new file mode 100644
index 0000000..bcd1970
--- /dev/null
+++ b/flite/flite-numbers.pd
@@ -0,0 +1,48 @@
+#N canvas 47 239 465 419 10;
+#X obj 69 219 random;
+#X floatatom 105 199 10 0 0;
+#X msg 105 176 65535;
+#X obj 105 153 loadbang;
+#X msg 14 13 start;
+#X msg 57 13 stop;
+#X msg 172 19 \; pd dsp 1;
+#X msg 238 19 \; pd dsp 0;
+#X msg 85 245 text \$1;
+#X obj 319 14 table \$0-numtab;
+#X obj 85 324 tabplay~ \$0-numtab;
+#X obj 85 277 flite \$0-numtab;
+#X obj 14 58 s \$0-start;
+#X obj 57 35 s \$0-stop;
+#X obj 39 124 r \$0-start;
+#X obj 39 148 t b b;
+#X msg 39 245 synth;
+#X obj 73 359 dac~;
+#X obj 206 371 s \$0-start;
+#X obj 206 347 spigot;
+#X msg 276 305 1;
+#X msg 243 305 0;
+#X obj 276 281 r \$0-start;
+#X obj 243 261 r \$0-stop;
+#X msg 210 295 0 1;
+#X connect 0 0 8 0;
+#X connect 1 0 0 1;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X connect 4 0 12 0;
+#X connect 5 0 13 0;
+#X connect 8 0 11 0;
+#X connect 10 0 17 0;
+#X connect 10 0 17 1;
+#X connect 10 1 19 0;
+#X connect 11 0 10 0;
+#X connect 14 0 15 0;
+#X connect 15 0 16 0;
+#X connect 15 1 0 0;
+#X connect 16 0 11 0;
+#X connect 19 0 18 0;
+#X connect 20 0 19 1;
+#X connect 21 0 19 1;
+#X connect 22 0 20 0;
+#X connect 23 0 21 0;
+#X connect 23 0 24 0;
+#X connect 24 0 10 0;
diff --git a/flite/flite-test.pd b/flite/flite-test.pd
new file mode 100644
index 0000000..52d34db
--- /dev/null
+++ b/flite/flite-test.pd
@@ -0,0 +1,70 @@
+#N canvas 164 1 726 560 10;
+#X msg 36 43 set ary2;
+#X msg 13 22 set ary1;
+#N canvas 0 0 450 300 graph1 0;
+#X array ary1 42489 float 0;
+#X coords 0 1 42488 -1 200 140 1;
+#X restore 41 223 graph;
+#N canvas 0 0 450 300 graph2 0;
+#X array ary2 10 float 0;
+#X coords 0 1 9 -1 200 140 1;
+#X restore 277 221 graph;
+#X obj 122 164 flite ary1;
+#X msg 121 16 text moo the cow;
+#X msg 133 38 text 42 marmosets;
+#X msg 149 83 synth;
+#X obj 390 418 hsl 128 15 0 127 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 11000 1;
+#X obj 388 442 dbtorms;
+#X obj 356 497 dac~;
+#X obj 365 472 *~ 0;
+#X msg 208 406 bang;
+#X msg 264 405 0 1;
+#X msg 264 384 stop;
+#X msg 208 384 start;
+#X obj 12 79 s aryset;
+#X obj 249 438 tabplay~ ary1;
+#X obj 302 405 r aryset;
+#X msg 46 390 set ary1;
+#X msg 111 389 set ary2;
+#X msg 472 452 \; pd dsp 1;
+#X msg 473 486 \; pd dsp 0;
+#X msg 145 61 text text;
+#X obj 108 471 spigot;
+#X obj 145 449 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X text 87 450 Loop;
+#X msg 285 15 list moo the cow;
+#X msg 287 40 list 42 marmosets;
+#X msg 289 66 list list;
+#X msg 291 91 list bang;
+#X obj 122 187 print flite-synth-done;
+#X connect 0 0 4 0;
+#X connect 0 0 16 0;
+#X connect 1 0 4 0;
+#X connect 1 0 16 0;
+#X connect 4 0 31 0;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 4 0;
+#X connect 8 0 9 0;
+#X connect 9 0 11 1;
+#X connect 11 0 10 0;
+#X connect 11 0 10 1;
+#X connect 12 0 17 0;
+#X connect 13 0 17 0;
+#X connect 13 0 25 0;
+#X connect 14 0 13 0;
+#X connect 15 0 12 0;
+#X connect 17 0 11 0;
+#X connect 17 1 24 0;
+#X connect 18 0 17 0;
+#X connect 19 0 17 0;
+#X connect 20 0 17 0;
+#X connect 23 0 4 0;
+#X connect 24 0 17 0;
+#X connect 25 0 24 1;
+#X connect 27 0 4 0;
+#X connect 28 0 4 0;
+#X connect 29 0 4 0;
+#X connect 30 0 4 0;
diff --git a/flite/flite-test2.pd b/flite/flite-test2.pd
new file mode 100644
index 0000000..20777d6
--- /dev/null
+++ b/flite/flite-test2.pd
@@ -0,0 +1,34 @@
+#N canvas 489 199 450 300 10;
+#X obj 72 150 flite testary;
+#X obj 312 53 table testary;
+#X msg 54 13 moo;
+#X msg 91 14 is;
+#X msg 127 13 a;
+#X msg 175 13 cow;
+#X msg 175 62 marmoset;
+#X msg 176 38 bovine;
+#X obj 72 174 tabplay~ testary;
+#X obj 181 199 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 110 222 hsl 128 15 0 127 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 8100 1;
+#X obj 107 245 dbtorms;
+#X obj 63 247 dac~;
+#X obj 72 222 *~ 0;
+#X msg 72 109 text \$1 \, synth;
+#X obj 72 87 pack s;
+#X connect 0 0 8 0;
+#X connect 2 0 15 0;
+#X connect 3 0 15 0;
+#X connect 4 0 15 0;
+#X connect 5 0 15 0;
+#X connect 6 0 15 0;
+#X connect 7 0 15 0;
+#X connect 8 0 13 0;
+#X connect 8 1 9 0;
+#X connect 10 0 11 0;
+#X connect 11 0 13 1;
+#X connect 13 0 12 0;
+#X connect 13 0 12 1;
+#X connect 14 0 0 0;
+#X connect 15 0 14 0;
diff --git a/flite/flite.c b/flite/flite.c
new file mode 100644
index 0000000..9493a38
--- /dev/null
+++ b/flite/flite.c
@@ -0,0 +1,264 @@
+/* -*- Mode: C -*- */
+/*=============================================================================*\
+ * File: flite.c
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: speech synthesis for PD
+ *
+ * PD interface to 'flite' C libraries.
+ *
+ *=============================================================================*/
+
+
+#include <m_pd.h>
+
+/* black magic */
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <math.h>
+#include <flite.h>
+#include <cst_wave.h>
+
+/*--------------------------------------------------------------------
+ * DEBUG
+ *--------------------------------------------------------------------*/
+//#define FLITE_DEBUG 1
+//#undef FLITE_DEBUG
+
+
+/*--------------------------------------------------------------------
+ * Globals
+ *--------------------------------------------------------------------*/
+extern cst_voice *PDFLITE_REGISTER_VOICE();
+static cst_voice *voice;
+
+#define DEFAULT_BUFSIZE 256
+#define DEFAULT_BUFSTEP 256
+
+/*=====================================================================
+ * Structures and Types
+ *=====================================================================*/
+
+static char *flite_description =
+ "flite: Text-to-Speech external v%s by Bryan Jurish";
+//static char *flite_acknowledge = "flite: based on code by ";
+//static char *flite_version = "flite: PD external v%s by Bryan Jurish";
+
+
+
+/*---------------------------------------------------------------------
+ * flite
+ *---------------------------------------------------------------------*/
+static t_class *flite_class;
+typedef struct _flite
+{
+ t_object x_obj; /* black magic (probably inheritance-related) */
+ t_symbol *x_arrayname; /* arrayname (from '_tabwrite' code in $PD_SRC/d_array.c) */
+ char *textbuf; /* text buffer (hack) */
+ int bufsize; /* text buffer size */
+} t_flite;
+
+
+/*--------------------------------------------------------------------
+ * flite_synth : synthesize current text-buffer
+ *--------------------------------------------------------------------*/
+void flite_synth(t_flite *x) {
+ cst_wave *wave;
+ int i,vecsize;
+ t_garray *a;
+ t_float *vec;
+
+# ifdef FLITE_DEBUG
+ post("flite: got message 'synth'");
+# endif
+
+ // -- sanity checks
+ if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+ error("flite: no such array '%s'", x->x_arrayname->s_name);
+ if (!x->textbuf) {
+ error("flite: attempt to synthesize empty text-buffer!");
+ return;
+ }
+
+# ifdef FLITE_DEBUG
+ post("flite: flite_text_to_wave()");
+# endif
+ wave = flite_text_to_wave(x->textbuf,voice);
+
+ if (!wave) {
+ error("flite: synthesis failed for text '%s'", x->textbuf);
+ return;
+ }
+
+ // -- resample
+# ifdef FLITE_DEBUG
+ post("flite: cst_wave_resample()");
+# endif
+ cst_wave_resample(wave,sys_getsr());
+
+ // -- resize & write to our array
+# ifdef FLITE_DEBUG
+ post("flite: garray_resize(%d)", wave->num_samples);
+# endif
+
+ garray_resize(a, wave->num_samples);
+ if (!garray_getfloatarray(a, &vecsize, &vec))
+ error("flite: bad template for write to array '%s'", x->x_arrayname->s_name);
+
+# ifdef FLITE_DEBUG
+ post("flite: ->write to garray loop<-");
+# endif
+ for (i = 0; i < wave->num_samples; i++) {
+ *vec++ = wave->samples[i]/32767.0;
+ }
+
+ // -- outlet synth-done-bang
+ outlet_bang(x->x_obj.ob_outlet);
+
+ // -- cleanup
+ delete_wave(wave);
+
+ // -- redraw
+ garray_redraw(a);
+}
+
+/*--------------------------------------------------------------------
+ * flite_text : set text-buffer
+ *--------------------------------------------------------------------*/
+void flite_text(t_flite *x, t_symbol *s, int argc, t_atom *argv) {
+ int i, alen, buffered;
+ t_symbol *asym;
+
+ // -- allocate initial text-buffer if required
+ if (x->textbuf == NULL) {
+ x->bufsize = DEFAULT_BUFSIZE;
+ x->textbuf = getbytes(x->bufsize);
+ }
+ if (x->textbuf == NULL) {
+ error("flite: allocation failed for text buffer");
+ x->bufsize = 0;
+ return;
+ }
+
+ // -- convert args to strings
+ buffered = 0;
+ for (i = 0; i < argc; i++) {
+ asym = atom_gensym(argv);
+ alen = 1+strlen(asym->s_name);
+
+ // -- reallocate if necessary
+ while (buffered + alen > x->bufsize) {
+ x->textbuf = resizebytes(x->textbuf,x->bufsize,x->bufsize+DEFAULT_BUFSTEP);
+ x->bufsize = x->bufsize+DEFAULT_BUFSTEP;
+ if (x->textbuf == NULL) {
+ error("flite: allocation failed for text buffer");
+ x->bufsize = 0;
+ return;
+ }
+ }
+
+ // -- append arg-string to text-buf
+ if (i == 0) {
+ strcpy(x->textbuf+buffered, asym->s_name);
+ buffered += alen-1;
+ } else {
+ *(x->textbuf+buffered) = ' ';
+ strcpy(x->textbuf+buffered+1, asym->s_name);
+ buffered += alen;
+ }
+
+ // -- increment/decrement
+ argv++;
+ }
+
+#ifdef FLITE_DEBUG
+ post("flite_debug: got text='%s'", x->textbuf);
+#endif
+}
+
+
+/*--------------------------------------------------------------------
+ * flite_list : parse & synthesize text in one swell foop
+ *--------------------------------------------------------------------*/
+void flite_list(t_flite *x, t_symbol *s, int argc, t_atom *argv) {
+ flite_text(x,s,argc,argv);
+ flite_synth(x);
+}
+
+
+/*--------------------------------------------------------------------
+ * flite_set : set arrayname
+ *--------------------------------------------------------------------*/
+static void flite_set(t_flite *x, t_symbol *ary) {
+#ifdef FLITE_DEBUG
+ post("flite_set: called with arg='%s'", ary->s_name);
+#endif
+ x->x_arrayname = ary;
+}
+
+
+/*--------------------------------------------------------------------
+ * constructor / destructor
+ *--------------------------------------------------------------------*/
+static void *flite_new(t_symbol *ary)
+{
+ t_flite *x;
+
+ x = (t_flite *)pd_new(flite_class);
+
+ // set initial arrayname
+ x->x_arrayname = ary;
+
+ // init textbuf
+ x->textbuf = NULL;
+ x->bufsize = 0;
+
+ // create bang-on-done outlet
+ outlet_new(&x->x_obj, &s_bang);
+
+ return (void *)x;
+}
+
+static void flite_free(t_flite *x) {
+ if (x->bufsize && x->textbuf != NULL) {
+ freebytes(x->textbuf, x->bufsize);
+ x->bufsize = 0;
+ }
+}
+
+/*--------------------------------------------------------------------
+ * setup
+ *--------------------------------------------------------------------*/
+void flite_setup(void) {
+ post("");
+ post(flite_description, PACKAGE_VERSION);
+ post("");
+
+ // --- setup synth
+ flite_init();
+ voice = PDFLITE_REGISTER_VOICE();
+
+ // --- register class
+ flite_class = class_new(gensym("flite"),
+ (t_newmethod)flite_new, // newmethod
+ (t_method)flite_free, // freemethod
+ sizeof(t_flite), // size
+ CLASS_DEFAULT, // flags
+ A_DEFSYM, // arg1: table-name
+ 0);
+
+ // --- class methods
+ class_addlist(flite_class, flite_list);
+ class_addmethod(flite_class, (t_method)flite_set, gensym("set"), A_DEFSYM, 0);
+ class_addmethod(flite_class, (t_method)flite_text, gensym("text"), A_GIMME, 0);
+ class_addmethod(flite_class, (t_method)flite_synth, gensym("synth"), 0);
+
+ // --- help patch
+ class_sethelpsymbol(flite_class, gensym("flite-help.pd"));
+}
diff --git a/gfsm/COPYING b/gfsm/COPYING
new file mode 100644
index 0000000..fa0bef4
--- /dev/null
+++ b/gfsm/COPYING
@@ -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/gfsm/Changes b/gfsm/Changes
new file mode 100644
index 0000000..082742a
--- /dev/null
+++ b/gfsm/Changes
@@ -0,0 +1,9 @@
+Change log for PD external 'pd-gfsm'
+
+v0.02 Tue, 21 Sep 2004 01:30:45 +0200
+ + added 'arc_seek' message to gfsm_state
+ + added 'add_weight' message to gfsm_state
+ + began work on 'gfsm_markov.pd'
+
+v0.01 Mon, 13 Sep 2004 11:11:43 +0200
+ + initial version
diff --git a/gfsm/Makefile.am b/gfsm/Makefile.am
new file mode 100644
index 0000000..4983beb
--- /dev/null
+++ b/gfsm/Makefile.am
@@ -0,0 +1,98 @@
+# File: ./Makefile.am
+# Package: pd-gfsm
+# Description:
+# + top-level automake file
+#
+# Process this file with Automake to create Makefile.in.
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Options & Subdirectories
+#-----------------------------------------------------------------------
+
+## --- automake options
+#AUTOMAKE_OPTIONS = foreign dist-bzip2 dist-zip
+AUTOMAKE_OPTIONS = foreign
+
+## --- recursion subdirectories
+SUBDIRS = config src
+
+## --- pseudo-deps for '.SUFFIXES'
+SUFFIXES = .pod .txt
+
+#-----------------------------------------------------------------------
+# Variables: cleanup
+#-----------------------------------------------------------------------
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+#CLEANFILES =
+
+## --- distclean: built by 'configure'
+DISTCLEANFILES = \
+ config.log \
+ config.cache \
+ config.status
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = *~ \
+ $(PODS:.pod=.txt) \
+ Makefile Makefile.in \
+ aclocal.m4 \
+ configure \
+ install-sh \
+ stamp-h.in \
+ config.h.in
+
+maintainer-clean-local:
+ rm -rf autom4te.cache
+
+#CVSCLEAN_SUBDIRS = $(SUBDIRS)
+
+#CVSCLEANFILES = Makefile.in Makefile
+
+
+#-----------------------------------------------------------------------
+# Additional Variables & Rules: PODS
+#-----------------------------------------------------------------------
+PODS = README.pod
+
+.pod.txt:
+ pod2text $< $@
+
+all-local: $(PODS:.pod=.txt)
+
+#-----------------------------------------------------------------------
+# Variables: distribution
+#-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = \
+ $(PODS:.pod=.txt) autogen.sh configure \
+ README.cvs COPYING
+
+## --- recursion subdirectories for 'make dist'
+#DIST_SUBDIRS = $(SUBDIRS)
+
+## --- dist-hook: when another 'Makefile.am' is overkill
+#DISTHOOK_DIRS = foo
+#DISTHOOK_FILES = foo/bar.txt foo/baz.txt
+#dist-hook:
+# for d in $(DISTHOOK_DIRS); do\
+# mkdir -p $(distdir)/$$d ;\
+# done
+# for f in $(DISTHOOK_FILES); do\
+# cp -p $(srcdir)/$$f $(distdir)/$$f ;\
+# done
+
+#dist-bz2: dist-bzip2 ;
+
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
+
diff --git a/gfsm/README.cvs b/gfsm/README.cvs
new file mode 100644
index 0000000..2a0ee0c
--- /dev/null
+++ b/gfsm/README.cvs
@@ -0,0 +1,13 @@
+To build from cvs, do the following:
+
+ ./autogen.sh
+ ./configure
+ make
+ make install
+
+NOTE: The README.txt file in the distribution
+is auto-generated from perl ".pod" format by
+the "pod2text" included in most perl distributions.
+
+marmosets,
+ Bryan
diff --git a/gfsm/README.pod b/gfsm/README.pod
new file mode 100644
index 0000000..1155c8c
--- /dev/null
+++ b/gfsm/README.pod
@@ -0,0 +1,60 @@
+=pod
+
+README for pd external package 'gfsm'
+
+Last updated for pd-gfsm v0.04
+
+=head1 DESCRIPTION
+
+pd-gfsm provides Pd bindings for the GFSM finite-state machine library.
+
+=head1 PREREQUISITES
+
+=over 4
+
+=item Pd
+
+Available from http://crca.ucsd.edu/~msp/software.html
+
+=item libgfsm >= v0.0.8-pre6
+
+Available from http://www.ling.uni-potsdam.de/~moocow/projects/gfsm
+
+=back
+
+=head1 INSTALLATION
+
+Issue the following commands to the shell:
+
+ cd DISTNAME-X.YY (or wherever you extracted the distribution)
+ ./configure
+ make
+ make install
+
+=head1 BUILD OPTIONS
+
+The 'configure' script supports the following options, among others:
+
+=over 4
+
+=item * --enable-debug , --disable-debug
+
+Whether to enable verbose debugging messages.
+Default=no.
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+PD by Miller Puckette and others.
+
+Ideas, black magic, and other nuggets of information drawn
+from code by Guenter Geiger, Larry Troxler, and iohannes m zmoelnig.
+
+=head1 KNOWN BUGS
+
+None known.
+
+=head1 AUTHOR
+
+Bryan Jurish E<lt>moocow@ling.uni-potsdam.deE<gt>
diff --git a/gfsm/autogen.sh b/gfsm/autogen.sh
new file mode 100755
index 0000000..845f276
--- /dev/null
+++ b/gfsm/autogen.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+#-----------------------------------------------------------------------
+# File: autogen.sh
+# Description:
+# + wrapper for m4 black-magic
+#-----------------------------------------------------------------------
+
+MY_ALDIRS="."
+MY_AHDIRS="."
+MY_AMDIRS="."
+MY_ACDIRS="."
+
+test -z "$ACLOCAL" && ACLOCAL=aclocal
+test -z "$AUTOHEADER" && AUTOHEADER=autoheader
+test -z "$AUTOMAKE" && AUTOMAKE=automake
+test -z "$AUTOCONF" && AUTOCONF=autoconf
+
+if test -n "$MY_ALDIRS"; then
+ for d in $MY_ALDIRS ; do
+ echo "(cd $d ; $ACLOCAL)"
+ (cd $d ; $ACLOCAL)
+ done
+fi
+
+if test -n "$MY_AHDIRS"; then
+ for d in $MY_AHDIRS ; do
+ echo "(cd $d ; $AUTOHEADER)"
+ (cd $d ; $AUTOHEADER)
+ done
+fi
+
+if test -n "$MY_AMDIRS"; then
+ for d in $MY_AMDIRS ; do
+ echo "(cd $d ; $AUTOMAKE -a)"
+ (cd $d ; $AUTOMAKE -a)
+ done
+fi
+
+if test -n "$MY_ACDIRS"; then
+ for d in $MY_ACDIRS ; do
+ echo "(cd $d ; $AUTOCONF)"
+ (cd $d ; $AUTOCONF)
+ done
+fi
+
+#echo "(./configure)"
+#./configure $*
diff --git a/gfsm/config/Makefile.am b/gfsm/config/Makefile.am
new file mode 100644
index 0000000..45bdb79
--- /dev/null
+++ b/gfsm/config/Makefile.am
@@ -0,0 +1,66 @@
+## File: config/Makefile.am
+## Package: ?
+## Description:
+## + automake file for 'config' package-subdir
+##
+## Process this file with Automake to create Makefile.in.
+##-----------------------------------------------------------------------
+
+##-----------------------------------------------------------------------
+## Variables: options
+##-----------------------------------------------------------------------
+
+##-----------------------------------------------------------------------
+## Variables: cleanup
+##-----------------------------------------------------------------------
+
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+#CLEANFILES =
+
+## --- distclean: built by 'configure'
+#DISTCLEANFILES =
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = \
+ *~ .*~ \
+ compile Makefile Makefile.in \
+ config.guess \
+ config.sub \
+ depcomp \
+ install-sh \
+ ltmain.sh \
+ missing \
+ mkinstalldirs \
+ texinfo.tex \
+ ylwrap
+
+
+##-----------------------------------------------------------------------
+## Variables: distribution
+##-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = \
+ Makefile.in \
+ depcomp \
+ install-sh \
+ mkinstalldirs \
+ missing
+
+# config.guess
+# config.sub
+# ltmain.sh
+# texinfo.tex
+
+## --- recursion subdirectories for 'make dist'
+#DIST_SUBDIRS = $(SUBDIRS)
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
diff --git a/gfsm/configure.in b/gfsm/configure.in
new file mode 100644
index 0000000..ea900a0
--- /dev/null
+++ b/gfsm/configure.in
@@ -0,0 +1,233 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl -- adapted from 'configure.in' in ggee distribution by Guenter Geiger
+AC_PREREQ(2.5)
+
+dnl Some handy macros
+define([THE_PACKAGE_NAME], [pd-gfsm])
+define([THE_PACKAGE_VERSION], [0.04])
+define([THE_PACKAGE_AUTHOR], [moocow@ling.uni-potsdam.de])
+
+AC_INIT(THE_PACKAGE_NAME, THE_PACKAGE_VERSION, THE_PACKAGE_AUTHOR)
+
+dnl
+dnl source & aux
+dnl
+AC_CONFIG_AUX_DIR(config)
+
+dnl
+dnl save user's CFLAGS,CPPFLAGS
+dnl
+UCPPFLAGS="$CPPFLAGS"
+UCFLAGS="$CFLAGS"
+#UCXXFLAGS="$CXXFLAGS"
+
+dnl
+dnl use automake
+dnl
+AM_INIT_AUTOMAKE(THE_PACKAGE_NAME, THE_PACKAGE_VERSION)
+
+dnl
+dnl use autoheader
+dnl
+AM_CONFIG_HEADER([src/config.h])
+
+dnl
+dnl Programs, prefix
+dnl
+AC_PROG_CC
+dnl AC_PROG_CXX
+AC_PROG_INSTALL
+AC_PREFIX_DEFAULT(/usr/local)
+
+dnl
+dnl Substitutions
+dnl
+AC_SUBST(DEFS)
+AC_SUBST(AFLAGS)
+AC_SUBST(DFLAGS)
+AC_SUBST(IFLAGS)
+AC_SUBST(LFLAGS)
+AC_SUBST(OFLAGS)
+AC_SUBST(WFLAGS)
+AC_SUBST(LD)
+AC_SUBST(PDEXT)
+
+dnl version stuff (automatically exported?)
+AC_SUBST(PACKAGE_VERSION)
+AC_SUBST(PACKAGE_NAME)
+AC_SUBST(BUGREPORT)
+
+
+dnl
+dnl pd-directory/ies
+dnl
+AC_ARG_WITH(pd-dir,
+ AC_HELP_STRING([--with-pd-dir=DIR], [PD base directory (default=/usr/local/pd)]),
+ [pddir="$withval"],
+ [pddir="/usr/local/pd"])
+pddocdir="${pddir}/doc/5.reference"
+AC_SUBST(pddir)
+AC_SUBST(pddocdir)
+
+AC_ARG_WITH(pd-include,
+ AC_HELP_STRING([--with-pd-include=DIR], [PD include directory (default=${PD_DIR}/src)]),
+ [pdincludedir="$withval"],
+ [pdincludedir="${PD_DIR}/src"])
+AC_SUBST(pdincludedir)
+
+AC_ARG_WITH(pd-extdir,
+ AC_HELP_STRING([--with-pd-extdir=DIR], [Directory for PD externals (default=PDDIR/externs)]),
+ [pdexternsdir="$withval"],
+ [pdexternsdir="$pddir/externs"])
+AC_SUBST(pdexternsdir)
+
+dnl
+dnl Check for m_pd.h
+dnl
+CPPFLAGS="$CPPFLAGS $IFLAGS"
+AC_CHECK_HEADER(m_pd.h,[],
+ AC_MSG_WARN([-----------------------------------------------------------------])
+ AC_MSG_WARN([could not find PD header file 'm_pd.h' -- things might get ugly.])
+ AC_MSG_WARN([-----------------------------------------------------------------]),
+ [/* nonempty includes: compile only */])
+
+dnl
+dnl debug version?
+dnl
+AC_MSG_CHECKING([whether we are building a debug version])
+AC_ARG_ENABLE([debug],
+ AC_HELP_STRING([--enable-debug],[build debug version (default=no)]))
+
+if test "$enable_debug" == "yes" ; then
+ AC_MSG_RESULT(yes)
+ DEBUG="yes"
+ DFLAGS="$DFLAGS -DDEBUG"
+else
+ AC_MSG_RESULT(no)
+ DEBUG="no"
+fi
+AC_SUBST(DEBUG)
+
+dnl ---------------------------------------------------------------
+dnl pkg-config : program
+dnl
+AC_ARG_VAR(PKG_CONFIG, [How to run the pkg-config program])
+AC_ARG_VAR(PKG_CONFIG_PATH, [Directories to search for pkg-config])
+if test -z "$PKG_CONFIG" ; then
+ AC_PATH_PROG(PKG_CONFIG,pkg-config,[])
+fi
+dnl pkg-config: destination directory
+AC_ARG_WITH(pkgconfig-dir,
+ AC_HELP_STRING([--with-pkgconfig-dir=DIR],
+ [install pkg-config metafile(s) in DIR (default=LIBDIR/pkgconfig)]),
+ [ac_cv_pkgconfigdir="$withval"])
+if test -z "$ac_cv_pkgconfigdir" ; then
+ ac_cv_pkgconfigdir="\$(libdir)/pkgconfig"
+fi
+pkgconfigdir="$ac_cv_pkgconfigdir"
+AC_SUBST(pkgconfigdir)
+dnl
+dnl pkg-config
+dnl ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+##vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+## gfsm (pkg-config)
+PKG_CHECK_MODULES(GFSM, gfsm >= 0.0.8,
+ [PC_HAVE_GFSM="yes"],
+ [PC_HAVE_GFSM=""])
+
+if test "$PC_HAVE_GFSM" != "yes" ; then
+ AC_MSG_WARN([])
+ AC_MSG_WARN([----------------------------------------------------------------])
+ AC_MSG_WARN([ gfsm library not found!])
+ AC_MSG_WARN([])
+ AC_MSG_WARN([ Is the directory containing gfsm.pc in your])
+ AC_MSG_WARN([ 'PKG_CONFIG_PATH' environment variable?])
+ AC_MSG_WARN([----------------------------------------------------------------])
+ AC_MSG_WARN([])
+ ac_cv_enable_gfsm="no"
+else
+ ac_cv_enable_gfsm="yes"
+fi
+
+if test "$ac_cv_enable_gfsm" != "no" ; then
+ ##-- gfsm: library
+ IFLAGS="$IFLAGS `$PKG_CONFIG --cflags-only-I gfsm`"
+ LFLAGS="$LFLAGS `$PKG_CONFIG --libs-only-L gfsm`"
+ LIBS="$LIBS `$PKG_CONFIG --libs-only-l gfsm`"
+fi
+## /gfsm
+##^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+dnl --------------------------------------------------------------------
+dnl BEGIN import from pd configure.in
+dnl --------------------------------------------------------------------
+dnl
+dnl machine-dependent variables
+dnl
+LD=ld
+if test `uname -s` = Linux;
+then
+ LFLAGS="-export_dynamic -shared"
+ if test "$DEBUG" == "no"; then
+ #OFLAGS="-O6 -funroll-loops -fomit-frame-pointer -finline-limit-10000000"
+ #OFLAGS="-O6 -funroll-loops -fomit-frame-pointer"
+ OFLAGS="-O3"
+ else
+ OFLAGS="-g"
+ fi
+ PDEXT=pd_linux
+fi
+
+if test `uname -m` = alpha;
+then
+ AFLAGS="-mieee -mcpu=ev56";
+ OFLAGS="$CFLAGS"
+fi
+
+if test `uname -s` = IRIX64;
+then
+ LFLAGS="-n32 -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \
+ -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \
+ -shared -rdata_shared"
+ OFLAGS="$CFLAGS"
+ PDEXT=pd_irix6
+fi
+
+if test `uname -s` = IRIX32;
+then
+ LFLAGS="-o32 -DUNIX -DIRIX -O2 -shared -rdata_shared"
+ OFLAGS="$CFLAGS"
+ PDEXT=pd_irix5
+fi
+
+dnl
+dnl Flags for MacOSX, borrowed from pd-0.35-test16
+dnl
+if test `uname -s` = Darwin;
+then
+ LD=cc
+ LFLAGS="-bundle -undefined suppress -flat_namespace"
+ PDEXT=pd_darwin
+ DFLAGS="$DFLAGS -DMACOSX"
+
+ if test "$DEBUG" == "no"; then
+ OFLAGS="-O2"
+ else
+ OFLAGS="-g"
+ fi
+fi
+dnl --------------------------------------------------------------------
+dnl END import from pd configure.in
+dnl --------------------------------------------------------------------
+
+dnl
+dnl restore user's CFLAGS
+dnl
+CFLAGS="$UCFLAGS"
+CPPFLAGS="$UCPPFLAGS"
+#CXXFLAGS="$UCXXFLAGS"
+
+AC_OUTPUT(config/Makefile src/Makefile Makefile)
diff --git a/gfsm/src/Makefile.am b/gfsm/src/Makefile.am
new file mode 100644
index 0000000..05d3eda
--- /dev/null
+++ b/gfsm/src/Makefile.am
@@ -0,0 +1,152 @@
+# File: ./src/Makefile.am
+# Package: pd-gfsm
+# Description:
+# + src-level automake file
+#
+# Process this file with Automake to create Makefile.in.
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Options & Subdirectories
+#-----------------------------------------------------------------------
+
+## --- recursion subdirectories
+#SUBDIRS =
+
+## --- pseudo-deps for '.SUFFIXES'
+SUFFIXES = .@PDEXT@
+
+#-----------------------------------------------------------------------
+# Flags and variables
+#-----------------------------------------------------------------------
+PDEXT = @PDEXT@
+EXEEXT = .@PDEXT@
+
+#-----------------------------------------------------------------------
+# pd externals (hacked _PROGRAMS target)
+#-----------------------------------------------------------------------
+
+## --- externals
+pdexterns_PROGRAMS = gfsm
+
+## --- patches
+pdexterns_DATA = \
+ gfsm_markov.pd
+
+## --- documentation
+pddoc_DATA = \
+ gfsm-help.pd \
+ gfsm_alphabet-help.pd \
+ gfsm_automaton-help.pd \
+ gfsm_state-help.pd \
+ gfsm_markov-help.pd
+
+#-----------------------------------------------------------------------
+# sources
+#-----------------------------------------------------------------------
+
+gfsm_SOURCES = \
+ config.h \
+ atom_alphabet.h atom_alphabet.c \
+ pd_alphabet.h pd_alphabet.c \
+ \
+ pd_automaton.h pd_automaton.c \
+ pd_algebra.c \
+ \
+ pd_state.h pd_state.c \
+ \
+ pd_io.h pd_io.c \
+ \
+ pd_gfsm.h pd_gfsm.c
+
+
+#----------------------------------------------------------------------
+# external compilation : flags
+#-----------------------------------------------------------------------
+DEFS = @DEFS@
+AFLAGS = @AFLAGS@
+DFLAGS = @DFLAGS@
+IFLAGS = @IFLAGS@
+LFLAGS = @LFLAGS@
+OFLAGS = @OFLAGS@
+WFLAGS = -Wall
+
+AM_CPPFLAGS = $(IFLAGS) $(DFLAGS)
+AM_CFLAGS = $(OFLAGS) $(WFLAGS) $(AFLAGS)
+AM_CXXFLAGS = $(OFLAGS) $(WFLAGS) $(AFLAGS)
+
+gfsm_LDFLAGS = $(LFLAGS)
+#gfsm_LDADD =
+
+#-----------------------------------------------------------------------
+# additional hacks
+#-----------------------------------------------------------------------
+#(none)
+
+#-----------------------------------------------------------------------
+# Variables: cleanup
+#-----------------------------------------------------------------------
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+CLEANFILES = *$(EXEEXT)
+
+## --- distclean: built by 'configure'
+DISTCLEANFILES = \
+ config.log \
+ config.cache \
+ config.status
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = *~ \
+ $(PODS:.pod=.txt) \
+ Makefile Makefile.in \
+ aclocal.m4 \
+ configure \
+ install-sh \
+ stamp-h.in \
+ config.h.in
+
+maintainer-clean-local:
+ rm -rf autom4te.cache
+
+#CVSCLEAN_SUBDIRS = $(SUBDIRS)
+
+#CVSCLEANFILES = Makefile.in Makefile
+
+
+#-----------------------------------------------------------------------
+# Variables: distribution
+#-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = \
+ $(pddoc_DATA) \
+ $(pdexterns_DATA)
+
+
+## --- recursion subdirectories for 'make dist'
+DIST_SUBDIRS = $(SUBDIRS)
+
+## --- dist-hook: when another 'Makefile.am' is overkill
+#DISTHOOK_DIRS = foo
+#DISTHOOK_FILES = foo/bar.txt foo/baz.txt
+#dist-hook:
+# for d in $(DISTHOOK_DIRS); do\
+# mkdir -p $(distdir)/$$d ;\
+# done
+# for f in $(DISTHOOK_FILES); do\
+# cp -p $(srcdir)/$$f $(distdir)/$$f ;\
+# done
+
+#dist-bz2: dist-bzip2 ;
+
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
+
diff --git a/gfsm/src/atom_alphabet.c b/gfsm/src/atom_alphabet.c
new file mode 100644
index 0000000..16f4bdd
--- /dev/null
+++ b/gfsm/src/atom_alphabet.c
@@ -0,0 +1,139 @@
+/*=============================================================================*\
+ * File: atom_alphabet.c
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd: atom alphabet
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+#include <atom_alphabet.h>
+#include <string.h>
+
+/*======================================================================
+ * constants
+ */
+gfsmUserAlphabetMethods pd_atom_alphabet_methods =
+ {
+ NULL, //-- key->label lookup function
+ NULL, //-- label->key lookup function
+ NULL, //-- insertion function: receives a newly copied key!
+ NULL, //-- label removal function
+ (gfsmAlphabetKeyReadFunc)gfsm_pd_atom_read, //-- key input function
+ (gfsmAlphabetKeyWriteFunc)gfsm_pd_atom_write //-- key output function
+ };
+
+/*======================================================================
+ * gfsmPdAtomAlphabet: user methods
+ */
+
+
+/*--------------------------------------------------------------
+ * hash()
+ */
+guint gfsm_pd_atom_hash(t_atom *a)
+{
+ if (!a) return 0;
+ switch (a->a_type) {
+ case A_FLOAT: return (guint)(a->a_w.w_float);
+ case A_SYMBOL: return (guint)(a->a_w.w_symbol);
+ case A_SEMI: return (guint)';';
+ case A_COMMA: return (guint)',';
+ default: return 0;
+ }
+ return 0; //-- never reached
+}
+
+/*--------------------------------------------------------------
+ * equal()
+ */
+gboolean gfsm_pd_atom_equal(t_atom *a1, t_atom *a2)
+{
+ if (a1->a_type != a2->a_type) return FALSE;
+ switch (a1->a_type) {
+ case A_FLOAT: return a1->a_w.w_float == a2->a_w.w_float;
+ case A_SYMBOL: return a1->a_w.w_symbol == a2->a_w.w_symbol;
+ default: return memcmp(a1,a2,sizeof(t_atom))==0;
+ }
+}
+
+/*--------------------------------------------------------------
+ * dup()
+ */
+t_atom *gfsm_pd_atom_dup(gfsmPdAtomAlphabet *alph, t_atom *a)
+{
+ //return (a ? copybytes(a, sizeof(t_atom)) : NULL);
+ return (a ? gfsm_mem_dup_n(a,sizeof(t_atom)) : NULL);
+}
+
+/*--------------------------------------------------------------
+ * free()
+ */
+void gfsm_pd_atom_free(t_atom *a)
+{ g_free(a); }
+
+/*--------------------------------------------------------------
+ * read()
+ */
+t_atom *gfsm_pd_atom_read(gfsmPdAtomAlphabet *alph, GString *gstr)
+{
+ binbuf_clear(alph->aa_binbuf);
+ binbuf_text(alph->aa_binbuf, gstr->str, gstr->len);
+ return binbuf_getvec(alph->aa_binbuf);
+}
+
+/*--------------------------------------------------------------
+ * write()
+ */
+void gfsm_pd_atom_write(gfsmPdAtomAlphabet *alph, t_atom *a, GString *gstr)
+{
+ atom_string(a, alph->aa_strbuf, PdGfsmStrBufSize);
+ g_string_assign(gstr, alph->aa_strbuf);
+}
+
+/*======================================================================
+ * gfsmPdAtomAlphabet: shortcuts
+ */
+
+/*--------------------------------------------------------------
+ * new
+ */
+gfsmPdAtomAlphabet *gfsm_pd_atom_alphabet_new(void)
+{
+ gfsmPdAtomAlphabet *alph = g_new0(gfsmPdAtomAlphabet,1);
+ ((gfsmAlphabet*)alph)->type = gfsmATUser;
+ gfsm_user_alphabet_init((gfsmUserAlphabet*)alph,
+ (gfsmAlphabetKeyDupFunc)gfsm_pd_atom_dup,
+ (GHashFunc)gfsm_pd_atom_hash,
+ (GEqualFunc)gfsm_pd_atom_equal,
+ (GDestroyNotify)gfsm_pd_atom_free,
+ NULL,
+ &pd_atom_alphabet_methods);
+ alph->aa_binbuf = binbuf_new();
+ return alph;
+}
+
+//-- destructor
+void gfsm_pd_atom_alphabet_free(gfsmPdAtomAlphabet *alph)
+{
+ if (alph->aa_binbuf) binbuf_free(alph->aa_binbuf);
+ gfsm_alphabet_free((gfsmAlphabet*)alph);
+}
diff --git a/gfsm/src/atom_alphabet.h b/gfsm/src/atom_alphabet.h
new file mode 100644
index 0000000..262ea2c
--- /dev/null
+++ b/gfsm/src/atom_alphabet.h
@@ -0,0 +1,80 @@
+/*=============================================================================*\
+ * File: atom_alphabet.h
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd: atom alphabet
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+#ifndef _PD_GFSM_ATOM_ALPHABET_H
+#define _PD_GFSM_ATOM_ALPHABET_H
+
+#include <m_pd.h>
+#include <gfsm.h>
+
+/*--------------------------------------------------------------
+ * Constants
+ */
+#define PdGfsmStrBufSize 256
+
+extern gfsmUserAlphabetMethods pd_atom_alphabet_methods;
+
+/*--------------------------------------------------------------
+ * Types: gfsmPdAtomAlphabet
+ */
+typedef struct {
+ gfsmUserAlphabet aa_alph;
+ t_binbuf *aa_binbuf;
+ char aa_strbuf[PdGfsmStrBufSize];
+} gfsmPdAtomAlphabet;
+
+/*--------------------------------------------------------------
+ * gfsmPdAtomAlphabet: user methods
+ */
+//-- hash function for pd atoms
+guint gfsm_pd_atom_hash(t_atom *a);
+
+//-- equality check for pd atoms
+gboolean gfsm_pd_atom_equal(t_atom *a1, t_atom *a2);
+
+//-- dup function for pd atoms
+t_atom *gfsm_pd_atom_dup(gfsmPdAtomAlphabet *alph, t_atom *a);
+
+//-- free function for pd atoms
+void gfsm_pd_atom_free(t_atom *a);
+
+//-- string read function for pd atoms
+t_atom *gfsm_pd_atom_read(gfsmPdAtomAlphabet *alph, GString *gstr);
+
+//-- string write function for pd atoms
+void gfsm_pd_atom_write(gfsmPdAtomAlphabet *alph, t_atom *a, GString *gstr);
+
+/*--------------------------------------------------------------
+ * gfsmPdAtomAlphabet: utilities
+ */
+//-- constructor
+gfsmPdAtomAlphabet *gfsm_pd_atom_alphabet_new(void);
+
+//-- destructor
+void gfsm_pd_atom_alphabet_free(gfsmPdAtomAlphabet *alph);
+
+#endif /* _PD_GFSM_ATOM_ALPHABET_H */
diff --git a/gfsm/src/gfsm-help.pd b/gfsm/src/gfsm-help.pd
new file mode 100644
index 0000000..c91aa46
--- /dev/null
+++ b/gfsm/src/gfsm-help.pd
@@ -0,0 +1,15 @@
+#N canvas 0 0 430 269 10;
+#X obj 66 7 gfsm;
+#X text 126 232 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X text 21 43 EXTERNALS:;
+#X obj 41 72 gfsm_alphabet;
+#X obj 41 98 gfsm_automaton;
+#X text 159 71 integer <-> atom mapping;
+#X obj 41 124 gfsm_state;
+#X text 161 125 automaton position;
+#X text 160 98 weighted finite state machine;
+#X text 21 184 SEE ALSO:;
+#X text 38 201 gfsmutils(1);
+#X text 99 8 : finite state machine external library;
+#X obj 40 150 gfsm_markov;
+#X text 161 151 trainable Markov chain;
diff --git a/gfsm/src/gfsm-help.tfst b/gfsm/src/gfsm-help.tfst
new file mode 100644
index 0000000..67e2bea
--- /dev/null
+++ b/gfsm/src/gfsm-help.tfst
@@ -0,0 +1,3 @@
+0 2 42 24 0.7
+0 1 2 3 4
+1 0
diff --git a/gfsm/src/gfsm_alphabet-help.pd b/gfsm/src/gfsm_alphabet-help.pd
new file mode 100644
index 0000000..b3d6653
--- /dev/null
+++ b/gfsm/src/gfsm_alphabet-help.pd
@@ -0,0 +1,64 @@
+#N canvas 16 0 646 547 10;
+#X text 289 523 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X text 9 524 SEE ALSO:;
+#X text 9 69 INLETS:;
+#X text 27 83 1 - control messages;
+#X text 244 68 OUTLETS:;
+#X obj 80 525 gfsm;
+#X text 48 48 NAME - symbolic name of the alphabet;
+#X text 260 81 1 - value outlet;
+#X text 260 96 2 - bang on missing value;
+#X text 14 31 SYNTAX: gfsm_alphabet [NAME];
+#X obj 13 493 print CHAR;
+#X obj 197 492 print ATOM;
+#X msg 29 182 insert x 1;
+#X text 163 185 "insert ATOM CHAR" : map ATOM<->CHAR;
+#X msg 33 203 insert y;
+#X text 198 203 "insert ATOM" : map ATOM to a new character label;
+#X msg 48 232 atom2char x;
+#X text 177 233 "atom2char ATOM" : lookup character label for ATOM
+;
+#X text 170 253 "atom2char! ATOM" : lookup or insert label for ATOM
+;
+#X text 184 284 "char2atom INT" : lookup atom for label INT;
+#X text 177 301 "char2atom! INT" : lookup or insert atom for INT;
+#X msg 63 281 char2atom 1;
+#X msg 65 301 char2atom! 42;
+#X msg 52 252 atom2char! foo;
+#X text 184 129 "alphabet NAME" : sets current alphabet;
+#X msg 19 151 alphabet;
+#X text 219 145 "alphabet" : use private alphabet;
+#X text 309 159 NOTE: alphabets of the same name share data;
+#X msg 75 332 clear;
+#X msg 91 405 print;
+#X text 240 404 "print" : dump alphabet contents to the console;
+#X msg 91 445 save tmp.lab;
+#X text 212 425 "load FILE" : load alphabet contents from a file;
+#X text 212 445 "save FILE" : save alphabet contents to a file;
+#X text 67 4 gfsm_alphabet : integer<->atom map for finite state machines
+;
+#X text 240 333 "clear" : clears entire alphabet;
+#X msg 76 353 rmatom x;
+#X msg 77 374 rmchar 1;
+#X text 205 372 "rmchar INT" : remove mapping for label INT;
+#X text 198 353 "rmatom ATOM" : remove mapping for atom ATOM;
+#X obj 117 525 gfsm_automaton;
+#X obj 13 471 gfsm_alphabet help-alphabet;
+#X msg 13 127 alphabet help-alphabet;
+#X msg 92 425 load tmp.lab;
+#X connect 12 0 41 0;
+#X connect 14 0 41 0;
+#X connect 16 0 41 0;
+#X connect 21 0 41 0;
+#X connect 22 0 41 0;
+#X connect 23 0 41 0;
+#X connect 25 0 41 0;
+#X connect 28 0 41 0;
+#X connect 29 0 41 0;
+#X connect 31 0 41 0;
+#X connect 36 0 41 0;
+#X connect 37 0 41 0;
+#X connect 41 0 10 0;
+#X connect 41 1 11 0;
+#X connect 42 0 41 0;
+#X connect 43 0 41 0;
diff --git a/gfsm/src/gfsm_automaton-help.pd b/gfsm/src/gfsm_automaton-help.pd
new file mode 100644
index 0000000..10f35ba
--- /dev/null
+++ b/gfsm/src/gfsm_automaton-help.pd
@@ -0,0 +1,288 @@
+#N canvas 126 0 473 476 10;
+#X text 89 7 gfsm_automaton : weighted finite state machine;
+#X text 173 441 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X text 7 379 SEE ALSO:;
+#X obj 22 399 gfsm;
+#X text 12 73 INLETS:;
+#X text 30 87 1 - control messages;
+#X text 244 74 OUTLETS:;
+#X text 260 87 1 - value outlet;
+#X text 48 48 NAME - symbolic name of the machine;
+#X text 14 31 SYNTAX: gfsm_automaton [NAME];
+#X text 7 211 SUBTOPICS:;
+#X text 10 114 DESCRIPTION:;
+#X text 245 211 GUTS:;
+#X text 28 130 gfsm_automaton objects represent weighted finite state
+machines (acceptors or transducers) -- rooted \, acyclic graphs whose
+edges are labelled with triples (LO \, HI \, WEIGHT) \, where LO and
+HI are alphabet labels (see gfsm_alphabet) \, and WEIGHT is a floating
+point number.;
+#X obj 265 272 print fsm-help-out;
+#X obj 137 400 gfsm_alphabet;
+#N canvas 192 14 651 458 help-automaton-flags 0;
+#X text 167 4 gfsm_automaton : flags;
+#X msg 22 36 weighted;
+#X msg 32 171 transducer 1;
+#X msg 33 192 transducer 0;
+#X msg 22 151 transducer;
+#X msg 33 57 weighted 1;
+#X msg 34 78 weighted 0;
+#X msg 24 275 semiring;
+#X msg 37 299 semiring boolean;
+#X msg 37 320 semiring log;
+#X msg 37 361 semiring real;
+#X msg 37 382 semiring trivial;
+#X msg 38 402 semiring tropical;
+#X text 192 35 "weighted" : get value of the boolean "weighted" flag
+;
+#X text 157 57 "weighted BOOL" : set "weighted" flag;
+#X text 214 87 weighted automata may behave differently than unweighted
+automata with respect to certain algebraic operations.;
+#X text 178 148 "transducer" : get value of the boolean "transducer"
+flag;
+#X text 143 170 "transducer BOOL" : set "transducer" flag;
+#X text 216 195 transducers may behave differently than acceptors (which
+have only one label per arc) with respect to certain algebraic operations.
+;
+#X text 157 297 "semiring TYPE" : set semiring to use for weight arithmetic
+;
+#X text 192 272 "semiring" : get semiring type used for weight arithmetic
+;
+#X text 336 434 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X text 218 328 algebraic operations may be called on to alter arc
+weights \; in this case \, the semiring type associated with the automaton
+will be used to interpret arc weights. work in progress -- if you need
+this for something \, let me know.;
+#X obj 22 101 s fsm-help-in;
+#X obj 22 216 s fsm-help-in;
+#X obj 24 428 s fsm-help-in;
+#X msg 37 341 semiring plog;
+#X connect 1 0 23 0;
+#X connect 2 0 24 0;
+#X connect 3 0 24 0;
+#X connect 4 0 24 0;
+#X connect 5 0 23 0;
+#X connect 6 0 23 0;
+#X connect 7 0 25 0;
+#X connect 8 0 25 0;
+#X connect 9 0 25 0;
+#X connect 10 0 25 0;
+#X connect 11 0 25 0;
+#X connect 12 0 25 0;
+#X connect 26 0 25 0;
+#X restore 19 230 pd help-automaton-flags;
+#N canvas 71 31 651 409 help-automaton-basic 0;
+#X text 345 383 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X obj 21 119 s fsm-help-in;
+#X text 167 4 gfsm_automaton : basic operations;
+#X msg 21 45 automaton;
+#X msg 28 69 automaton fsm-help-2;
+#X msg 29 91 automaton fsm-help;
+#X text 179 38 "automaton" : use an object-local machine;
+#X text 145 51 "automaton NAME" : use a shared machine named NAME;
+#X msg 29 193 clear;
+#X text 124 192 "clear" : clears the automaton;
+#X msg 34 217 info;
+#X text 130 215 "info" : prints summary information to the Pd console
+;
+#X msg 35 241 print;
+#X text 221 74 data is shared between automata of the same name. when
+using multiple shared automata \, take care always to leave at least
+one object "pointing" to each name \, since the underlying data structures
+are freed when all references are lost.;
+#X text 124 236 "print" : prints automaton in at&t text format to stdout
+;
+#X obj 19 269 s fsm-help-in;
+#X text 145 262 WARNING: these methods may hog the cpu for extended
+periods of time when called for large machines.;
+#X msg 22 169 renumber;
+#X text 102 170 "renumber" : renumber automaton states \, closing gaps
+;
+#X connect 3 0 1 0;
+#X connect 4 0 1 0;
+#X connect 5 0 1 0;
+#X connect 8 0 15 0;
+#X connect 10 0 15 0;
+#X connect 12 0 15 0;
+#X connect 17 0 15 0;
+#X restore 19 252 pd help-automaton-basic;
+#N canvas 27 14 658 321 help-automaton-io 0;
+#X text 101 2 gfsm_automaton : input/output;
+#X obj 13 93 s fsm-help-in;
+#X text 211 44 "load FILE" : load an automaton in at&t-style text format
+;
+#X text 212 68 "save FILE" : save automaton in at&t-style text format
+;
+#X obj 10 235 s fsm-help-in;
+#X text 225 160 "load_bin FILE" : load an automaton in GFSM binary
+format;
+#X text 354 292 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X msg 23 48 load gfsm-help.tfst;
+#X msg 17 162 load_bin gfsm-help.gfst;
+#X msg 23 69 save gfsm-help.tfst;
+#X text 243 240 NOTE: gfsm binary format is not portable across different
+architectures.;
+#X text 235 87 NOTE: currently \, all text i/o is done in "weighted
+transducer" format \, regardless of automaton flags or input file content.
+;
+#X text 227 184 "save_bin FILE" : save automaton in GFSM binary format
+;
+#X msg 18 184 save_bin gfsm-help.gfst;
+#X text 228 209 "save_bin FILE ZLEVEL" : save with zlib compression
+;
+#X msg 24 208 save_bin gfsm-help.gfst 9;
+#X connect 7 0 1 0;
+#X connect 8 0 4 0;
+#X connect 9 0 1 0;
+#X connect 13 0 4 0;
+#X connect 15 0 4 0;
+#X restore 21 296 pd help-automaton-io;
+#N canvas 199 1 636 611 help-automaton-algebra 0;
+#X msg 24 33 complement;
+#X msg 24 62 closure 0;
+#X msg 24 79 closure 1;
+#X msg 24 170 determinize;
+#X msg 24 201 difference fsm-help-2;
+#X msg 24 235 intersect fsm-help-2;
+#X msg 24 267 invert;
+#X msg 24 352 product fsm-help-2;
+#X msg 24 413 reverse;
+#X msg 24 444 rmepsilon;
+#X msg 24 479 union fsm-help-2;
+#X text 222 32 "complement" : compute complement of an acceptor;
+#X msg 24 140 concat fsm-help;
+#X text 215 141 "concat FSM2" : concatenate with automaton named FSM2
+;
+#X text 187 197 "difference FSM2" : remove language of automaton named
+FSM2;
+#X text 194 228 "intersect FSM2" : intersect with automaton named FSM2
+;
+#X text 250 266 "invert" : swap upper and lower labels;
+#X msg 24 302 project 0;
+#X msg 24 319 project 1;
+#X text 208 298 "project SIDE" : project one label side;
+#X text 327 311 SIDE=0: project lower labels;
+#X text 328 323 SIDE=1: project upper labels;
+#X text 208 348 "product FSM2" : compute Cartesian product with FSM2
+;
+#X text 243 407 "reverse" : reverse language of an automaton;
+#X text 95 6 gfsm_automaton : algebraic operations;
+#X text 229 439 "rmepsilon" : remove epsilon arcs;
+#X text 222 478 "union FSM2" : compute union with automaton FSM2;
+#X obj 24 505 s fsm-help-in;
+#X text 31 551 WARNING: these methods may block for long periods of
+time for large automata.;
+#X text 329 578 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X msg 24 109 compose fsm-help-2;
+#X text 208 109 "compose FSM2" : compose with transducer FSM2;
+#X text 229 70 "closure N" : compute N-ary closure;
+#X text 215 170 "determinize" : determinize an acceptor;
+#X msg 24 383 connect;
+#X text 244 382 "connect" : remove useless states and arcs;
+#X connect 0 0 27 0;
+#X connect 1 0 27 0;
+#X connect 2 0 27 0;
+#X connect 3 0 27 0;
+#X connect 4 0 27 0;
+#X connect 5 0 27 0;
+#X connect 6 0 27 0;
+#X connect 7 0 27 0;
+#X connect 8 0 27 0;
+#X connect 9 0 27 0;
+#X connect 10 0 27 0;
+#X connect 12 0 27 0;
+#X connect 17 0 27 0;
+#X connect 18 0 27 0;
+#X connect 30 0 27 0;
+#X connect 34 0 27 0;
+#X restore 21 342 pd help-automaton-algebra;
+#X obj 59 400 gfsm_state;
+#X obj 265 230 r fsm-help-in;
+#N canvas 293 117 651 504 help-automaton-access 0;
+#X msg 22 42 size;
+#X floatatom 33 66 5 0 0 0 - - -;
+#X msg 33 82 size \$1;
+#X obj 22 104 s fsm-help-in;
+#X text 118 38 "size" : get number of states in the machine;
+#X text 90 51 "size INT" : grow machine to at least INT states;
+#X text 99 5 gfsm_automaton : automaton access;
+#X floatatom 35 177 5 0 0 0 - - -;
+#X obj 24 215 s fsm-help-in;
+#X msg 24 153 root;
+#X msg 35 193 root \$1;
+#X text 120 149 "root" : get id of machine's initial state or "bang"
+;
+#X text 134 72 note that values reported do not take the VALIDITY of
+states into account -- your mileage may vary.;
+#X text 132 180 in the second form \, the state will be created if
+it does not already exist. states are internally stored in an array
+\, and indexed with positive integer IDs beginning from 0 (zero) --
+i.e. \, a message such as "root 1E+37" is likely to crash Pd.;
+#X text 99 162 "root ID" : set machine's initial state to ID (an integer)
+;
+#X text 139 273 "final ID" : check whether state ID is marked as final
+;
+#X text 104 297 "final ID BOOL" : set final-status of state ID to BOOL
+;
+#X obj 23 344 s fsm-help-in;
+#X text 143 314 same caveats as for "root";
+#X obj 26 436 s fsm-help-in;
+#X msg 23 276 final 1;
+#X msg 30 299 final 1 1;
+#X msg 31 319 final 1 0;
+#X text 207 388 "add_arc FROM TO LO HI WEIGHT" : add an arc;
+#X text 242 403 adds an arc from state FROM to state TO on lower (input)
+label LO and upper (output) label HI with weight WEIGHT. states FROM
+and TO are implicitly created.;
+#X msg 26 390 add_arc 0 1 2 3 4;
+#X msg 38 412 add_arc 0 2 42 24 0.7;
+#X text 349 480 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X connect 0 0 3 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 7 0 10 0;
+#X connect 9 0 8 0;
+#X connect 10 0 8 0;
+#X connect 20 0 17 0;
+#X connect 21 0 17 0;
+#X connect 22 0 17 0;
+#X connect 25 0 19 0;
+#X connect 26 0 19 0;
+#X restore 20 274 pd help-automaton-access;
+#N canvas 15 0 687 348 help-automaton-draw 0;
+#X obj 13 256 s fsm-help-in;
+#X text 246 63 NOTE: interpreting the resulting file requires the 'graphviz'
+package from at&t.;
+#X text 225 39 "draw_dot FILE [OPTIONS]" : save a 'dot' graph specification
+;
+#X text 235 97 OPTIONS:;
+#X text 318 113 title TITLE : graph title;
+#X text 318 168 width WIDTH : graph width (inches);
+#X text 248 127 ilabels ALPHABET_NAME : lower-label alphabet name;
+#X text 248 140 olabels ALPHABET_NAME : upper-label alphabet name;
+#X text 248 154 slabels ALPHABET_NAME : state-label alphabet name;
+#X text 304 180 height HEIGHT : graph height (inches);
+#X text 304 193 fontsize SIZE : font size (points?);
+#X text 304 206 fontname NAME : font name (?);
+#X text 304 219 portrait BOOL : draw in portrait mode? (default=no)
+;
+#X text 304 231 vertical BOOL : draw top-to-bottom? (default=no);
+#X text 297 244 nodesep INCHES : node-separation distance;
+#X text 297 257 ranksep INCHES : rank-separation distance;
+#X text 115 9 gfsm_automaton : draw;
+#X text 370 326 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X msg 13 40 draw_dot fsm-help.dot;
+#X obj 14 311 shell;
+#X msg 14 291 dotty fsm-help.dot;
+#X text 235 291 ... try this if you have the "graphviz" package installed
+;
+#X connect 18 0 0 0;
+#X connect 20 0 19 0;
+#X restore 20 318 pd help-automaton-draw;
+#X text 239 401 gfsmutils(1);
+#X obj 265 344 gfsm_automaton fsm-help-2;
+#X text 248 303 PLACEHOLDERS:;
+#X obj 265 323 gfsm_automaton fsm-help;
+#X obj 265 251 gfsm_automaton fsm-help;
+#X connect 21 0 28 0;
+#X connect 28 0 14 0;
diff --git a/gfsm/src/gfsm_markov-help.pd b/gfsm/src/gfsm_markov-help.pd
new file mode 100644
index 0000000..8d7a3a2
--- /dev/null
+++ b/gfsm/src/gfsm_markov-help.pd
@@ -0,0 +1,68 @@
+#N canvas 39 25 680 536 10;
+#X text 150 -2 gfsm_markov : Markov chain using gfsm;
+#X text 15 41 INLETS:;
+#X text 28 56 1 - control messages;
+#X text 233 41 OUTLETS:;
+#X text 17 21 SYNTAX: gfsm_markov OBJNAME;
+#X text 365 24 REQUIRES:;
+#X obj 433 24 gfsm;
+#X obj 469 24 zexy;
+#X text 246 83 3 - bang when stuck;
+#X text 247 69 2 - upper side atoms on "next";
+#X text 247 55 1 - lower side atoms on "next";
+#X obj 39 494 print lo;
+#X obj 134 494 print hi;
+#X obj 230 494 print stuck;
+#X obj 39 473 gfsm_markov help-gfsm-markov;
+#X msg 48 175 load_bin help-gfsm_markov;
+#X msg 49 192 save-bin help-gfsm_markov;
+#X msg 39 125 load help-gfsm_markov;
+#X msg 40 142 save help-gfsm_markov;
+#X msg 55 250 set foo;
+#X msg 61 267 set;
+#X msg 60 298 add foo bar 0.42;
+#X msg 65 361 addi foo baz 1;
+#X msg 78 408 next \$1;
+#X floatatom 78 392 5 0 0 0 - - -;
+#X msg 78 428 next;
+#X msg 78 450 bang;
+#X msg 53 223 clear;
+#X text 273 126 load BASE : load text files BASE.lab and BASE.tfst
+;
+#X text 274 142 save BASE : save text files BASE.lab \, BASE.tfst;
+#X text 246 175 load_bin BASE : load files BASE.lab \, BASE.gfst;
+#X text 246 192 save_bin BASE : save files BASE.lab \, BASE.gfst;
+#X text 302 224 clear : clear underlying objects;
+#X text 281 250 set ATOM : set current state to ATOM;
+#X text 316 268 set : reset to initial (root) state;
+#X text 227 297 add A1 A2 WEIGHT : add WEIGHT to arc on atom-pair A1:A2
+;
+#X text 276 316 add A1 A2 : like "add A1 A2 1";
+#X msg 62 315 add foo baz;
+#X text 297 332 add A1 : like "add A1 0 1";
+#X text 219 361 addi A1 A2 WEIGHT : add WEIGHT to initial arc on A1:A2
+;
+#X text 273 408 next PROB : follow next arc with PROB hint-probability
+;
+#X text 308 429 next : follow next arc \, random probability;
+#X text 308 450 bang : alias for "next";
+#X text 375 516 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X msg 65 332 add foo;
+#X connect 14 0 11 0;
+#X connect 14 1 12 0;
+#X connect 14 2 13 0;
+#X connect 15 0 14 0;
+#X connect 16 0 14 0;
+#X connect 17 0 14 0;
+#X connect 18 0 14 0;
+#X connect 19 0 14 0;
+#X connect 20 0 14 0;
+#X connect 21 0 14 0;
+#X connect 22 0 14 0;
+#X connect 23 0 14 0;
+#X connect 24 0 23 0;
+#X connect 25 0 14 0;
+#X connect 26 0 14 0;
+#X connect 27 0 14 0;
+#X connect 37 0 14 0;
+#X connect 44 0 14 0;
diff --git a/gfsm/src/gfsm_markov.pd b/gfsm/src/gfsm_markov.pd
new file mode 100644
index 0000000..ab7142d
--- /dev/null
+++ b/gfsm/src/gfsm_markov.pd
@@ -0,0 +1,414 @@
+#N canvas 386 0 450 300 10;
+#X text 85 2 gfsm_markov : Markov chain using gfsm;
+#X text 181 17 for details \, see:;
+#N canvas 266 0 499 471 gfsm_markov_doc 0;
+#X text 85 2 gfsm_markov : Markov chain using gfsm;
+#X text 15 67 INLETS:;
+#X text 28 84 1 - control messages;
+#X text 203 64 OUTLETS:;
+#X text 17 128 MESSAGES:;
+#X text 81 219 set ATOM : set current state to ATOM;
+#X text 116 231 set : reset to initial (root) state;
+#X text 107 441 bang : synonym for "next";
+#X text 16 24 SYNTAX: gfsm_markov OBJNAME;
+#X text 15 44 REQUIRES:;
+#X obj 83 44 gfsm;
+#X text 75 147 load BASE : load text files BASE.lab and BASE.tfst;
+#X text 75 159 save BASE : save text files BASE.lab \, BASE.tfst;
+#X text 47 182 load_bin BASE : load files BASE.lab \, BASE.gfst;
+#X text 47 194 save_bin BASE : save files BASE.lab \, BASE.gfst;
+#X obj 121 45 zexy;
+#X text 156 294 from current state \, and move to;
+#X text 23 281 add A1 A2 WEIGHT : add WEIGHT to arc on atom-pair A1:A2
+;
+#X text 73 411 next PROB : get next arc with PROB as nearest probability
+;
+#X text 107 427 next : get next arc with random probability;
+#X text 216 106 3 - bang when stuck;
+#X text 157 330 + WEIGHT defaults to 1;
+#X text 157 318 + A2 defaults to 0 (epsilon);
+#X text 157 378 + WEIGHT defaults to 1;
+#X text 157 366 + A2 defaults to 0 (epsilon);
+#X text 18 354 addi A1 A2 WEIGHT : add WEIGHT to initial arc on atoms
+A1:A2;
+#X text 156 305 (possibly new) state for atom A1;
+#X text 217 92 2 - upper side atoms on "next";
+#X text 217 78 1 - lower side atoms on "next";
+#X text 102 250 clear : clear underlying objects;
+#X restore 309 19 pd gfsm_markov_doc;
+#X obj 20 60 inlet;
+#X obj 22 261 outlet;
+#X obj 103 260 outlet;
+#N canvas 27 71 720 463 gfsm_markov_control_guts 0;
+#X obj 22 8 inlet;
+#X obj 450 32 print gfsm_markov_bad_message;
+#X obj 183 230 s \$0-load;
+#X obj 215 209 s \$0-save;
+#X obj 247 187 s \$0-load_bin;
+#X obj 280 164 s \$0-save_bin;
+#X obj 86 373 s \$0-set;
+#X obj 312 125 s \$0-clear;
+#X obj 118 337 s \$0-add;
+#X obj 22 409 s \$0-next;
+#X obj 303 99 s \$0-fsm;
+#X obj 335 78 s \$0-alph;
+#X obj 151 295 s \$0-addi;
+#X obj 415 79 s \$0-state-r;
+#X obj 22 28 route next bang set add addi load save load_bin save_bin
+clear fsm alph state add2;
+#X obj 449 122 s \$0-add2;
+#X connect 0 0 14 0;
+#X connect 14 0 9 0;
+#X connect 14 1 9 0;
+#X connect 14 2 6 0;
+#X connect 14 3 8 0;
+#X connect 14 4 12 0;
+#X connect 14 5 2 0;
+#X connect 14 6 3 0;
+#X connect 14 7 4 0;
+#X connect 14 8 5 0;
+#X connect 14 9 7 0;
+#X connect 14 10 10 0;
+#X connect 14 11 11 0;
+#X connect 14 12 13 0;
+#X connect 14 13 15 0;
+#X connect 14 14 1 0;
+#X restore 20 82 pd gfsm_markov_control_guts;
+#N canvas 0 252 310 205 gfsm_markov_fsm_guts 0;
+#X obj 40 121 gfsm_automaton \$1-fsm;
+#X obj 40 53 gfsm_alphabet \$1-alph;
+#X obj 40 100 r \$0-fsm;
+#X obj 40 33 r \$0-alph;
+#X connect 2 0 0 0;
+#X connect 3 0 1 0;
+#X restore 21 113 pd gfsm_markov_fsm_guts;
+#N canvas 114 67 710 486 gfsm_markov_io_guts 0;
+#X obj 21 87 symbol;
+#X msg 209 301 load \$1;
+#X obj 178 86 symbol;
+#X msg 556 308 save \$1;
+#X msg 21 215 load \$1;
+#X obj 367 85 symbol;
+#X obj 526 79 symbol;
+#X obj 21 20 r \$0-load;
+#X obj 367 22 r \$0-save;
+#X obj 526 26 r \$0-save_bin;
+#X obj 178 19 r \$0-load_bin;
+#X obj 21 110 t s s;
+#X obj 178 106 t s s;
+#X obj 367 107 t s s;
+#X obj 526 100 t s s;
+#X msg 179 215 load_bin \$1;
+#X msg 526 216 save_bin \$1;
+#X msg 367 215 save \$1;
+#X obj 21 193 makefilename %s.tfst;
+#X obj 178 192 makefilename %s.gfst;
+#X obj 367 193 makefilename %s.tfst;
+#X obj 526 193 makefilename %s.gfst;
+#X obj 556 286 makefilename %s.lab;
+#X obj 209 280 makefilename %s.lab;
+#X obj 179 434 s \$0-fsm;
+#X obj 367 429 s \$0-alph;
+#X connect 0 0 11 0;
+#X connect 1 0 25 0;
+#X connect 2 0 12 0;
+#X connect 3 0 25 0;
+#X connect 4 0 24 0;
+#X connect 5 0 13 0;
+#X connect 6 0 14 0;
+#X connect 7 0 0 0;
+#X connect 8 0 5 0;
+#X connect 9 0 6 0;
+#X connect 10 0 2 0;
+#X connect 11 0 18 0;
+#X connect 11 1 23 0;
+#X connect 12 0 19 0;
+#X connect 12 1 23 0;
+#X connect 13 0 20 0;
+#X connect 13 1 22 0;
+#X connect 14 0 21 0;
+#X connect 14 1 22 0;
+#X connect 15 0 24 0;
+#X connect 16 0 24 0;
+#X connect 17 0 24 0;
+#X connect 18 0 4 0;
+#X connect 19 0 15 0;
+#X connect 20 0 17 0;
+#X connect 21 0 16 0;
+#X connect 22 0 3 0;
+#X connect 23 0 1 0;
+#X restore 21 138 pd gfsm_markov_io_guts;
+#N canvas 150 351 551 242 gfsm_markov_set_guts 0;
+#X obj 32 18 r \$0-set;
+#X obj 32 40 route bang;
+#X obj 97 133 gfsm_alphabet \$1-alph;
+#X obj 97 61 route float list;
+#X msg 97 110 atom2char! \$1;
+#X obj 204 83 symbol;
+#X msg 97 156 set \$1;
+#X obj 97 178 s \$0-state;
+#X msg 32 83 0;
+#X obj 345 15 r \$0-clear;
+#X obj 389 78 s \$0-alph;
+#X obj 367 126 s \$0-fsm;
+#X msg 367 105 clear \, root 0;
+#X msg 389 57 clear \, atom2char! 0;
+#X obj 345 35 t b b b;
+#X msg 345 150 set 0;
+#X obj 346 170 s \$0-state;
+#X connect 0 0 1 0;
+#X connect 1 0 8 0;
+#X connect 1 1 3 0;
+#X connect 2 0 6 0;
+#X connect 3 0 4 0;
+#X connect 3 1 4 0;
+#X connect 3 2 5 0;
+#X connect 4 0 2 0;
+#X connect 5 0 4 0;
+#X connect 6 0 7 0;
+#X connect 8 0 4 0;
+#X connect 9 0 14 0;
+#X connect 12 0 11 0;
+#X connect 13 0 10 0;
+#X connect 14 0 15 0;
+#X connect 14 1 12 0;
+#X connect 14 2 13 0;
+#X connect 15 0 16 0;
+#X restore 21 162 pd gfsm_markov_set_guts;
+#X obj 261 60 loadbang;
+#N canvas 142 144 416 223 gfsm_markov_init_guts 0;
+#X obj 15 9 inlet;
+#X msg 15 97 char2atom! 0;
+#X obj 15 118 s \$0-alph;
+#X obj 15 66 t b b;
+#X obj 74 10 r \$0-loadbang;
+#X obj 179 124 gfsm_automaton \$1-fsm;
+#X msg 206 97 root;
+#X obj 179 145 route root;
+#X obj 179 168 route bang;
+#X msg 155 98 root 0;
+#X connect 0 0 3 0;
+#X connect 1 0 2 0;
+#X connect 3 0 1 0;
+#X connect 3 1 6 0;
+#X connect 4 0 3 0;
+#X connect 5 0 7 0;
+#X connect 6 0 5 0;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 9 0 5 0;
+#X restore 261 81 pd gfsm_markov_init_guts;
+#N canvas 66 12 666 508 gfsm_markov_add_guts 0;
+#X obj 28 231 gfsm_alphabet \$1-alph;
+#X obj 28 167 route float list;
+#X msg 28 211 atom2char! \$1;
+#X obj 95 190 symbol;
+#X obj 58 426 gfsm_state \$1-fsm;
+#X obj 71 402 r \$0-state;
+#X msg 508 322 set \$1;
+#X obj 508 428 s \$0-state;
+#X obj 28 12 r \$0-add1;
+#X obj 121 12 r \$0-add;
+#X obj 123 320 1;
+#X obj 28 260 t f f;
+#X obj 413 14 r \$0-addi1;
+#X obj 492 14 r \$0-addi;
+#X obj 443 89 gfsm_automaton \$1-fsm;
+#X msg 443 67 root;
+#X obj 413 39 t a b;
+#X obj 443 110 route root;
+#X obj 443 132 route bang;
+#X msg 481 67 root 0;
+#X msg 58 372 add_weight \$1 \$1 \$2 \$3;
+#X obj 28 89 t a b b;
+#X obj 58 347 pack 0 0 0;
+#X obj 90 320 0;
+#X text 139 347 <-- Q=LO HI WEIGHT;
+#X obj 28 112 niagara 1;
+#X obj 231 129 niagara 1;
+#X obj 231 236 gfsm_alphabet \$1-alph;
+#X obj 231 172 route float list;
+#X msg 231 216 atom2char! \$1;
+#X obj 298 195 symbol;
+#X obj 204 12 r \$0-add2;
+#X obj 28 42 t a b;
+#X obj 205 35 t a b;
+#X obj 446 297 spigot;
+#X obj 454 273 0;
+#X obj 479 273 1;
+#X connect 0 0 11 0;
+#X connect 1 0 2 0;
+#X connect 1 1 2 0;
+#X connect 1 2 3 0;
+#X connect 2 0 0 0;
+#X connect 3 0 2 0;
+#X connect 5 0 4 0;
+#X connect 6 0 7 0;
+#X connect 8 0 32 0;
+#X connect 9 0 32 0;
+#X connect 10 0 22 2;
+#X connect 11 0 34 0;
+#X connect 11 1 22 0;
+#X connect 12 0 16 0;
+#X connect 13 0 16 0;
+#X connect 14 0 17 0;
+#X connect 15 0 14 0;
+#X connect 16 0 21 0;
+#X connect 16 1 15 0;
+#X connect 17 0 18 0;
+#X connect 18 0 19 0;
+#X connect 18 1 6 0;
+#X connect 19 0 14 0;
+#X connect 20 0 4 0;
+#X connect 21 0 25 0;
+#X connect 21 1 23 0;
+#X connect 21 2 10 0;
+#X connect 22 0 20 0;
+#X connect 23 0 22 1;
+#X connect 25 0 1 0;
+#X connect 25 1 26 0;
+#X connect 26 0 28 0;
+#X connect 26 1 22 2;
+#X connect 27 0 22 1;
+#X connect 28 0 29 0;
+#X connect 28 1 29 0;
+#X connect 28 2 30 0;
+#X connect 29 0 27 0;
+#X connect 30 0 29 0;
+#X connect 31 0 33 0;
+#X connect 32 0 21 0;
+#X connect 32 1 36 0;
+#X connect 33 0 21 0;
+#X connect 33 1 35 0;
+#X connect 34 0 6 0;
+#X connect 35 0 34 1;
+#X connect 36 0 34 1;
+#X restore 21 186 pd gfsm_markov_add_guts;
+#N canvas 27 0 738 524 gfsm_markov_next_guts 0;
+#X obj 86 25 r \$0-next;
+#X obj 243 464 outlet;
+#X obj 86 47 route bang;
+#X obj 151 158 * -1;
+#X obj 151 136 * 1;
+#X obj 559 376 t b b;
+#N canvas 75 18 312 424 weight_sum 0;
+#X obj 24 9 inlet;
+#X msg 24 114 arc_next;
+#X obj 24 319 f 0;
+#X obj 199 92 0;
+#X obj 89 238 unpack 0 0 0 0;
+#X obj 183 262 + 0;
+#X obj 88 263 t f f;
+#X obj 24 350 outlet;
+#X obj 60 146 r \$0-state;
+#X obj 24 90 until;
+#X obj 24 214 route bang;
+#X obj 24 235 t b b;
+#X obj 24 192 route arc_next;
+#X obj 24 43 t b b b b;
+#X msg 91 114 arc_reset;
+#X obj 24 167 gfsm_state \$1-fsm 0;
+#X connect 0 0 13 0;
+#X connect 1 0 15 0;
+#X connect 2 0 7 0;
+#X connect 3 0 5 1;
+#X connect 4 3 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 5 1;
+#X connect 6 1 2 1;
+#X connect 8 0 15 0;
+#X connect 9 0 1 0;
+#X connect 10 0 11 0;
+#X connect 10 1 4 0;
+#X connect 11 0 2 0;
+#X connect 11 1 9 1;
+#X connect 12 0 10 0;
+#X connect 13 0 9 0;
+#X connect 13 1 3 0;
+#X connect 13 2 14 0;
+#X connect 13 3 9 1;
+#X connect 14 0 15 0;
+#X connect 15 0 12 0;
+#X restore 167 115 pd weight_sum;
+#X obj 25 95 random 131072;
+#X obj 25 116 / 131072;
+#X obj 86 69 t b b b;
+#X obj 151 69 t f b b;
+#X msg 559 227 arc_next;
+#X obj 594 269 r \$0-state;
+#X obj 559 205 until;
+#X obj 559 349 route bang;
+#X obj 559 326 route arc_next;
+#X msg 625 226 arc_reset;
+#X obj 151 180 t b b f;
+#X obj 405 461 outlet;
+#X obj 101 429 gfsm_alphabet \$1-alph;
+#X msg 101 407 char2atom! \$1;
+#X obj 179 296 moses 0;
+#X obj 179 251 + 0;
+#X obj 179 274 t f f;
+#X obj 86 225 unpack 0 0 0 0;
+#X obj 18 386 f 0;
+#X msg 18 411 set \$1;
+#X obj 18 432 s \$0-state;
+#X obj 559 292 gfsm_state \$1-fsm 0;
+#X obj 559 457 outlet;
+#X obj 263 428 gfsm_alphabet \$1-alph;
+#X msg 263 406 char2atom! \$1;
+#X obj 263 384 f 0;
+#X obj 101 385 f 0;
+#X obj 225 316 t b b b b;
+#X connect 0 0 2 0;
+#X connect 2 0 9 0;
+#X connect 2 1 10 0;
+#X connect 3 0 17 0;
+#X connect 4 0 3 0;
+#X connect 5 0 29 0;
+#X connect 5 1 13 1;
+#X connect 6 0 4 1;
+#X connect 7 0 8 0;
+#X connect 8 0 4 0;
+#X connect 9 0 7 0;
+#X connect 9 1 6 0;
+#X connect 9 2 13 1;
+#X connect 10 0 4 0;
+#X connect 10 1 6 0;
+#X connect 10 2 13 1;
+#X connect 11 0 28 0;
+#X connect 12 0 28 0;
+#X connect 13 0 11 0;
+#X connect 14 0 5 0;
+#X connect 14 1 24 0;
+#X connect 15 0 14 0;
+#X connect 16 0 28 0;
+#X connect 17 0 13 0;
+#X connect 17 1 16 0;
+#X connect 17 2 22 1;
+#X connect 19 1 1 0;
+#X connect 20 0 19 0;
+#X connect 21 1 34 0;
+#X connect 22 0 23 0;
+#X connect 23 0 21 0;
+#X connect 23 1 22 1;
+#X connect 24 0 25 1;
+#X connect 24 1 33 1;
+#X connect 24 2 32 1;
+#X connect 24 3 22 0;
+#X connect 25 0 26 0;
+#X connect 26 0 27 0;
+#X connect 28 0 15 0;
+#X connect 30 1 18 0;
+#X connect 31 0 30 0;
+#X connect 32 0 31 0;
+#X connect 33 0 20 0;
+#X connect 34 0 25 0;
+#X connect 34 1 33 0;
+#X connect 34 2 32 0;
+#X connect 34 3 13 1;
+#X restore 22 216 pd gfsm_markov_next_guts;
+#X obj 185 260 outlet;
+#X connect 3 0 6 0;
+#X connect 10 0 11 0;
+#X connect 13 0 4 0;
+#X connect 13 1 5 0;
+#X connect 13 2 14 0;
diff --git a/gfsm/src/gfsm_state-help.pd b/gfsm/src/gfsm_state-help.pd
new file mode 100644
index 0000000..e26ace2
--- /dev/null
+++ b/gfsm/src/gfsm_state-help.pd
@@ -0,0 +1,55 @@
+#N canvas 232 0 651 599 10;
+#X obj 85 569 gfsm;
+#X text 15 569 SEE ALSO:;
+#X text 41 6 gfsm_state : position "pointer" for finite-state automata
+;
+#X text 267 563 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X text 17 79 INLETS:;
+#X text 35 93 1 - control messages;
+#X text 255 82 OUTLETS:;
+#X text 271 95 1 - value outlet;
+#X text 18 30 SYNTAX: gfsm_state [FSM_NAME [STATE_ID]];
+#X text 52 47 FSM_NAME - symbolic name of a gfsm_automaton;
+#X text 52 61 STATE_ID - numeric Id of the target state;
+#X obj 26 531 print gfsm-state-out;
+#X msg 44 182 id;
+#X text 164 185 "id" : get current state Id;
+#X text 135 205 "set ID" : set current state Id;
+#X msg 50 205 set 0;
+#X msg 26 127 automaton;
+#X msg 31 149 automaton fsm-help;
+#X text 197 128 "automaton" : use an object-local machine;
+#X text 163 151 "automaton NAME" : use a shared machine named NAME
+;
+#X msg 58 239 degree;
+#X text 137 240 "degree" : get number of outgoing arcs (linear time)
+;
+#X msg 58 295 arc_first;
+#X msg 58 317 arc_next;
+#X msg 59 382 arc_reset;
+#X obj 26 508 gfsm_state fsm-help 0;
+#X text 229 398 arcs are output as a list:;
+#X text 277 414 NEXT_STATEID LO HI WEIGHT;
+#X text 306 359 (negative labels are ignored);
+#X msg 58 345 arc_seek 202 -1;
+#X text 208 294 "arc_first" : get first outgoing arc;
+#X text 214 318 "arc_next" : get next available outgoing arc (maybe
+first);
+#X text 173 344 "arc_seek LO HI" : get next arc with labels LO:HI;
+#X text 207 383 "arc_reset" : close internal arc iterator;
+#X msg 54 447 add_weight 1 -1 101 0.9;
+#X text 233 450 "add_weight ID LO HI W" : add W to 1st arc to state
+ID;
+#X text 416 463 with labels LO:HI;
+#X text 271 479 (implicitly resets arc iterator);
+#X connect 12 0 25 0;
+#X connect 15 0 25 0;
+#X connect 16 0 25 0;
+#X connect 17 0 25 0;
+#X connect 20 0 25 0;
+#X connect 22 0 25 0;
+#X connect 23 0 25 0;
+#X connect 24 0 25 0;
+#X connect 25 0 11 0;
+#X connect 29 0 25 0;
+#X connect 34 0 25 0;
diff --git a/gfsm/src/lkpin.tfst b/gfsm/src/lkpin.tfst
new file mode 100644
index 0000000..a9adbc9
--- /dev/null
+++ b/gfsm/src/lkpin.tfst
@@ -0,0 +1,4 @@
+0 1 2 2
+1 2 2 2
+2 3 3 3
+3
diff --git a/gfsm/src/lkptest.tfst b/gfsm/src/lkptest.tfst
new file mode 100644
index 0000000..11f371e
--- /dev/null
+++ b/gfsm/src/lkptest.tfst
@@ -0,0 +1,8 @@
+0 0 1 2 1
+0 0 2 3 1
+0 0 3 1 1
+0 1 2 2 1
+0 0
+1 2 2 2 1
+2 3 3 3 1
+3 0
diff --git a/gfsm/src/pd_algebra.c b/gfsm/src/pd_algebra.c
new file mode 100644
index 0000000..eecde1e
--- /dev/null
+++ b/gfsm/src/pd_algebra.c
@@ -0,0 +1,299 @@
+/*=============================================================================*\
+ * File: pd_algebra.c
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <pd_gfsm.h>
+#include <pd_automaton.h>
+#include <m_pd.h>
+
+/*--------------------------------------------------------------------
+ * DEBUG
+ *--------------------------------------------------------------------*/
+//#define PDFSM_DEBUG 1
+
+/*=====================================================================
+ * Structures and Types
+ *=====================================================================*/
+//(none)
+
+/*=====================================================================
+ * pd_gfsm_automaton_obj: Utilities
+ *=====================================================================*/
+//(none)
+
+/*=====================================================================
+ * pd_gfsm_automaton_obj: Algebra
+ *=====================================================================*/
+
+/*--------------------------------------------------------------------
+ * complement
+ */
+static void pd_gfsm_automaton_complement(t_pd_gfsm_automaton_obj *x)
+{
+ gfsm_automaton_complement(x->x_automaton_pd->x_automaton);
+ pd_gfsm_automaton_obj_outlet_bang(x, gensym("complement"));
+}
+
+/*--------------------------------------------------------------------
+ * closure
+ */
+static void pd_gfsm_automaton_closure(t_pd_gfsm_automaton_obj *x, t_float nf)
+{
+ gfsm_automaton_n_closure(x->x_automaton_pd->x_automaton, (guint)nf);
+ pd_gfsm_automaton_obj_outlet_float(x, gensym("closure"), nf);
+}
+
+/*--------------------------------------------------------------------
+ * compose
+ */
+static void pd_gfsm_automaton_compose(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
+{
+ t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
+ if (!fsm2_pd) {
+ error("pd_gfsm_automaton_compose(): no fsm named '%s'", fsm2_name->s_name);
+ return;
+ } else {
+ ++fsm2_pd->x_refcnt;
+ gfsm_automaton_compose(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
+ pd_gfsm_automaton_pd_release(fsm2_pd);
+ }
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("compose"), fsm2_name);
+}
+
+/*--------------------------------------------------------------------
+ * concat
+ */
+static void pd_gfsm_automaton_concat(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
+{
+ t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
+ if (!fsm2_pd) {
+ error("pd_gfsm_automaton_concat(): no fsm named '%s'", fsm2_name->s_name);
+ return;
+ } else {
+ ++fsm2_pd->x_refcnt;
+ gfsm_automaton_concat(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
+ pd_gfsm_automaton_pd_release(fsm2_pd);
+ }
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("concat"), fsm2_name);
+}
+
+/*--------------------------------------------------------------------
+ * determinize
+ */
+static void pd_gfsm_automaton_determinize(t_pd_gfsm_automaton_obj *x)
+{
+ gfsm_automaton_determinize(x->x_automaton_pd->x_automaton);
+ pd_gfsm_automaton_obj_outlet_bang(x, gensym("determinize"));
+}
+
+/*--------------------------------------------------------------------
+ * difference
+ */
+static void pd_gfsm_automaton_difference(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
+{
+ t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
+ if (!fsm2_pd) {
+ error("pd_gfsm_automaton_difference(): no fsm named '%s'", fsm2_name->s_name);
+ return;
+ } else {
+ ++fsm2_pd->x_refcnt;
+ gfsm_automaton_difference(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
+ pd_gfsm_automaton_pd_release(fsm2_pd);
+ }
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("difference"), fsm2_name);
+}
+
+/*--------------------------------------------------------------------
+ * intersection
+ */
+static void pd_gfsm_automaton_intersect(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
+{
+ t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
+ if (!fsm2_pd) {
+ error("pd_gfsm_automaton_intersect(): no fsm named '%s'", fsm2_name->s_name);
+ return;
+ } else {
+ ++fsm2_pd->x_refcnt;
+ gfsm_automaton_intersect(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
+ pd_gfsm_automaton_pd_release(fsm2_pd);
+ }
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("intersect"), fsm2_name);
+}
+
+/*--------------------------------------------------------------------
+ * invert
+ */
+static void pd_gfsm_automaton_invert(t_pd_gfsm_automaton_obj *x)
+{
+ gfsm_automaton_invert(x->x_automaton_pd->x_automaton);
+ pd_gfsm_automaton_obj_outlet_bang(x, gensym("invert"));
+}
+
+/*--------------------------------------------------------------------
+ * product
+ */
+static void pd_gfsm_automaton_product(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
+{
+ t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
+ if (!fsm2_pd) {
+ error("pd_gfsm_automaton_product(): no fsm named '%s'", fsm2_name->s_name);
+ return;
+ } else {
+ ++fsm2_pd->x_refcnt;
+ gfsm_automaton_product(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
+ pd_gfsm_automaton_pd_release(fsm2_pd);
+ }
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("intersect"), fsm2_name);
+}
+
+/*--------------------------------------------------------------------
+ * project
+ */
+static void pd_gfsm_automaton_project(t_pd_gfsm_automaton_obj *x, t_float which)
+{
+ gfsm_automaton_project(x->x_automaton_pd->x_automaton,
+ (which==0 ? gfsmLSLower : gfsmLSUpper));
+ pd_gfsm_automaton_obj_outlet_float(x, gensym("project"), which);
+}
+
+/*--------------------------------------------------------------------
+ * prune
+ */
+static void pd_gfsm_automaton_connect(t_pd_gfsm_automaton_obj *x)
+{
+ gfsm_automaton_connect(x->x_automaton_pd->x_automaton);
+ pd_gfsm_automaton_obj_outlet_bang(x, gensym("connect"));
+}
+
+/*--------------------------------------------------------------------
+ * renumber
+ */
+static void pd_gfsm_automaton_renumber(t_pd_gfsm_automaton_obj *x)
+{
+ gfsm_automaton_renumber_states(x->x_automaton_pd->x_automaton);
+ pd_gfsm_automaton_obj_outlet_bang(x, gensym("renumber"));
+}
+
+
+/*--------------------------------------------------------------------
+ * reverse
+ */
+static void pd_gfsm_automaton_reverse(t_pd_gfsm_automaton_obj *x)
+{
+ gfsm_automaton_reverse(x->x_automaton_pd->x_automaton);
+ pd_gfsm_automaton_obj_outlet_bang(x, gensym("reverse"));
+}
+
+/*--------------------------------------------------------------------
+ * rmepsilon
+ */
+static void pd_gfsm_automaton_rmepsilon(t_pd_gfsm_automaton_obj *x)
+{
+ gfsm_automaton_rmepsilon(x->x_automaton_pd->x_automaton);
+ pd_gfsm_automaton_obj_outlet_bang(x, gensym("rmepsilon"));
+}
+
+/*--------------------------------------------------------------------
+ * union
+ */
+static void pd_gfsm_automaton_union(t_pd_gfsm_automaton_obj *x, t_symbol *fsm2_name)
+{
+ t_pd_gfsm_automaton_pd *fsm2_pd = pd_gfsm_automaton_pd_find(fsm2_name);
+ if (!fsm2_pd) {
+ error("pd_gfsm_automaton_union(): no fsm named '%s'", fsm2_name->s_name);
+ return;
+ }
+ else if (fsm2_pd != x->x_automaton_pd) {
+ ++fsm2_pd->x_refcnt;
+ gfsm_automaton_union(x->x_automaton_pd->x_automaton, fsm2_pd->x_automaton);
+ pd_gfsm_automaton_pd_release(fsm2_pd);
+ }
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("union"), fsm2_name);
+}
+
+
+/*=====================================================================
+ * setup
+ *=====================================================================*/
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: setup()
+ */
+void pd_gfsm_algebra_setup(t_class *automaton_class)
+{
+ //-- methods: algebra
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_complement,
+ gensym("complement"), A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_closure,
+ gensym("closure"), A_DEFFLOAT, A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_compose,
+ gensym("compose"), A_SYMBOL, A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_concat,
+ gensym("concat"), A_SYMBOL, A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_determinize,
+ gensym("determinize"), A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_difference,
+ gensym("difference"), A_SYMBOL, A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_intersect,
+ gensym("intersect"), A_SYMBOL, A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_invert,
+ gensym("invert"), A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_product,
+ gensym("product"), A_SYMBOL, A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_project,
+ gensym("project"), A_DEFFLOAT, A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_connect,
+ gensym("connect"), A_NULL);
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_connect,
+ gensym("prune"), A_NULL); //-- backwards-compatible alias
+
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_renumber,
+ gensym("renumber"), A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_reverse,
+ gensym("reverse"), A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_rmepsilon,
+ gensym("rmepsilon"), A_NULL);
+
+ class_addmethod(automaton_class, (t_method)pd_gfsm_automaton_union,
+ gensym("union"), A_SYMBOL, A_NULL);
+}
diff --git a/gfsm/src/pd_alphabet.c b/gfsm/src/pd_alphabet.c
new file mode 100644
index 0000000..480a74a
--- /dev/null
+++ b/gfsm/src/pd_alphabet.c
@@ -0,0 +1,494 @@
+/*=============================================================================*\
+ * File: pd_alphabet.c
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd: alphabet
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <pd_alphabet.h>
+#include <pd_io.h>
+#include <string.h>
+
+/*=====================================================================
+ * DEBUG
+ *=====================================================================*/
+//#define ALPHABET_DEBUG
+
+/*=====================================================================
+ * Pd Constants
+ *=====================================================================*/
+static t_class *pd_gfsm_alphabet_pd_class;
+static t_class *pd_gfsm_alphabet_obj_class;
+
+/*=====================================================================
+ * pd_gfsm_alphabet_pd: Methods
+ *=====================================================================*/
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_pd: new
+ */
+static void *pd_gfsm_alphabet_pd_new(t_symbol *name)
+{
+ t_pd_gfsm_alphabet_pd *x = (t_pd_gfsm_alphabet_pd *)pd_new(pd_gfsm_alphabet_pd_class);
+
+#ifdef ALPHABET_DEBUG
+ post("pd_gfsm_alphabet_pd_new() called ; name=%s ; x=%p",
+ (name ? name->s_name : "(null)"),
+ x);
+#endif
+
+ //-- defaults
+ x->x_refcnt = 0;
+ x->x_name = name;
+ x->x_alphabet = (gfsmAlphabet*)gfsm_pd_atom_alphabet_new();
+
+ //-- bindings
+ if (name != &s_) pd_bind((t_pd*)x, name);
+
+ return (void *)x;
+}
+
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_pd: free
+ */
+static void pd_gfsm_alphabet_pd_free(t_pd_gfsm_alphabet_pd *x)
+{
+#ifdef ALPHABET_DEBUG
+ post("pd_gfsm_alphabet_pd_free() called ; x=%p", x);
+#endif
+
+ if (x->x_alphabet) gfsm_pd_atom_alphabet_free((gfsmPdAtomAlphabet*)(x->x_alphabet));
+
+ /* unbind the symbol of the name of hashtable in pd's global namespace */
+ if (x->x_name != &s_) pd_unbind((t_pd*)x, x->x_name);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_pd: find
+ */
+t_pd_gfsm_alphabet_pd *pd_gfsm_alphabet_pd_find(t_symbol *name)
+{
+ if (name != &s_)
+ return (t_pd_gfsm_alphabet_pd*)pd_findbyclass(name,pd_gfsm_alphabet_pd_class);
+ return NULL;
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_pd: get
+ */
+t_pd_gfsm_alphabet_pd *pd_gfsm_alphabet_pd_get(t_symbol *name)
+{
+ t_pd_gfsm_alphabet_pd *x = pd_gfsm_alphabet_pd_find(name);
+ if (!x) {
+ x = (t_pd_gfsm_alphabet_pd*)pd_gfsm_alphabet_pd_new(name);
+ x->x_refcnt = 0;
+ }
+ return x;
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_pd: release
+ */
+void pd_gfsm_alphabet_pd_release(t_pd_gfsm_alphabet_pd *x)
+{
+ if (x) {
+ if (x->x_refcnt) --x->x_refcnt;
+ if (!x->x_refcnt) pd_gfsm_alphabet_pd_free(x);
+ }
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_pd: setup
+ */
+void pd_gfsm_alphabet_pd_setup(void)
+{
+ //-- class
+ pd_gfsm_alphabet_pd_class = class_new(gensym("gfsm_alphabet_pd"),
+ (t_newmethod)pd_gfsm_alphabet_pd_new,
+ (t_method)pd_gfsm_alphabet_pd_free,
+ sizeof(t_pd_gfsm_alphabet_pd),
+ CLASS_PD,
+ A_DEFSYM,
+ A_NULL);
+}
+
+
+/*=====================================================================
+ * pd_gfsm_alphabet: Methods
+ *=====================================================================*/
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: new
+ */
+static void *pd_gfsm_alphabet_obj_new(t_symbol *name)
+{
+ t_pd_gfsm_alphabet_obj *x = (t_pd_gfsm_alphabet_obj *)pd_new(pd_gfsm_alphabet_obj_class);
+
+#ifdef ALPHABET_DEBUG
+ post("pd_gfsm_alphabet_obj_new() called: name=%s ; x=%p",
+ (name ? name->s_name : "(null)"),
+ x);
+#endif
+
+ //-- defaults
+ x->x_alphabet_pd = NULL;
+
+ //-- bindings
+ x->x_alphabet_pd = pd_gfsm_alphabet_pd_get(name);
+ x->x_alphabet_pd->x_refcnt++;
+
+ //-- outlets
+ x->x_labout = outlet_new(&x->x_obj, &s_float); //-- label / "char" outlet
+ x->x_keyout = outlet_new(&x->x_obj, &s_anything); //-- atom outlet
+
+ return (void *)x;
+}
+
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: free
+ */
+static void pd_gfsm_alphabet_obj_free(t_pd_gfsm_alphabet_obj *x)
+{
+#ifdef ALPHABET_DEBUG
+ post("pd_gfsm_alphabet_obj_free() called: x=%p", x);
+#endif
+
+ pd_gfsm_alphabet_pd_release(x->x_alphabet_pd);
+
+ //-- do we need to do this?
+ outlet_free(x->x_labout);
+ outlet_free(x->x_keyout);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: set
+ */
+static void pd_gfsm_alphabet_obj_alphabet(t_pd_gfsm_alphabet_obj *x, t_symbol *name)
+{
+#ifdef ALPHABET_DEBUG
+ post("pd_gfsm_alphabet_obj_alphabet() called ; oldname=%p=%s ; newname=%p=%s",
+ x->x_alphabet_pd->x_name, x->x_alphabet_pd->x_name->s_name, name, name->s_name);
+#endif
+ if (name == x->x_alphabet_pd->x_name) return;
+ pd_gfsm_alphabet_pd_release(x->x_alphabet_pd);
+
+ x->x_alphabet_pd = pd_gfsm_alphabet_pd_get(name);
+ ++x->x_alphabet_pd->x_refcnt;
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: load
+ */
+static void pd_gfsm_alphabet_obj_load(t_pd_gfsm_alphabet_obj *x, t_symbol *s)
+{
+ gfsmError *errp = NULL;
+ gfsm_alphabet_load_filename(x->x_alphabet_pd->x_alphabet, s->s_name, &errp);
+ if (errp != NULL) {
+ error("gfsm_alphabet: load %s: %s", s->s_name, errp->message);
+ g_error_free(errp);
+ }
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: print
+ */
+static void pd_gfsm_alphabet_obj_print(t_pd_gfsm_alphabet_obj *x)
+{
+ gfsmError *errp = NULL;
+ gfsmIOHandle *ioh = pd_gfsm_console_handle_new();
+ gfsm_alphabet_save_handle(x->x_alphabet_pd->x_alphabet, ioh, &errp);
+ if (errp != NULL) {
+ error("gfsm_alphabet: print: %s", errp->message);
+ g_error_free(errp);
+ }
+ pd_gfsm_console_handle_free(ioh);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: save
+ */
+static void pd_gfsm_alphabet_obj_save(t_pd_gfsm_alphabet_obj *x, t_symbol *s)
+{
+ gfsmError *errp = NULL;
+ gfsm_alphabet_save_filename(x->x_alphabet_pd->x_alphabet, s->s_name, &errp);
+ if (errp != NULL) {
+ error("gfsm_alphabet: save %s: %s", s->s_name, errp->message);
+ g_error_free(errp);
+ }
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: clear
+ */
+static void pd_gfsm_alphabet_obj_clear(t_pd_gfsm_alphabet_obj *x)
+{
+ gfsm_alphabet_clear(x->x_alphabet_pd->x_alphabet);
+}
+
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: outlet_pair
+ */
+static void pd_gfsm_alphabet_obj_outlet_pair(t_pd_gfsm_alphabet_obj *x, t_float lab, t_atom *a)
+{
+ if (a) {
+ switch (a->a_type) {
+ case A_SYMBOL:
+ outlet_symbol(x->x_keyout, a->a_w.w_symbol);
+ break;
+ case A_FLOAT:
+ outlet_float(x->x_keyout, a->a_w.w_float);
+ break;
+ default:
+ outlet_symbol(x->x_keyout, atom_getsymbol(a));
+ break;
+ }
+ } else {
+ outlet_bang(x->x_keyout);
+ }
+
+ if (lab != gfsmNoLabel) outlet_float(x->x_obj.ob_outlet, lab);
+ else outlet_bang(x->x_obj.ob_outlet);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: insert
+ */
+static void pd_gfsm_alphabet_obj_insert(t_pd_gfsm_alphabet_obj *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if (argc < 1) {
+ error("pd_gfsm_alphabet_obj_insert(): no atom to insert?");
+ return;
+ }
+ t_float labf = argc > 1 ? atom_getfloat(argv+1) : (t_float)gfsmNoLabel;
+
+ gfsm_alphabet_get_full(x->x_alphabet_pd->x_alphabet, argv, (gfsmLabelVal)labf);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: atom2label
+ */
+static void pd_gfsm_alphabet_obj_atom2label(t_pd_gfsm_alphabet_obj *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if (argc < 1) {
+ error("pd_gfsm_alphabet_obj_atom2label(): no arguments?");
+ return;
+ }
+ t_float labf = (t_float)(gfsm_alphabet_find_label(x->x_alphabet_pd->x_alphabet, argv));
+
+ pd_gfsm_alphabet_obj_outlet_pair(x, labf, argv);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: atom2label_force
+ */
+static void pd_gfsm_alphabet_obj_atom2label_force(t_pd_gfsm_alphabet_obj *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if (argc < 1) {
+ error("pd_gfsm_alphabet_obj_atom2label_force(): no arguments?");
+ return;
+ }
+ t_float labf = (t_float)(gfsm_alphabet_get_label(x->x_alphabet_pd->x_alphabet, argv));
+
+ pd_gfsm_alphabet_obj_outlet_pair(x, labf, argv);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: label2atom
+ */
+static void pd_gfsm_alphabet_obj_label2atom(t_pd_gfsm_alphabet_obj *x, t_float labf)
+{
+ t_atom *key = (t_atom*)gfsm_alphabet_find_key(x->x_alphabet_pd->x_alphabet, (gfsmLabelVal)labf);
+
+ if (key==NULL) pd_gfsm_alphabet_obj_outlet_pair(x, labf, NULL);
+ else pd_gfsm_alphabet_obj_outlet_pair(x, labf, key);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: label2atom_force
+ */
+static void pd_gfsm_alphabet_obj_label2atom_force(t_pd_gfsm_alphabet_obj *x, t_float labf)
+{
+ t_atom *key = (t_atom*)gfsm_alphabet_find_key(x->x_alphabet_pd->x_alphabet,
+ (gfsmLabelVal)labf);
+ if (key==NULL) {
+ t_atom labatom;
+ SETFLOAT(&labatom, labf);
+ gfsm_alphabet_insert(x->x_alphabet_pd->x_alphabet, &labatom, (gfsmLabelVal)labf);
+ pd_gfsm_alphabet_obj_outlet_pair(x, labf, &labatom);
+ }
+ else {
+ pd_gfsm_alphabet_obj_outlet_pair(x, labf, key);
+ }
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: rmatom()
+ */
+static void pd_gfsm_alphabet_obj_rmatom(t_pd_gfsm_alphabet_obj *x, t_symbol *sel, int argc, t_atom *argv)
+{
+ if (argc < 1) return;
+ gfsm_alphabet_remove_key(x->x_alphabet_pd->x_alphabet, argv);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet_obj: rmlabel()
+ */
+static void pd_gfsm_alphabet_obj_rmlabel(t_pd_gfsm_alphabet_obj *x, t_float labf)
+{
+ gfsm_alphabet_remove_label(x->x_alphabet_pd->x_alphabet, (gfsmLabelVal)labf);
+}
+
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_alphabet: setup
+ */
+void pd_gfsm_alphabet_setup(void)
+{
+ //-- pd_gfsm_alphabet_pd
+ pd_gfsm_alphabet_pd_setup();
+
+ //-- class
+ pd_gfsm_alphabet_obj_class = class_new(gensym("gfsm_alphabet"),
+ (t_newmethod)pd_gfsm_alphabet_obj_new,
+ (t_method)pd_gfsm_alphabet_obj_free,
+ sizeof(t_pd_gfsm_alphabet_obj),
+ CLASS_DEFAULT,
+ A_DEFSYM,
+ A_NULL);
+
+ //-- methods: I/O
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_print,
+ gensym("print"),
+ A_NULL);
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_load,
+ gensym("load"),
+ A_SYMBOL,
+ A_NULL);
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_save,
+ gensym("save"),
+ A_SYMBOL,
+ A_NULL);
+
+
+ //-- methods: whole-object manipulation
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_clear,
+ gensym("clear"),
+ A_NULL);
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_alphabet,
+ gensym("alphabet"),
+ A_DEFSYM,
+ A_NULL);
+
+
+ //-- methods: insert
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_insert,
+ gensym("insert"),
+ A_GIMME,
+ A_NULL);
+
+ //-- methods: safe access: atom->label
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_atom2label,
+ gensym("atom2char"),
+ A_GIMME,
+ A_NULL);
+ /*
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_atom2label,
+ gensym("a2c"),
+ A_GIMME,
+ A_NULL);
+ */
+
+ //-- methods: destructive access: atom->label
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_atom2label_force,
+ gensym("atom2char!"),
+ A_GIMME,
+ A_NULL);
+ /*
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_atom2label_force,
+ gensym("a2c!"),
+ A_GIMME,
+ A_NULL);
+ */
+
+
+ //-- methods: safe access: label->atom
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_label2atom,
+ gensym("char2atom"),
+ A_FLOAT,
+ A_NULL);
+ /*
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_label2atom,
+ gensym("c2a"),
+ A_FLOAT,
+ A_NULL);
+ */
+
+ //-- methods: destructive access: label->atom
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_label2atom_force,
+ gensym("char2atom!"),
+ A_FLOAT,
+ A_NULL);
+ /*
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_label2atom_force,
+ gensym("c2a!"),
+ A_FLOAT,
+ A_NULL);
+ */
+
+ //-- methods: removal
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_rmatom,
+ gensym("rmatom"),
+ A_GIMME,
+ A_NULL);
+ class_addmethod(pd_gfsm_alphabet_obj_class,
+ (t_method)pd_gfsm_alphabet_obj_rmlabel,
+ gensym("rmchar"),
+ A_FLOAT,
+ A_NULL);
+
+
+ //-- help symbol
+ class_sethelpsymbol(pd_gfsm_alphabet_obj_class, gensym("gfsm_alphabet-help.pd"));
+}
diff --git a/gfsm/src/pd_alphabet.h b/gfsm/src/pd_alphabet.h
new file mode 100644
index 0000000..e426fd4
--- /dev/null
+++ b/gfsm/src/pd_alphabet.h
@@ -0,0 +1,78 @@
+/*=============================================================================*\
+ * File: pd_alphabet.h
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+#ifndef _PD_GFSM_ALPHABET_H
+#define _PD_GFSM_ALPHABET_H
+
+#include <m_pd.h>
+#include <gfsm.h>
+#include <atom_alphabet.h>
+
+
+/*--------------------------------------------------------------
+ * pd_gfsm_alphabet
+ */
+typedef struct _pd_gfsm_alphabet_pd
+{
+ t_pd x_pd;
+ t_symbol *x_name;
+ size_t x_refcnt;
+ gfsmAlphabet *x_alphabet; //-- really a (gfsmPdAtomAlphabet*)
+} t_pd_gfsm_alphabet_pd;
+
+
+/*--------------------------------------------------------------
+ * pd_gfsm_alphabet
+ */
+typedef struct _pd_gfsm_alphabet_obj
+{
+ t_object x_obj;
+ t_pd_gfsm_alphabet_pd *x_alphabet_pd;
+ t_outlet *x_labout;
+ t_outlet *x_keyout;
+} t_pd_gfsm_alphabet_obj;
+
+
+/*--------------------------------------------------------------
+ * pd_gfsm_alphabet: methods
+ */
+//-- finds pd_gfsm_alphabet named 'name', returns NULL if it doesn't exist
+t_pd_gfsm_alphabet_pd *pd_gfsm_alphabet_pd_find(t_symbol *name);
+
+//-- finds pd_gfsm_alphabet named 'name', creating it if it doesn't exist
+t_pd_gfsm_alphabet_pd *pd_gfsm_alphabet_pd_get(t_symbol *name);
+
+//-- releases one reference to pd_gfsm_alphabet named 'name', possibly freeing the pd_gfsm_alphabet
+void pd_gfsm_alphabet_pd_release(t_pd_gfsm_alphabet_pd *x);
+
+/*--------------------------------------------------------------
+ * setup methods
+ */
+void pd_gfsm_alphabet_setup(void);
+
+
+#endif /* _PD_GFSM_ALPHABET_H */
diff --git a/gfsm/src/pd_automaton.c b/gfsm/src/pd_automaton.c
new file mode 100644
index 0000000..47ce4cd
--- /dev/null
+++ b/gfsm/src/pd_automaton.c
@@ -0,0 +1,765 @@
+/*=============================================================================*\
+ * File: pd_automaton.c
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <pd_automaton.h>
+#include <pd_io.h>
+#include <m_pd.h>
+
+/*--------------------------------------------------------------------
+ * DEBUG
+ *--------------------------------------------------------------------*/
+//#define PDFSM_DEBUG 1
+
+/*=====================================================================
+ * Structures and Types
+ *=====================================================================*/
+static t_class *pd_gfsm_automaton_pd_class;
+static t_class *pd_gfsm_automaton_obj_class;
+
+/*=====================================================================
+ * pd_gfsm_automaton_pd: Methods
+ *=====================================================================*/
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_pd: new()
+ */
+static void *pd_gfsm_automaton_pd_new(t_symbol *name)
+{
+ t_pd_gfsm_automaton_pd *x = (t_pd_gfsm_automaton_pd *)pd_new(pd_gfsm_automaton_pd_class);
+
+ //-- debug
+#ifdef PDFSM_DEBUG
+ post("pd_gfsm_automaton_pd_new() called; name=%s ; x=%p\n", name->s_name, x);
+#endif
+
+ //-- defaults
+ x->x_refcnt = 0;
+ x->x_name = name;
+ x->x_automaton = gfsm_automaton_new();
+
+ //-- bindings
+ if (name != &s_) pd_bind((t_pd*)x, name);
+
+ return (void *)x;
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_pd: free()
+ */
+static void pd_gfsm_automaton_pd_free(t_pd_gfsm_automaton_pd *x)
+{
+#ifdef PDFSM_DEBUG
+ post("pd_gfsm_automaton_pd_free() called ; x=%p", x);
+#endif
+
+ if (x->x_automaton) gfsm_automaton_free(x->x_automaton);
+ x->x_automaton = NULL;
+
+ /* unbind the symbol of the name of hashtable in pd's global namespace */
+ if (x->x_name != &s_) pd_unbind((t_pd*)x, x->x_name);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_pd: setup()
+ */
+void pd_gfsm_automaton_pd_setup(void)
+{
+ //-- class
+ pd_gfsm_automaton_pd_class = class_new(gensym("pd_gfsm_automaton_pd"),
+ (t_newmethod)pd_gfsm_automaton_pd_new,
+ (t_method)pd_gfsm_automaton_pd_free,
+ sizeof(t_pd_gfsm_automaton_pd),
+ CLASS_PD,
+ A_DEFSYM,
+ A_NULL);
+}
+
+/*=====================================================================
+ * Utilities
+ *=====================================================================*/
+
+/*--------------------------------------------------------------------
+ * Utilties: pd_gfsm_automaton_pd_find()
+ */
+t_pd_gfsm_automaton_pd *pd_gfsm_automaton_pd_find(t_symbol *name)
+{
+ if (name != &s_)
+ return (t_pd_gfsm_automaton_pd*)pd_findbyclass(name,pd_gfsm_automaton_pd_class);
+ return NULL;
+}
+
+/*--------------------------------------------------------------------
+ * Utilties: pd_gfsm_automaton_pd_get()
+ */
+t_pd_gfsm_automaton_pd *pd_gfsm_automaton_pd_get(t_symbol *name)
+{
+ t_pd_gfsm_automaton_pd *x = pd_gfsm_automaton_pd_find(name);
+ if (!x) {
+ x = (t_pd_gfsm_automaton_pd*)pd_gfsm_automaton_pd_new(name);
+ x->x_refcnt = 0;
+ }
+ return x;
+}
+
+/*--------------------------------------------------------------------
+ * Utilties: pd_gfsm_automaton_pd: release()
+ */
+void pd_gfsm_automaton_pd_release(t_pd_gfsm_automaton_pd *x)
+{
+ if (x) {
+ if (x->x_refcnt) --x->x_refcnt;
+ if (!x->x_refcnt) pd_gfsm_automaton_pd_free(x);
+ }
+}
+
+/*--------------------------------------------------------------------
+ * Utilties: pd_gfsm_automaton_obj: outlet_symbol()
+ */
+void pd_gfsm_automaton_obj_outlet_symbol(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_symbol *val)
+{
+ SETSYMBOL(x->x_argv, val);
+ outlet_anything(x->x_valout, sel, 1, x->x_argv);
+}
+
+/*--------------------------------------------------------------------
+ * Utilties: pd_gfsm_automaton_obj: outlet_symbol()
+ */
+void pd_gfsm_automaton_obj_outlet_symbol_float(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_symbol *sym, t_float f)
+{
+ SETSYMBOL(x->x_argv, sym);
+ SETFLOAT(x->x_argv+1, f);
+ outlet_anything(x->x_valout, sel, 2, x->x_argv);
+}
+
+/*--------------------------------------------------------------------
+ * Utilties: pd_gfsm_automaton_obj: outlet_float()
+ */
+void pd_gfsm_automaton_obj_outlet_float(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_float f)
+{
+ SETFLOAT(x->x_argv, f);
+ outlet_anything(x->x_valout, sel, 1, x->x_argv);
+}
+
+/*--------------------------------------------------------------------
+ * Utilties: pd_gfsm_automaton_obj: outlet_float_2()
+ */
+void pd_gfsm_automaton_obj_outlet_float_2(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_float f1, t_float f2)
+{
+ SETFLOAT(x->x_argv , f1);
+ SETFLOAT(x->x_argv+1, f2);
+ outlet_anything(x->x_valout, sel, 2, x->x_argv);
+}
+
+/*--------------------------------------------------------------------
+ * Utilties: pd_gfsm_automaton_obj: outlet_bang()
+ */
+void pd_gfsm_automaton_obj_outlet_bang(t_pd_gfsm_automaton_obj *x, t_symbol *sel)
+{
+ SETSYMBOL(x->x_argv, &s_bang);
+ outlet_anything(x->x_valout, sel, 1, x->x_argv);
+}
+
+
+
+/*=====================================================================
+ * pd_gfsm_automaton_obj: Methods
+ *=====================================================================*/
+
+/*=====================================================================
+ * Constructors, etc.
+ */
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: new
+ */
+static void *pd_gfsm_automaton_obj_new(t_symbol *name)
+{
+ t_pd_gfsm_automaton_obj *x =
+ (t_pd_gfsm_automaton_obj *)pd_new(pd_gfsm_automaton_obj_class);
+
+#ifdef PDFSM_DEBUG
+ post("pd_gfsm_automaton_obj_new() called: name=%s ; x=%p",
+ (name ? name->s_name : "(null)"),
+ x);
+#endif
+
+ //-- defaults
+ //x->x_automaton_pd = NULL;
+
+ //-- bindings
+ x->x_automaton_pd = pd_gfsm_automaton_pd_get(name);
+ x->x_automaton_pd->x_refcnt++;
+
+ //-- outlets
+ x->x_valout = outlet_new(&x->x_obj, &s_anything); //-- value outlet
+
+ return (void *)x;
+}
+
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: free
+ */
+static void pd_gfsm_automaton_obj_free(t_pd_gfsm_automaton_obj *x)
+{
+#ifdef PDFSM_DEBUG
+ post("pd_gfsm_automaton_obj_free() called: x=%p", x);
+#endif
+
+ pd_gfsm_automaton_pd_release(x->x_automaton_pd);
+
+ //-- do we need to do this?
+ outlet_free(x->x_valout);
+}
+
+/*=====================================================================
+ * automaton_obj: Basic Accessors
+ */
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: automaton
+ */
+static void pd_gfsm_automaton_obj_automaton(t_pd_gfsm_automaton_obj *x, t_symbol *name)
+{
+ if (name != x->x_automaton_pd->x_name) {
+ pd_gfsm_automaton_pd_release(x->x_automaton_pd);
+ x->x_automaton_pd = pd_gfsm_automaton_pd_get(name);
+ ++x->x_automaton_pd->x_refcnt;
+ }
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("automaton"), name);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: size()
+ */
+static void pd_gfsm_automaton_obj_size(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
+{
+ if (argc > 0) {
+ gfsmStateId n = (gfsmStateId)atom_getfloatarg(0,argc,argv);
+ gfsm_automaton_reserve(x->x_automaton_pd->x_automaton, n);
+ }
+ pd_gfsm_automaton_obj_outlet_float
+ (x, sel, (t_float)gfsm_automaton_n_states(x->x_automaton_pd->x_automaton));
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: clear()
+ */
+static void pd_gfsm_automaton_obj_clear(t_pd_gfsm_automaton_obj *x)
+{
+ gfsm_automaton_clear(x->x_automaton_pd->x_automaton);
+ pd_gfsm_automaton_obj_outlet_bang(x, gensym("clear"));
+}
+
+/*=====================================================================
+ * automaton_obj: flags
+ */
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: root()
+ */
+static void pd_gfsm_automaton_obj_root(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
+{
+ gfsmStateId q0;
+ if (argc > 0) {
+ q0 = (gfsmStateId)atom_getintarg(0,argc,argv);
+ gfsm_automaton_set_root(x->x_automaton_pd->x_automaton, q0);
+ } else {
+ q0 = gfsm_automaton_get_root(x->x_automaton_pd->x_automaton);
+ }
+
+ if (q0==gfsmNoState) pd_gfsm_automaton_obj_outlet_bang(x, sel);
+ else pd_gfsm_automaton_obj_outlet_float(x, sel, (t_float)q0);
+}
+
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: weighted()
+ */
+static void pd_gfsm_automaton_obj_weighted(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
+{
+ if (argc > 0)
+ x->x_automaton_pd->x_automaton->flags.is_weighted = atom_getboolarg(0,argc,argv);
+ pd_gfsm_automaton_obj_outlet_float
+ (x, sel, (t_float)(x->x_automaton_pd->x_automaton->flags.is_weighted));
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: transducer()
+ */
+static void pd_gfsm_automaton_obj_transducer(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
+{
+ if (argc > 0)
+ x->x_automaton_pd->x_automaton->flags.is_transducer = atom_getboolarg(0,argc,argv);
+ pd_gfsm_automaton_obj_outlet_float
+ (x, sel, (t_float)(x->x_automaton_pd->x_automaton->flags.is_transducer));
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: semiring()
+ */
+static void pd_gfsm_automaton_obj_semiring(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
+{
+ t_symbol *srsym;
+ if (argc > 0) {
+ srsym = atom_getsymbolarg(0,argc,argv);
+ gfsm_automaton_set_semiring_type(x->x_automaton_pd->x_automaton,
+ gfsm_sr_name_to_type(srsym->s_name));
+ }
+ srsym = gensym(gfsm_sr_type_to_name(x->x_automaton_pd->x_automaton->sr->type));
+ pd_gfsm_automaton_obj_outlet_symbol(x, sel, srsym);
+}
+
+/*=====================================================================
+ * automaton_obj: state properties
+ */
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: final()
+ */
+static void pd_gfsm_automaton_obj_final(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
+{
+ gboolean ans = FALSE;
+ t_float qf = atom_getfloatarg(0,argc,argv);
+ if (qf<0) qf = -qf;
+ if (argc > 1) {
+ ans = atom_getboolarg(1,argc,argv);
+ gfsm_automaton_set_final_state(x->x_automaton_pd->x_automaton, (gfsmStateId)qf, ans);
+ } else {
+ ans = gfsm_automaton_is_final_state(x->x_automaton_pd->x_automaton, (gfsmStateId)qf);
+ }
+ pd_gfsm_automaton_obj_outlet_float_2(x, sel, qf, (t_float)ans);
+}
+
+
+/*=====================================================================
+ * automaton_obj: states & arcs
+ */
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: add_state()
+ */
+static void pd_gfsm_automaton_obj_add_state(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
+{
+ gfsmStateId id;
+ if (argc>0) id = (gfsmStateId)atom_getfloatarg(0,argc,argv);
+ else id = gfsmNoState;
+
+ id = gfsm_automaton_ensure_state(x->x_automaton_pd->x_automaton, id);
+ pd_gfsm_automaton_obj_outlet_float(x, sel, (t_float)id);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: add_arc()
+ */
+static void pd_gfsm_automaton_obj_add_arc(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
+{
+ t_float qsrc=0, qdst=0;
+ t_float clo=0, chi=0;
+ t_float w=0;
+ if (argc < 2) {
+ error("gfsm_automaton: add_arc(): not enough arguments!");
+ return;
+ }
+ switch (argc) {
+ case 5: //-- +from, +to, +lo, +hi, +weight
+ w = atom_getfloat(argv+4);
+ case 4: //-- +from, +to, +lo, +hi, -weight
+ chi = atom_getfloat(argv+3);
+ case 3: //-- +from, +to, +lo, -hi, -weight
+ clo = atom_getfloat(argv+2);
+ case 2: //-- +from, +to, -lo, -hi, -weight
+ default:
+ qdst = atom_getfloat(argv+1);
+ qsrc = atom_getfloat(argv);
+
+ if (qdst<0) qdst = -qdst;
+ if (qsrc<0) qsrc = -qsrc;
+ break;
+ }
+
+ gfsm_automaton_add_arc(x->x_automaton_pd->x_automaton,
+ (gfsmStateId)qsrc,
+ (gfsmStateId)qdst,
+ (gfsmLabelId)clo,
+ (gfsmLabelId)chi,
+ (gfsmWeight)w);
+
+#ifdef PDFSM_DEBUG
+ post("pd_gfsm_automaton_obj_add_arc(): node(qsrc=%ld).out_degree=%u",
+ qsrc,
+ gfsm_automaton_out_degree(x->x_automaton_pd->x_automaton, qsrc));
+#endif
+
+ //-- output
+ SETFLOAT(x->x_argv , (t_float)qsrc);
+ SETFLOAT(x->x_argv+1, (t_float)qdst);
+ SETFLOAT(x->x_argv+2, (t_float)clo);
+ SETFLOAT(x->x_argv+3, (t_float)chi);
+ SETFLOAT(x->x_argv+4, (t_float)w);
+ outlet_anything(x->x_valout, sel, 5, x->x_argv);
+}
+
+/*=====================================================================
+ * automaton_obj: Text I/O
+ */
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: print()
+ */
+static void pd_gfsm_automaton_obj_print(t_pd_gfsm_automaton_obj *x)
+{
+ gfsmError *errp = NULL;
+ gfsmIOHandle *ioh = pd_gfsm_console_handle_new();
+ gfsm_automaton_print_handle(x->x_automaton_pd->x_automaton,
+ ioh, NULL,NULL,NULL, &errp);
+ if (errp) {
+ error("gfsm_automaton: print(): Error: %s\n", errp->message);
+ g_error_free(errp);
+ }
+ pd_gfsm_console_handle_free(ioh);
+ pd_gfsm_automaton_obj_outlet_bang(x, gensym("print"));
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: load_txt()
+ */
+static void pd_gfsm_automaton_obj_load_txt(t_pd_gfsm_automaton_obj *x, t_symbol *s)
+{
+ gfsmError *errp = NULL;
+ gfsm_automaton_compile_filename(x->x_automaton_pd->x_automaton, s->s_name, &errp);
+ if (errp) {
+ error("gfsm_automaton: load_txt(%s): Error: %s\n", s->s_name, errp->message);
+ g_error_free(errp);
+ }
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("load"), s);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: save_txt()
+ */
+static void pd_gfsm_automaton_obj_save_txt(t_pd_gfsm_automaton_obj *x, t_symbol *s)
+{
+ gfsmError *errp = NULL;
+ gfsm_automaton_print_filename(x->x_automaton_pd->x_automaton, s->s_name, &errp);
+ if (errp) {
+ error("gfsm_automaton: save_txt(%s): Error: %s\n", s->s_name, errp->message);
+ g_error_free(errp);
+ }
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("save"), s);
+}
+
+
+/*=====================================================================
+ * automaton_obj: Binary I/O
+ */
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: load_bin()
+ */
+static void pd_gfsm_automaton_obj_load_bin(t_pd_gfsm_automaton_obj *x, t_symbol *s)
+{
+ gfsmError *errp = NULL;
+ gfsm_automaton_load_bin_filename(x->x_automaton_pd->x_automaton, s->s_name, &errp);
+ if (errp) {
+ error("gfsm_automaton: load_bin(%s): Error: %s\n", s->s_name, errp->message);
+ g_error_free(errp);
+ }
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("load_bin"), s);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: save_bin()
+ */
+static void pd_gfsm_automaton_obj_save_bin(t_pd_gfsm_automaton_obj *x, t_symbol *s, t_float zlevel)
+{
+ gfsmError *errp = NULL;
+ gfsm_automaton_save_bin_filename(x->x_automaton_pd->x_automaton, s->s_name, (int)zlevel, &errp);
+ if (errp) {
+ error("gfsm_automaton: save_bin(%s,%d): Error: %s\n", s->s_name, (int)zlevel, errp->message);
+ g_error_free(errp);
+ }
+ pd_gfsm_automaton_obj_outlet_symbol_float(x, gensym("save_bin"), s, (int)zlevel);
+}
+
+
+/*=====================================================================
+ * automaton_obj: info
+ */
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: info()
+ */
+static void pd_gfsm_automaton_obj_info(t_pd_gfsm_automaton_obj *x)
+{
+ gfsmAutomaton *fsm = x->x_automaton_pd->x_automaton;
+ guint n_eps_i, n_eps_o, n_eps_io;
+
+#define bool2char(b) ((b) ? 'y' : 'n')
+
+ post("-- GFSM Automaton Info --");
+ post("%-24s: %s", "Name", x->x_automaton_pd->x_name->s_name);
+ post("%-24s: %s", "Semiring", gfsm_sr_type_to_name(fsm->sr->type));
+ post("%-24s: %c", "Transducer?", bool2char(gfsm_automaton_is_transducer(fsm)));
+ post("%-24s: %c", "Weighted?", bool2char(gfsm_automaton_is_weighted(fsm)));
+ post("%-24s: %c", "Deterministic?", bool2char(fsm->flags.is_deterministic));
+ post("%-24s: %s", "Sort Mode", gfsm_arc_sortmode_to_name(gfsm_automaton_sortmode(fsm)));
+ if (fsm->root_id == gfsmNoState)
+ post("%-24s: %s", "Initial state", "(none)");
+ else
+ post("%-24s: %u", "Initial state", fsm->root_id);
+ post("%-24s: %u", "# of states", gfsm_automaton_n_states(fsm));
+ post("%-24s: %u", "# of final states", gfsm_automaton_n_final_states(fsm));
+ post("%-24s: %u", "# of arcs", gfsm_automaton_n_arcs_full(fsm, &n_eps_i, &n_eps_o, &n_eps_io));
+ post("%-24s: %u", "# of i/o epsilon arcs", n_eps_io);
+ post("%-24s: %u", "# of input epsilon arcs", n_eps_i);
+ post("%-24s: %u", "# of output epsilon arcs", n_eps_o);
+ post("%-24s: %c", "cyclic?", bool2char(gfsm_automaton_is_cyclic(fsm)));
+ //...
+
+#undef bool2char
+
+ pd_gfsm_automaton_obj_outlet_bang(x, gensym("info"));
+}
+
+
+/*=====================================================================
+ * automaton_obj: draw
+ */
+
+/*--------------------------------------------------------------------
+ * automaton_obj: draw_dot()
+ */
+static void pd_gfsm_automaton_obj_draw_dot(t_pd_gfsm_automaton_obj *x, GIMME_ARGS)
+{
+ t_pd_gfsm_alphabet_pd *ialph=NULL, *oalph=NULL, *salph=NULL;
+ t_symbol
+ *filename = atom_getsymbolarg(0,argc,argv),
+ *title = x->x_automaton_pd->x_name,
+ *fontname = NULL;
+ float
+ width=0,
+ height=0,
+ nodesep=0,
+ ranksep=0;
+ int fontsize=0;
+ gboolean
+ portrait=FALSE,
+ vertical=FALSE;
+ gfsmError *errp = NULL;
+ int i;
+
+ for (i=1; i < argc; i++) {
+ t_symbol *opt = atom_getsymbolarg(i,argc,argv);
+
+ //--debug
+ //post("gfsm_automaton: draw_dot: checking option '%s'", opt->s_name);
+
+ if (opt==gensym("ilabels")) {
+ if (ialph) pd_gfsm_alphabet_pd_release(ialph);
+ ialph = pd_gfsm_alphabet_pd_find(atom_getsymbolarg(++i,argc,argv));
+ if (ialph) ialph->x_refcnt++;
+ }
+ else if (opt==gensym("olabels")) {
+ if (oalph) pd_gfsm_alphabet_pd_release(oalph);
+ oalph = pd_gfsm_alphabet_pd_find(atom_getsymbolarg(++i,argc,argv));
+ if (oalph) oalph->x_refcnt++;
+ }
+ else if (opt==gensym("slabels")) {
+ if (salph) pd_gfsm_alphabet_pd_release(salph);
+ salph = pd_gfsm_alphabet_pd_find(atom_getsymbolarg(++i,argc,argv));
+ if (salph) salph->x_refcnt++;
+ }
+ else if (opt==gensym("title")) title = atom_getsymbolarg(++i,argc,argv);
+ else if (opt==gensym("width")) width = atom_getfloatarg(++i,argc,argv);
+ else if (opt==gensym("height")) height = atom_getfloatarg(++i,argc,argv);
+ else if (opt==gensym("fontsize")) fontsize = atom_getintarg(++i,argc,argv);
+ else if (opt==gensym("fontname")) fontname = atom_getsymbolarg(++i,argc,argv);
+ else if (opt==gensym("portrait")) portrait = atom_getboolarg(++i,argc,argv);
+ else if (opt==gensym("vertical")) vertical = atom_getboolarg(++i,argc,argv);
+ else if (opt==gensym("nodesep")) nodesep = atom_getfloatarg(++i,argc,argv);
+ else if (opt==gensym("ranksep")) ranksep = atom_getfloatarg(++i,argc,argv);
+ else {
+ char buf[64];
+ atom_string(argv+i, buf, 64);
+ error("gfsm_automaton: draw_dot: unknown option '%s' ignored", buf);
+ }
+ }
+
+ gfsm_automaton_draw_dot_filename_full(x->x_automaton_pd->x_automaton,
+ filename->s_name,
+ (ialph ? ialph->x_alphabet : NULL),
+ (oalph ? oalph->x_alphabet : NULL),
+ (salph ? salph->x_alphabet : NULL),
+ title->s_name,
+ width,
+ height,
+ fontsize,
+ (fontname ? fontname->s_name : NULL),
+ portrait,
+ vertical,
+ nodesep,
+ ranksep,
+ &errp);
+
+ if (errp) {
+ error("gfsm_automaton: draw_dot(%s): Error: %s\n", filename->s_name, errp->message);
+ g_error_free(errp);
+ }
+
+ //-- cleanup
+ if (ialph) pd_gfsm_alphabet_pd_release(ialph);
+ if (oalph) pd_gfsm_alphabet_pd_release(oalph);
+ if (salph) pd_gfsm_alphabet_pd_release(salph);
+
+ pd_gfsm_automaton_obj_outlet_symbol(x, gensym("draw_dot"), filename);
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton_obj: setup()
+ */
+static void pd_gfsm_automaton_obj_setup(void)
+{
+ //-- class
+ pd_gfsm_automaton_obj_class = class_new(gensym("gfsm_automaton"),
+ (t_newmethod)pd_gfsm_automaton_obj_new,
+ (t_method)pd_gfsm_automaton_obj_free,
+ sizeof(t_pd_gfsm_automaton_obj),
+ CLASS_DEFAULT,
+ A_DEFSYM,
+ A_NULL);
+
+ //-- methods: automaton
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_automaton,
+ gensym("automaton"),
+ A_DEFSYM, A_NULL);
+
+ //-- methods: flags
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_root,
+ gensym("root"),
+ A_GIMME, A_NULL);
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_weighted,
+ gensym("weighted"),
+ A_GIMME, A_NULL);
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_transducer,
+ gensym("transducer"),
+ A_GIMME, A_NULL);
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_semiring,
+ gensym("semiring"),
+ A_GIMME, A_NULL);
+
+ //-- methods: size
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_size,
+ gensym("size"),
+ A_GIMME, A_NULL);
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_clear,
+ gensym("clear"),
+ A_NULL);
+
+ //-- methods: state properties
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_final,
+ gensym("final"),
+ A_GIMME, A_NULL);
+
+ //-- methods: states & arcs
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_add_state,
+ gensym("add_state"),
+ A_GIMME, A_NULL);
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_add_arc,
+ gensym("add_arc"),
+ A_GIMME, //-- qsrc,qdst,clo,chi,weight
+ A_NULL);
+
+
+ //-- methods: I/O: text
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_print,
+ gensym("print"),
+ A_NULL);
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_load_txt,
+ gensym("load"),
+ A_SYMBOL, A_NULL);
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_save_txt,
+ gensym("save"),
+ A_SYMBOL, A_NULL);
+
+ //-- methods: I/O: binary
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_load_bin,
+ gensym("load_bin"),
+ A_SYMBOL, A_NULL);
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_save_bin,
+ gensym("save_bin"),
+ A_SYMBOL, A_DEFFLOAT, A_NULL);
+
+ //-- methods: info
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_info,
+ gensym("info"),
+ A_NULL);
+
+ //-- methods: draw
+ class_addmethod(pd_gfsm_automaton_obj_class,
+ (t_method)pd_gfsm_automaton_obj_draw_dot,
+ gensym("draw_dot"),
+ A_GIMME, A_NULL);
+
+ //-- help symbol
+ class_sethelpsymbol(pd_gfsm_automaton_obj_class, gensym("gfsm_automaton-help.pd"));
+}
+
+
+/*=====================================================================
+ * automaton setup
+ *=====================================================================*/
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_automaton: setup()
+ */
+void pd_gfsm_automaton_setup(void)
+{
+ pd_gfsm_automaton_pd_setup();
+ pd_gfsm_automaton_obj_setup();
+ pd_gfsm_algebra_setup(pd_gfsm_automaton_obj_class);
+}
diff --git a/gfsm/src/pd_automaton.h b/gfsm/src/pd_automaton.h
new file mode 100644
index 0000000..ed95954
--- /dev/null
+++ b/gfsm/src/pd_automaton.h
@@ -0,0 +1,85 @@
+/*=============================================================================*\
+ * File: pd_automaton.h
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+/*=====================================================================
+ * Protos
+ *=====================================================================*/
+#ifndef PD_GFSM_AUTOMATON_H
+#define PD_GFSM_AUTOMATON_H
+
+/*----------------------------------------------------------------------
+ * includes
+ */
+#include <m_pd.h>
+#include <gfsm.h>
+#include <pd_alphabet.h>
+
+/*--------------------------------------------------------------
+ * pd_fsm_automaton_pd
+ */
+typedef struct _pd_gfsm_automaton_pd
+{
+ t_pd x_pd;
+ t_symbol *x_name;
+ size_t x_refcnt;
+ gfsmAutomaton *x_automaton;
+} t_pd_gfsm_automaton_pd;
+
+typedef struct _pd_gfsm_automaton_obj
+{
+ t_object x_obj;
+ t_pd_gfsm_automaton_pd *x_automaton_pd;
+ t_atom x_argv[5];
+ t_outlet *x_valout;
+} t_pd_gfsm_automaton_obj;
+
+/*--------------------------------------------------------------------
+ * utility macros
+ */
+#define atom_getboolarg(which,argc,argv) (atom_getintarg(which,argc,argv)==0 ? FALSE : TRUE)
+#define GIMME_ARGS t_symbol *sel, int argc, t_atom *argv
+
+/*----------------------------------------------------------------------
+ * utilities
+ */
+t_pd_gfsm_automaton_pd *pd_gfsm_automaton_pd_find(t_symbol *name);
+t_pd_gfsm_automaton_pd *pd_gfsm_automaton_pd_get(t_symbol *name);
+void pd_gfsm_automaton_pd_release(t_pd_gfsm_automaton_pd *x);
+
+void pd_gfsm_automaton_obj_outlet_symbol(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_symbol *val);
+void pd_gfsm_automaton_obj_outlet_float(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_float f);
+void pd_gfsm_automaton_obj_outlet_float_2(t_pd_gfsm_automaton_obj *x, t_symbol *sel, t_float f1, t_float f2);
+void pd_gfsm_automaton_obj_outlet_bang(t_pd_gfsm_automaton_obj *x, t_symbol *sel);
+
+/*----------------------------------------------------------------------
+ * setup routines
+ */
+extern void pd_gfsm_algebra_setup(t_class *automaton_class);
+
+void pd_gfsm_automaton_setup(void);
+
+#endif /* PD_GFSM_AUTOMATON_H */
diff --git a/gfsm/src/pd_gfsm.c b/gfsm/src/pd_gfsm.c
new file mode 100644
index 0000000..2deb6c8
--- /dev/null
+++ b/gfsm/src/pd_gfsm.c
@@ -0,0 +1,93 @@
+/*=============================================================================*\
+ * File: pd_gfsm.c
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <pd_gfsm.h>
+#include <pd_alphabet.h>
+
+#define USE_AUTOMATA
+
+#ifdef USE_AUTOMATA
+# include <pd_automaton.h>
+# include <pd_state.h>
+#endif
+
+/*=====================================================================
+ * Structures and Types
+ *=====================================================================*/
+static t_class *pd_gfsm_dummy_class;
+
+/*=====================================================================
+ * pd_gfsm_dummy
+ *=====================================================================*/
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_dummy: new()
+ */
+static void *pd_gfsm_dummy_new(void)
+{
+ t_pd_gfsm_dummy *x = (t_pd_gfsm_dummy *)pd_new(pd_gfsm_dummy_class);
+ return (void *)x;
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_dummy: free()
+ */
+static void pd_gfsm_dummy_free(t_pd_gfsm_dummy *x)
+{}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_dummy: setup()
+ */
+void gfsm_setup(void)
+{
+ //-- banner
+ post("");
+ post("gfsm: finite state machine externals v%s by Bryan Jurish", PACKAGE_VERSION);
+ //post("fsm: based on code by Helmut Schmid");
+
+ //-- library
+ pd_gfsm_alphabet_setup();
+#ifdef USE_AUTOMATA
+ pd_gfsm_automaton_setup();
+ pd_gfsm_state_setup();
+#endif
+
+ //-- class (dummy)
+ pd_gfsm_dummy_class = class_new(gensym("gfsm"),
+ (t_newmethod)pd_gfsm_dummy_new,
+ (t_method)pd_gfsm_dummy_free,
+ sizeof(t_pd_gfsm_dummy),
+ CLASS_DEFAULT,
+ A_NULL);
+
+ //-- help symbol
+ class_sethelpsymbol(pd_gfsm_dummy_class, gensym("gfsm-help.pd"));
+}
diff --git a/gfsm/src/pd_gfsm.h b/gfsm/src/pd_gfsm.h
new file mode 100644
index 0000000..e65069e
--- /dev/null
+++ b/gfsm/src/pd_gfsm.h
@@ -0,0 +1,54 @@
+/*=============================================================================*\
+ * File: pd_gfsm.h
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+/*=====================================================================
+ * Protos
+ *=====================================================================*/
+#ifndef PD_GFSM_H
+#define PD_GFSM_H
+
+/*----------------------------------------------------------------------
+ * includes
+ */
+#include <m_pd.h>
+#include <gfsm.h>
+
+/*----------------------------------------------------------------------
+ * structures and types
+ */
+typedef struct _pd_gfsm_dummy
+{
+ t_object x_obj;
+} t_pd_gfsm_dummy;
+
+
+/*----------------------------------------------------------------------
+ * setup routines
+ */
+void gfsm_setup(void);
+
+#endif /* PD_GFSM_H */
diff --git a/gfsm/src/pd_io.c b/gfsm/src/pd_io.c
new file mode 100644
index 0000000..5f82c2c
--- /dev/null
+++ b/gfsm/src/pd_io.c
@@ -0,0 +1,75 @@
+/*=============================================================================*\
+ * File: pd_io.c
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd: I/O
+ *
+ * Copyright (c) 2006 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <pd_io.h>
+
+/*=====================================================================
+ * I/O utilities
+ *=====================================================================*/
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_console_handle_flush()
+ */
+static void pd_gfsm_console_handle_flush(gfsmPosGString *pgs)
+{
+ if (pgs->gs->len) post(pgs->gs->str);
+ g_string_truncate(pgs->gs,0);
+ pgs->pos = 0;
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_console_handle_new()
+ */
+gfsmIOHandle *pd_gfsm_console_handle_new(void)
+{
+ GString *gs = g_string_new("");
+ gfsmPosGString *pgs = g_new(gfsmPosGString,1);
+ gfsmIOHandle *ioh;
+ pgs->gs = gs;
+ pgs->pos = 0;
+
+ ioh = gfsmio_new_gstring(pgs);
+ ioh->flush_func = (gfsmIOFlushFunc)pd_gfsm_console_handle_flush;
+
+ return ioh;
+}
+
+/*--------------------------------------------------------------------
+ * pd_gfsm_console_handle_free()
+ */
+void pd_gfsm_console_handle_free(gfsmIOHandle *ioh)
+{
+ gfsmPosGString *pgs = (gfsmPosGString*)ioh->handle;
+ gfsmio_flush(ioh);
+ g_string_free(pgs->gs,TRUE);
+ g_free(pgs);
+ g_free(ioh);
+}
diff --git a/gfsm/src/pd_io.h b/gfsm/src/pd_io.h
new file mode 100644
index 0000000..83de85b
--- /dev/null
+++ b/gfsm/src/pd_io.h
@@ -0,0 +1,47 @@
+/*=============================================================================*\
+ * File: pd_io.h
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd; I/O
+ *
+ * Copyright (c) 2006 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+/*=====================================================================
+ * Protos
+ *=====================================================================*/
+#ifndef PD_GFSM_IO_H
+#define PD_GFSM_IO_H
+
+/*----------------------------------------------------------------------
+ * includes
+ */
+#include <m_pd.h>
+#include <gfsm.h>
+
+/*----------------------------------------------------------------------
+ * I/O stuff
+ */
+gfsmIOHandle *pd_gfsm_console_handle_new(void);
+
+void pd_gfsm_console_handle_free(gfsmIOHandle *ioh);
+
+#endif /* PD_GFSM_IO_H */
diff --git a/gfsm/src/pd_state.c b/gfsm/src/pd_state.c
new file mode 100644
index 0000000..b7cd938
--- /dev/null
+++ b/gfsm/src/pd_state.c
@@ -0,0 +1,303 @@
+/*=============================================================================*\
+ * File: pd_state.c
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <pd_state.h>
+
+/*=====================================================================
+ * Structures and Types
+ *=====================================================================*/
+static t_class *pd_gfsm_state_class;
+
+
+/*=====================================================================
+ * pd_gfsm_state: Methods
+ *=====================================================================*/
+
+/*=====================================================================
+ * Constructors, etc.
+ */
+
+/*--------------------------------------------------------------------
+ * new()
+ */
+static void *pd_gfsm_state_new(t_symbol *sel, int argc, t_atom *argv)
+{
+ t_symbol *name = &s_;
+ t_pd_gfsm_state *x = (t_pd_gfsm_state *)pd_new(pd_gfsm_state_class);
+
+ //-- defaults
+ x->x_id = gfsmNoState;
+ gfsm_arciter_close(&x->x_arci);
+ x->x_open = FALSE;
+
+ //-- args
+ if (argc > 0) {
+ name = atom_getsymbolarg(0,argc,argv);
+ if (argc > 1) x->x_id = (gfsmStateId)atom_getfloatarg(1,argc,argv);
+ }
+
+ //-- bindings
+ x->x_automaton_pd = pd_gfsm_automaton_pd_get(name);
+ x->x_automaton_pd->x_refcnt++;
+
+ //-- outlets
+ x->x_valout = outlet_new(&x->x_obj, &s_anything); //-- value outlet
+
+ return (void *)x;
+}
+
+/*--------------------------------------------------------------------
+ * free
+ */
+static void pd_gfsm_state_free(t_pd_gfsm_state *x)
+{
+ gfsm_arciter_close(&x->x_arci);
+ pd_gfsm_automaton_pd_release(x->x_automaton_pd);
+
+ //-- do we need to do this?
+ outlet_free(x->x_valout);
+}
+
+/*=====================================================================
+ * Basic Accessors
+ */
+
+/*--------------------------------------------------------------------
+ * automaton
+ */
+static void pd_gfsm_state_automaton(t_pd_gfsm_state *x, t_symbol *name)
+{
+ gfsm_arciter_close(&x->x_arci);
+ x->x_open = FALSE;
+
+ if (name == x->x_automaton_pd->x_name) return;
+ pd_gfsm_automaton_pd_release(x->x_automaton_pd);
+
+ x->x_automaton_pd = pd_gfsm_automaton_pd_get(name);
+ ++x->x_automaton_pd->x_refcnt;
+}
+
+
+/*--------------------------------------------------------------------
+ * id
+ */
+static void pd_gfsm_state_id(t_pd_gfsm_state *x)
+{
+ SETSYMBOL(x->x_argv, gensym("id"));
+ if (x->x_id==gfsmNoState) SETSYMBOL(x->x_argv, &s_bang);
+ else SETFLOAT(x->x_argv, (t_float)(x->x_id));
+ outlet_anything(x->x_valout, gensym("id"), 1, x->x_argv);
+}
+
+/*--------------------------------------------------------------------
+ * set
+ */
+static void pd_gfsm_state_set(t_pd_gfsm_state *x, t_floatarg qf)
+{
+ if (qf<0) qf = -qf;
+ gfsm_arciter_close(&x->x_arci);
+ x->x_open = FALSE;
+ x->x_id = gfsm_automaton_ensure_state(x->x_automaton_pd->x_automaton, (gfsmStateId)qf);
+}
+
+/*--------------------------------------------------------------------
+ * degree
+ */
+static void pd_gfsm_state_degree(t_pd_gfsm_state *x)
+{
+ gfsmState *s = gfsm_automaton_find_state(x->x_automaton_pd->x_automaton, x->x_id);
+ SETFLOAT(x->x_argv, (s ? (t_float)gfsm_state_out_degree(s) : 0));
+ outlet_anything(x->x_valout, gensym("degree"), 1, x->x_argv);
+}
+
+/*=====================================================================
+ * Navigation
+ */
+
+/*--------------------------------------------------------------------
+ * utility: outlet_arc()
+ */
+static void pd_gfsm_state_outlet_arc(t_pd_gfsm_state *x, t_symbol *sel)
+{
+ //outlet_anything(x->x_opout, op, 0, NULL);
+ if (gfsm_arciter_ok(&x->x_arci)) {
+ gfsmArc *a = gfsm_arciter_arc(&x->x_arci);
+ SETFLOAT(x->x_argv, (t_float)(a->target));
+ SETFLOAT(x->x_argv+1, (t_float)(a->lower));
+ SETFLOAT(x->x_argv+2, (t_float)(a->upper));
+ SETFLOAT(x->x_argv+3, (t_float)(a->weight));
+ outlet_anything(x->x_valout, sel, 4, x->x_argv);
+ }
+ else {
+ SETSYMBOL(x->x_argv, &s_bang);
+ outlet_anything(x->x_valout, sel, 1, x->x_argv);
+ }
+}
+
+/*--------------------------------------------------------------------
+ * arc_first
+ */
+static void pd_gfsm_state_arc_first(t_pd_gfsm_state *x)
+{
+ gfsm_arciter_close(&x->x_arci);
+ gfsm_arciter_open(&x->x_arci, x->x_automaton_pd->x_automaton, x->x_id);
+ x->x_open = TRUE;
+ pd_gfsm_state_outlet_arc(x, gensym("arc_first"));
+}
+
+/*--------------------------------------------------------------------
+ * arc_next
+ */
+static void pd_gfsm_state_arc_next(t_pd_gfsm_state *x)
+{
+ gfsmState *s = gfsm_automaton_find_state(x->x_automaton_pd->x_automaton, x->x_id);
+ if (s) {
+ if (x->x_open && gfsm_arciter_ok(&x->x_arci)) {
+ gfsm_arciter_next(&x->x_arci);
+ } else if (!x->x_open) {
+ gfsm_arciter_open(&x->x_arci, x->x_automaton_pd->x_automaton, x->x_id);
+ x->x_open = TRUE;
+ }
+ }
+ pd_gfsm_state_outlet_arc(x, gensym("arc_next"));
+}
+
+/*--------------------------------------------------------------------
+ * arc_seek
+ */
+static void pd_gfsm_state_arc_seek(t_pd_gfsm_state *x, t_float flo, t_float fhi)
+{
+ gfsmState *s = gfsm_automaton_find_state(x->x_automaton_pd->x_automaton, x->x_id);
+ if (s) {
+ if (x->x_open && gfsm_arciter_ok(&x->x_arci)) {
+ gfsm_arciter_next(&x->x_arci);
+ } else if (!x->x_open) {
+ gfsm_arciter_open(&x->x_arci, x->x_automaton_pd->x_automaton, x->x_id);
+ x->x_open = TRUE;
+ }
+ }
+ gfsm_arciter_seek_both(&x->x_arci,
+ (flo < 0 ? gfsmNoLabel : ((gfsmLabelVal)flo)),
+ (fhi < 0 ? gfsmNoLabel : ((gfsmLabelVal)fhi)));
+ pd_gfsm_state_outlet_arc(x, gensym("arc_seek"));
+}
+
+
+/*--------------------------------------------------------------------
+ * arc_reset
+ */
+static void pd_gfsm_state_arc_reset(t_pd_gfsm_state *x)
+{
+ gfsm_arciter_close(&x->x_arci);
+ x->x_open = FALSE;
+}
+
+/*--------------------------------------------------------------------
+ * add_weight
+ */
+static void pd_gfsm_state_add_weight(t_pd_gfsm_state *x,
+ t_float fto,
+ t_float flo,
+ t_float fhi,
+ t_float w)
+{
+ gfsmStateId to = (fto < 0 ? (-fto) : ((gfsmStateId)fto));
+ gfsmLabelVal lo = (flo < 0 ? gfsmNoLabel : ((gfsmLabelVal)flo));
+ gfsmLabelVal hi = (fhi < 0 ? gfsmNoLabel : ((gfsmLabelVal)fhi));
+
+ if (x->x_open) pd_gfsm_state_arc_reset(x);
+
+ gfsm_arciter_open(&x->x_arci, x->x_automaton_pd->x_automaton, x->x_id);
+ gfsm_arciter_seek_both(&x->x_arci, lo, hi);
+
+ if (gfsm_arciter_ok(&x->x_arci)) {
+ gfsm_arciter_arc(&x->x_arci)->weight += w;
+ } else {
+ if (lo==gfsmNoLabel) lo = gfsmEpsilon;
+ if (hi==gfsmNoLabel) hi = gfsmEpsilon;
+ gfsm_automaton_add_arc(x->x_automaton_pd->x_automaton, x->x_id, to, lo, hi, w);
+ }
+
+ pd_gfsm_state_arc_reset(x);
+}
+
+
+
+/*=====================================================================
+ * Setup
+ */
+
+/*--------------------------------------------------------------------
+ * setup()
+ */
+void pd_gfsm_state_setup(void)
+{
+ //-- class
+ pd_gfsm_state_class = class_new(gensym("gfsm_state"),
+ (t_newmethod)pd_gfsm_state_new,
+ (t_method)pd_gfsm_state_free,
+ sizeof(t_pd_gfsm_state),
+ CLASS_DEFAULT,
+ A_GIMME, A_NULL);
+
+ //-- methods: automaton
+ class_addmethod(pd_gfsm_state_class,
+ (t_method)pd_gfsm_state_automaton,
+ gensym("automaton"),
+ A_DEFSYM, A_NULL);
+
+ //-- methods: id
+ class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_id,
+ gensym("id"), A_NULL);
+ class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_set,
+ gensym("set"), A_DEFFLOAT, A_NULL);
+
+ //-- methods: degree
+ class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_degree,
+ gensym("degree"), A_NULL);
+
+ //-- methods: navigation
+ class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_arc_first,
+ gensym("arc_first"), A_NULL);
+ class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_arc_next,
+ gensym("arc_next"), A_NULL);
+ class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_arc_seek,
+ gensym("arc_seek"), A_FLOAT, A_FLOAT, A_NULL);
+ class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_arc_reset,
+ gensym("arc_reset"), A_NULL);
+
+ //-- methods: manipulation
+ class_addmethod(pd_gfsm_state_class, (t_method)pd_gfsm_state_add_weight,
+ gensym("add_weight"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);
+
+ //-- help symbol
+ class_sethelpsymbol(pd_gfsm_state_class, gensym("gfsm_state-help.pd"));
+}
diff --git a/gfsm/src/pd_state.h b/gfsm/src/pd_state.h
new file mode 100644
index 0000000..b2e7576
--- /dev/null
+++ b/gfsm/src/pd_state.h
@@ -0,0 +1,58 @@
+/*=============================================================================*\
+ * File: pd_state.h
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: finite state automata for Pd
+ *
+ * Copyright (c) 2004 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+/*=====================================================================
+ * Protos
+ *=====================================================================*/
+#ifndef PD_GFSM_STATE_H
+#define PD_GFSM_STATE_H
+
+/*----------------------------------------------------------------------
+ * includes
+ */
+#include <pd_automaton.h>
+
+/*--------------------------------------------------------------
+ * pd_fsm_automaton_pd
+ */
+typedef struct _pd_gfsm_state
+{
+ t_object x_obj;
+ t_pd_gfsm_automaton_pd *x_automaton_pd;
+ gfsmStateId x_id;
+ gfsmArcIter x_arci;
+ gboolean x_open;
+ t_atom x_argv[4];
+ t_outlet *x_valout;
+} t_pd_gfsm_state;
+
+/*----------------------------------------------------------------------
+ * setup routines
+ */
+void pd_gfsm_state_setup(void);
+
+#endif /* PD_GFSM_STATE_H */
diff --git a/gfsm/src/test-alphabet.pd b/gfsm/src/test-alphabet.pd
new file mode 100644
index 0000000..4434b96
--- /dev/null
+++ b/gfsm/src/test-alphabet.pd
@@ -0,0 +1,3 @@
+#N canvas 0 0 450 300 10;
+#X obj 366 21 fsm;
+#X obj 130 127 fsm_alphabet;
diff --git a/gfsm/src/test-alphabet2.pd b/gfsm/src/test-alphabet2.pd
new file mode 100644
index 0000000..04e5928
--- /dev/null
+++ b/gfsm/src/test-alphabet2.pd
@@ -0,0 +1,44 @@
+#N canvas 484 16 460 391 10;
+#X obj 33 324 print LEFT;
+#X obj 112 324 print RIGHT;
+#X msg 24 13 alphabet foo;
+#X msg 30 37 alphabet;
+#X msg 132 7 insert x;
+#X msg 136 29 insert life 42;
+#X msg 201 79 atom2char x;
+#X msg 218 135 char2atom 42;
+#X msg 262 246 clear;
+#X msg 204 100 a2c life;
+#X msg 219 154 c2a 1;
+#X msg 262 274 print;
+#X floatatom 316 171 8 0 0 0 - - -;
+#X msg 317 191 insert z \$1;
+#X msg 405 190 c2a \$1;
+#X floatatom 408 171 5 0 0 0 - - -;
+#X msg 325 95 a2c \$1;
+#X msg 321 42 x;
+#X msg 349 42 life;
+#X msg 385 41 z;
+#X obj 324 73 symbol;
+#X obj 33 302 gfsm_alphabet foo;
+#X connect 2 0 21 0;
+#X connect 3 0 21 0;
+#X connect 4 0 21 0;
+#X connect 5 0 21 0;
+#X connect 6 0 21 0;
+#X connect 7 0 21 0;
+#X connect 8 0 21 0;
+#X connect 9 0 21 0;
+#X connect 10 0 21 0;
+#X connect 11 0 21 0;
+#X connect 12 0 13 0;
+#X connect 13 0 21 0;
+#X connect 14 0 21 0;
+#X connect 15 0 14 0;
+#X connect 16 0 21 0;
+#X connect 17 0 20 0;
+#X connect 18 0 20 0;
+#X connect 19 0 20 0;
+#X connect 20 0 16 0;
+#X connect 21 0 0 0;
+#X connect 21 1 1 0;
diff --git a/gfsm/src/test-automaton.pd b/gfsm/src/test-automaton.pd
new file mode 100644
index 0000000..6cdf837
--- /dev/null
+++ b/gfsm/src/test-automaton.pd
@@ -0,0 +1,260 @@
+#N canvas 31 7 974 447 10;
+#X obj 13 7 gfsm;
+#X obj 22 324 gfsm_automaton;
+#X obj 22 359 print GFSM-1;
+#X msg 26 70 automaton;
+#X msg 24 29 automaton a1;
+#X obj 16 91 s \$0-fsm;
+#X obj 23 300 r \$0-fsm;
+#X msg 153 75 size;
+#X floatatom 237 34 5 0 0 0 - - -;
+#X obj 237 16 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 144 34 5 0 0 0 - - -;
+#X msg 257 15 0;
+#X msg 145 13 42;
+#X floatatom 375 18 5 0 0 0 - - -;
+#X msg 347 17 0;
+#X floatatom 388 61 5 0 0 0 - - -;
+#X floatatom 517 34 5 0 0 0 - - -;
+#X floatatom 560 33 5 0 0 0 - - -;
+#X floatatom 603 33 5 0 0 0 - - -;
+#X floatatom 644 34 5 0 0 0 - - -;
+#X obj 543 59 pack 0 0 0 0 0;
+#X obj 494 24 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 494 57 t b b;
+#X msg 569 7 0;
+#X msg 495 105 add_arc \$1 \$2 \$3 \$4 \$5;
+#X obj 144 98 s \$0-fsm;
+#X obj 237 97 s \$0-fsm;
+#X obj 349 121 s \$0-fsm;
+#X obj 496 126 s \$0-fsm;
+#X msg 104 148 load test.tfst;
+#X msg 103 188 save tmp.tfst;
+#X msg 229 148 load_bin test.gfst;
+#X msg 250 304 save_bin tmp.gfst;
+#X msg 26 202 print;
+#X msg 22 179 clear;
+#X msg 18 158 info;
+#X obj 17 226 s \$0-fsm;
+#X obj 88 246 s \$0-fsm;
+#X obj 236 338 s \$0-fsm;
+#X msg 437 170 complement;
+#X msg 450 211 closure \$1;
+#X floatatom 466 193 5 0 0 0 - - -;
+#X obj 437 370 s \$0-fsm;
+#X obj 16 132 bng 20 250 50 0 \$0-draw-s empty DRAW 0 -6 0 8 -24198
+-1 -1;
+#X obj 450 193 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 457 236 compose a2;
+#X msg 462 264 concat a2;
+#X obj 51 6 zexy;
+#X obj 495 84 lister;
+#X msg 25 48 automaton a2;
+#X msg 464 291 determinize;
+#X msg 469 319 difference a2;
+#X msg 475 343 intersect a2;
+#X obj 603 368 s \$0-fsm;
+#X msg 598 148 invert;
+#X msg 607 174 product a2;
+#X msg 621 217 project \$1;
+#X floatatom 638 196 5 0 0 0 - - -;
+#X obj 619 198 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 631 269 reverse;
+#X msg 631 296 rmepsilon;
+#X msg 634 320 union a2;
+#X msg 103 168 load test2.tfst;
+#X msg 233 169 load_bin test2.gfst;
+#X msg 238 190 load_bin test3.gfst;
+#X obj 46 131 tgl 20 0 \$0-drawmode-s empty mode 0 -6 0 8 -225271 -1
+-1 0 1;
+#X msg 246 74 root;
+#X msg 237 51 root \$1;
+#X floatatom 618 8 5 0 0 0 - - -;
+#X msg 144 52 size \$1;
+#X msg 349 37 final \$1;
+#X obj 430 61 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 365 79 pack 0 0;
+#X msg 363 99 final \$1 \$2;
+#X msg 637 343 renumber;
+#X msg 252 282 load_bin tmp.gfst;
+#N canvas 0 0 450 300 flags 0;
+#X obj 26 67 s \$0-fsm;
+#X msg 36 21 weighted \$1;
+#X obj 19 21 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X msg 39 43 weighted;
+#X obj 145 19 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 155 65 s \$0-fsm;
+#X msg 162 19 transducer \$1;
+#X msg 165 41 transducer;
+#X obj 30 220 s \$0-fsm;
+#X msg 40 196 semiring;
+#X msg 30 174 semiring \$1;
+#X msg 29 125 boolean;
+#X msg 90 125 log;
+#X msg 122 126 real;
+#X msg 160 125 trivial;
+#X msg 218 125 tropical;
+#X obj 30 153 symbol;
+#X msg 286 125 OTHER;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 0 0;
+#X connect 4 0 6 0;
+#X connect 6 0 5 0;
+#X connect 7 0 5 0;
+#X connect 9 0 8 0;
+#X connect 10 0 8 0;
+#X connect 11 0 16 0;
+#X connect 12 0 16 0;
+#X connect 13 0 16 0;
+#X connect 14 0 16 0;
+#X connect 15 0 16 0;
+#X connect 16 0 10 0;
+#X connect 17 0 16 0;
+#X restore 711 65 pd flags;
+#X obj 600 8 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 361 336 concat a1;
+#X floatatom 689 35 5 0 0 0 - - -;
+#X obj 366 59 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 113 360 s \$0-fsm-out;
+#X obj 741 16 pool;
+#X msg 94 120 automaton fsm-help;
+#X msg 105 220 load gfsm-help.tfst;
+#N canvas 22 7 466 454 draw 0;
+#X obj 361 16 zexy;
+#X obj 26 15 r \$0-draw-s;
+#X obj 68 68 f \$0;
+#X obj 68 110 s \$0-fsm;
+#X obj 68 47 t b;
+#X obj 99 352 t b;
+#X obj 98 418 shell;
+#X obj 172 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 69 331 shell;
+#X obj 125 215 r \$0-drawmode-s;
+#X obj 67 238 demux 0 1;
+#X obj 240 214 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X msg 68 89 draw_dot \$1draw.dot;
+#X obj 67 136 r \$0-fsm-out;
+#X obj 67 158 route draw_dot;
+#X obj 67 180 symbol;
+#X msg 48 295 dotgv.sh \$1;
+#X msg 145 294 dotty \$1;
+#X obj 67 203 t s s;
+#X obj 98 372 symbol;
+#X msg 98 395 rm -f \$1;
+#X connect 1 0 4 0;
+#X connect 2 0 12 0;
+#X connect 4 0 2 0;
+#X connect 5 0 19 0;
+#X connect 7 0 4 0;
+#X connect 8 1 5 0;
+#X connect 9 0 10 1;
+#X connect 10 0 16 0;
+#X connect 10 1 17 0;
+#X connect 11 0 10 1;
+#X connect 12 0 3 0;
+#X connect 13 0 14 0;
+#X connect 14 0 15 0;
+#X connect 15 0 18 0;
+#X connect 16 0 8 0;
+#X connect 17 0 8 0;
+#X connect 18 0 10 0;
+#X connect 18 1 19 1;
+#X connect 19 0 20 0;
+#X connect 20 0 6 0;
+#X restore 16 251 pd draw;
+#X msg 258 216 load_bin lkptest.gfst;
+#X msg 261 238 load_bin lkpin.gfst;
+#X obj 21 385 gfsm_automaton a1;
+#X obj 22 404 gfsm_automaton a2;
+#X msg 626 245 connect;
+#X msg 739 352 clear;
+#X connect 1 0 2 0;
+#X connect 1 0 81 0;
+#X connect 3 0 5 0;
+#X connect 4 0 5 0;
+#X connect 6 0 1 0;
+#X connect 7 0 25 0;
+#X connect 8 0 67 0;
+#X connect 9 0 8 0;
+#X connect 10 0 69 0;
+#X connect 11 0 8 0;
+#X connect 12 0 10 0;
+#X connect 13 0 70 0;
+#X connect 14 0 13 0;
+#X connect 15 0 72 0;
+#X connect 16 0 20 0;
+#X connect 17 0 20 1;
+#X connect 18 0 20 2;
+#X connect 19 0 20 3;
+#X connect 20 0 48 1;
+#X connect 21 0 22 0;
+#X connect 22 0 48 0;
+#X connect 22 1 20 0;
+#X connect 23 0 16 0;
+#X connect 23 0 17 0;
+#X connect 23 0 18 0;
+#X connect 23 0 19 0;
+#X connect 24 0 28 0;
+#X connect 29 0 37 0;
+#X connect 30 0 37 0;
+#X connect 31 0 38 0;
+#X connect 32 0 38 0;
+#X connect 33 0 36 0;
+#X connect 34 0 36 0;
+#X connect 35 0 36 0;
+#X connect 39 0 42 0;
+#X connect 40 0 42 0;
+#X connect 41 0 40 0;
+#X connect 44 0 41 0;
+#X connect 45 0 42 0;
+#X connect 46 0 42 0;
+#X connect 48 0 24 0;
+#X connect 49 0 5 0;
+#X connect 50 0 42 0;
+#X connect 51 0 42 0;
+#X connect 52 0 42 0;
+#X connect 54 0 53 0;
+#X connect 55 0 53 0;
+#X connect 56 0 53 0;
+#X connect 57 0 56 0;
+#X connect 58 0 57 0;
+#X connect 59 0 53 0;
+#X connect 60 0 53 0;
+#X connect 61 0 53 0;
+#X connect 62 0 37 0;
+#X connect 63 0 38 0;
+#X connect 64 0 38 0;
+#X connect 66 0 26 0;
+#X connect 67 0 26 0;
+#X connect 68 0 17 0;
+#X connect 68 0 18 0;
+#X connect 68 0 19 0;
+#X connect 69 0 25 0;
+#X connect 70 0 27 0;
+#X connect 71 0 72 1;
+#X connect 72 0 73 0;
+#X connect 73 0 27 0;
+#X connect 74 0 53 0;
+#X connect 75 0 38 0;
+#X connect 77 0 68 0;
+#X connect 78 0 42 0;
+#X connect 79 0 20 4;
+#X connect 80 0 15 0;
+#X connect 83 0 5 0;
+#X connect 84 0 37 0;
+#X connect 86 0 38 0;
+#X connect 87 0 38 0;
+#X connect 90 0 53 0;
+#X connect 91 0 53 0;
diff --git a/gfsm/src/test-automaton2.pd b/gfsm/src/test-automaton2.pd
new file mode 100644
index 0000000..f503014
--- /dev/null
+++ b/gfsm/src/test-automaton2.pd
@@ -0,0 +1,196 @@
+#N canvas 110 261 845 398 10;
+#X obj 13 7 gfsm;
+#X obj 23 362 print GFSM-1;
+#X obj 116 362 print GFSM-2;
+#X obj 208 363 print GFSM-3;
+#X msg 26 70 automaton;
+#X msg 24 29 automaton a1;
+#X obj 16 91 s \$0-fsm;
+#X obj 93 294 r \$0-fsm;
+#X msg 153 75 size;
+#X floatatom 237 34 5 0 0 0 - - -;
+#X obj 237 16 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 237 51 set_root \$1;
+#X msg 246 74 get_root;
+#X msg 144 52 reserve \$1;
+#X floatatom 144 34 5 0 0 0 - - -;
+#X msg 257 15 0;
+#X msg 145 13 42;
+#X msg 349 37 is_final \$1;
+#X floatatom 375 18 5 0 0 0 - - -;
+#X msg 347 17 0;
+#X floatatom 388 61 5 0 0 0 - - -;
+#X msg 360 60 0;
+#X msg 363 80 set_final \$1 1;
+#X floatatom 517 34 5 0 0 0 - - -;
+#X floatatom 560 33 5 0 0 0 - - -;
+#X floatatom 603 33 5 0 0 0 - - -;
+#X floatatom 644 34 5 0 0 0 - - -;
+#X obj 543 59 pack 0 0 0 0 0;
+#X obj 494 24 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 494 57 t b b;
+#X msg 569 7 0;
+#X msg 495 105 add_arc \$1 \$2 \$3 \$4 \$5;
+#X obj 144 98 s \$0-fsm;
+#X obj 237 97 s \$0-fsm;
+#X obj 349 102 s \$0-fsm;
+#X obj 496 126 s \$0-fsm;
+#X msg 104 148 load test.tfst;
+#X msg 103 188 save tmp.tfst;
+#X msg 229 148 load_bin test.gfst;
+#X msg 234 232 save_bin tmp.gfst;
+#X msg 26 202 print;
+#X msg 22 179 clear;
+#X msg 18 158 info;
+#X obj 16 224 s \$0-fsm;
+#X obj 95 209 s \$0-fsm;
+#X obj 228 254 s \$0-fsm;
+#X msg 437 170 complement;
+#X msg 450 211 closure \$1;
+#X floatatom 466 193 5 0 0 0 - - -;
+#X obj 437 370 s \$0-fsm;
+#X obj 16 132 bng 20 250 50 0 \$0-draw-s empty DRAW 0 -6 0 8 -24198
+-1 -1;
+#X obj 450 193 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 457 236 compose a2;
+#X msg 462 264 concat a2;
+#X obj 51 6 zexy;
+#X obj 495 84 lister;
+#X msg 25 48 automaton a2;
+#X msg 464 291 determinize;
+#X msg 469 319 difference a2;
+#X msg 475 343 intersect a2;
+#X obj 603 368 s \$0-fsm;
+#X msg 603 165 invert;
+#X msg 612 191 product a2;
+#X msg 626 234 project \$1;
+#X floatatom 643 213 5 0 0 0 - - -;
+#X obj 624 215 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 631 262 prune;
+#X msg 636 286 reverse;
+#X msg 636 313 rmepsilon;
+#X msg 639 337 union a2;
+#X msg 103 168 load test2.tfst;
+#X msg 233 169 load_bin test2.gfst;
+#X obj 92 318 gfsm_automaton a2;
+#X msg 238 190 load_bin test3.gfst;
+#X floatatom 626 5 5 0 0 0 - - -;
+#N canvas 0 0 466 454 draw 0;
+#X obj 67 25 r \$0-draw-s;
+#X obj 68 68 f \$0;
+#X msg 176 74 save_bin \$1draw.gfst;
+#X obj 176 98 s \$0-fsm;
+#X obj 68 162 shell;
+#X obj 68 47 t b;
+#X obj 68 91 t f f;
+#X msg 69 237 dotgv.sh \$1draw.dot;
+#X obj 171 311 f \$0;
+#X obj 172 291 t b;
+#X obj 171 357 shell;
+#X obj 172 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 68 137 gfsmdraw \$1draw.gfst -F \$1draw.dot;
+#X msg 171 334 rm -f \$1draw.gfst \$1draw.dot;
+#X obj 142 270 shell;
+#X msg 220 236 dotty \$1draw.dot;
+#X obj 169 183 r \$0-drawmode-s;
+#X obj 111 206 demux 0 1;
+#X obj 110 163 t b;
+#X obj 111 184 f \$0;
+#X obj 284 182 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X connect 0 0 5 0;
+#X connect 1 0 6 0;
+#X connect 2 0 3 0;
+#X connect 4 1 18 0;
+#X connect 5 0 1 0;
+#X connect 6 0 12 0;
+#X connect 6 1 2 0;
+#X connect 7 0 14 0;
+#X connect 8 0 13 0;
+#X connect 9 0 8 0;
+#X connect 11 0 5 0;
+#X connect 12 0 4 0;
+#X connect 13 0 10 0;
+#X connect 14 1 9 0;
+#X connect 15 0 14 0;
+#X connect 16 0 17 1;
+#X connect 17 0 7 0;
+#X connect 17 1 15 0;
+#X connect 18 0 19 0;
+#X connect 19 0 17 0;
+#X connect 20 0 17 1;
+#X restore 71 118 pd draw;
+#X obj 44 130 tgl 20 0 \$0-drawmode-s empty mode 0 -6 0 8 -225271 -1
+-1 0 1;
+#X msg 152 120 automaton fsm-help-2;
+#X connect 4 0 6 0;
+#X connect 5 0 6 0;
+#X connect 7 0 72 0;
+#X connect 8 0 32 0;
+#X connect 9 0 11 0;
+#X connect 10 0 9 0;
+#X connect 11 0 33 0;
+#X connect 12 0 33 0;
+#X connect 13 0 32 0;
+#X connect 14 0 13 0;
+#X connect 15 0 9 0;
+#X connect 16 0 14 0;
+#X connect 17 0 34 0;
+#X connect 18 0 17 0;
+#X connect 19 0 18 0;
+#X connect 20 0 22 0;
+#X connect 21 0 20 0;
+#X connect 22 0 34 0;
+#X connect 23 0 27 0;
+#X connect 24 0 27 1;
+#X connect 25 0 27 2;
+#X connect 26 0 27 3;
+#X connect 27 0 55 1;
+#X connect 28 0 29 0;
+#X connect 29 0 55 0;
+#X connect 29 1 27 0;
+#X connect 30 0 23 0;
+#X connect 30 0 24 0;
+#X connect 30 0 25 0;
+#X connect 30 0 26 0;
+#X connect 31 0 35 0;
+#X connect 36 0 44 0;
+#X connect 37 0 44 0;
+#X connect 38 0 45 0;
+#X connect 39 0 45 0;
+#X connect 40 0 43 0;
+#X connect 41 0 43 0;
+#X connect 42 0 43 0;
+#X connect 46 0 49 0;
+#X connect 47 0 49 0;
+#X connect 48 0 47 0;
+#X connect 51 0 48 0;
+#X connect 52 0 49 0;
+#X connect 53 0 49 0;
+#X connect 55 0 31 0;
+#X connect 56 0 6 0;
+#X connect 57 0 49 0;
+#X connect 58 0 49 0;
+#X connect 59 0 49 0;
+#X connect 61 0 60 0;
+#X connect 62 0 60 0;
+#X connect 63 0 60 0;
+#X connect 64 0 63 0;
+#X connect 65 0 64 0;
+#X connect 66 0 60 0;
+#X connect 67 0 60 0;
+#X connect 68 0 60 0;
+#X connect 69 0 60 0;
+#X connect 70 0 44 0;
+#X connect 71 0 45 0;
+#X connect 72 0 1 0;
+#X connect 73 0 45 0;
+#X connect 74 0 24 0;
+#X connect 74 0 25 0;
+#X connect 74 0 26 0;
+#X connect 77 0 6 0;
diff --git a/gfsm/src/test-fsm.pd b/gfsm/src/test-fsm.pd
new file mode 100644
index 0000000..ed74881
--- /dev/null
+++ b/gfsm/src/test-fsm.pd
@@ -0,0 +1,2 @@
+#N canvas 0 0 450 300 10;
+#X obj 166 146 fsm;
diff --git a/gfsm/src/test-markov.pd b/gfsm/src/test-markov.pd
new file mode 100644
index 0000000..7ab52e8
--- /dev/null
+++ b/gfsm/src/test-markov.pd
@@ -0,0 +1,211 @@
+#N canvas 79 27 832 322 10;
+#X obj 21 23 bng 20 250 50 0 \$0-draw-s empty DRAW 0 -6 0 8 -24198
+-1 -1;
+#N canvas 0 0 466 454 draw 0;
+#X obj 361 16 zexy;
+#X obj 67 25 r \$0-draw-s;
+#X obj 68 68 f \$0;
+#X obj 67 177 shell;
+#X obj 68 47 t b;
+#X obj 68 91 t f f;
+#X msg 68 252 dotgv.sh \$1draw.dot;
+#X obj 170 326 f \$0;
+#X obj 171 306 t b;
+#X obj 170 372 shell;
+#X obj 172 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 170 349 rm -f \$1draw.gfst \$1draw.dot;
+#X obj 141 285 shell;
+#X msg 219 251 dotty \$1draw.dot;
+#X obj 168 198 r \$0-drawmode-s;
+#X obj 110 221 demux 0 1;
+#X obj 109 178 t b;
+#X obj 110 199 f \$0;
+#X obj 283 197 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 176 98 s \$0-markov;
+#X msg 176 74 save_bin \$1draw;
+#X msg 68 137 gfsmdraw -i \$1draw.lab -o \$1draw.lab \$1draw.gfst -F
+\$1draw.dot;
+#X connect 1 0 4 0;
+#X connect 2 0 5 0;
+#X connect 3 1 16 0;
+#X connect 4 0 2 0;
+#X connect 5 0 21 0;
+#X connect 5 1 20 0;
+#X connect 6 0 12 0;
+#X connect 7 0 11 0;
+#X connect 8 0 7 0;
+#X connect 10 0 4 0;
+#X connect 11 0 9 0;
+#X connect 12 1 8 0;
+#X connect 13 0 12 0;
+#X connect 14 0 15 1;
+#X connect 15 0 6 0;
+#X connect 15 1 13 0;
+#X connect 16 0 17 0;
+#X connect 17 0 15 0;
+#X connect 18 0 15 1;
+#X connect 20 0 19 0;
+#X connect 21 0 3 0;
+#X restore 22 47 pd draw;
+#X obj 34 203 r \$0-markov;
+#X obj 104 6 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225280 -1
+-1;
+#X obj 104 24 openpanel;
+#X msg 104 90 load_bin \$1;
+#X obj 104 68 symbol;
+#X msg 111 45 markov;
+#X obj 103 110 s \$0-markov;
+#X obj 204 6 bng 15 250 50 0 empty empty empty 0 -6 0 8 -228992 -1
+-1;
+#X obj 204 68 symbol;
+#X obj 203 110 s \$0-markov;
+#X obj 204 24 savepanel;
+#X msg 204 90 save_bin \$1;
+#X msg 211 45 markov2;
+#X obj 49 22 tgl 20 0 \$0-drawmode-s empty mode 0 -6 0 8 -225271 -1
+-1 0 1;
+#X msg 336 8 fsm info;
+#X msg 342 28 clear;
+#X obj 336 75 s \$0-markov;
+#X msg 339 151 next;
+#X obj 339 172 s \$0-markov;
+#X obj 339 108 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 339 127 metro 500;
+#X obj 302 153 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 364 107 6 0 0 0 - - -;
+#X msg 382 255 add1 \$1;
+#X floatatom 341 207 5 0 0 0 - - -;
+#X msg 382 208 foo;
+#X msg 413 208 bar;
+#X msg 442 209 baz;
+#X obj 382 279 s \$0-markov;
+#X obj 34 225 gfsm_markov markov;
+#X obj 384 234 symbol;
+#X floatatom 481 210 5 0 0 0 - - -;
+#X msg 522 211 foo;
+#X msg 553 211 bar;
+#X msg 582 212 baz;
+#X obj 522 282 s \$0-markov;
+#X obj 524 237 symbol;
+#X msg 521 258 addi1 \$1;
+#X msg 349 51 set;
+#X floatatom 538 57 5 0 0 0 - - -;
+#X msg 480 138 add1 \$1;
+#X floatatom 480 119 5 0 0 0 - - -;
+#X obj 539 170 s \$0-markov;
+#X floatatom 513 11 5 0 0 0 - - -;
+#X obj 480 29 metro 100;
+#X obj 480 11 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 480 98 + 1;
+#X floatatom 649 59 5 0 0 0 - - -;
+#X floatatom 591 121 5 0 0 0 - - -;
+#X floatatom 624 13 5 0 0 0 - - -;
+#X obj 591 31 metro 100;
+#X obj 591 13 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 591 100 + 1;
+#X msg 591 140 addi1 \$1;
+#X obj 480 77 random 16;
+#X obj 591 79 random 16;
+#X obj 34 260 spigot;
+#X obj 83 262 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 687 207 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 687 227 metro 2000;
+#X floatatom 715 208 5 0 0 0 - - -;
+#X msg 689 247 set;
+#X obj 689 267 s \$0-markov;
+#X obj 667 227 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 692 117 5 0 0 0 - - -;
+#X msg 692 137 addi \$1 42 5;
+#X obj 32 284 print MARKOV-LO;
+#X obj 155 284 print MARKOV-HI;
+#X obj 175 241 print MARKOV-X;
+#X obj 152 262 spigot;
+#X obj 201 264 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X floatatom 706 52 5 0 0 0 - - -;
+#X msg 705 70 add \$1 24 5;
+#X msg 138 192 set 0 \, next;
+#X obj 176 219 spigot;
+#X obj 224 221 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X msg 162 45 big;
+#X msg 270 44 big2;
+#X msg 49 73 markov2;
+#X connect 2 0 31 0;
+#X connect 3 0 4 0;
+#X connect 4 0 6 0;
+#X connect 5 0 8 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 0;
+#X connect 9 0 12 0;
+#X connect 10 0 13 0;
+#X connect 12 0 10 0;
+#X connect 13 0 11 0;
+#X connect 14 0 10 0;
+#X connect 16 0 18 0;
+#X connect 17 0 18 0;
+#X connect 19 0 20 0;
+#X connect 21 0 22 0;
+#X connect 22 0 19 0;
+#X connect 24 0 22 1;
+#X connect 25 0 30 0;
+#X connect 26 0 25 0;
+#X connect 27 0 32 0;
+#X connect 28 0 32 0;
+#X connect 29 0 32 0;
+#X connect 31 0 58 0;
+#X connect 31 1 71 0;
+#X connect 31 2 75 0;
+#X connect 31 2 76 0;
+#X connect 32 0 25 0;
+#X connect 33 0 39 0;
+#X connect 34 0 38 0;
+#X connect 35 0 38 0;
+#X connect 36 0 38 0;
+#X connect 38 0 39 0;
+#X connect 39 0 37 0;
+#X connect 40 0 18 0;
+#X connect 41 0 56 1;
+#X connect 42 0 44 0;
+#X connect 43 0 42 0;
+#X connect 45 0 46 1;
+#X connect 46 0 56 0;
+#X connect 47 0 46 0;
+#X connect 48 0 43 0;
+#X connect 49 0 57 1;
+#X connect 50 0 55 0;
+#X connect 51 0 52 1;
+#X connect 52 0 57 0;
+#X connect 53 0 52 0;
+#X connect 54 0 50 0;
+#X connect 55 0 44 0;
+#X connect 56 0 48 0;
+#X connect 57 0 54 0;
+#X connect 58 0 68 0;
+#X connect 59 0 58 1;
+#X connect 60 0 61 0;
+#X connect 61 0 63 0;
+#X connect 61 0 65 0;
+#X connect 62 0 61 1;
+#X connect 63 0 64 0;
+#X connect 66 0 67 0;
+#X connect 67 0 44 0;
+#X connect 71 0 69 0;
+#X connect 72 0 71 1;
+#X connect 73 0 74 0;
+#X connect 74 0 44 0;
+#X connect 75 0 31 0;
+#X connect 76 0 70 0;
+#X connect 77 0 76 1;
+#X connect 78 0 6 0;
+#X connect 79 0 10 0;
+#X connect 80 0 6 0;
diff --git a/gfsm/src/test-state.pd b/gfsm/src/test-state.pd
new file mode 100644
index 0000000..2ee2b77
--- /dev/null
+++ b/gfsm/src/test-state.pd
@@ -0,0 +1,427 @@
+#N canvas 430 0 616 494 10;
+#X obj 13 7 gfsm;
+#X msg 23 84 automaton;
+#X msg 21 43 automaton a1;
+#X obj 51 6 zexy;
+#X msg 22 62 automaton a2;
+#X obj 30 285 r \$0-state;
+#X obj 19 332 print STATE-1;
+#X obj 136 76 s \$0-state;
+#X msg 150 48 id;
+#X msg 136 27 set \$1;
+#X floatatom 153 9 5 0 0 0 - - -;
+#X obj 19 308 gfsm_state a1;
+#X obj 135 10 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 218 11 degree;
+#X obj 218 74 s \$0-state;
+#X msg 25 147 arc_first;
+#X msg 29 171 arc_next;
+#X obj 243 314 gfsm_automaton a1;
+#X obj 243 180 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225280 -1
+-1;
+#X obj 243 198 openpanel;
+#X msg 243 264 load_bin \$1;
+#X obj 243 335 print A1-1;
+#X obj 254 293 r \$0-fsm;
+#X obj 337 226 bng 20 250 50 0 \$0-draw-s empty DRAW 0 -6 0 8 -24198
+-1 -1;
+#N canvas 0 0 466 454 draw 0;
+#X obj 361 16 zexy;
+#X obj 67 25 r \$0-draw-s;
+#X obj 68 68 f \$0;
+#X msg 176 74 save_bin \$1draw.gfst;
+#X obj 176 98 s \$0-fsm;
+#X obj 68 162 shell;
+#X obj 68 47 t b;
+#X obj 68 91 t f f;
+#X msg 69 237 dotgv.sh \$1draw.dot;
+#X obj 171 311 f \$0;
+#X obj 172 291 t b;
+#X obj 171 357 shell;
+#X obj 172 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 68 137 gfsmdraw \$1draw.gfst -F \$1draw.dot;
+#X msg 171 334 rm -f \$1draw.gfst \$1draw.dot;
+#X obj 142 270 shell;
+#X msg 220 236 dotty \$1draw.dot;
+#X obj 169 183 r \$0-drawmode-s;
+#X obj 111 206 demux 0 1;
+#X obj 110 163 t b;
+#X obj 111 184 f \$0;
+#X obj 284 182 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X connect 1 0 6 0;
+#X connect 2 0 7 0;
+#X connect 3 0 4 0;
+#X connect 5 1 19 0;
+#X connect 6 0 2 0;
+#X connect 7 0 13 0;
+#X connect 7 1 3 0;
+#X connect 8 0 15 0;
+#X connect 9 0 14 0;
+#X connect 10 0 9 0;
+#X connect 12 0 6 0;
+#X connect 13 0 5 0;
+#X connect 14 0 11 0;
+#X connect 15 1 10 0;
+#X connect 16 0 15 0;
+#X connect 17 0 18 1;
+#X connect 18 0 8 0;
+#X connect 18 1 16 0;
+#X connect 19 0 20 0;
+#X connect 20 0 18 0;
+#X connect 21 0 18 1;
+#X restore 338 250 pd draw;
+#X obj 365 226 tgl 20 0 \$0-drawmode-s empty mode 0 -6 0 8 -225271
+-1 -1 0 1;
+#X msg 250 219 test3.gfst;
+#X obj 243 242 symbol;
+#X obj 115 141 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 38 17 452 375 weight_sum 0;
+#X obj 34 11 inlet;
+#X msg 34 61 arc_first;
+#X msg 46 88 arc_next;
+#X obj 34 292 f 0;
+#X obj 238 59 0;
+#X obj 34 177 route arc_first arc_next;
+#X obj 34 203 route bang;
+#X obj 99 222 t b l;
+#X obj 129 244 unpack 0 0 0 0;
+#X obj 222 268 + 0;
+#X obj 178 267 t f f;
+#X obj 87 11 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 34 323 outlet;
+#X obj 34 224 t b;
+#X obj 34 143 gfsm_state a1 0;
+#X obj 45 119 r \$0-state;
+#X obj 88 323 s \$0-wsum-out;
+#X obj 113 13 r \$0-wsum-in;
+#X obj 71 250 delay 1;
+#X obj 34 33 t b b b;
+#X msg 290 56 stop;
+#X floatatom 240 293 5 0 0 0 - - -;
+#X obj 322 168 until;
+#X connect 0 0 19 0;
+#X connect 1 0 14 0;
+#X connect 2 0 14 0;
+#X connect 3 0 12 0;
+#X connect 3 0 16 0;
+#X connect 4 0 9 1;
+#X connect 5 0 6 0;
+#X connect 5 1 6 0;
+#X connect 6 0 13 0;
+#X connect 6 1 7 0;
+#X connect 7 0 18 0;
+#X connect 7 1 8 0;
+#X connect 8 3 9 0;
+#X connect 9 0 10 0;
+#X connect 9 0 21 0;
+#X connect 10 0 9 1;
+#X connect 10 1 3 1;
+#X connect 11 0 19 0;
+#X connect 13 0 3 0;
+#X connect 14 0 5 0;
+#X connect 15 0 14 0;
+#X connect 17 0 19 0;
+#X connect 18 0 2 0;
+#X connect 19 0 1 0;
+#X connect 19 1 4 0;
+#X connect 19 2 20 0;
+#X connect 20 0 18 0;
+#X restore 115 161 pd weight_sum;
+#X obj 114 332 s \$0-state-out;
+#X floatatom 114 182 8 0 0 0 - - -;
+#X obj 114 224 print WSUM;
+#X obj 252 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 302 0 392 492 rand_arc 0;
+#X obj 40 9 inlet;
+#X obj 83 9 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1
+;
+#X msg 41 56 arc_first;
+#X msg 56 93 arc_next;
+#X obj 41 177 route arc_first arc_next;
+#X obj 41 203 route bang;
+#X obj 150 244 unpack 0 0 0 0;
+#X obj 41 451 outlet;
+#X obj 41 143 gfsm_state a1 0;
+#X obj 77 122 r \$0-state;
+#X obj 257 73 s \$0-wsum-in;
+#X obj 259 95 r \$0-wsum-out;
+#X obj 259 142 random 131072;
+#X obj 259 116 t b f;
+#X obj 259 166 / 131072;
+#X obj 259 190 * 1;
+#X obj 41 224 t b;
+#X obj 243 316 moses 0;
+#X obj 259 213 * -1;
+#X obj 243 271 + 0;
+#X obj 243 294 t f f;
+#X obj 242 335 t b b;
+#X obj 128 403 spigot;
+#X obj 165 381 0;
+#X obj 192 381 1;
+#X obj 106 306 spigot;
+#X obj 106 222 t b l l;
+#X obj 286 335 t b b;
+#X obj 169 284 0;
+#X obj 143 284 1;
+#X obj 107 10 r \$0-randarc-in;
+#X obj 92 451 s \$0-randarc-out;
+#X obj 81 326 delay 1;
+#X obj 41 30 t b b b;
+#X msg 177 127 stop;
+#X connect 0 0 33 0;
+#X connect 1 0 33 0;
+#X connect 2 0 8 0;
+#X connect 3 0 8 0;
+#X connect 4 0 5 0;
+#X connect 4 1 5 0;
+#X connect 5 0 16 0;
+#X connect 5 1 26 0;
+#X connect 6 3 19 0;
+#X connect 8 0 4 0;
+#X connect 9 0 8 0;
+#X connect 11 0 13 0;
+#X connect 12 0 14 0;
+#X connect 13 0 12 0;
+#X connect 13 1 15 1;
+#X connect 14 0 15 0;
+#X connect 15 0 18 0;
+#X connect 16 0 7 0;
+#X connect 16 0 31 0;
+#X connect 17 0 21 0;
+#X connect 17 1 27 0;
+#X connect 18 0 19 1;
+#X connect 19 0 20 0;
+#X connect 20 0 17 0;
+#X connect 20 1 19 1;
+#X connect 21 0 29 0;
+#X connect 21 1 23 0;
+#X connect 22 0 7 0;
+#X connect 22 0 31 0;
+#X connect 23 0 22 1;
+#X connect 24 0 22 1;
+#X connect 25 0 32 0;
+#X connect 26 0 25 0;
+#X connect 26 1 22 0;
+#X connect 26 2 6 0;
+#X connect 27 0 24 0;
+#X connect 27 1 28 0;
+#X connect 28 0 25 1;
+#X connect 29 0 25 1;
+#X connect 30 0 33 0;
+#X connect 32 0 3 0;
+#X connect 33 0 2 0;
+#X connect 33 1 10 0;
+#X connect 33 2 34 0;
+#X connect 34 0 32 0;
+#X restore 252 116 pd rand_arc;
+#X obj 395 113 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 102 2 392 492 rand_incr 0;
+#X obj 40 9 inlet;
+#X obj 83 9 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1
+;
+#X obj 41 54 s \$0-randarc-in;
+#X obj 43 76 r \$0-randarc-out;
+#X obj 42 98 route bang;
+#X obj 41 30 t b;
+#X obj 42 177 gfsm_automaton a1;
+#X obj 209 157 unpack 0 0 0 0;
+#X obj 55 154 r \$0-automaton;
+#X msg 42 131 root;
+#X obj 42 199 route root;
+#X obj 42 221 route bang;
+#X obj 107 336 outlet;
+#X obj 211 337 outlet;
+#X obj 271 335 outlet;
+#X msg 8 247 root 0;
+#X obj 107 254 t f f;
+#X obj 137 295 s \$0-state;
+#X msg 137 274 set \$1;
+#X obj 326 336 outlet;
+#X connect 0 0 5 0;
+#X connect 1 0 5 0;
+#X connect 3 0 4 0;
+#X connect 4 0 9 0;
+#X connect 4 1 7 0;
+#X connect 5 0 2 0;
+#X connect 6 0 10 0;
+#X connect 7 0 16 0;
+#X connect 7 1 13 0;
+#X connect 7 2 14 0;
+#X connect 7 3 19 0;
+#X connect 8 0 6 0;
+#X connect 9 0 6 0;
+#X connect 10 0 11 0;
+#X connect 11 0 15 0;
+#X connect 11 1 16 0;
+#X connect 15 0 6 0;
+#X connect 16 0 12 0;
+#X connect 16 1 18 0;
+#X connect 18 0 17 0;
+#X restore 395 132 pd rand_incr;
+#X obj 254 157 print RAND_ARC;
+#X obj 336 33 s \$0-state;
+#X obj 326 54 s \$0-fsm;
+#X obj 13 105 s \$0-automaton;
+#X obj 326 12 r \$0-automaton;
+#X obj 21 197 s \$0-state-a;
+#X obj 19 262 r \$0-state-a;
+#X obj 195 192 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 230 140 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 470 10 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X floatatom 493 10 5 0 0 0 - - -;
+#X obj 471 30 metro 1000;
+#X obj 417 300 gfsm_alphabet alph1;
+#X obj 518 214 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225280 -1
+-1;
+#X obj 518 232 openpanel;
+#X obj 518 254 symbol;
+#X msg 518 275 load \$1;
+#X obj 452 342 print RI-ATOM;
+#X msg 419 273 char2atom \$1;
+#X floatatom 436 245 5 0 0 0 - - -;
+#X obj 452 321 fromsymbol;
+#N canvas 0 0 450 300 ri_print 0;
+#X obj 48 22 inlet;
+#X obj 101 22 inlet;
+#X obj 155 22 inlet;
+#X obj 206 22 inlet;
+#X obj 319 22 inlet;
+#X obj 93 97 spigot;
+#X obj 93 57 pack 0 0 0 0;
+#X obj 93 122 unpack 0 0 0 0;
+#X obj 124 196 print RI-LO;
+#X obj 186 155 print RI-WT;
+#X obj 155 175 print RI-HI;
+#X obj 93 215 print RI-NXT;
+#X connect 0 0 6 0;
+#X connect 1 0 6 1;
+#X connect 2 0 6 2;
+#X connect 3 0 6 3;
+#X connect 4 0 5 1;
+#X connect 5 0 7 0;
+#X connect 6 0 5 0;
+#X connect 7 0 11 0;
+#X connect 7 1 8 0;
+#X connect 7 2 10 0;
+#X connect 7 3 9 0;
+#X restore 420 160 pd ri_print;
+#X obj 488 131 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 114 203 spigot;
+#X obj 162 203 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 253 138 spigot;
+#X obj 301 138 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 29 410 grattsdict;
+#X obj 247 417 gvol~;
+#X obj 246 454 dac~;
+#X obj 470 51 t b b;
+#X obj 475 100 spigot;
+#X msg 506 80 0;
+#X msg 534 80 1;
+#X obj 548 456 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 0 0 450 300 load_dict 0;
+#X obj 31 16 inlet;
+#X obj 31 38 t b;
+#X msg 31 67 load /home/moocow/src/pd/externs/ratts/dict/beep-b.txt
+cr;
+#X obj 33 108 outlet;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X restore 30 391 pd load_dict;
+#X obj 31 371 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 366 367 gpratts~ 10 \$0p /gpratts;
+#X obj 171 396 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X msg 171 417 \; pd dsp \$1;
+#X obj 434 74 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 435 103 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 424 202 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 367 340 route 0;
+#X connect 1 0 40 0;
+#X connect 2 0 40 0;
+#X connect 4 0 40 0;
+#X connect 5 0 11 0;
+#X connect 8 0 7 0;
+#X connect 9 0 7 0;
+#X connect 10 0 9 0;
+#X connect 11 0 6 0;
+#X connect 11 0 30 0;
+#X connect 12 0 10 0;
+#X connect 13 0 14 0;
+#X connect 15 0 42 0;
+#X connect 16 0 42 0;
+#X connect 17 0 21 0;
+#X connect 18 0 19 0;
+#X connect 19 0 27 0;
+#X connect 20 0 17 0;
+#X connect 22 0 17 0;
+#X connect 26 0 27 0;
+#X connect 27 0 20 0;
+#X connect 28 0 29 0;
+#X connect 29 0 31 0;
+#X connect 29 0 44 0;
+#X connect 31 0 60 0;
+#X connect 33 0 34 0;
+#X connect 34 0 45 0;
+#X connect 34 0 62 0;
+#X connect 35 0 36 0;
+#X connect 36 0 58 0;
+#X connect 36 0 55 0;
+#X connect 36 0 79 0;
+#X connect 36 1 58 1;
+#X connect 36 2 58 2;
+#X connect 36 3 58 3;
+#X connect 41 0 39 0;
+#X connect 41 0 38 0;
+#X connect 43 0 11 0;
+#X connect 46 0 48 0;
+#X connect 47 0 48 1;
+#X connect 48 0 67 0;
+#X connect 49 1 57 0;
+#X connect 50 0 51 0;
+#X connect 51 0 52 0;
+#X connect 52 0 53 0;
+#X connect 53 0 49 0;
+#X connect 55 0 49 0;
+#X connect 56 0 55 0;
+#X connect 57 0 54 0;
+#X connect 57 0 80 0;
+#X connect 59 0 58 4;
+#X connect 60 0 32 0;
+#X connect 61 0 60 1;
+#X connect 62 0 37 0;
+#X connect 63 0 62 1;
+#X connect 65 0 66 0;
+#X connect 65 0 66 1;
+#X connect 67 0 69 0;
+#X connect 67 0 77 0;
+#X connect 67 1 68 0;
+#X connect 68 0 36 0;
+#X connect 68 0 78 0;
+#X connect 69 0 68 1;
+#X connect 70 0 68 1;
+#X connect 72 0 64 0;
+#X connect 73 0 72 0;
+#X connect 74 0 65 0;
+#X connect 74 1 71 0;
+#X connect 74 1 70 0;
+#X connect 75 0 76 0;
+#X connect 80 1 74 0;
diff --git a/gfsm/src/test-state2.pd b/gfsm/src/test-state2.pd
new file mode 100644
index 0000000..a9983d0
--- /dev/null
+++ b/gfsm/src/test-state2.pd
@@ -0,0 +1,415 @@
+#N canvas 346 27 616 494 10;
+#X obj 13 7 gfsm;
+#X msg 23 84 automaton;
+#X msg 21 43 automaton a1;
+#X obj 51 6 zexy;
+#X msg 22 62 automaton a2;
+#X obj 30 285 r \$0-state;
+#X obj 19 332 print STATE-1;
+#X obj 136 76 s \$0-state;
+#X msg 150 48 id;
+#X msg 136 27 set \$1;
+#X floatatom 153 9 5 0 0 0 - - -;
+#X obj 19 308 gfsm_state a1;
+#X obj 135 10 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 218 11 degree;
+#X obj 218 74 s \$0-state;
+#X msg 19 164 arc_first;
+#X msg 23 188 arc_next;
+#X obj 243 314 gfsm_automaton a1;
+#X obj 243 180 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225280 -1
+-1;
+#X obj 243 198 openpanel;
+#X msg 243 264 load_bin \$1;
+#X obj 243 335 print A1-1;
+#X obj 254 293 r \$0-fsm;
+#X obj 337 226 bng 20 250 50 0 \$0-draw-s empty DRAW 0 -6 0 8 -24198
+-1 -1;
+#N canvas 0 0 466 454 draw 0;
+#X obj 361 16 zexy;
+#X obj 67 25 r \$0-draw-s;
+#X obj 68 68 f \$0;
+#X msg 176 74 save_bin \$1draw.gfst;
+#X obj 176 98 s \$0-fsm;
+#X obj 68 162 shell;
+#X obj 68 47 t b;
+#X obj 68 91 t f f;
+#X msg 69 237 dotgv.sh \$1draw.dot;
+#X obj 171 311 f \$0;
+#X obj 172 291 t b;
+#X obj 171 357 shell;
+#X obj 172 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 68 137 gfsmdraw \$1draw.gfst -F \$1draw.dot;
+#X msg 171 334 rm -f \$1draw.gfst \$1draw.dot;
+#X obj 142 270 shell;
+#X msg 220 236 dotty \$1draw.dot;
+#X obj 169 183 r \$0-drawmode-s;
+#X obj 111 206 demux 0 1;
+#X obj 110 163 t b;
+#X obj 111 184 f \$0;
+#X obj 284 182 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X connect 1 0 6 0;
+#X connect 2 0 7 0;
+#X connect 3 0 4 0;
+#X connect 5 1 19 0;
+#X connect 6 0 2 0;
+#X connect 7 0 13 0;
+#X connect 7 1 3 0;
+#X connect 8 0 15 0;
+#X connect 9 0 14 0;
+#X connect 10 0 9 0;
+#X connect 12 0 6 0;
+#X connect 13 0 5 0;
+#X connect 14 0 11 0;
+#X connect 15 1 10 0;
+#X connect 16 0 15 0;
+#X connect 17 0 18 1;
+#X connect 18 0 8 0;
+#X connect 18 1 16 0;
+#X connect 19 0 20 0;
+#X connect 20 0 18 0;
+#X connect 21 0 18 1;
+#X restore 338 250 pd draw;
+#X obj 365 226 tgl 20 0 \$0-drawmode-s empty mode 0 -6 0 8 -225271
+-1 -1 0 1;
+#X obj 243 242 symbol;
+#X obj 115 141 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 486 0 310 377 weight_sum 1;
+#X obj 34 11 inlet;
+#X msg 34 104 arc_next;
+#X obj 34 309 f 0;
+#X obj 209 82 0;
+#X obj 99 228 unpack 0 0 0 0;
+#X obj 193 252 + 0;
+#X obj 98 253 t f f;
+#X obj 87 11 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 34 340 outlet;
+#X obj 34 157 gfsm_state a1 0;
+#X obj 70 136 r \$0-state;
+#X obj 88 340 s \$0-wsum-out;
+#X obj 113 13 r \$0-wsum-in;
+#X obj 34 80 until;
+#X obj 34 204 route bang;
+#X obj 34 225 t b b;
+#X obj 34 182 route arc_next;
+#X obj 34 33 t b b b b;
+#X msg 101 104 arc_reset;
+#X connect 0 0 17 0;
+#X connect 1 0 9 0;
+#X connect 2 0 8 0;
+#X connect 2 0 11 0;
+#X connect 3 0 5 1;
+#X connect 4 3 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 5 1;
+#X connect 6 1 2 1;
+#X connect 7 0 17 0;
+#X connect 9 0 16 0;
+#X connect 10 0 9 0;
+#X connect 12 0 17 0;
+#X connect 13 0 1 0;
+#X connect 14 0 15 0;
+#X connect 14 1 4 0;
+#X connect 15 0 2 0;
+#X connect 15 1 13 1;
+#X connect 16 0 14 0;
+#X connect 17 0 13 0;
+#X connect 17 1 3 0;
+#X connect 17 2 18 0;
+#X connect 17 3 13 1;
+#X connect 18 0 9 0;
+#X restore 115 161 pd weight_sum;
+#X obj 114 332 s \$0-state-out;
+#X obj 114 224 print WSUM;
+#X obj 252 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 298 9 405 465 rand_arc 0;
+#X obj 40 9 inlet;
+#X obj 83 9 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1
+;
+#X msg 41 98 arc_next;
+#X obj 136 266 unpack 0 0 0 0;
+#X obj 41 415 outlet;
+#X obj 41 163 gfsm_state a1 0;
+#X obj 76 140 r \$0-state;
+#X obj 243 97 s \$0-wsum-in;
+#X obj 245 119 r \$0-wsum-out;
+#X obj 245 166 random 131072;
+#X obj 245 140 t b f;
+#X obj 245 190 / 131072;
+#X obj 245 214 * 1;
+#X obj 229 334 moses 0;
+#X obj 245 237 * -1;
+#X obj 229 289 + 0;
+#X obj 229 312 t f f;
+#X obj 106 327 spigot;
+#X obj 143 304 0;
+#X obj 170 304 1;
+#X obj 107 10 r \$0-randarc-in;
+#X obj 92 415 s \$0-randarc-out;
+#X obj 41 76 until;
+#X obj 41 220 route bang;
+#X obj 106 244 t l l;
+#X obj 228 353 t b;
+#X obj 272 353 t b;
+#X obj 106 348 t l b;
+#X obj 41 348 t b b;
+#X obj 41 197 route arc_next;
+#X msg 107 97 arc_reset;
+#X obj 41 30 t b b b b;
+#X connect 0 0 31 0;
+#X connect 1 0 31 0;
+#X connect 2 0 5 0;
+#X connect 3 3 15 0;
+#X connect 5 0 29 0;
+#X connect 6 0 5 0;
+#X connect 8 0 10 0;
+#X connect 9 0 11 0;
+#X connect 10 0 9 0;
+#X connect 10 1 12 1;
+#X connect 11 0 12 0;
+#X connect 12 0 14 0;
+#X connect 13 0 25 0;
+#X connect 13 1 26 0;
+#X connect 14 0 15 1;
+#X connect 15 0 16 0;
+#X connect 16 0 13 0;
+#X connect 16 1 15 1;
+#X connect 17 0 27 0;
+#X connect 18 0 17 1;
+#X connect 19 0 17 1;
+#X connect 20 0 31 0;
+#X connect 22 0 2 0;
+#X connect 23 0 28 0;
+#X connect 23 1 24 0;
+#X connect 24 0 17 0;
+#X connect 24 1 3 0;
+#X connect 25 0 18 0;
+#X connect 26 0 19 0;
+#X connect 27 0 21 0;
+#X connect 27 0 4 0;
+#X connect 27 1 22 1;
+#X connect 28 0 4 0;
+#X connect 28 0 21 0;
+#X connect 28 1 22 1;
+#X connect 29 0 23 0;
+#X connect 30 0 5 0;
+#X connect 31 0 22 0;
+#X connect 31 1 30 0;
+#X connect 31 2 7 0;
+#X connect 31 3 22 1;
+#X restore 252 116 pd rand_arc;
+#X obj 395 113 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 102 2 392 492 rand_incr 0;
+#X obj 40 9 inlet;
+#X obj 83 9 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1
+;
+#X obj 41 54 s \$0-randarc-in;
+#X obj 43 76 r \$0-randarc-out;
+#X obj 42 98 route bang;
+#X obj 41 30 t b;
+#X obj 42 177 gfsm_automaton a1;
+#X obj 209 157 unpack 0 0 0 0;
+#X obj 55 154 r \$0-automaton;
+#X msg 42 131 root;
+#X obj 42 199 route root;
+#X obj 42 221 route bang;
+#X obj 107 336 outlet;
+#X obj 211 337 outlet;
+#X obj 271 335 outlet;
+#X msg 8 247 root 0;
+#X obj 107 254 t f f;
+#X obj 137 295 s \$0-state;
+#X msg 137 274 set \$1;
+#X obj 326 336 outlet;
+#X connect 0 0 5 0;
+#X connect 1 0 5 0;
+#X connect 3 0 4 0;
+#X connect 4 0 9 0;
+#X connect 4 1 7 0;
+#X connect 5 0 2 0;
+#X connect 6 0 10 0;
+#X connect 7 0 16 0;
+#X connect 7 1 13 0;
+#X connect 7 2 14 0;
+#X connect 7 3 19 0;
+#X connect 8 0 6 0;
+#X connect 9 0 6 0;
+#X connect 10 0 11 0;
+#X connect 11 0 15 0;
+#X connect 11 1 16 0;
+#X connect 15 0 6 0;
+#X connect 16 0 12 0;
+#X connect 16 1 18 0;
+#X connect 18 0 17 0;
+#X restore 395 132 pd rand_incr;
+#X obj 254 157 print RAND_ARC;
+#X obj 336 33 s \$0-state;
+#X obj 326 54 s \$0-fsm;
+#X obj 13 105 s \$0-automaton;
+#X obj 326 12 r \$0-automaton;
+#X obj 13 214 s \$0-state-a;
+#X obj 19 262 r \$0-state-a;
+#X obj 195 192 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 230 140 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 470 10 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X floatatom 493 10 5 0 0 0 - - -;
+#X obj 471 30 metro 1000;
+#X obj 417 300 gfsm_alphabet alph1;
+#X obj 518 214 bng 15 250 50 0 empty empty empty 0 -6 0 8 -225280 -1
+-1;
+#X obj 518 232 openpanel;
+#X obj 518 254 symbol;
+#X msg 518 275 load \$1;
+#X obj 481 375 print RI-ATOM;
+#X msg 419 273 char2atom \$1;
+#X floatatom 436 245 5 0 0 0 - - -;
+#X obj 482 332 fromsymbol;
+#N canvas 0 0 450 300 ri_print 0;
+#X obj 48 22 inlet;
+#X obj 101 22 inlet;
+#X obj 155 22 inlet;
+#X obj 206 22 inlet;
+#X obj 319 22 inlet;
+#X obj 93 97 spigot;
+#X obj 93 57 pack 0 0 0 0;
+#X obj 93 122 unpack 0 0 0 0;
+#X obj 124 196 print RI-LO;
+#X obj 186 155 print RI-WT;
+#X obj 155 175 print RI-HI;
+#X obj 93 215 print RI-NXT;
+#X connect 0 0 6 0;
+#X connect 1 0 6 1;
+#X connect 2 0 6 2;
+#X connect 3 0 6 3;
+#X connect 4 0 5 1;
+#X connect 5 0 7 0;
+#X connect 6 0 5 0;
+#X connect 7 0 11 0;
+#X connect 7 1 8 0;
+#X connect 7 2 10 0;
+#X connect 7 3 9 0;
+#X restore 420 160 pd ri_print;
+#X obj 488 131 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 114 181 spigot;
+#X obj 162 181 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 253 138 spigot;
+#X obj 301 138 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 29 410 grattsdict;
+#X obj 470 51 t b b;
+#X obj 475 100 spigot;
+#X msg 506 80 0;
+#X msg 534 80 1;
+#X obj 548 456 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 0 0 450 300 load_dict 0;
+#X obj 31 16 inlet;
+#X obj 31 38 t b;
+#X msg 31 67 load /home/moocow/src/pd/externs/ratts/dict/beep-b.txt
+cr;
+#X obj 33 108 outlet;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X restore 30 391 pd load_dict;
+#X obj 31 371 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 243 365 gpratts~ 10 \$0p /gpratts;
+#X obj 30 432 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X msg 30 453 \; pd dsp \$1;
+#X obj 434 74 bng 15 250 20 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 435 103 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 424 202 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 367 340 route 0;
+#X msg 202 284 info;
+#X msg 13 141 arc_reset;
+#X msg 250 219 markov.gfst;
+#X msg 538 211 markov.lab;
+#X floatatom 114 204 8 0 0 0 - - -;
+#X obj 481 355 spigot;
+#X obj 533 354 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 145 359 ms8a~ p gpr;
+#X connect 1 0 38 0;
+#X connect 2 0 38 0;
+#X connect 4 0 38 0;
+#X connect 5 0 11 0;
+#X connect 8 0 7 0;
+#X connect 9 0 7 0;
+#X connect 10 0 9 0;
+#X connect 11 0 6 0;
+#X connect 11 0 29 0;
+#X connect 12 0 10 0;
+#X connect 13 0 14 0;
+#X connect 15 0 40 0;
+#X connect 16 0 40 0;
+#X connect 17 0 21 0;
+#X connect 18 0 19 0;
+#X connect 19 0 26 0;
+#X connect 20 0 17 0;
+#X connect 22 0 17 0;
+#X connect 26 0 20 0;
+#X connect 27 0 28 0;
+#X connect 31 0 32 0;
+#X connect 32 0 60 0;
+#X connect 33 0 34 0;
+#X connect 34 0 56 0;
+#X connect 34 0 53 0;
+#X connect 34 1 56 1;
+#X connect 34 2 56 2;
+#X connect 34 3 56 3;
+#X connect 39 0 37 0;
+#X connect 39 0 36 0;
+#X connect 41 0 11 0;
+#X connect 44 0 46 0;
+#X connect 45 0 46 1;
+#X connect 46 0 63 0;
+#X connect 47 1 55 0;
+#X connect 48 0 49 0;
+#X connect 49 0 50 0;
+#X connect 50 0 51 0;
+#X connect 51 0 47 0;
+#X connect 53 0 47 0;
+#X connect 54 0 53 0;
+#X connect 55 0 76 0;
+#X connect 55 0 82 0;
+#X connect 57 0 56 4;
+#X connect 58 0 81 0;
+#X connect 59 0 58 1;
+#X connect 60 0 35 0;
+#X connect 61 0 60 1;
+#X connect 63 0 65 0;
+#X connect 63 1 64 0;
+#X connect 64 0 34 0;
+#X connect 65 0 64 1;
+#X connect 66 0 64 1;
+#X connect 68 0 62 0;
+#X connect 69 0 68 0;
+#X connect 70 0 84 0;
+#X connect 70 0 84 1;
+#X connect 70 1 66 0;
+#X connect 71 0 72 0;
+#X connect 76 1 70 0;
+#X connect 77 0 17 0;
+#X connect 78 0 40 0;
+#X connect 79 0 26 0;
+#X connect 80 0 50 0;
+#X connect 81 0 30 0;
+#X connect 82 0 52 0;
+#X connect 83 0 82 1;
diff --git a/gfsm/src/test.lab b/gfsm/src/test.lab
new file mode 100644
index 0000000..a339b5f
--- /dev/null
+++ b/gfsm/src/test.lab
@@ -0,0 +1,5 @@
+<epsilon> 0
+a 1
+b 2
+c 3
+foo 42
diff --git a/gfsm/src/test.tfst b/gfsm/src/test.tfst
new file mode 100644
index 0000000..e07da8c
--- /dev/null
+++ b/gfsm/src/test.tfst
@@ -0,0 +1,3 @@
+0 1 1 1 0
+1 2 2 2 0
+2
diff --git a/gfsm/src/test2.lab b/gfsm/src/test2.lab
new file mode 100644
index 0000000..08f153a
--- /dev/null
+++ b/gfsm/src/test2.lab
@@ -0,0 +1,6 @@
+<epsilon> 0
+a 1
+b 2
+c 3
+foo 42
+x 1
diff --git a/gfsm/src/test2.tfst b/gfsm/src/test2.tfst
new file mode 100644
index 0000000..e5e2be6
--- /dev/null
+++ b/gfsm/src/test2.tfst
@@ -0,0 +1,4 @@
+0 1 3 30 0
+0 2 4 40 0
+1 0
+2 0
diff --git a/gfsm/src/test3.tfst b/gfsm/src/test3.tfst
new file mode 100644
index 0000000..e124810
--- /dev/null
+++ b/gfsm/src/test3.tfst
@@ -0,0 +1,4 @@
+0 1 3 30 0.3
+0 2 4 40 0.7
+1 0
+2 0
diff --git a/readdir/COPYING b/readdir/COPYING
new file mode 100644
index 0000000..fa0bef4
--- /dev/null
+++ b/readdir/COPYING
@@ -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/readdir/Changes b/readdir/Changes
new file mode 100644
index 0000000..c124f80
--- /dev/null
+++ b/readdir/Changes
@@ -0,0 +1,7 @@
+Change log for PD external 'readdir'
+
+v0.02 Thu, 02 Feb 2006 12:52:35 +0100
+ + automake-ified
+
+v0.01 Sun, 26 Oct 2003 14:06:29 +0100
+ + initial version
diff --git a/readdir/Makefile.am b/readdir/Makefile.am
new file mode 100644
index 0000000..5e5d148
--- /dev/null
+++ b/readdir/Makefile.am
@@ -0,0 +1,98 @@
+# File: ./Makefile.am
+# Package: readdir
+# Description:
+# + top-level automake file
+#
+# Process this file with Automake to create Makefile.in.
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Options & Subdirectories
+#-----------------------------------------------------------------------
+
+## --- automake options
+#AUTOMAKE_OPTIONS = foreign dist-bzip2 dist-zip
+AUTOMAKE_OPTIONS = foreign
+
+## --- recursion subdirectories
+SUBDIRS = config src
+
+## --- pseudo-deps for '.SUFFIXES'
+SUFFIXES = .pod .txt
+
+#-----------------------------------------------------------------------
+# Variables: cleanup
+#-----------------------------------------------------------------------
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+#CLEANFILES =
+
+## --- distclean: built by 'configure'
+DISTCLEANFILES = \
+ config.log \
+ config.cache \
+ config.status
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = *~ \
+ $(PODS:.pod=.txt) \
+ Makefile Makefile.in \
+ aclocal.m4 \
+ configure \
+ install-sh \
+ stamp-h.in \
+ config.h.in
+
+maintainer-clean-local:
+ rm -rf autom4te.cache
+
+#CVSCLEAN_SUBDIRS = $(SUBDIRS)
+
+#CVSCLEANFILES = Makefile.in Makefile
+
+
+#-----------------------------------------------------------------------
+# Additional Variables & Rules: PODS
+#-----------------------------------------------------------------------
+PODS = README.pod
+
+.pod.txt:
+ pod2text $< $@
+
+all-local: $(PODS:.pod=.txt)
+
+#-----------------------------------------------------------------------
+# Variables: distribution
+#-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = \
+ $(PODS:.pod=.txt) autogen.sh configure \
+ README.cvs COPYING
+
+## --- recursion subdirectories for 'make dist'
+#DIST_SUBDIRS = $(SUBDIRS)
+
+## --- dist-hook: when another 'Makefile.am' is overkill
+#DISTHOOK_DIRS = foo
+#DISTHOOK_FILES = foo/bar.txt foo/baz.txt
+#dist-hook:
+# for d in $(DISTHOOK_DIRS); do\
+# mkdir -p $(distdir)/$$d ;\
+# done
+# for f in $(DISTHOOK_FILES); do\
+# cp -p $(srcdir)/$$f $(distdir)/$$f ;\
+# done
+
+#dist-bz2: dist-bzip2 ;
+
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
+
diff --git a/readdir/README.cvs b/readdir/README.cvs
new file mode 100644
index 0000000..2a0ee0c
--- /dev/null
+++ b/readdir/README.cvs
@@ -0,0 +1,13 @@
+To build from cvs, do the following:
+
+ ./autogen.sh
+ ./configure
+ make
+ make install
+
+NOTE: The README.txt file in the distribution
+is auto-generated from perl ".pod" format by
+the "pod2text" included in most perl distributions.
+
+marmosets,
+ Bryan
diff --git a/readdir/README.pod b/readdir/README.pod
new file mode 100644
index 0000000..cfcb4ab
--- /dev/null
+++ b/readdir/README.pod
@@ -0,0 +1,46 @@
+=pod
+
+README for pd external 'readdir'
+
+Last updated for readdir v0.02
+
+=head1 DESCRIPTION
+
+The 'readdir' object lets you read the contents of a directory.
+
+=head1 INSTALLATION
+
+Issue the following commands to the shell:
+
+ cd readdir-X.YY (or wherever you extracted the distribution)
+ ./configure
+ make
+ make install
+
+=head1 BUILD OPTIONS
+
+The 'configure' script supports the following options, among others:
+
+=over 4
+
+=item * --enable-debug , --disable-debug
+
+Whether to enable verbose debugging messages.
+Default=no.
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+PD by Miller Puckette and others.
+
+Ideas, black magic, and other nuggets of information drawn
+from code by Guenter Geiger, Larry Troxler, and iohannes m zmoelnig.
+
+=head1 KNOWN BUGS
+
+None known.
+
+=head1 AUTHOR
+
+Bryan Jurish E<lt>moocow@ling.uni-potsdam.deE<gt>
diff --git a/readdir/autogen.sh b/readdir/autogen.sh
new file mode 100755
index 0000000..845f276
--- /dev/null
+++ b/readdir/autogen.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+#-----------------------------------------------------------------------
+# File: autogen.sh
+# Description:
+# + wrapper for m4 black-magic
+#-----------------------------------------------------------------------
+
+MY_ALDIRS="."
+MY_AHDIRS="."
+MY_AMDIRS="."
+MY_ACDIRS="."
+
+test -z "$ACLOCAL" && ACLOCAL=aclocal
+test -z "$AUTOHEADER" && AUTOHEADER=autoheader
+test -z "$AUTOMAKE" && AUTOMAKE=automake
+test -z "$AUTOCONF" && AUTOCONF=autoconf
+
+if test -n "$MY_ALDIRS"; then
+ for d in $MY_ALDIRS ; do
+ echo "(cd $d ; $ACLOCAL)"
+ (cd $d ; $ACLOCAL)
+ done
+fi
+
+if test -n "$MY_AHDIRS"; then
+ for d in $MY_AHDIRS ; do
+ echo "(cd $d ; $AUTOHEADER)"
+ (cd $d ; $AUTOHEADER)
+ done
+fi
+
+if test -n "$MY_AMDIRS"; then
+ for d in $MY_AMDIRS ; do
+ echo "(cd $d ; $AUTOMAKE -a)"
+ (cd $d ; $AUTOMAKE -a)
+ done
+fi
+
+if test -n "$MY_ACDIRS"; then
+ for d in $MY_ACDIRS ; do
+ echo "(cd $d ; $AUTOCONF)"
+ (cd $d ; $AUTOCONF)
+ done
+fi
+
+#echo "(./configure)"
+#./configure $*
diff --git a/readdir/config/Makefile.am b/readdir/config/Makefile.am
new file mode 100644
index 0000000..0ab0c12
--- /dev/null
+++ b/readdir/config/Makefile.am
@@ -0,0 +1,66 @@
+## File: config/Makefile.am
+## Package: readdir
+## Description:
+## + automake file for 'config' package-subdir
+##
+## Process this file with Automake to create Makefile.in.
+##-----------------------------------------------------------------------
+
+##-----------------------------------------------------------------------
+## Variables: options
+##-----------------------------------------------------------------------
+
+##-----------------------------------------------------------------------
+## Variables: cleanup
+##-----------------------------------------------------------------------
+
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+#CLEANFILES =
+
+## --- distclean: built by 'configure'
+#DISTCLEANFILES =
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = \
+ *~ .*~ \
+ compile Makefile Makefile.in \
+ config.guess \
+ config.sub \
+ depcomp \
+ install-sh \
+ ltmain.sh \
+ missing \
+ mkinstalldirs \
+ texinfo.tex \
+ ylwrap
+
+
+##-----------------------------------------------------------------------
+## Variables: distribution
+##-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = \
+ Makefile.in \
+ depcomp \
+ install-sh \
+ mkinstalldirs \
+ missing
+
+# config.guess
+# config.sub
+# ltmain.sh
+# texinfo.tex
+
+## --- recursion subdirectories for 'make dist'
+#DIST_SUBDIRS = $(SUBDIRS)
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
diff --git a/readdir/configure.in b/readdir/configure.in
new file mode 100644
index 0000000..466924a
--- /dev/null
+++ b/readdir/configure.in
@@ -0,0 +1,197 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl -- for a clean build, run: aclocal && autoheader && automake -a && autoconf
+AC_PREREQ(2.5)
+
+dnl Some handy macros
+define([THE_PACKAGE_NAME], [readdir])
+define([THE_PACKAGE_VERSION], [0.02])
+define([THE_PACKAGE_AUTHOR], [moocow@ling.uni-potsdam.de])
+
+AC_INIT(THE_PACKAGE_NAME, THE_PACKAGE_VERSION, THE_PACKAGE_AUTHOR)
+
+dnl
+dnl source & aux
+dnl
+AC_CONFIG_AUX_DIR(config)
+
+dnl
+dnl save user's CFLAGS,CPPFLAGS
+dnl
+UCPPFLAGS="$CPPFLAGS"
+UCFLAGS="$CFLAGS"
+
+dnl
+dnl use automake
+dnl
+AM_INIT_AUTOMAKE(THE_PACKAGE_NAME, THE_PACKAGE_VERSION)
+
+dnl
+dnl use autoheader
+dnl
+AM_CONFIG_HEADER(src/config.h)
+
+
+dnl
+dnl Programs, prefix
+dnl
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PREFIX_DEFAULT(/usr/local)
+
+dnl
+dnl Substitutions
+dnl
+AC_SUBST(DEFS)
+AC_SUBST(AFLAGS)
+AC_SUBST(DFLAGS)
+AC_SUBST(IFLAGS)
+AC_SUBST(LFLAGS)
+AC_SUBST(OFLAGS)
+AC_SUBST(WFLAGS)
+AC_SUBST(LD)
+
+AC_SUBST(PDEXT)
+
+dnl version stuff (automatically exported?)
+AC_SUBST(PACKAGE_VERSION)
+AC_SUBST(PACKAGE_NAME)
+AC_SUBST(BUGREPORT)
+
+dnl other flags
+dnl AC_ISC_POSIX
+
+dnl Checks for header files.
+dnl AC_HEADER_STDC
+AC_CHECK_HEADERS([dirent.h fcntl.h string.h errno.h],
+ [],
+ AC_MSG_WARN([-----------------------------------------------------------------])
+ AC_MSG_WARN([could not find standard C headers -- things may get ugly])
+ AC_MSG_WARN([-----------------------------------------------------------------]),
+ [/* nonempty includes: compile only */])
+
+
+dnl PD externals
+PD_OBJECT_EXTERNALS="readdir\$(EXEEXT)"
+AC_SUBST(PD_OBJECT_EXTERNALS)
+
+
+dnl
+dnl pd-directory/ies
+dnl
+AC_ARG_WITH(pd-dir,
+ AC_HELP_STRING([--with-pd-dir=DIR], [PD base directory (default=PREFIX/pd)]),
+ [pddir="$withval"],
+ [pddir="\${prefix}/pd"])
+pddocdir="${pddir}/doc/5.reference"
+AC_SUBST(pddir)
+AC_SUBST(pddocdir)
+
+
+
+AC_ARG_WITH(pd-include,
+ AC_HELP_STRING([--with-pd-include=DIR], [PD include directory (default=NONE)]),
+ [pdincludedir="$withval"],
+ [pdincludedir=""])
+if test -n "$pdincludedir" ; then
+ IFLAGS="$IFLAGS -I$pdincludedir"
+fi
+AC_SUBST(pdincludedir)
+
+AC_ARG_WITH(pd-extdir,
+ AC_HELP_STRING([--with-pd-extdir=DIR], [Directory for PD externals (default=PDDIR/externs)]),
+ [pdexternsdir="$withval"],
+ [pdexternsdir="$pddir/externs"])
+AC_SUBST(pdexternsdir)
+
+dnl
+dnl Check for m_pd.h
+dnl
+CPPFLAGS="$CPPFLAGS $IFLAGS"
+AC_CHECK_HEADER(m_pd.h,[],
+ AC_MSG_WARN([-----------------------------------------------------------------])
+ AC_MSG_WARN([could not find PD header file 'm_pd.h' -- things might get ugly.])
+ AC_MSG_WARN([-----------------------------------------------------------------]),
+ [/* nonempty includes: compile only */])
+
+
+dnl
+dnl debug version?
+dnl
+AC_MSG_CHECKING([whether we are building a debug version])
+AC_ARG_ENABLE([debug],
+ AC_HELP_STRING([--enable-debug],[build debug version (default=no)]))
+if test "$enable_debug" == "yes" ; then
+ AC_MSG_RESULT(yes)
+ DEBUG="yes"
+ AC_DEFINE(READDIR_DEBUG,1,
+ [Define this to include debugging code for the 'readdir' external.])
+else
+ AC_MSG_RESULT(no)
+ DEBUG="no"
+fi
+AC_SUBST(DEBUG)
+
+
+
+dnl
+dnl machine-dependent variables
+dnl
+LD=ld
+if test `uname -s` = Linux;
+then
+ LFLAGS="-export_dynamic -shared"
+ if test "$DEBUG" == "no"; then
+ #OFLAGS="-O6 -funroll-loops -fomit-frame-pointer -finline-limit-10000000"
+ OFLAGS="-O6 -funroll-loops -fomit-frame-pointer"
+ else
+ OFLAGS="-g"
+ fi
+ PDEXT=pd_linux
+fi
+
+if test `uname -m` = alpha;
+then
+ AFLAGS="-mieee -mcpu=ev56";
+ OFLAGS="$CFLAGS"
+fi
+
+if test `uname -s` = IRIX64;
+then
+ LFLAGS="-n32 -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \
+ -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \
+ -shared -rdata_shared"
+ OFLAGS="$CFLAGS"
+ PDEXT=pd_irix6
+fi
+
+if test `uname -s` = IRIX32;
+then
+ LFLAGS="-o32 -DUNIX -DIRIX -O2 -shared -rdata_shared"
+ OFLAGS="$CFLAGS"
+ PDEXT=pd_irix5
+fi
+
+dnl
+dnl Flags for MacOSX, borrowed from pd-0.35-test16
+dnl
+if test `uname -s` = Darwin;
+then
+ LD=cc
+ LFLAGS="-bundle -undefined suppress -flat_namespace"
+ PDEXT=pd_darwin
+ DFLAGS="$DFLAGS -DMACOSX"
+
+ if test "$DEBUG" == "no"; then
+ OFLAGS="-O2"
+ else
+ OFLAGS="-g"
+ fi
+fi
+
+dnl
+dnl restore user's CFLAGS
+dnl
+CFLAGS="$UCFLAGS"
+CPPFLAGS="$UCPPFLAGS"
+
+AC_OUTPUT(config/Makefile src/Makefile Makefile)
diff --git a/readdir/src/Makefile.am b/readdir/src/Makefile.am
new file mode 100644
index 0000000..53f09c0
--- /dev/null
+++ b/readdir/src/Makefile.am
@@ -0,0 +1,135 @@
+# File: ./src/Makefile.am
+# Package: readdir
+# Description:
+# + src-level automake file
+#
+# Process this file with Automake to create Makefile.in.
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Options & Subdirectories
+#-----------------------------------------------------------------------
+
+## --- recursion subdirectories
+#SUBDIRS =
+
+## --- pseudo-deps for '.SUFFIXES'
+SUFFIXES = .@PDEXT@
+
+#-----------------------------------------------------------------------
+# Flags and variables
+#-----------------------------------------------------------------------
+PDEXT = @PDEXT@
+EXEEXT = .@PDEXT@
+
+#-----------------------------------------------------------------------
+# pd externals (hacked _PROGRAMS target)
+#-----------------------------------------------------------------------
+
+## --- externals
+pdexterns_PROGRAMS = @PD_OBJECT_EXTERNALS@
+
+## --- possible externals
+EXTRA_PROGRAMS = \
+ readdir
+
+## --- patches
+pdexterns_DATA =
+
+## --- documentation
+pddoc_DATA = readdir-help.pd
+
+
+#-----------------------------------------------------------------------
+# sources
+#-----------------------------------------------------------------------
+
+readdir_SOURCES = \
+ readdir.c
+
+#-----------------------------------------------------------------------
+# external compilation : flags
+#-----------------------------------------------------------------------
+DEFS = @DEFS@
+AFLAGS = @AFLAGS@
+DFLAGS = @DFLAGS@
+IFLAGS = @IFLAGS@
+LFLAGS = @LFLAGS@
+OFLAGS = @OFLAGS@
+WFLAGS = -Wall -Winline
+
+#GLIB_IFLAGS = @GLIB_IFLAGS@
+#GLIB_LFLAGS = @GLIB_LFLAGS@
+
+AM_CPPFLAGS = $(IFLAGS) $(GLIB_IFLAGS) $(DFLAGS)
+AM_CFLAGS = $(OFLAGS) $(WFLAGS) $(AFLAGS)
+
+readdir_LDFLAGS = $(LFLAGS)
+readdir_LDADD = $(GLIB_LFLAGS)
+
+#-----------------------------------------------------------------------
+# Variables: cleanup
+#-----------------------------------------------------------------------
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+CLEANFILES = *$(EXEEXT)
+
+## --- distclean: built by 'configure'
+DISTCLEANFILES = \
+ config.log \
+ config.cache \
+ config.status
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = *~ \
+ $(PODS:.pod=.txt) \
+ Makefile Makefile.in \
+ aclocal.m4 \
+ configure \
+ install-sh \
+ stamp-h.in \
+ config.h.in
+
+maintainer-clean-local:
+ rm -rf autom4te.cache
+
+#CVSCLEAN_SUBDIRS = $(SUBDIRS)
+
+#CVSCLEANFILES = Makefile.in Makefile
+
+
+#-----------------------------------------------------------------------
+# Variables: distribution
+#-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = \
+ $(pddoc_DATA) \
+ $(pdexterns_DATA)
+
+## --- recursion subdirectories for 'make dist'
+DIST_SUBDIRS = $(SUBDIRS)
+
+## --- dist-hook: when another 'Makefile.am' is overkill
+#DISTHOOK_DIRS = foo
+#DISTHOOK_FILES = foo/bar.txt foo/baz.txt
+#dist-hook:
+# for d in $(DISTHOOK_DIRS); do\
+# mkdir -p $(distdir)/$$d ;\
+# done
+# for f in $(DISTHOOK_FILES); do\
+# cp -p $(srcdir)/$$f $(distdir)/$$f ;\
+# done
+
+#dist-bz2: dist-bzip2 ;
+
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
+
diff --git a/readdir/src/readdir-help.pd b/readdir/src/readdir-help.pd
new file mode 100644
index 0000000..c3e752c
--- /dev/null
+++ b/readdir/src/readdir-help.pd
@@ -0,0 +1,41 @@
+#N canvas 356 19 535 566 10;
+#X msg 89 227 close;
+#X msg 52 79 bang;
+#X msg 83 160 tell;
+#X obj 38 322 print dir-entry;
+#X obj 82 294 print end-of-directory;
+#X text 130 8 readdir : simple directory accessor;
+#X text 231 543 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X text 157 46 open DIR : opens the directory DIR;
+#X text 185 75 bang : outlet next directory entry;
+#X text 185 91 next : ditto;
+#X msg 59 101 next;
+#X msg 71 137 rewind;
+#X text 173 137 rewind : return to beginning of directory;
+#X text 188 158 tell : output current position;
+#X text 146 182 seek FLOAT : goto position FLOAT;
+#X msg 86 184 seek 0;
+#X text 181 223 close : close directory;
+#X text 258 295 2nd outlet bangs at end of directory;
+#X text 260 325 Directory entries go to 1st outlet;
+#X text 39 370 Directory entries appear as messages of the form TYPE
+NAME \, where NAME is the name of the entry \, and TYPE is one of the
+following:;
+#X text 65 515 unknown : something else;
+#X text 87 419 file : regular file;
+#X text 93 434 dir : subdirectory;
+#X text 86 450 fifo : named pipe;
+#X text 85 466 sock : local-domain socket;
+#X text 71 482 chrdev : character device;
+#X text 71 498 blkdev : block device;
+#X obj 38 267 readdir;
+#X msg 39 47 open /tmp;
+#X connect 0 0 27 0;
+#X connect 1 0 27 0;
+#X connect 2 0 27 0;
+#X connect 10 0 27 0;
+#X connect 11 0 27 0;
+#X connect 15 0 27 0;
+#X connect 27 0 3 0;
+#X connect 27 1 4 0;
+#X connect 28 0 27 0;
diff --git a/readdir/src/readdir-test.pd b/readdir/src/readdir-test.pd
new file mode 100644
index 0000000..dbfc3a7
--- /dev/null
+++ b/readdir/src/readdir-test.pd
@@ -0,0 +1,28 @@
+#N canvas 468 56 337 420 10;
+#X obj 64 274 readdir;
+#X msg 141 236 close;
+#X obj 108 301 print end-of-directory;
+#X msg 85 119 bang;
+#X msg 64 93 open \$1;
+#X msg 64 37 .;
+#X msg 101 37 test;
+#X msg 144 37 foo;
+#X obj 64 69 symbol;
+#X obj 64 328 print entry;
+#X msg 109 166 tell;
+#X msg 105 142 rewind;
+#X msg 148 202 seek \$1;
+#X floatatom 147 183 5 0 0;
+#X connect 0 0 9 0;
+#X connect 0 1 2 0;
+#X connect 1 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 8 0;
+#X connect 6 0 8 0;
+#X connect 7 0 8 0;
+#X connect 8 0 4 0;
+#X connect 10 0 0 0;
+#X connect 11 0 0 0;
+#X connect 12 0 0 0;
+#X connect 13 0 12 0;
diff --git a/readdir/src/readdir.c b/readdir/src/readdir.c
new file mode 100644
index 0000000..5500408
--- /dev/null
+++ b/readdir/src/readdir.c
@@ -0,0 +1,278 @@
+/* -*- Mode: C -*- */
+/*=============================================================================*\
+ * File: readdir.c
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: general directory access object
+ *
+ * Copyright (c) 2003 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include <m_pd.h>
+
+/* black magic */
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/*--------------------------------------------------------------------
+ * DEBUG
+ *--------------------------------------------------------------------*/
+//#define READDIR_DEBUG 1
+
+
+/*=====================================================================
+ * Constants
+ *=====================================================================*/
+#ifdef READDIR_DEBUG
+// error-message buffer
+#define EBUFSIZE 256
+static char readdir_errbuf[EBUFSIZE];
+#endif
+
+/*=====================================================================
+ * Structures and Types
+ *=====================================================================*/
+
+static char *readdir_banner = "\nreaddir version %s by Bryan Jurish : simple directory accessor";
+
+static t_class *readdir_class;
+
+typedef struct _readdir
+{
+ t_object x_obj;
+ DIR *x_dir; //-- current directory
+ t_symbol *x_dirname; //-- current directory name
+ //struct dirent *x_dirent; //-- current entry of current directory
+ t_atom x_eatom; //-- current output atom (symbol)
+ t_outlet *x_ent_outlet; //-- entry outlet
+ t_outlet *x_eod_outlet; //-- end-of-directory outlet
+} t_readdir;
+
+/*=====================================================================
+ * Constants
+ *=====================================================================*/
+static t_symbol *sp_none;
+static t_symbol *sp_unknown;
+static t_symbol *sp_file;
+static t_symbol *sp_dir;
+static t_symbol *sp_fifo;
+static t_symbol *sp_sock;
+static t_symbol *sp_chrdev;
+static t_symbol *sp_blkdev;
+
+/*--------------------------------------------------------------------
+ * close
+ */
+static void readdir_close(t_readdir *x)
+{
+ if (!x->x_dir) return;
+ if (0 != closedir(x->x_dir)) {
+ error("readdir: cannot close %s: %s", x->x_dirname->s_name, strerror(errno));
+ return;
+ }
+ x->x_dir = NULL;
+ x->x_dirname = sp_none;
+}
+
+/*--------------------------------------------------------------------
+ * open DIR
+ */
+static void readdir_open(t_readdir *x, t_symbol *dirname)
+{
+#ifdef READDIR_DEBUG
+ post("readdir: got message: open %s", dirname->s_name);
+#endif
+
+ if (x->x_dir) readdir_close(x);
+ if ( !(x->x_dir = opendir(dirname->s_name)) ) {
+ error("readdir: cannot open %s: %s", dirname->s_name, strerror(errno));
+ return;
+ }
+ x->x_dirname = dirname;
+}
+
+/*--------------------------------------------------------------------
+ * next : get next entry
+ */
+static void readdir_next(t_readdir *x)
+{
+ t_symbol *sel = sp_unknown;
+ struct dirent *result = NULL;
+ if ( !x->x_dir || !(result = readdir(x->x_dir)) ) {
+ if (errno == EBADF) {
+ //-- real error
+ error("readdir: cannot read from %s: %s", x->x_dirname->s_name, strerror(errno));
+ }
+ else {
+ //-- end of directory
+ outlet_bang(x->x_eod_outlet);
+ }
+ return;
+ }
+
+ //-- get type
+ switch (result->d_type)
+ {
+ case DT_REG:
+ sel = sp_file;
+ break;
+
+ case DT_DIR:
+ sel = sp_dir;
+ break;
+
+ case DT_FIFO:
+ sel = sp_fifo;
+ break;
+
+ case DT_SOCK:
+ sel = sp_sock;
+ break;
+
+ case DT_CHR:
+ sel = sp_chrdev;
+ break;
+
+ case DT_BLK:
+ sel = sp_blkdev;
+ break;
+
+ default:
+ sel = sp_unknown;
+ break;
+ }
+
+ x->x_eatom.a_w.w_symbol = gensym(result->d_name);
+ outlet_anything(x->x_ent_outlet, sel, 1, &x->x_eatom);
+}
+
+/*--------------------------------------------------------------------
+ * rewind
+ */
+static void readdir_rewind(t_readdir *x)
+{
+ if (x->x_dir) rewinddir(x->x_dir);
+}
+
+/*--------------------------------------------------------------------
+ * tell
+ */
+static void readdir_tell(t_readdir *x)
+{
+ off_t off = 0;
+ if (x->x_dir) off = telldir(x->x_dir);
+ outlet_float(x->x_ent_outlet, (t_float)off);
+}
+
+/*--------------------------------------------------------------------
+ * seek FLOAT
+ */
+static void readdir_seek(t_readdir *x, t_floatarg pos)
+{
+ if (!x->x_dir) {
+ error("readdir: seek %f: no directory opened!", pos);
+ return;
+ }
+ seekdir(x->x_dir, (off_t)pos);
+}
+
+
+/*--------------------------------------------------------------------
+ * new
+ */
+static void *readdir_new(void)
+{
+ t_readdir *x = (t_readdir *)pd_new(readdir_class);
+
+ //-- defaults
+ x->x_dir = NULL;
+ x->x_dirname = sp_none;
+ SETSYMBOL(&x->x_eatom, sp_none);
+
+ //-- outlets
+ x->x_ent_outlet = outlet_new(&x->x_obj, &s_symbol);
+ x->x_eod_outlet = outlet_new(&x->x_obj, &s_bang);
+
+ return (void *)x;
+}
+
+/*--------------------------------------------------------------------
+ * free
+ */
+static void readdir_free(t_readdir *x)
+{
+ readdir_close(x);
+ outlet_free(x->x_ent_outlet);
+ outlet_free(x->x_eod_outlet);
+ return;
+}
+
+/*--------------------------------------------------------------------
+ * setup
+ */
+void readdir_setup(void)
+{
+ post(readdir_banner, PACKAGE_VERSION);
+#ifdef READDIR_DEBUG
+ post("readdir : debugging enabled");
+#endif
+
+ //-- constants
+ sp_none = gensym("none");
+ sp_unknown = gensym("unknown");
+ sp_file = gensym("file");
+ sp_dir = gensym("dir");
+ sp_fifo = gensym("fifo");
+ sp_sock = gensym("sock");
+ sp_chrdev = gensym("chrdev");
+ sp_blkdev = gensym("blkdev");
+
+ //-- class
+ readdir_class = class_new(gensym("readdir"),
+ (t_newmethod)readdir_new,
+ (t_method)readdir_free,
+ sizeof(t_readdir),
+ CLASS_DEFAULT,
+ 0);
+
+ //-- methods
+ class_addmethod(readdir_class, (t_method)readdir_open, gensym("open"), A_DEFSYMBOL, 0);
+ class_addmethod(readdir_class, (t_method)readdir_close, gensym("close"), 0);
+ class_addmethod(readdir_class, (t_method)readdir_next, gensym("next"), 0);
+ class_addbang(readdir_class, (t_method)readdir_next);
+ class_addmethod(readdir_class, (t_method)readdir_rewind, gensym("rewind"), 0);
+ class_addmethod(readdir_class, (t_method)readdir_tell, gensym("tell"), 0);
+ class_addmethod(readdir_class, (t_method)readdir_seek, gensym("seek"), A_DEFFLOAT, 0);
+
+ //-- help symbol
+ class_sethelpsymbol(readdir_class, gensym("readdir-help.pd"));
+}
diff --git a/weightmap/COPYING b/weightmap/COPYING
new file mode 100644
index 0000000..fa0bef4
--- /dev/null
+++ b/weightmap/COPYING
@@ -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/weightmap/Changes b/weightmap/Changes
new file mode 100644
index 0000000..6e9711a
--- /dev/null
+++ b/weightmap/Changes
@@ -0,0 +1,7 @@
+Change log for PD external 'weightmap'
+
+v0.02 Thu, 02 Feb 2006 12:41:36 +0100
+ + automake'd version
+
+v0.01 Sat Apr 20 21:52:03 CEST 2002
+ + initial distributed version
diff --git a/weightmap/Makefile.am b/weightmap/Makefile.am
new file mode 100644
index 0000000..e1c1480
--- /dev/null
+++ b/weightmap/Makefile.am
@@ -0,0 +1,98 @@
+# File: ./Makefile.am
+# Package: weightmap
+# Description:
+# + top-level automake file
+#
+# Process this file with Automake to create Makefile.in.
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Options & Subdirectories
+#-----------------------------------------------------------------------
+
+## --- automake options
+#AUTOMAKE_OPTIONS = foreign dist-bzip2 dist-zip
+AUTOMAKE_OPTIONS = foreign
+
+## --- recursion subdirectories
+SUBDIRS = config src
+
+## --- pseudo-deps for '.SUFFIXES'
+SUFFIXES = .pod .txt
+
+#-----------------------------------------------------------------------
+# Variables: cleanup
+#-----------------------------------------------------------------------
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+#CLEANFILES =
+
+## --- distclean: built by 'configure'
+DISTCLEANFILES = \
+ config.log \
+ config.cache \
+ config.status
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = *~ \
+ $(PODS:.pod=.txt) \
+ Makefile Makefile.in \
+ aclocal.m4 \
+ configure \
+ install-sh \
+ stamp-h.in \
+ config.h.in
+
+maintainer-clean-local:
+ rm -rf autom4te.cache
+
+#CVSCLEAN_SUBDIRS = $(SUBDIRS)
+
+#CVSCLEANFILES = Makefile.in Makefile
+
+
+#-----------------------------------------------------------------------
+# Additional Variables & Rules: PODS
+#-----------------------------------------------------------------------
+PODS = README.pod
+
+.pod.txt:
+ pod2text $< $@
+
+all-local: $(PODS:.pod=.txt)
+
+#-----------------------------------------------------------------------
+# Variables: distribution
+#-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = \
+ $(PODS:.pod=.txt) autogen.sh configure \
+ README.cvs COPYING
+
+## --- recursion subdirectories for 'make dist'
+#DIST_SUBDIRS = $(SUBDIRS)
+
+## --- dist-hook: when another 'Makefile.am' is overkill
+#DISTHOOK_DIRS = foo
+#DISTHOOK_FILES = foo/bar.txt foo/baz.txt
+#dist-hook:
+# for d in $(DISTHOOK_DIRS); do\
+# mkdir -p $(distdir)/$$d ;\
+# done
+# for f in $(DISTHOOK_FILES); do\
+# cp -p $(srcdir)/$$f $(distdir)/$$f ;\
+# done
+
+#dist-bz2: dist-bzip2 ;
+
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
+
diff --git a/weightmap/README.cvs b/weightmap/README.cvs
new file mode 100644
index 0000000..96b1253
--- /dev/null
+++ b/weightmap/README.cvs
@@ -0,0 +1,16 @@
+To build from cvs, do the following:
+
+ ./autogen.sh
+ ./configure
+ make
+ make install
+
+You will need recent versions of GNU automake and
+autoconf in order to build from the CVS tree.
+
+NOTE: The README.txt file in the distribution
+is auto-generated from perl ".pod" format by
+the "pod2text" included in most perl distributions.
+
+marmosets,
+ Bryan
diff --git a/weightmap/README.pod b/weightmap/README.pod
new file mode 100644
index 0000000..a7cdde9
--- /dev/null
+++ b/weightmap/README.pod
@@ -0,0 +1,40 @@
+=pod
+
+README for weightmap
+
+Last updated for weightmap v0.02
+
+=head1 DESCRIPTION
+
+weightmap is a PD external which maps incoming probability
+values to integers, inspired in part by Yves Degoyon's 'probalizer' object.
+
+
+=head1 INSTALLATION
+
+Issue the following commands to the shell:
+
+ cd weightmap-X.YY (or wherever you extracted the distribution)
+ ./configure
+ make
+ make install
+
+=head1 ACKNOWLEDGEMENTS
+
+PD by Miller Puckette and others.
+
+probalizer object by Yves Degoyon.
+
+Ideas, black magic, and other nuggets of information drawn
+from code by Guenter Geiger, Larry Troxler, and iohannes m zmoelnig.
+
+=head1 BUGS
+
+It's a misleading name: higher input "weights" don't neccesarily
+correspond to higer stored "weights".
+
+Probably many more serious ones as well.
+
+=head1 AUTHOR
+
+Bryan Jurish E<lt>moocow@ling.uni-potsdam.deE<gt>
diff --git a/weightmap/autogen.sh b/weightmap/autogen.sh
new file mode 100755
index 0000000..845f276
--- /dev/null
+++ b/weightmap/autogen.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+#-----------------------------------------------------------------------
+# File: autogen.sh
+# Description:
+# + wrapper for m4 black-magic
+#-----------------------------------------------------------------------
+
+MY_ALDIRS="."
+MY_AHDIRS="."
+MY_AMDIRS="."
+MY_ACDIRS="."
+
+test -z "$ACLOCAL" && ACLOCAL=aclocal
+test -z "$AUTOHEADER" && AUTOHEADER=autoheader
+test -z "$AUTOMAKE" && AUTOMAKE=automake
+test -z "$AUTOCONF" && AUTOCONF=autoconf
+
+if test -n "$MY_ALDIRS"; then
+ for d in $MY_ALDIRS ; do
+ echo "(cd $d ; $ACLOCAL)"
+ (cd $d ; $ACLOCAL)
+ done
+fi
+
+if test -n "$MY_AHDIRS"; then
+ for d in $MY_AHDIRS ; do
+ echo "(cd $d ; $AUTOHEADER)"
+ (cd $d ; $AUTOHEADER)
+ done
+fi
+
+if test -n "$MY_AMDIRS"; then
+ for d in $MY_AMDIRS ; do
+ echo "(cd $d ; $AUTOMAKE -a)"
+ (cd $d ; $AUTOMAKE -a)
+ done
+fi
+
+if test -n "$MY_ACDIRS"; then
+ for d in $MY_ACDIRS ; do
+ echo "(cd $d ; $AUTOCONF)"
+ (cd $d ; $AUTOCONF)
+ done
+fi
+
+#echo "(./configure)"
+#./configure $*
diff --git a/weightmap/config/Makefile.am b/weightmap/config/Makefile.am
new file mode 100644
index 0000000..a2bb5d1
--- /dev/null
+++ b/weightmap/config/Makefile.am
@@ -0,0 +1,66 @@
+## File: config/Makefile.am
+## Package: weightmap
+## Description:
+## + automake file for 'config' package-subdir
+##
+## Process this file with Automake to create Makefile.in.
+##-----------------------------------------------------------------------
+
+##-----------------------------------------------------------------------
+## Variables: options
+##-----------------------------------------------------------------------
+
+##-----------------------------------------------------------------------
+## Variables: cleanup
+##-----------------------------------------------------------------------
+
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+#CLEANFILES =
+
+## --- distclean: built by 'configure'
+#DISTCLEANFILES =
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = \
+ *~ .*~ \
+ compile Makefile Makefile.in \
+ config.guess \
+ config.sub \
+ depcomp \
+ install-sh \
+ ltmain.sh \
+ missing \
+ mkinstalldirs \
+ texinfo.tex \
+ ylwrap
+
+
+##-----------------------------------------------------------------------
+## Variables: distribution
+##-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = \
+ Makefile.in \
+ depcomp \
+ install-sh \
+ mkinstalldirs \
+ missing
+
+# config.guess
+# config.sub
+# ltmain.sh
+# texinfo.tex
+
+## --- recursion subdirectories for 'make dist'
+#DIST_SUBDIRS = $(SUBDIRS)
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
diff --git a/weightmap/configure.in b/weightmap/configure.in
new file mode 100644
index 0000000..958750b
--- /dev/null
+++ b/weightmap/configure.in
@@ -0,0 +1,197 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl -- for a clean build, run: aclocal && autoheader && automake -a && autoconf
+AC_PREREQ(2.5)
+
+dnl Some handy macros
+define([THE_PACKAGE_NAME], [weightmap])
+define([THE_PACKAGE_VERSION], [0.01])
+define([THE_PACKAGE_AUTHOR], [moocow@ling.uni-potsdam.de])
+
+AC_INIT(THE_PACKAGE_NAME, THE_PACKAGE_VERSION, THE_PACKAGE_AUTHOR)
+
+dnl
+dnl source & aux
+dnl
+AC_CONFIG_AUX_DIR(config)
+
+dnl
+dnl save user's CFLAGS,CPPFLAGS
+dnl
+UCPPFLAGS="$CPPFLAGS"
+UCFLAGS="$CFLAGS"
+
+dnl
+dnl use automake
+dnl
+AM_INIT_AUTOMAKE(THE_PACKAGE_NAME, THE_PACKAGE_VERSION)
+
+dnl
+dnl use autoheader
+dnl
+AM_CONFIG_HEADER(src/config.h)
+
+
+dnl
+dnl Programs, prefix
+dnl
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PREFIX_DEFAULT(/usr/local)
+
+dnl
+dnl Substitutions
+dnl
+AC_SUBST(DEFS)
+AC_SUBST(AFLAGS)
+AC_SUBST(DFLAGS)
+AC_SUBST(IFLAGS)
+AC_SUBST(LFLAGS)
+AC_SUBST(OFLAGS)
+AC_SUBST(WFLAGS)
+AC_SUBST(LD)
+
+AC_SUBST(PDEXT)
+
+dnl version stuff (automatically exported?)
+AC_SUBST(PACKAGE_VERSION)
+AC_SUBST(PACKAGE_NAME)
+AC_SUBST(BUGREPORT)
+
+dnl other flags
+dnl AC_ISC_POSIX
+
+dnl Checks for header files.
+dnl AC_HEADER_STDC
+AC_CHECK_HEADERS([math.h],
+ [],
+ AC_MSG_WARN([-----------------------------------------------------------------])
+ AC_MSG_WARN([could not find standard C headers -- things may get ugly])
+ AC_MSG_WARN([-----------------------------------------------------------------]),
+ [/* nonempty includes: compile only */])
+
+
+dnl PD externals
+PD_OBJECT_EXTERNALS="weightmap\$(EXEEXT)"
+AC_SUBST(PD_OBJECT_EXTERNALS)
+
+
+dnl
+dnl pd-directory/ies
+dnl
+AC_ARG_WITH(pd-dir,
+ AC_HELP_STRING([--with-pd-dir=DIR], [PD base directory (default=PREFIX/pd)]),
+ [pddir="$withval"],
+ [pddir="\${prefix}/pd"])
+pddocdir="${pddir}/doc/5.reference"
+AC_SUBST(pddir)
+AC_SUBST(pddocdir)
+
+
+
+AC_ARG_WITH(pd-include,
+ AC_HELP_STRING([--with-pd-include=DIR], [PD include directory (default=NONE)]),
+ [pdincludedir="$withval"],
+ [pdincludedir=""])
+if test -n "$pdincludedir" ; then
+ IFLAGS="$IFLAGS -I$pdincludedir"
+fi
+AC_SUBST(pdincludedir)
+
+AC_ARG_WITH(pd-extdir,
+ AC_HELP_STRING([--with-pd-extdir=DIR], [Directory for PD externals (default=PDDIR/externs)]),
+ [pdexternsdir="$withval"],
+ [pdexternsdir="$pddir/externs"])
+AC_SUBST(pdexternsdir)
+
+dnl
+dnl Check for m_pd.h
+dnl
+CPPFLAGS="$CPPFLAGS $IFLAGS"
+AC_CHECK_HEADER(m_pd.h,[],
+ AC_MSG_WARN([-----------------------------------------------------------------])
+ AC_MSG_WARN([could not find PD header file 'm_pd.h' -- things might get ugly.])
+ AC_MSG_WARN([-----------------------------------------------------------------]),
+ [/* nonempty includes: compile only */])
+
+
+dnl
+dnl debug version?
+dnl
+AC_MSG_CHECKING([whether we are building a debug version])
+AC_ARG_ENABLE([debug],
+ AC_HELP_STRING([--enable-debug],[build debug version (default=no)]))
+if test "$enable_debug" == "yes" ; then
+ AC_MSG_RESULT(yes)
+ DEBUG="yes"
+ AC_DEFINE(WEIGHTMAP_DEBUG,1,
+ [Define this to include debugging code for the 'weightmap' external.])
+else
+ AC_MSG_RESULT(no)
+ DEBUG="no"
+fi
+AC_SUBST(DEBUG)
+
+
+
+dnl
+dnl machine-dependent variables
+dnl
+LD=ld
+if test `uname -s` = Linux;
+then
+ LFLAGS="-export_dynamic -shared"
+ if test "$DEBUG" == "no"; then
+ #OFLAGS="-O6 -funroll-loops -fomit-frame-pointer -finline-limit-10000000"
+ OFLAGS="-O6 -funroll-loops -fomit-frame-pointer"
+ else
+ OFLAGS="-g"
+ fi
+ PDEXT=pd_linux
+fi
+
+if test `uname -m` = alpha;
+then
+ AFLAGS="-mieee -mcpu=ev56";
+ OFLAGS="$CFLAGS"
+fi
+
+if test `uname -s` = IRIX64;
+then
+ LFLAGS="-n32 -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \
+ -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \
+ -shared -rdata_shared"
+ OFLAGS="$CFLAGS"
+ PDEXT=pd_irix6
+fi
+
+if test `uname -s` = IRIX32;
+then
+ LFLAGS="-o32 -DUNIX -DIRIX -O2 -shared -rdata_shared"
+ OFLAGS="$CFLAGS"
+ PDEXT=pd_irix5
+fi
+
+dnl
+dnl Flags for MacOSX, borrowed from pd-0.35-test16
+dnl
+if test `uname -s` = Darwin;
+then
+ LD=cc
+ LFLAGS="-bundle -undefined suppress -flat_namespace"
+ PDEXT=pd_darwin
+ DFLAGS="$DFLAGS -DMACOSX"
+
+ if test "$DEBUG" == "no"; then
+ OFLAGS="-O2"
+ else
+ OFLAGS="-g"
+ fi
+fi
+
+dnl
+dnl restore user's CFLAGS
+dnl
+CFLAGS="$UCFLAGS"
+CPPFLAGS="$UCPPFLAGS"
+
+AC_OUTPUT(config/Makefile src/Makefile Makefile)
diff --git a/weightmap/src/Makefile.am b/weightmap/src/Makefile.am
new file mode 100644
index 0000000..a7feb67
--- /dev/null
+++ b/weightmap/src/Makefile.am
@@ -0,0 +1,135 @@
+# File: ./src/Makefile.am
+# Package: weightmap
+# Description:
+# + src-level automake file
+#
+# Process this file with Automake to create Makefile.in.
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Options & Subdirectories
+#-----------------------------------------------------------------------
+
+## --- recursion subdirectories
+#SUBDIRS =
+
+## --- pseudo-deps for '.SUFFIXES'
+SUFFIXES = .@PDEXT@
+
+#-----------------------------------------------------------------------
+# Flags and variables
+#-----------------------------------------------------------------------
+PDEXT = @PDEXT@
+EXEEXT = .@PDEXT@
+
+#-----------------------------------------------------------------------
+# pd externals (hacked _PROGRAMS target)
+#-----------------------------------------------------------------------
+
+## --- externals
+pdexterns_PROGRAMS = @PD_OBJECT_EXTERNALS@
+
+## --- possible externals
+EXTRA_PROGRAMS = \
+ weightmap
+
+## --- patches
+pdexterns_DATA =
+
+## --- documentation
+pddoc_DATA = weightmap-help.pd
+
+
+#-----------------------------------------------------------------------
+# sources
+#-----------------------------------------------------------------------
+
+weightmap_SOURCES = \
+ weightmap.c
+
+#-----------------------------------------------------------------------
+# external compilation : flags
+#-----------------------------------------------------------------------
+DEFS = @DEFS@
+AFLAGS = @AFLAGS@
+DFLAGS = @DFLAGS@
+IFLAGS = @IFLAGS@
+LFLAGS = @LFLAGS@
+OFLAGS = @OFLAGS@
+WFLAGS = -Wall -Winline
+
+#GLIB_IFLAGS = @GLIB_IFLAGS@
+#GLIB_LFLAGS = @GLIB_LFLAGS@
+
+AM_CPPFLAGS = $(IFLAGS) $(GLIB_IFLAGS) $(DFLAGS)
+AM_CFLAGS = $(OFLAGS) $(WFLAGS) $(AFLAGS)
+
+weightmap_LDFLAGS = $(LFLAGS)
+weightmap_LDADD = $(GLIB_LFLAGS)
+
+#-----------------------------------------------------------------------
+# Variables: cleanup
+#-----------------------------------------------------------------------
+## --- mostlyclean: built by 'make' & commonly rebuilt
+#MOSTLYCLEANFILES =
+
+## --- clean: built by 'make'
+CLEANFILES = *$(EXEEXT)
+
+## --- distclean: built by 'configure'
+DISTCLEANFILES = \
+ config.log \
+ config.cache \
+ config.status
+
+## -- maintainerclean: built by maintainer / by hand
+MAINTAINERCLEANFILES = *~ \
+ $(PODS:.pod=.txt) \
+ Makefile Makefile.in \
+ aclocal.m4 \
+ configure \
+ install-sh \
+ stamp-h.in \
+ config.h.in
+
+maintainer-clean-local:
+ rm -rf autom4te.cache
+
+#CVSCLEAN_SUBDIRS = $(SUBDIRS)
+
+#CVSCLEANFILES = Makefile.in Makefile
+
+
+#-----------------------------------------------------------------------
+# Variables: distribution
+#-----------------------------------------------------------------------
+
+## --- extra distribution files
+EXTRA_DIST = \
+ $(pddoc_DATA) \
+ $(pdexterns_DATA)
+
+## --- recursion subdirectories for 'make dist'
+DIST_SUBDIRS = $(SUBDIRS)
+
+## --- dist-hook: when another 'Makefile.am' is overkill
+#DISTHOOK_DIRS = foo
+#DISTHOOK_FILES = foo/bar.txt foo/baz.txt
+#dist-hook:
+# for d in $(DISTHOOK_DIRS); do\
+# mkdir -p $(distdir)/$$d ;\
+# done
+# for f in $(DISTHOOK_FILES); do\
+# cp -p $(srcdir)/$$f $(distdir)/$$f ;\
+# done
+
+#dist-bz2: dist-bzip2 ;
+
+
+#-----------------------------------------------------------------------
+# Rules: cleanup
+#-----------------------------------------------------------------------
+.PHONY: cvsclean cvsclean-hook
+
+cvsclean: maintainer-clean ;
+
diff --git a/weightmap/src/weightmap-help.pd b/weightmap/src/weightmap-help.pd
new file mode 100644
index 0000000..91709ff
--- /dev/null
+++ b/weightmap/src/weightmap-help.pd
@@ -0,0 +1,74 @@
+#N canvas 18 0 910 582 10;
+#X text 33 1 weightmap : map probabilities to associated integers;
+#X obj 114 364 print wmap_dump;
+#X obj 8 364 print wmap_out;
+#X obj 8 338 weightmap 3 100;
+#X text 463 79 SIZE : number of elements (integer);
+#X text 429 91 MAXWEIGHT : maximum expected input (float) [default=100]
+;
+#X text 395 65 weightmap SIZE [MAXWEIGHT];
+#X text 375 51 SYNTAX:;
+#X text 373 119 INLETS:;
+#X text 393 133 1 - floats ("weights" or "probabilities");
+#X text 421 147 OR messages;
+#X text 373 175 OUTLETS:;
+#X text 391 201 2 - miscellaneous output;
+#X text 391 187 1 - index (int) of stored weight matching input float
+;
+#X text 377 239 MESSAGES:;
+#X text 441 313 dump : dump the current weight-vector as a list to
+outlet-2;
+#X text 441 293 zero : resets all stored weights to zero;
+#X text 379 271 max MAXWEIGHT : change maximum expected input probability
+;
+#X msg 63 207 dump;
+#X msg 67 289 resize 4;
+#X msg 69 235 max 1;
+#X msg 69 257 max 100;
+#X msg 57 177 zero;
+#X msg 27 75 set 420 24 7;
+#X msg 33 97 set 50 25 25;
+#X text 127 85 set entire weight-vector;
+#X text 107 127 set selected weights;
+#X text 91 175 reset all weights;
+#X text 97 207 dump weights to 2nd outlet;
+#X text 113 239 adjust maximum input-value;
+#X text 131 297 adjust length of weight-vector;
+#X msg 67 311 resize 2;
+#X floatatom 14 44 5 0 0;
+#X text 63 43 output matching weight index;
+#X text 371 367 map IDX WEIGHT :;
+#X text 491 367 associate element IDX (int) of the stored weight-vector
+with weight WEIGHT (float). Multiple (index \, weight) pairs may also
+be specified.;
+#X text 393 335 set WEIGHTS :;
+#X text 600 556 Bryan Jurish <moocow@ling.uni-potsdam.de>;
+#X text 393 253 resize SIZE : resizes the weight-vector to SIZE elements
+;
+#X text 491 335 sets the stored weight-vector to WEIGHTS. possibly
+resizes the vector.;
+#X text 11 402 NOTES:;
+#X msg 41 125 map 1 42;
+#X msg 47 147 map 1 10 2 20 3 30;
+#X text 11 521 incoming floats are expected to be in the range 0..MAXWEIGHT
+\; floats which exceed MAXWEIGHT will cause the weightmap to outlet
+"0 "(zero) \, indicating a failed match.;
+#X text 11 418 weightmap stores a vector of "weights" -- arbitrary
+floats representing probability values \, which are matched against
+incoming floats to generate integers at the outlet. Greater input floats
+do not neccesarily correspond to greater stored "weights" \, but greater
+"weights" do cause their associated indices to be output more frequently
+for random input floats.;
+#X connect 3 0 2 0;
+#X connect 3 1 1 0;
+#X connect 18 0 3 0;
+#X connect 19 0 3 0;
+#X connect 20 0 3 0;
+#X connect 21 0 3 0;
+#X connect 22 0 3 0;
+#X connect 23 0 3 0;
+#X connect 24 0 3 0;
+#X connect 31 0 3 0;
+#X connect 32 0 3 0;
+#X connect 41 0 3 0;
+#X connect 42 0 3 0;
diff --git a/weightmap/src/weightmap-test.pd b/weightmap/src/weightmap-test.pd
new file mode 100644
index 0000000..41ca643
--- /dev/null
+++ b/weightmap/src/weightmap-test.pd
@@ -0,0 +1,135 @@
+#N canvas 33 18 810 430 10;
+#X obj 94 168 weightmap 3;
+#X msg 154 41 dump;
+#X obj 215 210 print wm_out2;
+#X msg 158 63 zero;
+#X msg 196 41 resize \$1;
+#X floatatom 195 12 5 0 0;
+#X floatatom 548 33 5 0 0;
+#X floatatom 598 33 5 0 0;
+#X obj 548 59 pack 0 0;
+#X text 549 116 bad input;
+#X msg 412 11 set 420 24 7;
+#X msg 549 82 map \$1 \$2;
+#X msg 549 132 map 0 1 1 2 2;
+#X floatatom 106 13 5 0 0;
+#N canvas 0 0 820 480 statistics 0;
+#X obj 146 16 inlet;
+#X msg 169 87 dump;
+#X msg 63 89 dump;
+#X obj 170 136 prependany del;
+#X obj 60 286 outlet;
+#X obj 274 210 pack 0 0;
+#X msg 453 127 0;
+#X obj 324 160 int;
+#X obj 274 86 t f b f b;
+#X obj 324 184 + 1;
+#X obj 306 10 maphash stats;
+#X obj 170 112 mapread stats;
+#X obj 62 116 mapread stats;
+#X obj 340 126 mapread stats;
+#X obj 274 242 mapwrite stats;
+#X text 569 30 Total;
+#X obj 570 121 int 0;
+#X msg 601 84 0;
+#X obj 616 121 + 1;
+#X obj 148 50 route dump clear;
+#X obj 62 153 unpack 0 0;
+#X obj 128 181 / 1;
+#X obj 62 233 pack 0 0 0;
+#X msg 61 258 \$1: \$2 = \$3%;
+#X obj 128 207 * 100;
+#X obj 540 191 int;
+#X msg 541 226 total = \$1;
+#X msg 519 167 bang;
+#X connect 0 0 19 0;
+#X connect 1 0 11 0;
+#X connect 2 0 12 0;
+#X connect 3 0 14 0;
+#X connect 5 0 14 0;
+#X connect 6 0 7 1;
+#X connect 7 0 9 0;
+#X connect 8 0 5 0;
+#X connect 8 1 7 0;
+#X connect 8 2 13 0;
+#X connect 8 3 6 0;
+#X connect 8 3 16 0;
+#X connect 9 0 5 1;
+#X connect 11 0 3 0;
+#X connect 12 0 20 0;
+#X connect 13 0 7 1;
+#X connect 16 0 18 0;
+#X connect 17 0 16 1;
+#X connect 17 0 25 1;
+#X connect 18 0 16 1;
+#X connect 18 0 25 1;
+#X connect 19 0 27 0;
+#X connect 19 0 2 0;
+#X connect 19 1 1 0;
+#X connect 19 1 17 0;
+#X connect 19 2 8 0;
+#X connect 20 0 22 0;
+#X connect 20 1 21 0;
+#X connect 20 1 22 1;
+#X connect 21 0 24 0;
+#X connect 22 0 23 0;
+#X connect 23 0 4 0;
+#X connect 24 0 22 2;
+#X connect 25 0 26 0;
+#X connect 25 0 21 1;
+#X connect 26 0 4 0;
+#X connect 27 0 25 0;
+#X restore 224 293 pd statistics;
+#X msg 261 260 dump;
+#X msg 303 260 clear;
+#X obj 224 325 print stats;
+#X obj 24 13 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1
+;
+#X obj 24 57 random 100;
+#X floatatom 49 12 5 0 0;
+#X obj 335 294 print -----;
+#X msg 412 37 set 10 20 30 40;
+#X msg 68 238 0;
+#X msg 70 268 1;
+#X obj 24 35 metro 1;
+#X msg 412 61 set 50 25 25;
+#X floatatom 285 12 5 0 0;
+#X msg 286 41 max \$1;
+#X msg 410 85 set 2 1 1;
+#X obj 6 101 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1
+;
+#X obj 6 145 random 100;
+#X obj 6 123 metro 1;
+#X obj 15 168 / 100;
+#X connect 0 0 14 0;
+#X connect 0 1 2 0;
+#X connect 1 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 4 0;
+#X connect 6 0 8 0;
+#X connect 7 0 8 1;
+#X connect 8 0 11 0;
+#X connect 10 0 0 0;
+#X connect 11 0 0 0;
+#X connect 12 0 0 0;
+#X connect 13 0 0 0;
+#X connect 14 0 17 0;
+#X connect 15 0 21 0;
+#X connect 15 0 14 0;
+#X connect 16 0 14 0;
+#X connect 18 0 25 0;
+#X connect 19 0 0 0;
+#X connect 20 0 25 1;
+#X connect 22 0 0 0;
+#X connect 23 0 14 0;
+#X connect 24 0 14 0;
+#X connect 25 0 19 0;
+#X connect 26 0 0 0;
+#X connect 27 0 28 0;
+#X connect 28 0 0 0;
+#X connect 29 0 0 0;
+#X connect 30 0 32 0;
+#X connect 31 0 33 0;
+#X connect 32 0 31 0;
+#X connect 33 0 0 0;
diff --git a/weightmap/src/weightmap.c b/weightmap/src/weightmap.c
new file mode 100644
index 0000000..1406ddc
--- /dev/null
+++ b/weightmap/src/weightmap.c
@@ -0,0 +1,364 @@
+/* -*- Mode: C -*- */
+/*=============================================================================*\
+ * File: weightmap.c
+ * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
+ * Description: gui-less finer-grained probability-to-integer-map for PD
+ *
+ * - inspired in part by Yves Degoyon's 'probalizer' object
+ *
+
+ *
+ * Copyright (c) 2002-2006 Bryan Jurish.
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See file LICENSE for further informations on licensing terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *=============================================================================*/
+
+
+#include <m_pd.h>
+
+/* black magic */
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include <math.h>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/*--------------------------------------------------------------------
+ * DEBUG
+ *--------------------------------------------------------------------*/
+//#define WEIGHTMAP_DEBUG 1
+
+
+/*=====================================================================
+ * Constants
+ *=====================================================================*/
+#define DEFAULT_WEIGHT_VALUE 0
+#define DEFAULT_WEIGHT_MAX 100
+
+/*=====================================================================
+ * Structures and Types
+ *=====================================================================*/
+
+static char *weightmap_banner = "weightmap version %s by Bryan Jurish : map probabilities to associated integers";
+
+static t_class *weightmap_class;
+
+typedef struct _weightmap
+{
+ t_object x_obj; /* black magic (probably inheritance-related) */
+ t_float x_wmax; /* maximum expected input weight */
+ t_int x_nvalues; /* number of stored values */
+ t_float *x_weights; /* weight of each event (0..x_wmax) */
+ t_float x_wsum; /* sum of all weights (internal use only) */
+ t_outlet *x_dumpoutlet; /* outlet for 'dump' messages */
+} t_weightmap;
+
+
+
+/*--------------------------------------------------------------------
+ * FLOAT : the guts : handle incoming weights
+ *--------------------------------------------------------------------*/
+void weightmap_float(t_weightmap *x, t_floatarg f) {
+ int i;
+ float wt;
+
+ // scale weight from (0..x->x_wmax) to (0..x->x_wsum)
+ wt = (f * x->x_wsum) / x->x_wmax;
+
+#ifdef WEIGHTMAP_DEBUG
+ post("weightmap_debug : float : rescale(%f : 0..%f) = %f : 0..%f", f, x->x_wmax, wt, x->x_wsum);
+#endif
+
+ // find match
+ for (i = 0; i < x->x_nvalues; i++) {
+ wt -= x->x_weights[i];
+ if (wt < 0) {
+ // end of search : outlet current index (counting from 1, for compatibility)
+ outlet_float(x->x_obj.ob_outlet, i+1);
+ return;
+ }
+ }
+ // no matching value found: ouput 0
+ outlet_float(x->x_obj.ob_outlet, 0);
+}
+
+
+/*--------------------------------------------------------------------
+ * map : set selected values (no resize)
+ *--------------------------------------------------------------------*/
+void weightmap_map(t_weightmap *x, t_symbol *s, int argc, t_atom *argv) {
+ int i, idx;
+ float wt;
+
+#ifdef WEIGHTMAP_DEBUG
+ post("weightmap_debug : map : argc=%d", argc);
+#endif
+
+ for (i = 0; i < argc; i += 2) {
+ // get index
+ idx = atom_getint(argv+i);
+ if (idx <= 0 || idx > x->x_nvalues) {
+ // sanity check: index-range
+ error("weightmap : map : index out of range : %d", idx);
+ continue;
+ }
+ idx--;
+
+ // get weight-value
+ wt = atom_getfloatarg(i+1, argc, argv);
+
+ // adjust sum
+ x->x_wsum += wt - x->x_weights[idx];
+
+ // assign weight
+ x->x_weights[idx] = wt;
+ }
+}
+
+/*--------------------------------------------------------------------
+ * zero : zero the weight-vector
+ *--------------------------------------------------------------------*/
+void weightmap_zero(t_weightmap *x) {
+ int i;
+ // zero all weights
+ for (i = 0; i < x->x_nvalues; i++) {
+ *(x->x_weights+i) = 0;
+ }
+ // reset sum
+ x->x_wsum = 0;
+}
+
+
+/*--------------------------------------------------------------------
+ * set : set the entire weight-vector in one go (with possible resize)
+ *--------------------------------------------------------------------*/
+void weightmap_set(t_weightmap *x, t_symbol *s, int argc, t_atom *argv) {
+ int i;
+ float wt;
+
+ if (x->x_nvalues != argc) {
+ // set number of elements
+ x->x_nvalues = argc;
+ if ( x->x_nvalues < 1 ) x->x_nvalues = 1;
+
+ // (re-)allocate weights
+ if (x->x_weights) {
+ freebytes(x->x_weights, x->x_nvalues*sizeof(t_float));
+ }
+ x->x_weights = (t_float *)getbytes(x->x_nvalues*sizeof(t_float));
+ if (!x->x_weights) {
+ error("weightmap : failed to allocate new weight vector");
+ return;
+ }
+ }
+
+ // zero sum
+ x->x_wsum = 0;
+
+ // assign new weight-vector
+ for (i = 0; i < x->x_nvalues; i++) {
+ if (i >= argc) {
+ // sanity check: existence
+ x->x_weights[i] = DEFAULT_WEIGHT_VALUE;
+ }
+ else {
+ // normal case: set weight value
+ x->x_weights[i] = atom_getfloat(argv);
+ }
+ x->x_wsum += x->x_weights[i];
+ argv++;
+ }
+}
+
+/*--------------------------------------------------------------------
+ * resize : reset number of values & re-allocate
+ *--------------------------------------------------------------------*/
+void weightmap_resize(t_weightmap *x, t_floatarg f) {
+ int i;
+ t_int old_nvalues = x->x_nvalues;
+ t_float *old_weights = x->x_weights;
+
+#ifdef WEIGHTMAP_DEBUG
+ post("weightmap_debug : resize : size=%d", (int)f);
+#endif
+
+ // reset number of elements
+ x->x_nvalues = f;
+ if ( x->x_nvalues < 1 ) x->x_nvalues = 1;
+
+ // allocate new weight-vector
+ x->x_weights = (t_float *)getbytes(x->x_nvalues*sizeof(t_float));
+ if (!x->x_weights) {
+ error("weightmap : resize : failed to allocate new weight vector");
+ return;
+ }
+
+ // zero sum
+ x->x_wsum = 0;
+
+ // copy old values
+ for (i = 0; i < x->x_nvalues; i++) {
+ if (i >= old_nvalues) {
+ x->x_weights[i] = DEFAULT_WEIGHT_VALUE;
+ } else {
+ x->x_weights[i] = old_weights[i];
+ x->x_wsum += old_weights[i];
+ }
+ }
+
+ // free old vector
+ freebytes(old_weights, old_nvalues*sizeof(t_float));
+}
+
+
+/*--------------------------------------------------------------------
+ * max : set maximum expected input-weight
+ *--------------------------------------------------------------------*/
+void weightmap_max(t_weightmap *x, t_floatarg f) {
+#ifdef WEIGHTMAP_DEBUG
+ post("weightmap_debug : max : max=%f", f);
+#endif
+ if (f > 0) {
+ x->x_wmax = f;
+ } else {
+ error("weightmap : invalid maximum weight : %f", f);
+ }
+}
+
+
+/*--------------------------------------------------------------------
+ * dump : outputs weight-vector as a list
+ *--------------------------------------------------------------------*/
+void weightmap_dump(t_weightmap *x) {
+ int i;
+ float f;
+ t_atom *dumpus;
+
+#ifdef WEIGHTMAP_DEBUG
+ post("weightmap_debug : dump : sum=%f, max=%f", x->x_wsum, x->x_wmax);
+#endif
+
+ // allocate dump-list
+ dumpus = (t_atom *)getbytes(x->x_nvalues*sizeof(t_atom));
+ if (!dumpus) {
+ error("weightmap : failed to allocate dump list");
+ return;
+ }
+
+ // populate dump-list
+ for (i = 0; i < x->x_nvalues; i++) {
+ f = x->x_weights[i];
+ SETFLOAT(dumpus+i, f);
+ }
+
+ // output dump-list
+ outlet_list(x->x_dumpoutlet,
+ &s_list,
+ x->x_nvalues,
+ dumpus);
+
+}
+
+
+/*--------------------------------------------------------------------
+ * new SIZE
+ *--------------------------------------------------------------------*/
+static void *weightmap_new(t_floatarg f, t_floatarg max)
+{
+ t_weightmap *x;
+ int i;
+
+ x = (t_weightmap *)pd_new(weightmap_class);
+
+ // create float (index) outlet
+ outlet_new(&x->x_obj, &s_float);
+ // create list (dump) outlet
+ x->x_dumpoutlet = outlet_new(&x->x_obj, &s_list);
+
+ // set number of elements
+ x->x_nvalues = f;
+ if ( x->x_nvalues < 1 ) x->x_nvalues = 1;
+
+ // set maximum expected input probability
+ x->x_wmax = max;
+ if (!x->x_wmax) x->x_wmax = DEFAULT_WEIGHT_MAX;
+
+ // allocate weight-vector
+ x->x_weights = (t_float *)getbytes(x->x_nvalues*sizeof(t_float));
+ if (!x->x_weights) {
+ error("weightmap : failed to allocate weight vector");
+ return NULL;
+ }
+
+ // initialize weights
+ for (i = 0; i < x->x_nvalues; i++) {
+ *(x->x_weights+i) = DEFAULT_WEIGHT_VALUE;
+ }
+ // initialize sum
+ x->x_wsum = DEFAULT_WEIGHT_VALUE * x->x_nvalues;
+
+#ifdef WEIGHTMAP_DEBUG
+ post("weightmap_debug : create : nvalues=%d , wmax=%f", x->x_nvalues, x->x_wmax);
+#endif
+
+ return (void *)x;
+}
+
+/*--------------------------------------------------------------------
+ * free
+ *--------------------------------------------------------------------*/
+static void weightmap_free(t_weightmap *x) {
+#ifdef WEIGHTMAP_DEBUG
+ post("weightmap_debug : free");
+#endif
+ if (x->x_weights) {
+ freebytes(x->x_weights, x->x_nvalues*sizeof(t_float));
+ }
+}
+
+/*--------------------------------------------------------------------
+ * setup
+ *--------------------------------------------------------------------*/
+void weightmap_setup(void) {
+ post(weightmap_banner, PACKAGE_VERSION);
+ weightmap_class = class_new(gensym("weightmap"), /* name */
+ (t_newmethod)weightmap_new, /* newmethod */
+ (t_method)weightmap_free, /* freemethod */
+ sizeof(t_weightmap), /* size */
+ 0, /* flags */
+ A_DEFFLOAT, /* ARGLIST: arg1 (size) */
+ A_DEFFLOAT, /* ARGLIST: arg2 (max) */
+ 0); /* ARGLIST: END */
+
+ class_addmethod(weightmap_class, (t_method)weightmap_float, &s_float, A_FLOAT, 0);
+ class_addmethod(weightmap_class, (t_method)weightmap_map, gensym("map"), A_GIMME, 0);
+ class_addmethod(weightmap_class, (t_method)weightmap_zero, gensym("zero"), 0);
+ class_addmethod(weightmap_class, (t_method)weightmap_set, gensym("set"), A_GIMME, 0);
+ class_addmethod(weightmap_class, (t_method)weightmap_resize, gensym("resize"), A_DEFFLOAT, 0);
+ class_addmethod(weightmap_class, (t_method)weightmap_max, gensym("max"), A_DEFFLOAT, 0);
+ class_addmethod(weightmap_class, (t_method)weightmap_dump, gensym("dump"), 0);
+
+ class_sethelpsymbol(weightmap_class, gensym("weightmap-help.pd"));
+}