aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Geiger <ggeiger@users.sourceforge.net>2002-06-17 10:13:57 +0000
committerGuenter Geiger <ggeiger@users.sourceforge.net>2002-06-17 10:13:57 +0000
commitfc3d3c0a4f110a23335398c327ac0a4fc949d5cb (patch)
tree1849d6afbe34cee9cec97bdb2295401f5126870b
This commit was generated by cvs2svn to compensate for changes in r12,svn2git-root
which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/ggee/; revision=13
-rw-r--r--KNOWNBUGS12
-rw-r--r--Makefile75
-rw-r--r--VERSION1
-rw-r--r--authors16
-rw-r--r--build.bat32
-rw-r--r--changes100
-rw-r--r--clean.bat32
-rwxr-xr-xconfigure2002
-rw-r--r--configure.in107
-rwxr-xr-xcontrol/Makefile53
-rwxr-xr-xcontrol/constant.c61
-rwxr-xr-xcontrol/inv.c74
-rwxr-xr-xcontrol/inv.pd26
-rwxr-xr-xcontrol/osctl66
-rwxr-xr-xcontrol/prepend.c74
-rwxr-xr-xcontrol/qread.c129
-rwxr-xr-xcontrol/receivelocal.pd18
-rwxr-xr-xcontrol/rl.c80
-rwxr-xr-xcontrol/rtout.c41
-rwxr-xr-xcontrol/sendlocal.pd18
-rwxr-xr-xcontrol/serial_bird.c264
-rwxr-xr-xcontrol/serial_bird.pd35
-rwxr-xr-xcontrol/serial_ms.c120
-rwxr-xr-xcontrol/serial_mt.c77
-rwxr-xr-xcontrol/serialctl.c463
-rwxr-xr-xcontrol/serialctl.pd61
-rwxr-xr-xcontrol/serialize.c58
-rwxr-xr-xcontrol/serialize.pd8
-rwxr-xr-xcontrol/serialmouse.pd35
-rwxr-xr-xcontrol/shell.c206
-rwxr-xr-xcontrol/shell.pd21
-rwxr-xr-xcontrol/sinh.c54
-rwxr-xr-xcontrol/sl.c73
-rwxr-xr-xcontrol/stripdir.c48
-rwxr-xr-xcontrol/stripdir.pd7
-rwxr-xr-xcontrol/unserialize.c57
-rwxr-xr-xcontrol/unwonk.c119
-rwxr-xr-xcontrol/unwonk.pd36
-rwxr-xr-xexperimental/Makefile47
-rwxr-xr-xexperimental/Object.h142
-rwxr-xr-xexperimental/fasor.pd10
-rwxr-xr-xexperimental/fasor~.c149
-rwxr-xr-xexperimental/fofsynth.pd78
-rwxr-xr-xexperimental/fofsynth~.c354
-rwxr-xr-xexperimental/pvocfreq.c114
-rwxr-xr-xexperimental/stk.cpp207
-rwxr-xr-xexperimental/stk.h91
-rwxr-xr-xexperimental/stk.pd76
-rwxr-xr-xfilters/Makefile50
-rwxr-xr-xfilters/bandpass.c86
-rwxr-xr-xfilters/bandpass.pd38
-rwxr-xr-xfilters/equalizer.c89
-rwxr-xr-xfilters/equalizer.pd39
-rwxr-xr-xfilters/filters.h74
-rwxr-xr-xfilters/filtgain.pd74
-rwxr-xr-xfilters/highpass.c87
-rwxr-xr-xfilters/highpass.pd35
-rwxr-xr-xfilters/highshelf.c90
-rwxr-xr-xfilters/highshelf.pd39
-rwxr-xr-xfilters/hlshelf.c226
-rwxr-xr-xfilters/hlshelf.pd34
-rwxr-xr-xfilters/lowpass.c89
-rwxr-xr-xfilters/lowpass.pd35
-rwxr-xr-xfilters/lowshelf.c91
-rwxr-xr-xfilters/lowshelf.pd39
-rwxr-xr-xfilters/moog~.c182
-rwxr-xr-xfilters/moog~.pd39
-rwxr-xr-xfilters/notch.c89
-rwxr-xr-xfilters/notch.pd35
-rw-r--r--ggee.c134
-rwxr-xr-xgui/Makefile49
-rwxr-xr-xgui/envgen.c296
-rwxr-xr-xgui/envgen.h50
-rwxr-xr-xgui/envgen.pd70
-rwxr-xr-xgui/hslider.pd10
-rwxr-xr-xgui/slider.c62
-rwxr-xr-xgui/slider.h439
-rwxr-xr-xgui/slider.pd32
-rwxr-xr-xgui/state.05
-rwxr-xr-xgui/state.14
-rwxr-xr-xgui/state.24
-rwxr-xr-xgui/state.32
-rwxr-xr-xgui/state.c384
-rwxr-xr-xgui/state.list2
-rwxr-xr-xgui/state.pd44
-rwxr-xr-xgui/testsave.19
-rwxr-xr-xgui/testsave.29
-rwxr-xr-xgui/ticker.c337
-rwxr-xr-xgui/ticker.pd11
-rwxr-xr-xgui/toddle.c382
-rwxr-xr-xgui/toddle.pd50
-rwxr-xr-xgui/w_envgen.h452
-rwxr-xr-xinclude/g_canvas.h560
-rwxr-xr-xinclude/ggee.h13
-rwxr-xr-xinclude/m_imp.h222
-rwxr-xr-xinclude/m_pd.h592
-rw-r--r--install77
-rw-r--r--install-sh251
-rw-r--r--license.txt31
-rw-r--r--m_pd.h592
-rw-r--r--makefile.in68
-rw-r--r--makefile.stk42
-rwxr-xr-xother/Makefile44
-rwxr-xr-xother/ls_setup29
-rwxr-xr-xother/ls_setup1629
-rwxr-xr-xother/messages.c40
-rwxr-xr-xother/vbap.c298
-rwxr-xr-xother/vbap.pd51
-rwxr-xr-xsignal/Makefile51
-rw-r--r--signal/apply~.c151
-rw-r--r--signal/apply~.pd19
-rwxr-xr-xsignal/atan2~.c86
-rwxr-xr-xsignal/atan2~.pd4
-rwxr-xr-xsignal/mixer~.c107
-rwxr-xr-xsignal/mixer~.pd87
-rwxr-xr-xsignal/pipewrite~.c216
-rwxr-xr-xsignal/rtin~.c76
-rwxr-xr-xsignal/rtin~.pd32
-rwxr-xr-xsignal/sfread~.c317
-rwxr-xr-xsignal/sfread~.pd44
-rwxr-xr-xsignal/sfwrite.pd45
-rwxr-xr-xsignal/sfwrite~.c284
-rwxr-xr-xsignal/stream.h30
-rwxr-xr-xsignal/streamin~.c404
-rwxr-xr-xsignal/streamin~.pd41
-rwxr-xr-xsignal/streamout~.c323
-rwxr-xr-xsignal/streamout~.pd49
-rwxr-xr-xtools/Makefile19
-rwxr-xr-xtools/README.ggext22
-rwxr-xr-xtools/define_louds_routines.c548
-rwxr-xr-xtools/define_loudspeakersbin0 -> 39118 bytes
-rwxr-xr-xtools/define_loudspeakers.c142
-rwxr-xr-xtools/define_loudspeakers.h69
-rwxr-xr-xtools/loudspeaker_directions_2D6
-rwxr-xr-xtools/loudspeaker_directions_3D9
-rw-r--r--version1
136 files changed, 16545 insertions, 0 deletions
diff --git a/KNOWNBUGS b/KNOWNBUGS
new file mode 100644
index 0000000..546c1d3
--- /dev/null
+++ b/KNOWNBUGS
@@ -0,0 +1,12 @@
+
+
+
+envgen has different methods of data output (indexed, line~pairs, dump) which
+all go to the same outlet
+
+sfread doesn't work on Windows (and will never do, use readsf~^H^H^H^H^H
+sfplay instead)
+
+the objects for serial control only work under Linux
+
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..1ce7599
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,75 @@
+#
+
+EXT = pd_linux
+DEFS = -DHAVE_LIBM=1 -DHAVE_LIBPTHREAD=1 -DSTDC_HEADERS=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_UNISTD_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_SOCKET=1 -DHAVE_STRERROR=1 -DPD_VERSION_MINOR=32
+CC = gcc
+CXX = c++
+LD = ld
+AFLAGS =
+LFLAGS = -export_dynamic -shared
+WFLAGS =
+IFLAGS = -I./include
+INSTALL_PREFIX=/usr
+
+VERSION = \"$(shell cat VERSION)\"
+DISTVERSION = $(shell cat VERSION)
+
+.SUFFIXES: .$(EXT)
+
+PDCFLAGS = -g -O2 $(DEFS) $(IFLAGS) $(WFLAGS) $(LFLAGS) $(AFLAGS) -DVERSION=$(VERSION)
+CFLAGS = -g -O2 $(DEFS) $(IFLAGS) $(WFLAGS) -DVERSION=$(VERSION)
+CXXFLAGS = $(CFLAGS)
+
+STKPD=
+STK=
+BUILD_STK =
+#LIBS = -lc -lm
+LIBS = -lpthread -lm
+SOURCES = control/constant.c control/inv.c control/prepend.c control/qread.c control/rl.c control/rtout.c control/serial_bird.c control/serial_ms.c control/serial_mt.c control/serialctl.c control/serialize.c control/shell.c control/sinh.c control/sl.c control/stripdir.c control/unserialize.c control/unwonk.c experimental/fasor~.c experimental/fofsynth~.c experimental/pvocfreq.c filters/bandpass.c filters/equalizer.c filters/highpass.c filters/highshelf.c filters/hlshelf.c filters/lowpass.c filters/lowshelf.c filters/notch.c gui/envgen.c gui/hslider.c gui/slider.c gui/state.c gui/ticker.c gui/toddle.c other/messages.c other/vbap.c signal/atan2~.c signal/exp~.c signal/log~.c signal/mixer~.c signal/moog~.c signal/pipewrite~.c signal/rtin~.c signal/sfplay~.c signal/sfread~.c signal/sfwrite~.c signal/streamin~.c signal/streamout~.c tools/define_louds_routines.c tools/define_loudspeakers.c
+TARGETS = $(SOURCES:.c=.$(EXT)) $(STKPD)
+
+all: $(STK) $(TARGETS)
+
+ggext: $(STK) $(TARGETS)
+ cc -c $(CFLAGS) -DPD ggee.c
+ $(LD) -export_dynamic -shared -o ggext.pd_linux ggee.o */*.o $(LIBS)
+ strip --strip-unneeded ggext.pd_linux
+
+clean::
+ -rm */*.$(EXT) *.$(EXT) so_locations rm */*~ *~ *.o */*.o
+
+distclean: clean
+ -rm config.cache config.log config.status makefile
+
+
+distcleancvs:
+ -rm -r CVS reference/CVS
+
+
+.c.o:
+ $(CC) -c -o $@ $(CFLAGS) -DPD $*.c
+
+# cp $@ $*_stat.o
+
+.o.pd_linux:
+ $(CC) -o $@ $(PDCFLAGS) -DPD $*.o
+
+
+include makefile.stk
+
+
+install::
+ install -d $(INSTALL_PREFIX)/lib/pd/externs
+ install -m 644 */*.pd_linux $(INSTALL_PREFIX)/lib/pd/externs
+ -install -m 644 ggext.pd_linux $(INSTALL_PREFIX)/lib/pd/externs
+ install -m 644 */*.pd $(INSTALL_PREFIX)/lib/pd/doc/5.reference
+
+
+dist: distclean
+ (cd ..;tar czvf ggee-$(DISTVERSION).tgz ggee)
+
+ntdist:
+ (mkdir tmp; cd tmp; mkdir ggee; cd ggee; cp `find ../.. -name "*.pd"` .;\
+ cp `find ../.. -name "*.dll"` .; cd ..; zip ggee$(DISTVERSION).zip ggee)
+
+
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..7d385d4
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.25
diff --git a/authors b/authors
new file mode 100644
index 0000000..b95eb23
--- /dev/null
+++ b/authors
@@ -0,0 +1,16 @@
+
+
+Guenter Geiger <geiger@xdv.org>
+
+with the help of many people,
+
+pd Miller Puckette <mpuckett@man104-1.ucsd.edu>
+piperead and pipewrite d13 <d13@sil.at>
+sfplay Winfried Ritsch <ritsch@iem.kug.ac.at>
+mixer and others opt@test.at
+suggestions and testing klaus@xdv.org
+vbap Ville Pulkki
+filters math Robert Bristow-Johnson
+
+and several others which I may have forgotten to mention, please notify me
+if you feel you should be included. \ No newline at end of file
diff --git a/build.bat b/build.bat
new file mode 100644
index 0000000..50ce235
--- /dev/null
+++ b/build.bat
@@ -0,0 +1,32 @@
+current: nt
+
+
+# TARGETS += stk
+
+VERSION = \"0.24\"
+
+.SUFFIXES: .dll .obj
+# ----------------------- NT ----------------------------
+
+
+
+cd control
+nmake
+cd ..
+cd experimental
+nmake
+cd ..
+cd filters
+nmake
+cd ..
+cd gui
+nmake
+cd ..
+cd other
+nmake
+cd ..
+cd signal
+nmake
+cd ..
+
+
diff --git a/changes b/changes
new file mode 100644
index 0000000..4cb4549
--- /dev/null
+++ b/changes
@@ -0,0 +1,100 @@
+0.1 First compilation, changed object names to include "~"
+
+0.2 Added basic fof~ object
+
+0.3 added Windows nt support (no sfread yet)
+
+0.4 added the format message to streamout~ (will be autodetected by streamin~).
+ improved fof~ (offset bug, signal frequency)
+ added adsr~ object.
+
+0.5 fixed deadlock bug in streamin~ - streamout~
+ added 8bit format, fixed makefile flags for alpha (-mieee)
+ added host message and default arguments to streamout~
+
+0.6 added sfwrite object
+ compilation support for Windows
+ added state object (savestate)
+ added slider object
+
+0.7 envgen~ prototype
+ bugfixes in sfread (multichannel, added loop switch)
+ initialization bug in state object, added support for saving with symbols
+ toddle object (was here in 0.6 already)
+
+
+0.8 state - in order to prevent overwriting of states, the save messages stays only valid
+ for 2 seconds now.
+ state - initialization bug
+
+ slider - made slider thicker
+
+ envgen - added freeze message to envgen, fixed bug in duration setting
+ delete points when deleting widget, reorganized durations structure,
+ fixed bug during object instantiation.
+
+
+0.9
+ envgen is a message object now, which sends messages to a line~
+ implemented state for envgen.
+
+0.10
+ added stk object.
+
+
+0.11 - 0.12
+ fixed bug in ticker (moving when on)
+ added several objects
+ serial (speeks the Micosoft Mouse protocol)
+ rtout (for sending realtime (raw) midi messages)
+ locals, localr (sending messages locally)
+ 1/x~ , 1/x ... simple shortcuts for the inverse
+ fasor~ ( a phasor which changes it's frequency only on phase 0)
+ sfplay ... from Winfried Ritsch
+ unwonk .. an unpack which sends it's rest through the last outlet
+ atan2~ ... the signal arctan to figure out phase values. This is
+ very slow.
+
+0.14
+ - slider: now has a width argument, thanks to dieter@rhiz.org
+ fixed the "drawing when hidden" bug.
+
+ - readserial: several updates for the MicroTouch ThruGlass controller
+
+ - log~, exp~, .. just what they say, very bad performers ....
+
+ - envgen memory bug fixed.
+
+ - sfread fixed segfault when open fails during play
+
+0.15
+ - added different filter objects, which create lists suitable for biquad.
+ - again several other minor bugfixes
+ - first implementation of a dynamic mixer object
+ - added wave header for sfwrite, improved performance
+
+0.16
+ - renamed ggext to ggee, new compilation scheme which produces single externals
+ - speed improvments for sfread~
+
+0.17
+ - fixed build problem for "make ggext"
+
+0.18
+0.19
+ - rewrote selections for envgen.
+ - added (endoffile) bang to sfplay if file is not found
+0.20
+ - fixed shell external
+0.21
+ - added patch from <jdl@xdv.org> to serialize
+ - fixed pipe exhaustion problem in shell
+
+0.22
+ - removed the GUI Objects Slider, HSlider, toddle, ticker
+
+0.23
+ - updated the stk external to use stk 3.2
+
+0.24
+ - moved moog~ to filters, improved stability. \ No newline at end of file
diff --git a/clean.bat b/clean.bat
new file mode 100644
index 0000000..8f29a39
--- /dev/null
+++ b/clean.bat
@@ -0,0 +1,32 @@
+current: nt
+
+
+# TARGETS += stk
+
+VERSION = \"0.16\"
+
+.SUFFIXES: .dll .obj
+# ----------------------- NT ----------------------------
+
+
+
+cd control
+nmake clean
+cd ..
+cd experimental
+nmake clean
+cd ..
+cd filters
+nmake clean
+cd ..
+cd gui
+nmake clean
+cd ..
+cd other
+nmake clean
+cd ..
+cd signal
+nmake clean
+cd ..
+
+
diff --git a/configure b/configure
new file mode 100755
index 0000000..3647291
--- /dev/null
+++ b/configure
@@ -0,0 +1,2002 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_default_prefix=/usr
+ac_help="$ac_help
+
+ --with-stk=PATH path to stk"
+ac_help="$ac_help
+
+ --with-minor-version=version pd-version(without 0.)"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=ggee.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:536: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:566: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:617: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:649: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 660 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:691: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:696: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:705: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:724: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:786: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:843: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CXX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+ echo "$ac_t""$CXX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:875: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 886 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:891: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cxx_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cxx_cross=no
+ else
+ ac_cv_prog_cxx_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+ { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:917: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:922: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.C <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:931: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gxx=yes
+else
+ ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:950: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+ ac_cv_prog_cxx_g=yes
+else
+ ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+LD=ld
+
+
+
+
+
+echo $ac_n "checking for main in -lm""... $ac_c" 1>&6
+echo "configure:1000: checking for main in -lm" >&5
+ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1008 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:1015: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lm $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking for main in -lpthread""... $ac_c" 1>&6
+echo "configure:1045: checking for main in -lpthread" >&5
+ac_lib_var=`echo pthread'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lpthread $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1053 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:1060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo pthread | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lpthread $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1090: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1105 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1111: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1122 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1128: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1139 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1145: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1170: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1175 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1183: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1200 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1218 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1239 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in fcntl.h sys/time.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1277: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1282 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1287: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1315: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1320 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1329: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1354: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1359 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1364: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1393: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1398 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1421: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:1446: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1454 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:1594: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+for ac_func in select socket strerror
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1619: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1624 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+
+
+
+
+
+
+
+MYSOURCES="`echo */*.c`"
+
+if test `uname -m` = alpha;
+then
+ AFLAGS="-mieee -mcpu=ev56";
+fi
+
+if test `uname -s` = Linux;
+then
+ LFLAGS="-export_dynamic -shared"
+ EXT=pd_linux
+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"
+EXT=pd_irix6
+fi
+
+if test `uname -s` = IRIX32;
+then
+LFLAGS="-o32 -DUNIX -DIRIX -O2
+ -shared -rdata_shared"
+EXT=pd_irix5
+fi
+
+# Check whether --with-stk or --without-stk was given.
+if test "${with_stk+set}" = set; then
+ withval="$with_stk"
+ BUILDSTK="$withval";
+ STK=libstk;
+ STKPD=experimental/stk.$EXT;
+ LD="c++"
+
+fi
+
+
+# Check whether --with-minor-version or --without-minor-version was given.
+if test "${with_minor_version+set}" = set; then
+ withval="$with_minor_version"
+ pd_minor_version="$withval"
+else
+ pd_minor_version="32"
+fi
+
+
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@CXX@%$CXX%g
+s%@STK@%$STK%g
+s%@STKPD@%$STKPD%g
+s%@BUILDSTK@%$BUILDSTK%g
+s%@AFLAGS@%$AFLAGS%g
+s%@MYSOURCES@%$MYSOURCES%g
+s%@LFLAGS@%$LFLAGS%g
+s%@EXT@%$EXT%g
+s%@LD@%$LD%g
+s%@pd_minor_version@%$pd_minor_version%g
+s%@CPP@%$CPP%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..b9635b9
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,107 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(ggee.c)
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_CXX
+
+AC_SUBST(STK)
+AC_SUBST(STKPD)
+AC_SUBST(BUILDSTK)
+AC_SUBST(AFLAGS)
+AC_SUBST(MYSOURCES)
+AC_SUBST(LFLAGS)
+AC_SUBST(EXT)
+AC_SUBST(LD)
+AC_SUBST(pd_minor_version)
+
+
+LD=ld
+
+
+AC_PREFIX_DEFAULT(/usr)
+
+dnl Replace `main' with a function in -lm:
+
+AC_CHECK_LIB(m, main)
+
+dnl Replace `main' with a function in -lpthread:
+
+AC_CHECK_LIB(pthread, main)
+
+dnl AC_CHECK_LIB(sndfile, sf_close)
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_TIME
+
+dnl Checks for library functions.
+AC_FUNC_MMAP
+AC_CHECK_FUNCS(select socket strerror)
+
+
+
+
+
+
+dnl Replace `main' with a function in -lstk:
+dnl stk is broken atm
+dnl
+dnl LIBS="$LFLAGS -L../stk/STK"
+dnl CFLAGS="$CFLAGS -I../stk/STK"
+dnl AC_CHECK_LIB(stk, main, STK=stk)
+
+
+
+dnl
+dnl OK, checks for machines are here now
+dnl
+
+MYSOURCES="`echo */*.c`"
+
+if test `uname -m` = alpha;
+then
+ AFLAGS="-mieee -mcpu=ev56";
+fi
+
+if test `uname -s` = Linux;
+then
+ LFLAGS="-export_dynamic -shared"
+ EXT=pd_linux
+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"
+EXT=pd_irix6
+fi
+
+if test `uname -s` = IRIX32;
+then
+LFLAGS="-o32 -DUNIX -DIRIX -O2
+ -shared -rdata_shared"
+EXT=pd_irix5
+fi
+
+AC_ARG_WITH(stk,[
+ --with-stk=PATH path to stk],
+ BUILDSTK="$withval";
+ STK=libstk;
+ STKPD=experimental/stk.$EXT;
+ LD="c++"
+,)
+
+AC_ARG_WITH(minor-version,[
+ --with-minor-version=version pd-version(without 0.)],pd_minor_version="$withval",pd_minor_version="32")
+
+
+
+
+AC_OUTPUT(makefile)
+dnl AC_OUTPUT(makefile signal/makefile control/makefile gui/makefile filters/makefile experimental/makefile other/makefile)
diff --git a/control/Makefile b/control/Makefile
new file mode 100755
index 0000000..abcf9dd
--- /dev/null
+++ b/control/Makefile
@@ -0,0 +1,53 @@
+current: nt
+
+
+# TARGETS += stk
+
+VERSION = \"0.16\"
+
+.SUFFIXES: .dll .obj
+# ----------------------- NT ----------------------------
+
+NTOBJECTS = *.obj
+NTDLLS = *.dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+
+PDNTINCLUDE = /I. /I..\..\pd\src
+
+ProgramFiles = c:\Program Files
+PDNTLDIR = "$(ProgramFiles)\Microsoft Visual Studio\Vc98\lib"
+
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\wsock32.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ $(PDNTLDIR)\uuid.lib \
+ ..\..\pd\bin\pd.lib
+
+nt: $(NTOBJECTS)
+ -link /dll $(PDNTLIB) constant.obj /export:constant_setup
+ -link /dll $(PDNTLIB) inv.obj /export:inv_setup
+ -link /dll $(PDNTLIB) qread.obj /export:qread_setup
+ -link /dll $(PDNTLIB) rl.obj /export:rl_setup
+ -link /dll $(PDNTLIB) rtout.obj /export:rtout_setup
+ -link /dll $(PDNTLIB) unserialize.obj /export:unserialize_setup
+ -link /dll $(PDNTLIB) serialize.obj /export:serialize_setup
+ -link /dll $(PDNTLIB) sinh.obj /export:sinh_setup
+ -link /dll $(PDNTLIB) sl.obj /export:sl_setup
+ -link /dll $(PDNTLIB) stripdir.obj /export:stripdir_setup
+ -link /dll $(PDNTLIB) unwonk.obj /export:unwonk_setup
+
+clean:
+ del *.obj
+ del *.dll
+
+
+.c.obj:
+ -cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+
+.obj.dll:
+
+
+
+
diff --git a/control/constant.c b/control/constant.c
new file mode 100755
index 0000000..7e8ccfa
--- /dev/null
+++ b/control/constant.c
@@ -0,0 +1,61 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include <math.h>
+#include <string.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ constant ----------------------------- */
+#ifndef M_PI
+#define M_PI 3.141593f
+#endif
+
+static t_class *constant_class;
+
+
+typedef struct _constant
+{
+ t_object x_obj;
+ t_float x_constant;
+} t_constant;
+
+
+void constant_bang(t_constant *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_constant);
+}
+
+static void *constant_new(t_symbol* s)
+{
+ t_constant *x = (t_constant *)pd_new(constant_class);
+
+ if (s == &s_)
+ x->x_constant = M_PI;
+
+ if (!strcmp(s->s_name,"PI"))
+ x->x_constant = M_PI;
+
+ if (!strcmp(s->s_name,"TWOPI"))
+ x->x_constant = 2*M_PI;
+
+ if (!strcmp(s->s_name,"e"))
+ x->x_constant = exp(1.0);
+
+
+
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void constant_setup(void)
+{
+ constant_class = class_new(gensym("constant"), (t_newmethod)constant_new, 0,
+ sizeof(t_constant), 0,0);
+ class_addbang(constant_class,constant_bang);
+}
+
+
diff --git a/control/inv.c b/control/inv.c
new file mode 100755
index 0000000..ef9f736
--- /dev/null
+++ b/control/inv.c
@@ -0,0 +1,74 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+#include <m_pd.h>
+
+
+typedef struct inv
+{
+ t_object x_obj;
+} t_inv;
+
+static t_class *inv_class;
+
+static void *inv_new(void)
+{
+ t_inv *x = (t_inv *)pd_new(inv_class);
+ outlet_new(&x->x_obj, gensym("signal"));
+ return (x);
+}
+
+static t_int *inv_perform(t_int *w) /* not static; also used in d_fft.c */
+{
+ float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
+ t_int n = *(t_int *)(w+3);
+ while (n--)
+ {
+ *out++ = 1/ *in++;
+ }
+ return (w + 4);
+}
+
+static void inv_dsp(t_inv *x, t_signal **sp)
+{
+ dsp_add(inv_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+void inv_setup(void)
+{
+ inv_class = class_new(gensym("1/x~"), (t_newmethod)inv_new, 0,
+ sizeof(t_inv), 0, 0);
+
+ class_addmethod(inv_class, nullfn, gensym("signal"), 0);
+ class_addmethod(inv_class, (t_method)inv_dsp, gensym("dsp"), 0);
+}
+
+
+
+
+typedef struct scalarinv
+{
+ t_object x_obj;
+} t_scalarinv;
+
+static t_class *scalarinv_class;
+
+static void *scalarinv_new(void)
+{
+ t_scalarinv *x = (t_scalarinv *)pd_new(scalarinv_class);
+ outlet_new(&x->x_obj, gensym("float"));
+ return (x);
+}
+
+static void scalarinv_float(t_scalarinv *x,t_float val)
+{
+ outlet_float(x->x_obj.ob_outlet,1.0f/val);
+
+}
+
+void scalarinv_setup(void)
+{
+ scalarinv_class = class_new(gensym("1/x"), (t_newmethod)scalarinv_new, 0,
+ sizeof(t_scalarinv), 0, 0);
+
+ class_addfloat(scalarinv_class, (t_method)scalarinv_float);
+}
diff --git a/control/inv.pd b/control/inv.pd
new file mode 100755
index 0000000..4724449
--- /dev/null
+++ b/control/inv.pd
@@ -0,0 +1,26 @@
+#N canvas 201 39 506 289 10;
+#X floatatom 32 76;
+#X floatatom 32 137;
+#X obj 188 93 sig~ 220;
+#X floatatom 188 74;
+#X obj 188 150 1/x~;
+#X obj 188 192 clip~ -1 1;
+#X obj 181 222 dac~;
+#X text 25 267 (C) Guenter Geiger;
+#X obj 188 111 phasor~;
+#X obj 188 129 +~ 1;
+#X obj 188 173 -~ 0.5;
+#X text 184 54 the signal version doesnt look useful to me;
+#X text 34 54 To make life easier;
+#X text 32 12 1/x takes the inverse of the input;
+#X obj 32 107 invert;
+#X connect 0 0 14 0;
+#X connect 2 0 8 0;
+#X connect 3 0 2 0;
+#X connect 4 0 10 0;
+#X connect 5 0 6 0;
+#X connect 5 0 6 1;
+#X connect 8 0 9 0;
+#X connect 9 0 4 0;
+#X connect 10 0 5 0;
+#X connect 14 0 1 0;
diff --git a/control/osctl b/control/osctl
new file mode 100755
index 0000000..a6ab246
--- /dev/null
+++ b/control/osctl
@@ -0,0 +1,66 @@
+#include <m_pd.h>
+#include <math.h>
+#include <string.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ osctl ----------------------------- */
+#ifndef M_PI
+#define M_PI 3.141593f
+#endif
+
+void InitOSCReceive() {
+ struct OSCReceiveMemoryTuner rt;
+ Boolean result;
+
+ rt.InitTimeMemoryAllocator = MyInitTimeMalloc;
+ rt.RealTimeMemoryAllocator = MyRealTimeMalloc;
+ rt.receiveBufferSize = 1000;
+ rt.numReceiveBuffers = 100;
+ rt.numQueuedObjects = 200;
+ rt.numCallbackListNodes = 100;
+
+ result = OSCInitReceive(&rt);
+
+ if (result == FALSE) {
+ fatal_error("OSCInitReceive returned FALSE!\n");
+ }
+}
+
+
+
+static t_class *osctl_class;
+
+
+typedef struct _osctl
+{
+ t_object x_obj;
+} t_osctl;
+
+
+void osctl_bang(t_osctl *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_osctl);
+}
+
+static void *osctl_new(t_symbol* s)
+{
+ t_osctl *x = (t_osctl *)pd_new(osctl_class);
+
+ InitOSCReceive();
+
+
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void osctl_setup(void)
+{
+ osctl_class = class_new(gensym("osctl"), (t_newmethod)osctl_new, 0,
+ sizeof(t_osctl), 0,0);
+ class_addbang(osctl_class,osctl_bang);
+}
+
+
diff --git a/control/prepend.c b/control/prepend.c
new file mode 100755
index 0000000..f2fc4af
--- /dev/null
+++ b/control/prepend.c
@@ -0,0 +1,74 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ prepend ----------------------------- */
+
+static t_class *prepend_class;
+
+
+typedef struct _prepend
+{
+ t_object x_obj;
+ t_symbol* x_s;
+} t_prepend;
+
+
+void prepend_anything(t_prepend *x,t_symbol* s,t_int argc,t_atom* argv)
+{
+ int i = argc;
+ t_symbol* cur;
+ t_atom a_out[256];
+ int c_out = 0;
+ t_atom* a = a_out;
+
+#if 1
+ SETSYMBOL(a,s);
+ a++;
+ c_out++;
+#endif
+ while (i--) {
+ switch( argv->a_type) {
+ case A_FLOAT:
+ post("%f",atom_getfloat(argv));
+ break;
+ case A_SYMBOL:
+ post("%s",atom_getsymbol(argv)->s_name);
+ SETSYMBOL(a,atom_getsymbol(argv));
+ a++;
+ c_out++;
+ break;
+ default:
+ post("unknown type");
+ }
+ argv++;
+ }
+
+ outlet_list(x->x_obj.ob_outlet,x->x_s,c_out,(t_atom*)&a_out);
+ post("done");
+}
+
+static void *prepend_new(t_symbol* s)
+{
+ t_prepend *x = (t_prepend *)pd_new(prepend_class);
+ outlet_new(&x->x_obj, &s_float);
+ if (s != &s_)
+ x->x_s = s;
+ else
+ x->x_s = gensym("prepend");
+ return (x);
+}
+
+void prepend_setup(void)
+{
+ prepend_class = class_new(gensym("prepend"), (t_newmethod)prepend_new, 0,
+ sizeof(t_prepend), 0,A_DEFSYM,NULL);
+ class_addanything(prepend_class,prepend_anything);
+}
+
+
diff --git a/control/qread.c b/control/qread.c
new file mode 100755
index 0000000..bfad03e
--- /dev/null
+++ b/control/qread.c
@@ -0,0 +1,129 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_imp.h>
+#include "g_canvas.h"
+/* ------------------------ qread ----------------------------- */
+
+#include <stdio.h>
+
+static t_class *qread_class;
+
+
+#define MAXLINE 255
+
+typedef struct _qread
+{
+ t_object x_obj;
+ FILE* x_file;
+ int x_size;
+ t_clock* x_clock;
+ t_glist * x_glist;
+ int x_num;
+ t_symbol* x_name;
+} t_qread;
+
+
+
+static void qread_open(t_qread *x,t_symbol *filename)
+{
+ char fname[MAXPDSTRING];
+
+ if (filename == &s_) {
+ post("sfread: open without filename");
+ return;
+ }
+
+ canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name,
+ fname, MAXPDSTRING);
+
+
+ /* close the old file */
+
+ if (x->x_file) fclose(x->x_file);
+
+ if (!(x->x_file = fopen(fname,"r")))
+ {
+ error("can't open %s",fname);
+ return;
+ }
+
+
+}
+
+void qread_next(t_qread *x)
+{
+ int i;
+ float delay;
+ char name[MAXLINE];
+ t_atom at[20];
+ int ac=0;
+ t_floatarg ff;
+
+ if (!x->x_file) return;
+
+ fscanf(x->x_file,"%f",&delay);
+ if (feof(x->x_file)) {
+ clock_unset(x->x_clock);
+ return;
+ }
+
+ fscanf(x->x_file,"%s",name);
+#ifdef DEBUG
+ post("next: name = %s delay = %f",name,delay);
+#endif
+
+ for (i=0;i<=x->x_num && !feof(x->x_file);i++) {
+ fscanf(x->x_file,"%f",&ff);
+ SETFLOAT(at+i,ff);
+ }
+ ac = i-1;
+ fscanf(x->x_file,";");
+
+
+ clock_delay(x->x_clock,delay);
+
+ outlet_list(x->x_obj.ob_outlet, gensym(name), ac, at);
+}
+
+static void qread_bang(t_qread *x)
+{
+ if (!x->x_file) return;
+
+ fseek(x->x_file,0,SEEK_SET);
+ clock_delay(x->x_clock,0);
+
+#ifdef DEBUG
+ post("bang");
+#endif
+}
+
+static void qread_stop(t_qread *x)
+{
+ clock_unset(x->x_clock);
+}
+
+static void *qread_new(t_floatarg n)
+{
+ t_qread *x = (t_qread *)pd_new(qread_class);
+ outlet_new(&x->x_obj, &s_float);
+
+ x->x_name = gensym("qread");
+ x->x_glist = (t_glist*) canvas_getcurrent();
+ x->x_clock = clock_new(x, (t_method)qread_next);
+ x->x_file = NULL;
+ x->x_num = n;
+ return (x);
+}
+
+void qread_setup(void)
+{
+ qread_class = class_new(gensym("qread"), (t_newmethod)qread_new, 0,
+ sizeof(t_qread), 0,A_DEFFLOAT,A_NULL);
+ class_addbang(qread_class,qread_bang);
+ class_addmethod(qread_class,(t_method)qread_next,gensym("next"),A_NULL);
+ class_addmethod(qread_class,(t_method)qread_open,gensym("open"),A_SYMBOL,A_NULL);
+ class_addmethod(qread_class,(t_method)qread_stop,gensym("stop"),A_NULL);
+}
+
+
diff --git a/control/receivelocal.pd b/control/receivelocal.pd
new file mode 100755
index 0000000..5ada9f9
--- /dev/null
+++ b/control/receivelocal.pd
@@ -0,0 +1,18 @@
+#N canvas 245 35 596 413 10;
+#N canvas 296 238 600 380 /SUBPATCH/ 0;
+#X obj 104 220 print subpatch;
+#X obj 105 160 rl test;
+#X connect 1 0 0 0;
+#X restore 254 192 pd;
+#X obj 39 285 print local;
+#X floatatom 38 142;
+#X msg 72 138 nope dope;
+#X text 38 327 (C) 1999 Guenter Geiger;
+#X obj 41 198 sl test1;
+#X obj 39 259 rl test1;
+#X text 31 38 receive locally sent messages with receivelocal;
+#X text 31 20 send messages locally (per canvas) with sendlocal;
+#X text 30 56 aliases are "sl" and "rl";
+#X connect 2 0 5 0;
+#X connect 3 0 5 0;
+#X connect 6 0 1 0;
diff --git a/control/rl.c b/control/rl.c
new file mode 100755
index 0000000..7a789d5
--- /dev/null
+++ b/control/rl.c
@@ -0,0 +1,80 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include <stdio.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+/* -------------------- lreceive ------------------------------ */
+
+static t_class *lreceive_class;
+
+typedef struct _lreceive
+{
+ t_object x_obj;
+ t_symbol *x_sym;
+} t_lreceive;
+
+static void lreceive_bang(t_lreceive *x)
+{
+ outlet_bang(x->x_obj.ob_outlet);
+}
+
+static void lreceive_float(t_lreceive *x, t_float f)
+{
+ outlet_float(x->x_obj.ob_outlet, f);
+}
+
+static void lreceive_symbol(t_lreceive *x, t_symbol *s)
+{
+ outlet_symbol(x->x_obj.ob_outlet, s);
+}
+
+static void lreceive_pointer(t_lreceive *x, t_gpointer *gp)
+{
+ outlet_pointer(x->x_obj.ob_outlet, gp);
+}
+
+static void lreceive_list(t_lreceive *x, t_symbol *s, int argc, t_atom *argv)
+{
+ outlet_list(x->x_obj.ob_outlet, s, argc, argv);
+}
+
+static void lreceive_anything(t_lreceive *x, t_symbol *s, int argc, t_atom *argv)
+{
+ outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
+}
+
+static void *lreceive_new(t_symbol *s)
+{
+ t_lreceive *x = (t_lreceive *)pd_new(lreceive_class);
+ char mysym[MAXPDSTRING];
+
+ sprintf(mysym,"%s%p",s->s_name,canvas_getcurrent());
+ x->x_sym = gensym(mysym);
+ pd_bind(&x->x_obj.ob_pd, x->x_sym);
+ outlet_new(&x->x_obj, 0);
+ return (x);
+}
+
+static void lreceive_free(t_lreceive *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, x->x_sym);
+}
+
+void rl_setup(void)
+{
+ lreceive_class = class_new(gensym("receivelocal"), (t_newmethod)lreceive_new,
+ (t_method)lreceive_free, sizeof(t_lreceive), CLASS_NOINLET, A_SYMBOL, 0);
+ class_addcreator((t_newmethod)lreceive_new, gensym("rl"), A_DEFSYM, 0);
+ class_addbang(lreceive_class, lreceive_bang);
+ class_addfloat(lreceive_class, (t_method)lreceive_float);
+ class_addsymbol(lreceive_class, lreceive_symbol);
+ class_addpointer(lreceive_class, lreceive_pointer);
+ class_addlist(lreceive_class, lreceive_list);
+ class_addanything(lreceive_class, lreceive_anything);
+}
diff --git a/control/rtout.c b/control/rtout.c
new file mode 100755
index 0000000..95df28c
--- /dev/null
+++ b/control/rtout.c
@@ -0,0 +1,41 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+
+/* -------------------------- rtout -------------------------- */
+
+void sys_putmidimess(int portno, int a, int b, int c);
+
+static t_class *rtout_class;
+
+
+
+typedef struct _rtout
+{
+ t_object x_obj;
+ t_float x_rt;
+ t_float x_channel;
+} t_rtout;
+
+static void *rtout_new(t_floatarg channel)
+{
+ t_rtout *x = (t_rtout *)pd_new(rtout_class);
+ if (channel <= 0) channel = 1;
+ x->x_channel = channel;
+ return (x);
+}
+
+static void rtout_float(t_rtout *x, t_float f)
+{
+ int binchan = (int) x->x_channel - 1;
+ sys_putmidimess((binchan>>4),(int) f,0,0);
+}
+
+void rtout_setup(void)
+{
+ rtout_class = class_new(gensym("rtout"), (t_newmethod)rtout_new, 0,
+ sizeof(t_rtout), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(rtout_class, rtout_float);
+}
+
diff --git a/control/sendlocal.pd b/control/sendlocal.pd
new file mode 100755
index 0000000..5ada9f9
--- /dev/null
+++ b/control/sendlocal.pd
@@ -0,0 +1,18 @@
+#N canvas 245 35 596 413 10;
+#N canvas 296 238 600 380 /SUBPATCH/ 0;
+#X obj 104 220 print subpatch;
+#X obj 105 160 rl test;
+#X connect 1 0 0 0;
+#X restore 254 192 pd;
+#X obj 39 285 print local;
+#X floatatom 38 142;
+#X msg 72 138 nope dope;
+#X text 38 327 (C) 1999 Guenter Geiger;
+#X obj 41 198 sl test1;
+#X obj 39 259 rl test1;
+#X text 31 38 receive locally sent messages with receivelocal;
+#X text 31 20 send messages locally (per canvas) with sendlocal;
+#X text 30 56 aliases are "sl" and "rl";
+#X connect 2 0 5 0;
+#X connect 3 0 5 0;
+#X connect 6 0 1 0;
diff --git a/control/serial_bird.c b/control/serial_bird.c
new file mode 100755
index 0000000..25a837d
--- /dev/null
+++ b/control/serial_bird.c
@@ -0,0 +1,264 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+
+#define DEBUG(x)
+/*#define DEBUG(x) x*/
+
+static t_class *serial_bird_class;
+
+
+#define BIRD_DATA_START 0x80
+
+#define BIRDCMD_MODE_POS 86
+#define BIRD_BYTES_POS 6
+
+#define BIRDCMD_MODE_POSANG 89
+#define BIRD_BYTES_POSANG 12
+
+#define BIRDCMD_MODE_POSMAT 90
+#define BIRD_BYTES_POSMAT 24
+
+#define BIRDCMD_MODE_POSQUAT 93
+#define BIRD_BYTES_POSQUAT 14
+
+#define BIRDCMD_MODE_QUAT 92
+#define BIRD_BYTES_QUAT 8
+
+#define BIRDCMD_STREAM 64
+#define BIRDCMD_POINT 66
+
+#define BIRD_GETDATA(x,y) ((float)((short)(y<<9 | x<<2)))
+
+#define MAXBUFFER 32
+
+
+
+typedef struct _serial_bird
+{
+ t_object x_obj;
+ char x_c[MAXBUFFER];
+ t_int x_dataformat;
+ t_int x_maxcount;
+ t_int x_count;
+ t_float x_posx;
+ t_float x_posy;
+ t_float x_posz;
+ t_outlet *x_out2;
+} t_serial_bird;
+
+
+static void serial_bird_reset( t_serial_bird* x)
+{
+ x->x_posx=0;
+ x->x_posy=0;
+ x->x_count = 0;
+ outlet_float(x->x_obj.ob_outlet, x->x_posx);
+ outlet_float(x->x_out2, x->x_posy);
+}
+
+static void serial_bird_float( t_serial_bird* x,t_floatarg f)
+{
+ unsigned char c = (unsigned char) f;
+ t_atom at[BIRD_BYTES_POSMAT];
+ t_int ac = 0;
+
+ if (c&BIRD_DATA_START) {
+ x->x_count=0;
+ x->x_c[x->x_count] = c & 0x7f;
+ }
+ else
+ x->x_c[x->x_count] = c;
+
+ DEBUG(post("data %d in = %x, start = %d",x->x_count,c,c&BIRD_DATA_START);)
+
+ if (x->x_count == x->x_maxcount-1) {
+ switch (x->x_dataformat) {
+ case BIRDCMD_MODE_POS:
+ ac = 3;
+ SETFLOAT(&at[0], 0.25*BIRD_GETDATA(x->x_c[0],x->x_c[1]));
+ SETFLOAT(&at[1], 0.25*BIRD_GETDATA(x->x_c[2],x->x_c[3]));
+ SETFLOAT(&at[2], 0.25*BIRD_GETDATA(x->x_c[4],x->x_c[5]));
+ break;
+ case BIRDCMD_MODE_POSANG:
+ ac = 6;
+ SETFLOAT(&at[0], 0.25*BIRD_GETDATA(x->x_c[0],x->x_c[1]));
+ SETFLOAT(&at[1], 0.25*BIRD_GETDATA(x->x_c[2],x->x_c[3]));
+ SETFLOAT(&at[2], 0.25*BIRD_GETDATA(x->x_c[4],x->x_c[5]));
+ SETFLOAT(&at[3], BIRD_GETDATA(x->x_c[6],x->x_c[7]));
+ SETFLOAT(&at[4], BIRD_GETDATA(x->x_c[8],x->x_c[9]));
+ SETFLOAT(&at[5], BIRD_GETDATA(x->x_c[10],x->x_c[11]));
+ break;
+ case BIRDCMD_MODE_POSMAT:
+ ac = 12;
+ SETFLOAT(&at[0], BIRD_GETDATA(x->x_c[0],x->x_c[1]));
+ SETFLOAT(&at[1], BIRD_GETDATA(x->x_c[2],x->x_c[3]));
+ SETFLOAT(&at[2], BIRD_GETDATA(x->x_c[4],x->x_c[5]));
+ SETFLOAT(&at[3], BIRD_GETDATA(x->x_c[6],x->x_c[7]));
+ SETFLOAT(&at[4], BIRD_GETDATA(x->x_c[8],x->x_c[9]));
+ SETFLOAT(&at[5], BIRD_GETDATA(x->x_c[10],x->x_c[11]));
+ SETFLOAT(&at[6], BIRD_GETDATA(x->x_c[12],x->x_c[13]));
+ SETFLOAT(&at[7], BIRD_GETDATA(x->x_c[14],x->x_c[15]));
+ SETFLOAT(&at[8], BIRD_GETDATA(x->x_c[16],x->x_c[17]));
+ SETFLOAT(&at[9], BIRD_GETDATA(x->x_c[18],x->x_c[19]));
+ SETFLOAT(&at[10], BIRD_GETDATA(x->x_c[20],x->x_c[21]));
+ SETFLOAT(&at[11], BIRD_GETDATA(x->x_c[22],x->x_c[23]));
+ break;
+ case BIRDCMD_MODE_POSQUAT:
+ ac = 7;
+ SETFLOAT(&at[0], BIRD_GETDATA(x->x_c[0],x->x_c[1]));
+ SETFLOAT(&at[1], BIRD_GETDATA(x->x_c[2],x->x_c[3]));
+ SETFLOAT(&at[2], BIRD_GETDATA(x->x_c[4],x->x_c[5]));
+ SETFLOAT(&at[3], BIRD_GETDATA(x->x_c[6],x->x_c[7]));
+ SETFLOAT(&at[4], BIRD_GETDATA(x->x_c[8],x->x_c[9]));
+ SETFLOAT(&at[5], BIRD_GETDATA(x->x_c[10],x->x_c[11]));
+ SETFLOAT(&at[6], BIRD_GETDATA(x->x_c[12],x->x_c[13]));
+ break;
+ case BIRDCMD_MODE_QUAT:
+ ac = 4;
+ SETFLOAT(&at[0], BIRD_GETDATA(x->x_c[0],x->x_c[1]));
+ SETFLOAT(&at[1], BIRD_GETDATA(x->x_c[2],x->x_c[3]));
+ SETFLOAT(&at[2], BIRD_GETDATA(x->x_c[4],x->x_c[5]));
+ SETFLOAT(&at[3], BIRD_GETDATA(x->x_c[6],x->x_c[7]));
+ break;
+ }
+
+/* post("posx %d, posy %d",x->x_posx,x->x_posy);*/
+ outlet_list(x->x_obj.ob_outlet,&s_list, ac, at);
+ }
+
+ x->x_count = (++x->x_count)%(x->x_maxcount);
+}
+
+static void serial_bird_poll( t_serial_bird* x)
+{
+ post("poll");
+ /* outlet_float(x->x_out2,(float)x->x_dataformat);*/
+ outlet_float(x->x_out2,(float)BIRDCMD_POINT);
+}
+
+static void serial_bird_mode( t_serial_bird* x,t_symbol* s)
+{
+ post("mode");
+ /* outlet_float(x->x_out2,(float)x->x_dataformat);*/
+
+
+ if (!strcmp(s->s_name,"position")) {
+ x->x_dataformat = BIRDCMD_MODE_POS;
+ x->x_maxcount = BIRD_BYTES_POS;
+ }
+
+ if (!strcmp(s->s_name,"positionangle")) {
+ x->x_dataformat = BIRDCMD_MODE_POSANG;
+ x->x_maxcount = BIRD_BYTES_POSANG;
+ }
+
+ if (!strcmp(s->s_name,"positionmatrix")) {
+ x->x_dataformat = BIRDCMD_MODE_POSMAT;
+ x->x_maxcount = BIRD_BYTES_POSMAT;
+ }
+
+ if (!strcmp(s->s_name,"positionquat")) {
+ x->x_dataformat = BIRDCMD_MODE_POSQUAT;
+ x->x_maxcount = BIRD_BYTES_POSQUAT;
+ }
+
+ if (!strcmp(s->s_name,"quaternion")) {
+ x->x_dataformat = BIRDCMD_MODE_QUAT;
+ x->x_maxcount = BIRD_BYTES_QUAT;
+ }
+
+ outlet_float(x->x_out2,(float)x->x_dataformat);
+}
+
+static void serial_bird_init( t_serial_bird* x)
+{
+ t_atom cmd[8];
+
+ SETFLOAT(cmd,14400.);
+ outlet_anything(x->x_out2,gensym("speed"),1,cmd);
+
+
+ SETFLOAT(cmd,0.);
+ SETSYMBOL(cmd+1,gensym("CLOCAL"));
+ SETSYMBOL(cmd+2,gensym("CREAD"));
+ SETSYMBOL(cmd+3,gensym("CS8"));
+ outlet_anything(x->x_out2,gensym("setcontrol"),4,cmd);
+
+ SETFLOAT(cmd,0.);
+ SETSYMBOL(cmd+1,gensym("IXOFF"));
+ outlet_anything(x->x_out2,gensym("setinput"),2,cmd);
+
+ SETFLOAT(cmd,0.);
+ outlet_anything(x->x_out2,gensym("setlocal"),1,cmd);
+
+ SETFLOAT(cmd,0.);
+ SETFLOAT(cmd+1,20.);
+ outlet_anything(x->x_out2,gensym("vtime"),2,cmd);
+
+
+ SETSYMBOL(cmd,gensym("RTS"));
+ SETFLOAT(cmd+1,0.);
+ outlet_anything(x->x_out2,gensym("setlines"),2,cmd);
+
+ SETSYMBOL(cmd,gensym("DTR"));
+ SETFLOAT(cmd+1,1.);
+ outlet_anything(x->x_out2,gensym("setlines"),2,cmd);
+
+
+ /* start the polling on the serial device immediately */
+
+ outlet_anything(x->x_out2,gensym("start"),0,cmd);
+
+}
+
+static void serial_bird_start( t_serial_bird* x)
+{
+ post("start");
+ /* outlet_float(x->x_out2,(float)x->x_dataformat);*/
+ outlet_float(x->x_out2,(float)BIRDCMD_STREAM);
+}
+
+
+static void serial_bird_stop( t_serial_bird* x)
+{
+ post("stop");
+ outlet_float(x->x_out2,(float)BIRDCMD_POINT);
+}
+
+static void *serial_bird_new(t_symbol *s)
+{
+ t_serial_bird *x = (t_serial_bird *)pd_new(serial_bird_class);
+
+ x->x_count = 0;
+ x->x_posx = 0;
+ x->x_posy = 0;
+ x->x_dataformat = BIRDCMD_MODE_POSANG;
+ x->x_maxcount = BIRD_BYTES_POSANG;
+
+
+ outlet_new(&x->x_obj, &s_float);
+ x->x_out2 = outlet_new(&x->x_obj, &s_float);
+
+ return x;
+}
+
+
+void serial_bird_setup(void)
+{
+ serial_bird_class = class_new(gensym("serial_bird"), (t_newmethod)serial_bird_new,
+ NULL,
+ sizeof(t_serial_bird), 0,A_DEFSYM,0);
+ class_addfloat(serial_bird_class,serial_bird_float);
+ class_addmethod(serial_bird_class,(t_method) serial_bird_reset,gensym("reset"),0);
+ class_addmethod(serial_bird_class,(t_method) serial_bird_init,gensym("init"),0);
+
+
+ class_addmethod(serial_bird_class,(t_method) serial_bird_start,gensym("start"),0);
+ class_addmethod(serial_bird_class,(t_method) serial_bird_stop,gensym("stop"),0);
+ class_addmethod(serial_bird_class,(t_method) serial_bird_poll,gensym("poll"),0);
+ class_addmethod(serial_bird_class,(t_method) serial_bird_mode,gensym("mode"),A_SYMBOL,NULL);
+}
+
+
diff --git a/control/serial_bird.pd b/control/serial_bird.pd
new file mode 100755
index 0000000..bec40d9
--- /dev/null
+++ b/control/serial_bird.pd
@@ -0,0 +1,35 @@
+#N canvas 48 227 891 382 10;
+#X obj 77 254 serial_bird;
+#X msg 98 89 start;
+#X msg 90 55 poll;
+#X msg 414 97 mode position;
+#X msg 77 26 init;
+#X msg 414 80 mode positionangle;
+#X obj 77 277 unpack 1 2 3 4 5 6;
+#X floatatom 180 310;
+#X floatatom 159 331;
+#X floatatom 138 355;
+#X floatatom 97 323;
+#X floatatom 76 344;
+#X floatatom 55 368;
+#X text 415 23 The serial_bird object interprets the acsension Flock of Birds device.;
+#X text 414 51 The mode command sets the output mode (see FOB description for further information;
+#X text 114 24 Init initializes the serial device;
+#X text 125 50 poll stops streaming mode and outputs;
+#X text 125 60 one data set;
+#X text 136 89 start streaming mode with start;
+#X obj 180 254 serialctl /dev/ttyS0;
+#X connect 0 0 6 0;
+#X connect 0 1 19 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 12 0;
+#X connect 6 1 11 0;
+#X connect 6 2 10 0;
+#X connect 6 3 9 0;
+#X connect 6 4 8 0;
+#X connect 6 5 7 0;
+#X connect 19 0 0 0;
diff --git a/control/serial_ms.c b/control/serial_ms.c
new file mode 100755
index 0000000..723b8bf
--- /dev/null
+++ b/control/serial_ms.c
@@ -0,0 +1,120 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+
+
+static t_class *serial_ms_class;
+
+
+typedef struct _serial_ms
+{
+ t_object x_obj;
+ char x_c[4];
+ t_int x_count;
+ t_int x_posx;
+ t_int x_posy;
+ t_outlet *x_out2;
+} t_serial_ms;
+
+
+static void serial_ms_reset( t_serial_ms* x)
+{
+ x->x_posx=0;
+ x->x_posy=0;
+ x->x_count = 0;
+ outlet_float(x->x_obj.ob_outlet, x->x_posx);
+ outlet_float(x->x_out2, x->x_posy);
+}
+
+static void serial_ms_init( t_serial_ms* x)
+{
+ t_atom cmd[8];
+
+ SETFLOAT(cmd,0.);
+ SETSYMBOL(cmd+1,gensym("CLOCAL"));
+ SETSYMBOL(cmd+2,gensym("CREAD"));
+ SETSYMBOL(cmd+3,gensym("CS7"));
+/* SETSYMBOL(cmd+4,gensym("HUPCL")); */
+ outlet_anything(x->x_out2,gensym("setcontrol"),4,cmd);
+
+ SETFLOAT(cmd,0.);
+ SETSYMBOL(cmd+1,gensym("IGNBRK"));
+ SETSYMBOL(cmd+2,gensym("IGNPAR"));
+ outlet_anything(x->x_out2,gensym("setinput"),3,cmd);
+
+ SETFLOAT(cmd,0.);
+ SETFLOAT(cmd+1,1.);
+ outlet_anything(x->x_out2,gensym("vtime"),2,cmd);
+
+ SETFLOAT(cmd,1200.);
+ outlet_anything(x->x_out2,gensym("speed"),1,cmd);
+
+ SETSYMBOL(cmd,gensym("*n"));
+ outlet_anything(x->x_out2,gensym("send"),1,cmd);
+
+
+ SETSYMBOL(cmd,gensym("N"));
+ outlet_anything(x->x_out2,gensym("send"),1,cmd);
+
+
+}
+
+
+
+static void serial_ms_float( t_serial_ms* x,t_floatarg f)
+{
+ int dx,dy;
+ t_atom at[2];
+
+ x->x_c[x->x_count] = (char) f;
+
+ x->x_count = (++x->x_count)%3;
+
+ if (x->x_count==2) {
+ dx= (signed char)(((x->x_c[0] & 0x03) << 6) |
+ (x->x_c[1] & 0x3F));
+ dy= (signed char)(((x->x_c[0] & 0x0C) << 4) |
+ (x->x_c[2] & 0x3F));
+ x->x_posx += dx;
+ x->x_posy += dy;
+/* post("posx %d, posy %d",x->x_posx,x->x_posy);*/
+
+ SETFLOAT(at,x->x_posx);
+ SETFLOAT(at+1,x->x_posy);
+ outlet_list(x->x_obj.ob_outlet,&s_list, 2, at);
+ }
+
+
+}
+
+
+static void *serial_ms_new(t_symbol *s)
+{
+ t_serial_ms *x = (t_serial_ms *)pd_new(serial_ms_class);
+
+ x->x_count = 0;
+ x->x_posx = 0;
+ x->x_posy = 0;
+
+
+ outlet_new(&x->x_obj, &s_float);
+ x->x_out2 = outlet_new(&x->x_obj, &s_float);
+
+ return x;
+}
+
+
+void serial_ms_setup(void)
+{
+ serial_ms_class = class_new(gensym("serial_ms"), (t_newmethod)serial_ms_new,
+ NULL,
+ sizeof(t_serial_ms), 0,A_DEFSYM,0);
+ class_addfloat(serial_ms_class,serial_ms_float);
+ class_addmethod(serial_ms_class,(t_method) serial_ms_reset,gensym("reset"),0);
+ class_addmethod(serial_ms_class, (t_method)serial_ms_init, gensym("init"),0);
+
+
+}
+
+
diff --git a/control/serial_mt.c b/control/serial_mt.c
new file mode 100755
index 0000000..ed8a0ed
--- /dev/null
+++ b/control/serial_mt.c
@@ -0,0 +1,77 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+
+
+static t_class *serial_mt_class;
+
+
+typedef struct _serial_mt
+{
+ t_object x_obj;
+ char x_c[4];
+ t_int x_count;
+ t_int x_posx;
+ t_int x_posy;
+ t_outlet *x_out2;
+} t_serial_mt;
+
+
+static void serial_mt_reset( t_serial_mt* x)
+{
+ x->x_posx=0;
+ x->x_posy=0;
+ x->x_count = 0;
+}
+
+static void serial_mt_float( t_serial_mt* x,t_floatarg f)
+{
+ int dx,dy;
+
+ x->x_c[x->x_count] = (char) f;
+
+ x->x_count = (++x->x_count)%3;
+
+ if (x->x_count==2) {
+ dx= (signed char)(((x->x_c[0] & 0x03) << 6) |
+ (x->x_c[1] & 0x3F));
+ dy= (signed char)(((x->x_c[0] & 0x0C) << 4) |
+ (x->x_c[2] & 0x3F));
+ x->x_posx += dx;
+ x->x_posy += dy;
+/* post("posx %d, posy %d",x->x_posx,x->x_posy); */
+ outlet_float(x->x_obj.ob_outlet, x->x_posx);
+ outlet_float(x->x_out2, x->x_posy);
+ }
+
+
+}
+
+
+static void *serial_mt_new(t_symbol *s)
+{
+ t_serial_mt *x = (t_serial_mt *)pd_new(serial_mt_class);
+
+ x->x_count = 0;
+ x->x_posx = 0;
+ x->x_posy = 0;
+
+
+ outlet_new(&x->x_obj, &s_float);
+ x->x_out2 = outlet_new(&x->x_obj, &s_float);
+
+ return x;
+}
+
+
+void serial_mt_setup(void)
+{
+ serial_mt_class = class_new(gensym("serial_mt"), (t_newmethod)serial_mt_new,
+ NULL,
+ sizeof(t_serial_mt), 0,A_DEFSYM,0);
+ class_addfloat(serial_mt_class,serial_mt_float);
+ class_addmethod(serial_mt_class,(t_method) serial_mt_reset,gensym("reset"),0);
+}
+
+
diff --git a/control/serialctl.c b/control/serialctl.c
new file mode 100755
index 0000000..4a80bbb
--- /dev/null
+++ b/control/serialctl.c
@@ -0,0 +1,463 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_imp.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <termios.h>
+
+
+#ifndef __linux__
+#define CRTSCTS 0
+#endif
+
+#define DEBUG(x)
+/*#define DEBUG(x) x*/
+
+
+#define SETBIT(yy,ww,xx) \
+if (!strcmp(yy->s_name,#xx)) \
+ valid=1,ww |= ##xx;\
+if (!strcmp(yy->s_name,"~"#xx))\
+ valid=1,ww &= ~##xx;\
+if (!strcmp(yy->s_name,"list"))\
+ valid=1,post(#xx);
+
+
+/* ------------------------ serialctl ----------------------------- */
+
+static t_class *serialctl_class;
+
+
+typedef struct _serialctl
+{
+ t_object x_obj;
+ t_int x_fd;
+ t_symbol* x_devname;
+ int read_ok;
+ int started;
+ int numbytes;
+ struct termios x_termios;
+ struct termios x_oldtermios;
+} t_serialctl;
+
+
+
+static int serialctl_close(t_serialctl *x)
+{
+ if (x->x_fd <0) return 0;
+
+ close(x->x_fd);
+ return 1;
+}
+
+static int serialctl_open(t_serialctl *x,t_symbol* s)
+{
+ serialctl_close(x);
+
+ if (s != &s_)
+ x->x_devname = s;
+
+ if (x->x_devname) {
+ post("opening ...");
+ x->x_fd = open(x->x_devname->s_name,O_RDWR | O_NOCTTY);
+ if (x->x_fd >= 0 ) post("done");
+ else post("failed");
+ }
+ else {
+ return 1;
+ }
+
+ if (x->x_fd >= 0)
+ post("%s opened",x->x_devname->s_name);
+ else {
+ post("unable to open %s",x->x_devname->s_name);
+ x->x_fd = -1;
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+static int serialctl_read(t_serialctl *x,int fd)
+{
+ unsigned char c;
+ if (x->x_fd < 0) return 0;
+ if (x->read_ok) {
+ DEBUG(post("reading %d",x->numbytes);)
+ if (read(x->x_fd,&c,1) < 0) {
+ post("serialctl: read failed");
+ x->read_ok = 0;
+ return 0;
+ }
+ x->numbytes++;
+ }
+ outlet_float(x->x_obj.ob_outlet,(float)c);
+
+ return 1;
+
+}
+
+
+/*
+ * Configuration Options
+ */
+
+static void serialctl_setlines(t_serialctl *x,t_symbol* s,t_floatarg f)
+{
+ int lines;
+
+ ioctl(x->x_fd,TIOCMGET,&lines);
+ if (!strcmp(s->s_name,"RTS")) {
+ if (f)
+ lines |= TIOCM_RTS;
+ else
+ lines &= ~TIOCM_RTS;
+ }
+ if (!strcmp(s->s_name,"DTR")) {
+ if (f)
+ lines |= TIOCM_DTR;
+ else
+ lines &= ~TIOCM_DTR;
+ }
+
+
+
+ ioctl(x->x_fd,TIOCMSET,&lines);
+
+}
+
+
+static void serialctl_getlines(t_serialctl *x)
+{
+ int lines;
+ /* check hardware signals */
+
+ ioctl(x->x_fd,TIOCMGET,&lines);
+ post("serialctl: CD %s",lines&TIOCM_CD ? "on":"off");
+ post("serialctl: DTR %s",lines&TIOCM_DTR ? "on":"off");
+ post("serialctl: DSR %s",lines&TIOCM_DSR ? "on":"off");
+ post("serialctl: RTS %s",lines&TIOCM_RTS ? "on":"off");
+ post("serialctl: CTS %s",lines&TIOCM_CTS ? "on":"off");
+
+}
+
+
+static void serialctl_setlocal(t_serialctl *x,t_symbol* s,t_int ac, t_atom* at)
+{
+ int valid =0;
+ int i;
+
+
+ for (i=0;i< ac;i++) {
+ valid = 0;
+
+ if (at[i].a_type == A_FLOAT) {
+ x->x_termios.c_lflag = (int)atom_getfloat(at+i);
+ DEBUG(post("localflags set to %d",(int)atom_getfloat(at+i));)
+ valid = 1;
+ }
+
+ if (at[i].a_type == A_SYMBOL) {
+ DEBUG(post("symbol %s",atom_getsymbolarg(i,ac,at)->s_name);)
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ISIG);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ICANON);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ECHO);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ECHOE);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ECHOK);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ECHONL);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, NOFLSH);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, TOSTOP);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, IEXTEN);
+
+ if (!valid) post("serialctl: invalide flag %s",atom_getsymbolarg(i,ac,at)->s_name);
+ }
+ }
+
+ if (x->x_fd < 0) return;
+
+ if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0)
+ post("serialctl: set attributes failed");
+
+}
+
+static void serialctl_setcontrol(t_serialctl *x,t_symbol* s,t_int ac,t_atom* at)
+{
+ int valid =0;
+ int i;
+
+
+ for (i=0;i< ac;i++) {
+ valid = 0;
+
+ if (at[i].a_type == A_FLOAT) {
+ x->x_termios.c_cflag = (int) atom_getfloat(at+i);
+ DEBUG(post("controlflags set to %d",(int)atom_getfloat(at+i)));
+ valid = 1;
+ }
+
+ if (at[i].a_type == A_SYMBOL) {
+ DEBUG(post("symbol %s",atom_getsymbolarg(i,ac,at)->s_name);)
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,PARENB);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,PARODD);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CS5);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CS6);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CS7);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CS8);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CLOCAL);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CREAD);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CSTOPB);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CRTSCTS);
+ if (!valid) post("serialctl: invalide flag %s",atom_getsymbolarg(i,ac,at)->s_name);
+ }
+ }
+
+ if (x->x_fd < 0) return;
+
+
+ if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0)
+ post("serialctl: set attributes failed");
+
+}
+
+
+static void serialctl_setinput(t_serialctl *x,t_symbol* s,t_int ac,t_atom* at)
+{
+ int valid =0;
+ int i;
+
+
+ for (i=0;i< ac;i++) {
+ valid = 0;
+
+ if (at[i].a_type == A_FLOAT) {
+ x->x_termios.c_iflag = (int)atom_getfloat(at+i);
+ DEBUG(post("inputflags set to %d",(int)atom_getfloat(at+i)));
+ valid = 1;
+ }
+
+ if (at[i].a_type == A_SYMBOL) {
+ DEBUG(post("symbol %s",atom_getsymbolarg(i,ac,at)->s_name);)
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IGNBRK);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, BRKINT);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IGNPAR);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, PARMRK);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, INPCK);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, ISTRIP);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, INLCR);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IGNCR);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, ICRNL);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IUCLC);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IXON);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IXANY);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IXOFF);
+ SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IMAXBEL);
+
+ if (!valid) post("serialctl: invalide flag %s",atom_getsymbolarg(i,ac,at)->s_name);
+ }
+ }
+
+ if (x->x_fd < 0) return;
+
+
+ if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0)
+ post("serialctl: set attributes failed");
+
+}
+
+static void serialctl_makeraw(t_serialctl *x,t_floatarg f)
+{
+ cfmakeraw(&x->x_termios);
+ if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0)
+ post("serialctl: set attributes failed");
+}
+
+
+static void serialctl_vmintime(t_serialctl *x,t_floatarg f,t_floatarg ft)
+{
+
+ post("vmin = %f, vtime = %f",f,ft);
+ x->x_termios.c_cc[VMIN] = (int) f;
+ x->x_termios.c_cc[VTIME] = (int) ft;
+ if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0)
+ post("serialctl: set attributes failed");
+
+}
+
+
+static void serialctl_canonical(t_serialctl *x,t_floatarg f)
+{
+ post("setting canonical");
+ x->x_termios.c_iflag |= IGNBRK | IGNPAR;
+ x->x_termios.c_cflag |= CS8 | CREAD | PARENB| CLOCAL | CRTSCTS;
+ x->x_termios.c_lflag = 0;
+}
+
+
+static void serialctl_speed(t_serialctl *x,t_floatarg f)
+{
+
+ int speed = f;
+ post("setting speed %f",f);
+
+ cfsetospeed (&x->x_termios,speed);
+ cfsetispeed (&x->x_termios,speed);
+ if (x->x_fd < 0) return;
+
+ if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0)
+ post("serialctl: set attributes failed");
+}
+
+
+/* Actions */
+static void serialctl_bang(t_serialctl* x)
+{
+
+}
+
+static void serialctl_float(t_serialctl* x,t_float f)
+{
+ int ret = -1;
+ unsigned char c = (unsigned char) f;
+ DEBUG(post("serialctl: sending %d",c));
+ if (f < 256.) {
+ ret = write(x->x_fd,&c,1);
+ DEBUG(post("done"));
+ if (ret != 1)
+ post("serialctl: send %f %s",f,((ret < 0) ? strerror(ret) : "ok"));
+ ioctl(x->x_fd,TCFLSH,TCIOFLUSH);
+ return;
+ }
+ post("unable to send char < 256");
+
+}
+
+static void serialctl_send(t_serialctl* x,t_symbol* s)
+{
+ int ret;
+ if (s == &s_) return;
+ ret = write(x->x_fd,s->s_name,sizeof(s->s_name));
+ post("serialctl: send %s %s",s->s_name,((ret < 0) ? "not ok" : "ok"));
+}
+
+
+
+
+void serialctl_start(t_serialctl* x)
+{
+ if (x->x_fd >= 0 && !x->started) {
+ sys_addpollfn(x->x_fd, (t_fdpollfn)serialctl_read, x);
+ post("serialctl: start");
+ x->started = 1;
+ }
+}
+
+
+void serialctl_stop(t_serialctl* x)
+{
+ if (x->x_fd >= 0 && x->started) {
+ sys_rmpollfn(x->x_fd);
+ post("serialctl: stop");
+ x->started = 0;
+ }
+}
+
+
+/* Misc setup functions */
+
+
+static void serialctl_free(t_serialctl* x)
+{
+ if (x->x_fd < 0) return;
+
+ serialctl_stop(x);
+
+ if (tcsetattr(x->x_fd, TCSANOW,&x->x_oldtermios) < 0)
+ post("serialctl: set attributes failed");
+
+
+ close(x->x_fd);
+}
+
+
+
+static void *serialctl_new(t_symbol *s)
+{
+ t_serialctl *x = (t_serialctl *)pd_new(serialctl_class);
+
+ x->x_fd = -1;
+ x->read_ok = 1;
+ x->numbytes = 0;
+ x->started = 0;
+ outlet_new(&x->x_obj, &s_float);
+ if (s != &s_)
+ x->x_devname = s;
+
+ /* Open the device and save settings */
+
+ if (!serialctl_open(x,s)) return x;
+
+ if (tcgetattr(x->x_fd,&x->x_oldtermios) < 0)
+ post("serialctl: get attributes failed");
+
+ if (tcgetattr(x->x_fd,&x->x_termios) < 0)
+ post("serialctl: get attributes failed");
+
+
+ tcflush(x->x_fd, TCIOFLUSH);
+ return (x);
+}
+
+
+void serialctl_setup(void)
+{
+ serialctl_class = class_new(gensym("serialctl"), (t_newmethod)serialctl_new,
+ (t_method)serialctl_free,
+ sizeof(t_serialctl), 0,A_DEFSYM,0);
+
+ class_addmethod(serialctl_class,(t_method) serialctl_start,gensym("start"),0);
+ class_addmethod(serialctl_class,(t_method) serialctl_stop,gensym("stop"),0);
+ class_addmethod(serialctl_class, (t_method) serialctl_open,gensym("open"),A_DEFSYM);
+ class_addmethod(serialctl_class,(t_method) serialctl_close,gensym("close"),0);
+
+ /* used to configure the device via symbols or with bytes */
+
+ class_addmethod(serialctl_class, (t_method) serialctl_send, gensym("send"), A_DEFSYM,A_NULL);
+
+
+ class_addfloat(serialctl_class,(t_method) serialctl_float);
+
+ class_addmethod(serialctl_class,(t_method) serialctl_getlines,gensym("getlines"),0);
+ class_addmethod(serialctl_class,(t_method) serialctl_setlines,gensym("setlines"),A_DEFSYM,A_DEFFLOAT,NULL);
+
+
+
+ /* general controlling */
+
+ class_addmethod(serialctl_class,(t_method) serialctl_setcontrol,gensym("setcontrol"),A_GIMME,NULL);
+ class_addmethod(serialctl_class,(t_method) serialctl_setlocal,gensym("setlocal"),A_GIMME,NULL);
+ class_addmethod(serialctl_class,(t_method) serialctl_setinput,gensym("setinput"),A_GIMME,NULL);
+
+
+ /* specifics */
+
+ class_addmethod(serialctl_class,(t_method) serialctl_canonical,gensym("canonical"),A_DEFFLOAT);
+ class_addmethod(serialctl_class,(t_method) serialctl_speed,gensym("speed"),A_DEFFLOAT);
+ class_addmethod(serialctl_class,(t_method) serialctl_makeraw,gensym("makeraw"),0);
+ class_addmethod(serialctl_class,(t_method) serialctl_vmintime,gensym("vtime"),A_DEFFLOAT,A_DEFFLOAT,NULL);
+
+}
+
+
+
diff --git a/control/serialctl.pd b/control/serialctl.pd
new file mode 100755
index 0000000..34fd023
--- /dev/null
+++ b/control/serialctl.pd
@@ -0,0 +1,61 @@
+#N canvas 91 60 907 514 10;
+#X msg 202 243 getlines;
+#X msg 201 169 setlines RTS 0;
+#X msg 201 187 setlines RTS 1;
+#X msg 24 213 start;
+#X msg 24 195 stop;
+#X msg 515 231 vtime 0 20;
+#X msg 515 212 setlocal 0;
+#X msg 515 193 setcontrol 0 CS8 CLOCAL CREAD;
+#X msg 201 224 setlines DTR 1;
+#X msg 201 206 setlines DTR 0;
+#X text 12 489 (C) 2000 Guenter Geiger;
+#X text 32 22 serialin reads from a Unix serial device. There are several ways how serial devices can be setup \, and serialin provides access to these serial device settings. This makes it possible to interpret the data stream from a serial device either within pd itself \, or via a specially written external for the device attached to the serial port (see serial_bird and serial_ms).;
+#X msg 516 431 79 \, 75 \, 13;
+#X msg 517 451 OK \, 13;
+#X text 201 138 setlines set the serial port;
+#X text 199 151 lines (only acces to RTS and DTR is provided;
+#X text 23 153 start/stop;
+#X text 23 165 reading characters;
+#X text 23 177 from the device;
+#X text 510 69 setinput \, setcontrol \, setlocal \, vtime provide access to the termios status bits of the serial device. This is lowlevel configuration and is sometimes necessary.;
+#X text 512 296 set the baudrate;
+#X msg 514 348 makeraw;
+#X text 513 330 configure the device as "raw";
+#X text 511 110 If a 0 is prepended to the flags \, the flags are reset before any bits are switched. All other commands set the corresponding bits to either 1 (e.g. CLOCAL) or 0 (!CLOCAL).;
+#X msg 516 250 listflags;
+#X msg 716 210 setinput list;
+#X text 511 151 the "list flag" lists all available flags.;
+#X text 514 412 data can be sent as symbols or as ASCII character code;
+#X msg 716 230 setcontrol list;
+#X msg 717 191 setlocal list;
+#X msg 514 175 setinput 0 IXOFF;
+#X floatatom 590 314;
+#X msg 513 313 speed \$1;
+#X obj 24 455 print;
+#X floatatom 62 243;
+#X msg 73 277 send c;
+#X obj 24 429 serialctl /dev/ttyS0;
+#X connect 0 0 36 0;
+#X connect 1 0 36 0;
+#X connect 2 0 36 0;
+#X connect 3 0 36 0;
+#X connect 4 0 36 0;
+#X connect 5 0 36 0;
+#X connect 6 0 36 0;
+#X connect 7 0 36 0;
+#X connect 8 0 36 0;
+#X connect 9 0 36 0;
+#X connect 12 0 36 0;
+#X connect 13 0 36 0;
+#X connect 21 0 36 0;
+#X connect 24 0 36 0;
+#X connect 25 0 36 0;
+#X connect 28 0 36 0;
+#X connect 29 0 36 0;
+#X connect 30 0 36 0;
+#X connect 31 0 32 0;
+#X connect 32 0 36 0;
+#X connect 34 0 36 0;
+#X connect 35 0 36 0;
+#X connect 36 0 33 0;
diff --git a/control/serialize.c b/control/serialize.c
new file mode 100755
index 0000000..d288ec4
--- /dev/null
+++ b/control/serialize.c
@@ -0,0 +1,58 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ serialize ----------------------------- */
+
+#define MAX_ELEMENTS 256
+
+static t_class *serialize_class;
+
+
+typedef struct _serialize
+{
+ t_object x_obj;
+ t_atom x_abuf[MAX_ELEMENTS];
+ t_int x_count;
+ t_float x_elements;
+} t_serialize;
+
+
+void serialize_float(t_serialize *x,t_floatarg f)
+{
+ SETFLOAT(&x->x_abuf[x->x_count],f);
+ x->x_count++;
+
+ if (x->x_count == x->x_elements) {
+ outlet_list(x->x_obj.ob_outlet,0,x->x_count,x->x_abuf);
+ x->x_count = 0;
+ }
+}
+
+
+static void *serialize_new(t_floatarg f)
+{
+ t_serialize *x = (t_serialize *)pd_new(serialize_class);
+ outlet_new(&x->x_obj,&s_float);
+ x->x_elements = f;
+ x->x_count=0;
+ if ((f <= 0) || (f > MAX_ELEMENTS)) x->x_elements = 1;
+ floatinlet_new(&x->x_obj, &x->x_elements);
+ return (x);
+}
+
+
+
+void serialize_setup(void)
+{
+ serialize_class = class_new(gensym("serialize"), (t_newmethod)serialize_new, 0,
+ sizeof(t_serialize),0, A_DEFFLOAT,0);
+ class_addfloat(serialize_class,serialize_float);
+}
+
+
diff --git a/control/serialize.pd b/control/serialize.pd
new file mode 100755
index 0000000..0fbacf6
--- /dev/null
+++ b/control/serialize.pd
@@ -0,0 +1,8 @@
+#N canvas 246 82 551 292 10;
+#X obj 34 106 serialize 4;
+#X obj 34 141 print;
+#X floatatom 34 69;
+#X text 30 195 (C) 2000 Guenter Geiger;
+#X text 30 39 serialize ... turn a stream of floats into a list;
+#X connect 0 0 1 0;
+#X connect 2 0 0 0;
diff --git a/control/serialmouse.pd b/control/serialmouse.pd
new file mode 100755
index 0000000..4591119
--- /dev/null
+++ b/control/serialmouse.pd
@@ -0,0 +1,35 @@
+#N canvas 515 351 462 262 10;
+#X obj 251 170 print reading;
+#X msg 154 72 start;
+#X msg 155 90 stop;
+#X obj 59 147 serial_ms;
+#X text 35 9 decodes serial mice attached to the 1 serial port;
+#X text 35 258 (C) Guenter Geiger;
+#X msg 37 43 init;
+#X msg 245 88 setcontrol 0 CREAD CLOCAL CS7;
+#X msg 247 67 getlines;
+#X obj 59 170 unpack;
+#X floatatom 59 192;
+#X floatatom 90 192;
+#X msg 344 46 setlines RTS 1;
+#X msg 247 27 setlines DTR 0;
+#X msg 247 45 setlines RTS 0;
+#X msg 342 27 setlines DTR 1;
+#X msg 304 123 setlocal 0;
+#X obj 155 113 serialctl /dev/ttyS0;
+#X connect 1 0 17 0;
+#X connect 2 0 17 0;
+#X connect 3 0 9 0;
+#X connect 3 1 17 0;
+#X connect 6 0 3 0;
+#X connect 7 0 17 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 9 1 11 0;
+#X connect 12 0 17 0;
+#X connect 13 0 17 0;
+#X connect 14 0 17 0;
+#X connect 15 0 17 0;
+#X connect 16 0 17 0;
+#X connect 17 0 0 0;
+#X connect 17 0 3 0;
diff --git a/control/shell.c b/control/shell.c
new file mode 100755
index 0000000..b60744c
--- /dev/null
+++ b/control/shell.c
@@ -0,0 +1,206 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+/* ------------------------ shell ----------------------------- */
+
+#define INBUFSIZE 1024
+
+static t_class *shell_class;
+
+
+typedef struct _shell
+{
+ t_object x_obj;
+ int x_echo;
+ char *sr_inbuf;
+ int sr_inhead;
+ int sr_intail;
+ void* x_binbuf;
+ int fdpipe[2];
+ int pid;
+} t_shell;
+
+static int shell_pid;
+
+void child_handler(int n)
+{
+ int ret;
+ waitpid(-1,&ret,WNOHANG);
+}
+
+void shell_bang(t_shell *x)
+{
+ post("bang");
+}
+
+#if 1
+static void shell_doit(void *z, t_binbuf *b)
+{
+ t_atom messbuf[1024];
+ t_shell *x = (t_shell *)z;
+ int msg, natom = binbuf_getnatom(b);
+ t_atom *at = binbuf_getvec(b);
+
+ for (msg = 0; msg < natom;)
+ {
+ int emsg;
+ for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA
+ && at[emsg].a_type != A_SEMI; emsg++)
+ ;
+ if (emsg > msg)
+ {
+ int i;
+ for (i = msg; i < emsg; i++)
+ if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM)
+ {
+ pd_error(x, "netreceive: got dollar sign in message");
+ goto nodice;
+ }
+ if (at[msg].a_type == A_FLOAT)
+ {
+ if (emsg > msg + 1)
+ outlet_list(x->x_obj.ob_outlet, 0, emsg-msg, at + msg);
+ else outlet_float(x->x_obj.ob_outlet, at[msg].a_w.w_float);
+ }
+ else if (at[msg].a_type == A_SYMBOL)
+ outlet_anything(x->x_obj.ob_outlet, at[msg].a_w.w_symbol,
+ emsg-msg-1, at + msg + 1);
+ }
+ nodice:
+ msg = emsg + 1;
+ }
+}
+
+
+void shell_read(t_shell *x, int fd)
+{
+ char buf[INBUFSIZE];
+ t_binbuf* bbuf = binbuf_new();
+ int i;
+ int readto =
+ (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
+ int ret;
+
+ ret = read(fd, buf,INBUFSIZE);
+ buf[ret] = '\0';
+
+ for (i=0;i<ret;i++)
+ if (buf[i] == '\n') buf[i] = ';';
+ if (ret < 0)
+ {
+ error("shell: pipe read error");
+ sys_rmpollfn(fd);
+ x->fdpipe[0] = -1;
+ close(fd);
+ return;
+ }
+ else if (ret == 0)
+ {
+ post("EOF on socket %d\n", fd);
+ sys_rmpollfn(fd);
+ x->fdpipe[0] = -1;
+ close(fd);
+ return;
+ }
+ else
+ {
+ int natom;
+ t_atom *at;
+ binbuf_text(bbuf, buf, strlen(buf));
+
+ natom = binbuf_getnatom(bbuf);
+ at = binbuf_getvec(bbuf);
+ shell_doit(x,bbuf);
+
+ }
+ binbuf_free(bbuf);
+}
+
+#endif
+
+static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at)
+{
+ int i;
+ char* argv[20];
+
+ argv[0] = s->s_name;
+
+ if (x->fdpipe[0] != -1) {
+ close(x->fdpipe[0]);
+ close(x->fdpipe[1]);
+ sys_rmpollfn(x->fdpipe[0]);
+ x->fdpipe[0] = -1;
+ x->fdpipe[1] = -1;
+ kill(x->pid,SIGKILL);
+ }
+
+
+
+ for (i=1;i<=ac;i++) {
+ argv[i] = atom_getsymbolarg(i-1,ac,at)->s_name;
+ /* post("argument %s",argv[i]);*/
+ }
+ argv[i] = 0;
+
+ if (pipe(x->fdpipe) < 0)
+ error("unable to create pipe");
+
+ sys_addpollfn(x->fdpipe[0],shell_read,x);
+
+ if (!(x->pid = fork())) {
+ /* reassign stdout */
+ dup2(x->fdpipe[1],1);
+ execvp(s->s_name,argv);
+ exit(0);
+ }
+
+ if (x->x_echo)
+ outlet_anything(x->x_obj.ob_outlet, s, ac, at);
+}
+
+
+
+void shell_free(t_shell* x)
+{
+ binbuf_free(x->x_binbuf);
+}
+
+static void *shell_new()
+{
+ t_shell *x = (t_shell *)pd_new(shell_class);
+
+ x->x_echo = 0;
+ x->fdpipe[0] = -1;
+ x->fdpipe[1] = -1;
+
+ x->sr_inhead = x->sr_intail = 0;
+ if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");;
+
+ x->x_binbuf = binbuf_new();
+
+ outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+void shell_setup(void)
+{
+ shell_class = class_new(gensym("shell"), (t_newmethod)shell_new,
+ (t_method)shell_free,sizeof(t_shell), 0,0);
+ class_addbang(shell_class,shell_bang);
+ class_addanything(shell_class, shell_anything);
+ signal(SIGCHLD, child_handler);
+}
+
+
diff --git a/control/shell.pd b/control/shell.pd
new file mode 100755
index 0000000..a3b1735
--- /dev/null
+++ b/control/shell.pd
@@ -0,0 +1,21 @@
+#N canvas 338 239 450 300 10;
+#X obj 137 98 shell;
+#X msg 36 39 ls;
+#X obj 121 165 print;
+#X msg 64 40 ls makefile;
+#X msg 287 159 date +%k%M;
+#X floatatom 287 195 4 0 0;
+#X obj 287 177 shell;
+#X text 287 141 Getting the date;
+#X msg 118 17 bang;
+#X msg 140 42 ./startwrapper;
+#X obj 60 17 metro 10;
+#X floatatom 271 89 4 0 0;
+#X connect 0 0 2 0;
+#X connect 1 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 6 0;
+#X connect 6 0 5 0;
+#X connect 8 0 10 0;
+#X connect 9 0 0 0;
+#X connect 10 0 3 0;
diff --git a/control/sinh.c b/control/sinh.c
new file mode 100755
index 0000000..609ef3f
--- /dev/null
+++ b/control/sinh.c
@@ -0,0 +1,54 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include <math.h>
+
+
+
+/* ------------------------ sinh ----------------------------- */
+
+static t_class *sinh_class;
+
+
+typedef struct _sinh
+{
+ t_object x_obj;
+} t_sinh;
+
+
+void sinh_bang(t_sinh *x)
+{
+ post("bang");
+}
+
+
+void sinh_float(t_sinh *x,t_floatarg f)
+{
+
+ outlet_float(x->x_obj.ob_outlet,sinh(f));
+}
+
+
+static void *sinh_new()
+{
+ t_sinh *x = (t_sinh *)pd_new(sinh_class);
+
+ outlet_new(&x->x_obj,&s_float);
+ return (x);
+}
+
+void sinh_setup(void)
+{
+ sinh_class = class_new(gensym("sinh"), (t_newmethod)sinh_new, 0,
+ sizeof(t_sinh), 0,0);
+ class_addbang(sinh_class,sinh_bang);
+ class_addfloat(sinh_class,sinh_float);
+}
+
+
diff --git a/control/sl.c b/control/sl.c
new file mode 100755
index 0000000..2c94cb5
--- /dev/null
+++ b/control/sl.c
@@ -0,0 +1,73 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include <stdio.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+/* -------------------- lsend ------------------------------ */
+
+static t_class *lsend_class;
+
+typedef struct _lsend
+{
+ t_object x_obj;
+ t_symbol *x_sym;
+} t_lsend;
+
+static void lsend_bang(t_lsend *x)
+{
+ if (x->x_sym->s_thing) pd_bang(x->x_sym->s_thing);
+}
+
+static void lsend_float(t_lsend *x, t_float f)
+{
+ if (x->x_sym->s_thing) pd_float(x->x_sym->s_thing, f);
+}
+
+static void lsend_symbol(t_lsend *x, t_symbol *s)
+{
+ if (x->x_sym->s_thing) pd_symbol(x->x_sym->s_thing, s);
+}
+
+static void lsend_pointer(t_lsend *x, t_gpointer *gp)
+{
+ if (x->x_sym->s_thing) pd_pointer(x->x_sym->s_thing, gp);
+}
+
+static void lsend_list(t_lsend *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if (x->x_sym->s_thing) pd_list(x->x_sym->s_thing, s, argc, argv);
+}
+
+static void lsend_anything(t_lsend *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if (x->x_sym->s_thing) typedmess(x->x_sym->s_thing, s, argc, argv);
+}
+
+static void *lsend_new(t_symbol *s)
+{
+ t_lsend *x = (t_lsend *)pd_new(lsend_class);
+ char mysym[MAXPDSTRING];
+
+ sprintf(mysym,"%s%p",s->s_name,canvas_getcurrent());
+ x->x_sym = gensym(mysym);
+ return (x);
+}
+
+void sl_setup(void)
+{
+ lsend_class = class_new(gensym("sendlocal"), (t_newmethod)lsend_new, 0,
+ sizeof(t_lsend), 0, A_DEFSYM, 0);
+ class_addcreator((t_newmethod)lsend_new, gensym("sl"), A_DEFSYM, 0);
+ class_addbang(lsend_class, lsend_bang);
+ class_addfloat(lsend_class, lsend_float);
+ class_addsymbol(lsend_class, lsend_symbol);
+ class_addpointer(lsend_class, lsend_pointer);
+ class_addlist(lsend_class, lsend_list);
+ class_addanything(lsend_class, lsend_anything);
+}
diff --git a/control/stripdir.c b/control/stripdir.c
new file mode 100755
index 0000000..10ba19b
--- /dev/null
+++ b/control/stripdir.c
@@ -0,0 +1,48 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include <string.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ stripdir ----------------------------- */
+
+static t_class *stripdir_class;
+
+
+typedef struct _stripdir
+{
+ t_object x_obj;
+} t_stripdir;
+
+
+void stripdir_symbol(t_stripdir *x,t_symbol* s)
+{
+ int len = strlen(s->s_name);
+
+ while (len--)
+ if (*(s->s_name + len) == '/') {
+ outlet_symbol(x->x_obj.ob_outlet,gensym(s->s_name + len + 1));
+ break;
+ }
+
+}
+
+static void *stripdir_new()
+{
+ t_stripdir *x = (t_stripdir *)pd_new(stripdir_class);
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void stripdir_setup(void)
+{
+ stripdir_class = class_new(gensym("stripdir"), (t_newmethod)stripdir_new, 0,
+ sizeof(t_stripdir), 0,0);
+ class_addsymbol(stripdir_class,stripdir_symbol);
+}
+
+
diff --git a/control/stripdir.pd b/control/stripdir.pd
new file mode 100755
index 0000000..1d200a8
--- /dev/null
+++ b/control/stripdir.pd
@@ -0,0 +1,7 @@
+#N canvas 231 207 452 294 10;
+#X obj 22 78 stripdir;
+#X symbolatom 22 48 0 0 0;
+#X obj 22 105 print;
+#X text 20 22 strips all leading directories from a path;
+#X connect 0 0 2 0;
+#X connect 1 0 0 0;
diff --git a/control/unserialize.c b/control/unserialize.c
new file mode 100755
index 0000000..6133ead
--- /dev/null
+++ b/control/unserialize.c
@@ -0,0 +1,57 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ unserialize ----------------------------- */
+
+#define MAX_ELEMENTS 256
+
+static t_class *unserialize_class;
+
+
+typedef struct _unserialize
+{
+ t_object x_obj;
+ t_atom x_abuf[MAX_ELEMENTS];
+ t_int x_count;
+ t_int x_elements;
+} t_unserialize;
+
+
+void unserialize_float(t_unserialize *x,t_floatarg f)
+{
+ SETFLOAT(&x->x_abuf[x->x_count],f);
+ x->x_count++;
+
+ if (x->x_count == x->x_elements) {
+ outlet_list(x->x_obj.ob_outlet,0,x->x_count,x->x_abuf);
+ x->x_count = 0;
+ }
+}
+
+
+static void *unserialize_new(t_floatarg f)
+{
+ t_unserialize *x = (t_unserialize *)pd_new(unserialize_class);
+ outlet_new(&x->x_obj,&s_float);
+ x->x_elements = f;
+ x->x_count=0;
+ if ((f <= 0) || (f > MAX_ELEMENTS)) x->x_elements = 1;
+ return (x);
+}
+
+
+
+void unserialize_setup(void)
+{
+ unserialize_class = class_new(gensym("unserialize"), (t_newmethod)unserialize_new,
+ 0,sizeof(t_unserialize),0, A_DEFFLOAT,0);
+ class_addfloat(unserialize_class,unserialize_float);
+}
+
+
diff --git a/control/unwonk.c b/control/unwonk.c
new file mode 100755
index 0000000..e44ef10
--- /dev/null
+++ b/control/unwonk.c
@@ -0,0 +1,119 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+
+
+/* -------------------------- unwonk ------------------------------ */
+
+static t_class *unwonk_class;
+
+typedef struct unwonkout
+{
+ t_atomtype u_type;
+ t_outlet *u_outlet;
+} t_unwonkout;
+
+typedef struct _unwonk
+{
+ t_object x_obj;
+ t_int x_n;
+ t_unwonkout *x_vec;
+} t_unwonk;
+
+static void *unwonk_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_unwonk *x = (t_unwonk *)pd_new(unwonk_class);
+ t_atom defarg[2], *ap;
+ t_unwonkout *u;
+ int i;
+ if (!argc)
+ {
+ argv = defarg;
+ argc = 2;
+ SETFLOAT(&defarg[0], 0);
+ SETFLOAT(&defarg[1], 0);
+ }
+
+ x->x_n = argc + 1;
+ x->x_vec = (t_unwonkout *)getbytes(x->x_n * sizeof(*x->x_vec));
+
+ for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
+ {
+ t_atomtype type = ap->a_type;
+ if (type == A_SYMBOL)
+ {
+ char c = *ap->a_w.w_symbol->s_name;
+ if (c == 's')
+ {
+ u->u_type = A_SYMBOL;
+ u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
+ }
+ else if (c == 'p')
+ {
+ u->u_type = A_POINTER;
+ u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
+ }
+ else
+ {
+ if (c != 'f') error("unwonk: %s: bad type",
+ ap->a_w.w_symbol->s_name);
+ u->u_type = A_FLOAT;
+ u->u_outlet = outlet_new(&x->x_obj, &s_float);
+ }
+ }
+ else
+ {
+ u->u_type = A_FLOAT;
+ u->u_outlet = outlet_new(&x->x_obj, &s_float);
+ }
+ }
+
+ u->u_type = A_GIMME;
+ u->u_outlet = outlet_new(&x->x_obj, &s_list);
+
+ return (x);
+}
+
+static void unwonk_list(t_unwonk *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_atom *ap;
+ t_unwonkout *u;
+ int i;
+ int margc = argc;
+
+
+ if (argc > x->x_n - 1) margc = x->x_n - 1;
+
+ if (argc - margc > 0) {
+ ap = argv + margc;
+ u = x->x_vec + margc;
+ outlet_list(u->u_outlet,0,argc - margc, ap);
+ }
+
+ for (i = margc, u = x->x_vec + i, ap = argv + i; u--, ap--, i--;)
+ {
+ t_atomtype type = u->u_type;
+ if (type != ap->a_type)
+ error("unwonk: type mismatch");
+ else if (type == A_FLOAT)
+ outlet_float(u->u_outlet, ap->a_w.w_float);
+ else if (type == A_SYMBOL)
+ outlet_symbol(u->u_outlet, ap->a_w.w_symbol);
+ else outlet_pointer(u->u_outlet, ap->a_w.w_gpointer);
+ }
+
+
+}
+
+static void unwonk_free(t_unwonk *x)
+{
+ freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
+}
+
+void unwonk_setup(void)
+{
+ unwonk_class = class_new(gensym("unwonk"), (t_newmethod)unwonk_new,
+ (t_method)unwonk_free, sizeof(t_unwonk), 0, A_GIMME, 0);
+ class_addlist(unwonk_class, unwonk_list);
+}
diff --git a/control/unwonk.pd b/control/unwonk.pd
new file mode 100755
index 0000000..2769a1e
--- /dev/null
+++ b/control/unwonk.pd
@@ -0,0 +1,36 @@
+#N canvas 273 9 542 405 10;
+#X obj 53 134 unwonk;
+#X obj 211 246 print;
+#X floatatom 39 175;
+#X floatatom 65 175;
+#X obj 144 179 unwonk 1 2 3;
+#X floatatom 119 223;
+#X floatatom 145 223;
+#X floatatom 171 223;
+#X msg 30 100 1 2 3 4 5 6 7 8;
+#X obj 30 267 unwonk 1 2 3 4 5 6 7 8 9;
+#X floatatom 27 310;
+#X floatatom 53 310;
+#X floatatom 79 310;
+#X floatatom 105 311;
+#X floatatom 131 311;
+#X floatatom 157 311;
+#X text 25 364 (C) 1999 Guenter Geiger;
+#X text 27 24 unwonk is an unpack which sends;
+#X text 27 41 unused symbols to the last outlet;
+#X text 25 59 instead of discarding them;
+#X connect 0 0 2 0;
+#X connect 0 1 3 0;
+#X connect 0 2 4 0;
+#X connect 4 0 5 0;
+#X connect 4 1 6 0;
+#X connect 4 2 7 0;
+#X connect 4 3 1 0;
+#X connect 8 0 0 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 9 1 11 0;
+#X connect 9 2 12 0;
+#X connect 9 3 13 0;
+#X connect 9 4 14 0;
+#X connect 9 5 15 0;
diff --git a/experimental/Makefile b/experimental/Makefile
new file mode 100755
index 0000000..89ac9f7
--- /dev/null
+++ b/experimental/Makefile
@@ -0,0 +1,47 @@
+current: nt
+
+
+# TARGETS += stk
+
+VERSION = \"0.16\"
+
+.SUFFIXES: .dll .obj
+# ----------------------- NT ----------------------------
+
+NTOBJECTS = *.obj
+NTDLLS = *.dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+
+PDNTINCLUDE = /I. /I..\..\pd\src
+
+ProgramFiles = C:\Program Files
+PDNTLDIR = "$(ProgramFiles)\Microsoft Visual Studio\Vc98\lib"
+#PDNTLDIR = "C:\Programme\Msdev\Vc98\lib"
+
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\wsock32.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ $(PDNTLDIR)\uuid.lib \
+ ..\..\pd\bin\pd.lib
+
+nt: $(NTOBJECTS)
+ -link /dll $(PDNTLIB) fofsynth~.obj /export:fofsynth_tilde_setup
+ -link /dll $(PDNTLIB) pvocfreq.obj /export:pvocfreq_setup
+ -link /dll $(PDNTLIB) fasor~.obj /export:fasor_tilde_setup
+
+
+clean:
+ del *.obj
+ del *.dll
+
+
+.c.obj:
+ -cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+
+.obj.dll:
+
+
+
+
diff --git a/experimental/Object.h b/experimental/Object.h
new file mode 100755
index 0000000..6b453c1
--- /dev/null
+++ b/experimental/Object.h
@@ -0,0 +1,142 @@
+/*********************************************/
+/* Object Class, by Perry R. Cook, 1995-99 */
+/* */
+/* This is mostly here for compatibility */
+/* with Objective C. We'll also stick */
+/* global defines here, so everyone will */
+/* see them. */
+/*********************************************/
+
+#if !defined(__Object_h)
+#define __Object_h
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+class Object
+{
+ public:
+ protected:
+ Object();
+ virtual ~Object();
+};
+
+/* The OS type definitions are made in the Makefile */
+
+#if defined(__OS_NeXT_) /* For NeXTStep - Black or White Hardware */
+ #define RANDLIMIT 2147483647
+#elif defined(__OS_IRIX_) /* For SGI */
+ #define __STK_REALTIME_
+ #define RANDLIMIT 2147483647
+#elif defined(__OS_Linux_) /* For Linux */
+ #define __STK_REALTIME_
+ #define __OSS_API_ /* Use OSS API */
+// #define __MIDIATOR_ /* Use special MIDIator support */
+// #define __ALSA_API_ /* Use ALSA API */
+ #define __LITTLE_ENDIAN__
+ #define RANDLIMIT 2147483647
+#elif defined(__OS_Win_) /* For WindowsXX or NT */
+ #define __STK_REALTIME_
+ #define __LITTLE_ENDIAN__
+ #define RANDLIMIT 32767
+#endif
+
+/*
+ Real-time audio input and output buffer size. If clicks
+ are occuring in the input or output sound stream, a
+ larger buffer size may help. Larger buffer sizes, however,
+ produce more latency between input and output.
+*/
+#define RT_BUFFER_SIZE 256
+
+/*
+ The following definition is concatenated to the beginning
+ of all references to rawwave files in the various STK core
+ classes (ex. Clarinet.cpp). If you wish to move the
+ rawwaves directory to a different location in your file
+ system, you will need to set this path definition
+ appropriately. The current definition is a relative reference
+ that will work "out of the box" for the STK distribution.
+*/
+#ifndef RAWWAVE_PATH
+#define RAWWAVE_PATH "../../"
+#endif
+
+/* Sampling Rate */
+#ifndef SRATE
+#define SRATE (MY_FLOAT) 22050.0
+#endif
+
+/* Other SRATE derived defines */
+#define SRATE_OVER_TWO (MY_FLOAT) (SRATE / 2)
+#define ONE_OVER_SRATE (MY_FLOAT) (1 / SRATE)
+#define TWO_PI_OVER_SRATE (MY_FLOAT) (2 * PI / SRATE)
+
+/* Yer Basic Trigonometric constants */
+#if !defined(PI)
+ #define PI (MY_FLOAT) 3.14159265359
+#endif
+#define TWO_PI (MY_FLOAT) (MY_FLOAT) (2 * PI)
+#define ONE_OVER_TWO_PI (MY_FLOAT) (1.0 / PI)
+#define SQRT_TWO 1.414213562
+
+/* Useful random number generator values */
+#define ONE_OVER_RANDLIMIT (1.0/RANDLIMIT)
+#define RANDLIMIT_OVER_TWO (int)(RANDLIMIT/2)
+
+/* FPU Underflow Limit
+ * The IEEE specification doesn't call for automatic
+ * zeroing of floating-point values when they reach
+ * their numerical limits. Instead, most processors
+ * switch to a much more computation-intensive mode
+ * when a FPU underflow occurs. We set a lower limit
+ * here for our own (not so efficient) checks. Here's
+ * a useful macro for limiting MY_FLOATs. At this time,
+ * no FPU underflow checks are being performed.
+ */
+
+#define FPU_UFLOW_LIMIT 0.0000000001
+#define LIMIT_MY_FLOAT(j) ((((j)<(MY_FLOAT)FPU_UFLOW_LIMIT)&&((j)>(MY_FLOAT)-FPU_UFLOW_LIMIT))?(MY_FLOAT)0.0:(j))
+
+/* States for Envelopes, etc. */
+#define ATTACK 0
+#define DECAY 1
+#define SUSTAIN 2
+#define RELEASE 3
+
+/* Machine dependent stuff, possibly useful for optimization.
+ * For example, changing double to float here increases
+ * performance (speed) by a whopping 4-6% on 486-flavor machines.
+ * BUT!! a change from float to double here increases speed by
+ * 30% or so on SGI machines.
+*/
+#define MY_FLOAT double
+//#define MY_FLOAT float
+
+/* MY_MULTI is just a pointer to MY_FLOAT. This type is used
+ * to pass multichannel data back and forth within STK.
+*/
+typedef MY_FLOAT *MY_MULTI;
+
+/* INT16 is just that ... a 16-bit signed integer. */
+typedef signed short INT16;
+
+/* INT32 is just that ... a 32-bit signed integer. */
+typedef int INT32;
+
+/* Boolean values */
+#define FALSE 0
+#define TRUE 1
+
+/* Debugging define, causes massive printf's to come out.
+ * Also enables timing calculations in WaveOut class, other stuff.
+ * Uncomment to enable.
+ */
+//#define _debug_ 1
+
+/* MIDI definitions */
+#define NORM_7 (MY_FLOAT) 0.0078125 /* this is 1/128 */
+
+#endif
diff --git a/experimental/fasor.pd b/experimental/fasor.pd
new file mode 100755
index 0000000..8294558
--- /dev/null
+++ b/experimental/fasor.pd
@@ -0,0 +1,10 @@
+#N canvas 166 117 500 171 10;
+#X obj 30 43 fasor~;
+#X obj 21 90 dac~;
+#X floatatom 30 14;
+#X text 110 8 fasor is similar to phasor~ \, but changes it's frequency;
+#X text 110 23 only at phase 0;
+#X text 28 142 (C) 1999 - 2000 Guenter Geiger;
+#X connect 0 0 1 0;
+#X connect 0 0 1 1;
+#X connect 2 0 0 0;
diff --git a/experimental/fasor~.c b/experimental/fasor~.c
new file mode 100755
index 0000000..ac9b4d3
--- /dev/null
+++ b/experimental/fasor~.c
@@ -0,0 +1,149 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include "math.h"
+
+#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
+
+ /* machine-dependent definitions. These ifdefs really
+ should have been by CPU type and not by operating system! */
+#ifdef IRIX
+ /* big-endian. Most significant byte is at low address in memory */
+#define HIOFFSET 0 /* word offset to find MSB */
+#define LOWOFFSET 1 /* word offset to find LSB */
+#define int32 long /* a data type that has 32 bits */
+#else
+#ifdef NT
+ /* little-endian; most significant byte is at highest address */
+#define HIOFFSET 1
+#define LOWOFFSET 0
+#define int32 long
+#else
+#ifdef __linux__
+
+#include <endian.h>
+
+#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
+#error No byte order defined
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define HIOFFSET 1
+#define LOWOFFSET 0
+#else
+#define HIOFFSET 0 /* word offset to find MSB */
+#define LOWOFFSET 1 /* word offset to find LSB */
+#endif /* __BYTE_ORDER */
+
+#include <sys/types.h>
+#define int32 int32_t
+
+#endif /* __linux__ */
+#endif /* NT */
+#endif /* SGI */
+
+union tabfudge
+{
+ double tf_d;
+ int32 tf_i[2];
+};
+
+typedef struct fasor
+{
+ t_object x_obj;
+ double x_phase;
+ float x_conv;
+ float x_f; /* used for scalar only */
+ float x_fnew; /* used for scalar only */
+ double x_flast; /* used for scalar only */
+} t_fasor;
+
+static t_class *fasor_class;
+
+static void *fasor_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_fasor *x;
+ x = (t_fasor *)pd_new(fasor_class);
+
+ if (argc)
+ x->x_f = atom_getfloatarg(0, argc, argv);
+ else
+ x->x_f = 0;
+
+
+ x->x_flast = 1.0;
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ x->x_phase = 0;
+ x->x_conv = 0;
+ outlet_new(&x->x_obj, gensym("signal"));
+ return (x);
+}
+
+static t_int *fasor_perform(t_int *w)
+{
+ t_fasor *x = (t_fasor *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ int n = (int)(w[3]);
+
+ double dphase = x->x_phase + UNITBIT32;
+ union tabfudge tf;
+ int normhipart;
+ float conv = x->x_conv;
+ double freq = x->x_f;
+ double flast = x->x_flast;
+ double fout;
+
+ tf.tf_d = UNITBIT32;
+ normhipart = tf.tf_i[HIOFFSET];
+ tf.tf_d = dphase;
+ fout = tf.tf_d;
+
+ while (n--)
+ {
+ tf.tf_i[HIOFFSET] = normhipart;
+ dphase += freq * conv;
+ *out++ = (t_float) (fout = tf.tf_d - UNITBIT32);
+ tf.tf_d = dphase;
+
+ if (fout <= flast) {
+ freq = x->x_f = x->x_fnew; /*!! performance if freq = 0 ?? */
+ }
+
+ flast = fout;
+ }
+
+ x->x_flast = flast;
+ tf.tf_i[HIOFFSET] = normhipart;
+ x->x_phase = tf.tf_d - UNITBIT32;
+ return (w+4);
+}
+
+static void fasor_dsp(t_fasor *x, t_signal **sp)
+{
+
+ x->x_conv = 1.f/sp[0]->s_sr;
+ dsp_add(fasor_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
+}
+
+static void fasor_ft1(t_fasor *x, t_float f)
+{
+ x->x_phase = f;
+}
+
+static void fasor_float(t_fasor *x, t_float f)
+{
+ x->x_fnew = (float) fabs(f);
+}
+
+
+void fasor_tilde_setup(void)
+{
+ fasor_class = class_new(gensym("fasor~"), (t_newmethod)fasor_new, 0,
+ sizeof(t_fasor), 0, A_GIMME, 0);
+ class_addmethod(fasor_class, nullfn, gensym("signal"), 0);
+ class_addmethod(fasor_class, (t_method)fasor_dsp, gensym("dsp"), 0);
+ class_addmethod(fasor_class, (t_method)fasor_ft1,
+ gensym("ft1"), A_FLOAT, 0);
+ class_addfloat(fasor_class,fasor_float);
+}
diff --git a/experimental/fofsynth.pd b/experimental/fofsynth.pd
new file mode 100755
index 0000000..1689622
--- /dev/null
+++ b/experimental/fofsynth.pd
@@ -0,0 +1,78 @@
+#N canvas 82 59 828 630 8;
+#X floatatom 103 48;
+#X floatatom 222 82;
+#X floatatom 235 117;
+#X floatatom 249 179;
+#X obj 202 403 dac~;
+#X obj 209 237 fofsynth~;
+#X text 262 232 fofsynth~ is the same as fof~;
+#X text 101 31 fundamental frequency;
+#X text 257 82 formant frequency;
+#X text 273 116 raise time in percent;
+#X text 26 611 (C) Guenter Geiger 1999;
+#X obj 209 338 *~;
+#X obj 219 285 dbtorms;
+#X floatatom 219 267;
+#X obj 14 204 osc~;
+#X floatatom 14 173;
+#X obj 14 223 *~;
+#X obj 40 205 sig~ 3;
+#X floatatom 54 172;
+#X text 12 130 vibrato;
+#X text 11 150 freq;
+#X text 54 150 depth;
+#X obj 103 210 line~;
+#X obj 219 319 line~;
+#X obj 219 302 pack 100 300;
+#X obj 209 372 clip~ -1 1;
+#X msg 183 196 debug;
+#X msg 623 211 bang;
+#X graph graph2 0 -1 10240 1 411 607 811 307;
+#X array array1 10240 float;
+#X pop;
+#X obj 623 283 tabwrite~ array1;
+#X msg 710 274 \; array1 resize 10240;
+#X msg 151 68 200;
+#X obj 542 268 *~;
+#X obj 552 248 sig~ 0.2;
+#X text 621 191 debug;
+#X text 319 5 fof~ in its default mode;
+#X text 298 17 =================================;
+#X text 291 180 fall time in % of period;
+#X floatatom 543 180;
+#X text 334 43 THIS IS STILL NOT REALLY FINISHED;
+#X msg 151 103 1;
+#X obj 14 188 sig~ 4;
+#X msg 153 165 200;
+#X msg 47 34 120;
+#X obj 103 191 pack 100 100;
+#X connect 0 0 44 0;
+#X connect 1 0 5 1;
+#X connect 2 0 5 2;
+#X connect 3 0 5 3;
+#X connect 5 0 11 0;
+#X connect 5 0 32 0;
+#X connect 11 0 25 0;
+#X connect 12 0 24 0;
+#X connect 13 0 12 0;
+#X connect 14 0 16 0;
+#X connect 15 0 41 0;
+#X connect 16 0 5 0;
+#X connect 17 0 16 1;
+#X connect 18 0 17 0;
+#X connect 22 0 5 0;
+#X connect 23 0 11 1;
+#X connect 24 0 23 0;
+#X connect 25 0 4 1;
+#X connect 25 0 4 0;
+#X connect 26 0 5 0;
+#X connect 27 0 29 0;
+#X connect 31 0 1 0;
+#X connect 32 0 29 0;
+#X connect 33 0 32 1;
+#X connect 38 0 33 0;
+#X connect 40 0 2 0;
+#X connect 41 0 14 0;
+#X connect 42 0 3 0;
+#X connect 43 0 0 0;
+#X connect 44 0 22 0;
diff --git a/experimental/fofsynth~.c b/experimental/fofsynth~.c
new file mode 100755
index 0000000..53df270
--- /dev/null
+++ b/experimental/fofsynth~.c
@@ -0,0 +1,354 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include <math.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ fofsynth~ ----------------------------- */
+
+#ifndef NT
+void garray_usedindsp(t_garray *x);
+#endif
+
+#define DEBUG(a,b) if (x->debug) post(a,b);
+
+#define MAXGRAINS 1000
+#define PD_PI 3.14159
+
+static float* cos_table;
+static float* halfcos_table;
+static float* exp_table;
+
+static void cos_maketable(void)
+{
+ int i;
+ float *fp, phase, phsinc = (2. * PD_PI) / COSTABSIZE;
+
+ if (cos_table) return;
+ cos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+
+ for (i = COSTABSIZE + 1, fp = cos_table, phase = 0; i--;
+ fp++, phase += phsinc)
+ *fp = cos(phase);
+
+}
+
+static void halfcos_maketable(void)
+{
+ int i;
+ float *fp, phase, phsinc = (PD_PI) / COSTABSIZE;
+
+ if (halfcos_table) return;
+ halfcos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+
+ for (i = COSTABSIZE + 1, fp = halfcos_table, phase = PD_PI; i--;
+ fp++, phase += phsinc)
+ *fp = 0.5*(cos(phase) + 1.0);
+}
+
+
+static void exp_maketable(void)
+{
+ int i;
+ float *fp, phase, phsinc = (2 * PD_PI) / COSTABSIZE;
+
+ if (exp_table) return;
+ exp_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+
+ for (i = COSTABSIZE + 1, fp = exp_table, phase = 0; i--;
+ fp++, phase += phsinc)
+ *fp = exp(-phase);
+}
+
+
+static t_class *fofsynth_class;
+
+typedef struct _grain
+{
+ struct _grain *next;
+ t_float formph; /* 0 ... 1 */
+ t_float formphinc;
+ t_float envph;
+ int falling;
+} t_grain;
+
+
+typedef struct _fofsynth
+{
+ t_object x_obj;
+
+ /* it is possible to use 2 array, prob change this one
+ int the future */
+
+ t_symbol* x_arrayname;
+
+ /* template */
+
+ int x_npoints;
+ t_float *x_vec;
+
+ /* fof */
+ int debug;
+
+ int maxgrains;
+ int numgrains;
+
+ float* x_envelope;
+
+ /* the queue of grains */
+
+ t_grain* grainbase;
+ t_grain* grainstart;
+ t_grain* grainend;
+
+
+ t_float fundph; /* 0 to 1; if 1 -> add a new grain */
+
+ t_float fundfreq; /* input parameter 1 */
+ t_float formfreq; /* input paramter 2 */
+ t_float risedur; /* input parameter 3 ( in % of total duration )*/
+ t_float falldur; /* input parameter 5 ( in % of total duration */
+
+ /* other */
+ int neednewgrain;
+} t_fofsynth;
+
+
+
+
+/* build a cyclic list */
+static t_grain* grain_makecyclic(t_grain* base,int num)
+{
+ t_grain* cur = base;
+ while (--num) {
+ cur->next = cur+1;
+ cur++;
+ }
+ cur->next = base;
+ return base;
+}
+
+
+
+
+
+static t_int *fofsynth_perform(t_int *w)
+{
+ t_fofsynth* x = (t_fofsynth*) (w[1]);
+ t_float *in = (t_float *)(w[2]);
+ t_float *out = (t_float *)(w[3]);
+ int n = (int)(w[4]);
+
+ float totaldur = (x->risedur+ x->falldur)*0.01/ *in;
+
+ float srate = 44100.0; /*((t_signal*)w[2])->s_sr;*/
+ float israte = 1.0/srate;
+
+ float fundphase = x->fundph;
+ float numperiods = totaldur*x->formfreq;
+ float formphinc = (x->formfreq/srate);
+
+ float risinc;
+ float fallinc;
+
+ t_grain* cur;
+
+ risinc = (x->risedur == 0) ? 1.0 : 1.0/ (srate*totaldur*0.01*x->risedur);
+ fallinc = (x->falldur == 0.0) ? 1.0 :1.0/ (srate*totaldur*0.01*x->falldur);
+
+ DEBUG(" fundph %3.2f",x->fundph);
+ DEBUG(" fundfreq %3.2f",x->fundfreq);
+ DEBUG(" formfreq %3.2f",x->formfreq);
+ DEBUG(" risedur %3.2f %",x->risedur);
+ DEBUG(" falldur %3.2f %",x->falldur);
+ DEBUG(" totaldur %3.2f s",totaldur);
+ DEBUG(" risinc %0.6f",risinc);
+ DEBUG(" fallinc %0.6f",fallinc);
+ DEBUG(" formant increase %3.2f",formphinc);
+ DEBUG(" numgrains %d",x->numgrains);
+
+ while (n--)
+ {
+ fundphase+=*++in*israte;
+ *out = 0.0;
+
+ if (x->neednewgrain) { /* new grain, they are deleted separetely */
+ t_grain* newgrain = x->grainend;
+/* DEBUG("new grain created",0); */
+ if (newgrain->next == x->grainstart) {
+ post("fof: grain overflow");
+ x->neednewgrain = 0;
+ }
+ else {
+ x->numgrains++;
+ x->grainend = newgrain->next;
+ newgrain->formphinc = formphinc;
+ newgrain->falling = 0;
+ newgrain->formph = newgrain->envph = 0.0;
+ x->neednewgrain = 0;
+ }
+ }
+
+ cur = x->grainstart;
+ while (cur != x->grainend) {
+ float formphase = cur->formph;
+ float envelope;
+
+ float tph = (formphase - (float)((int) formphase));
+ float val = *(x->x_vec + (int) (tph * x->x_npoints));
+
+ /* Apply the envelope */
+
+ if (!cur->falling && (cur->envph <= 1.0)) {
+ envelope = *(halfcos_table + (int) (cur->envph * COSTABSIZE));
+ cur->envph+=risinc;
+ val *= envelope;
+ }
+ else if (!cur->falling)
+ {
+ cur->falling = 1;
+ cur->envph = 0;
+ }
+
+
+ if (cur->falling) {
+ envelope = *(exp_table + (int) (cur->envph * COSTABSIZE));
+ cur->envph+=fallinc;
+ val *= envelope;
+ }
+
+ /* end of envelope code */
+
+
+ formphase+=cur->formphinc;
+ cur->formph = formphase;
+
+ if (formphase >= numperiods) { /* dead */
+ DEBUG("grain died",0);
+ x->grainstart = cur->next;
+ x->numgrains--;/* not needed */
+ }
+
+ cur = cur->next;
+ *out += val;
+ }
+
+
+ if (fundphase > 1.0) {
+ fundphase -= 1.0;
+ x->neednewgrain=1;
+ }
+ out++;
+ }
+
+ x->fundph=fundphase;
+ x->debug = 0;
+
+
+ return (w+5);
+}
+
+void fofsynth_usearray(t_symbol* s,int* points,t_float** vec)
+{
+ t_garray *a;
+ if (!(a = (t_garray *)pd_findbyclass(s, garray_class)))
+ error("%s: no such array", s->s_name);
+ else if (!garray_getfloatarray(a,points,vec))
+ error("%s: bad template for fof~", s->s_name);
+ else
+ garray_usedindsp(a);
+}
+
+static void fofsynth_dsp(t_fofsynth *x, t_signal **sp)
+{
+
+ if (x->x_arrayname)
+ fofsynth_usearray(x->x_arrayname,&x->x_npoints, &x->x_vec);
+ else {
+ x->x_npoints=COSTABSIZE;
+ x->x_vec = cos_table;
+ }
+
+ dsp_add(fofsynth_perform, 4, x,
+ sp[0]->s_vec,sp[1]->s_vec, sp[0]->s_n);
+}
+
+
+static void fofsynth_free(t_fofsynth *x)
+{
+ freebytes(x->grainbase,sizeof(t_grain)*x->maxgrains);
+}
+
+
+static void fofsynth_debug(t_fofsynth* x)
+{
+ x->debug = 1;
+}
+
+
+static void fofsynth_float(t_fofsynth* x,t_float f)
+{
+ x->fundfreq = f > 0.0 ? f : -f;
+}
+
+
+static void *fofsynth_new(t_symbol* s,t_float a,t_float b,t_float c,t_float d)
+{
+ int maxgrains = MAXGRAINS;
+ t_fofsynth *x = (t_fofsynth *)pd_new(fofsynth_class);
+
+ x->debug = 0;
+ x->x_arrayname = s;
+
+ if (s == &s_)
+ x->x_arrayname = NULL;
+
+ /* setup the grain queue */
+
+ x->grainbase = getbytes(sizeof(t_grain)*maxgrains);
+ x->maxgrains = maxgrains;
+ grain_makecyclic(x->grainbase,maxgrains);
+ x->grainstart = x->grainbase;
+ x->grainend = x->grainbase;
+ x->numgrains = 0;
+
+ /* some of them could be signals too */
+
+ floatinlet_new(&x->x_obj, &x->formfreq);
+ floatinlet_new(&x->x_obj, &x->risedur);
+ floatinlet_new(&x->x_obj, &x->falldur);
+
+ x->fundph = 0.0;
+ x->fundfreq = 200.0;
+ x->formfreq = 600.0;
+ x->risedur = 5.0;
+ x->falldur = 140.0;
+
+ if (a) x->fundfreq = a;
+ if (b) x->formfreq = b;
+ if (c) x->risedur = c;
+ if (d) x->falldur = d;
+
+ outlet_new(&x->x_obj, &s_signal);
+ return (x);
+}
+
+void fofsynth_tilde_setup(void)
+{
+ cos_table = NULL;
+ halfcos_table = NULL;
+ fofsynth_class = class_new(gensym("fof~"), (t_newmethod) fofsynth_new,(t_method) fofsynth_free,
+ sizeof(t_fofsynth), 0,A_DEFSYM, A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addcreator((t_newmethod)fofsynth_new,gensym("fofsynth~"),A_DEFSYM, A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addmethod(fofsynth_class, nullfn, gensym("signal"), 0);
+ class_addmethod(fofsynth_class, (t_method) fofsynth_dsp, gensym("dsp"), 0);
+ class_addfloat(fofsynth_class, (t_method) fofsynth_float);
+ class_addmethod(fofsynth_class,(t_method) fofsynth_debug, gensym("debug"),0);
+ cos_maketable();
+ halfcos_maketable();
+ exp_maketable();
+}
diff --git a/experimental/pvocfreq.c b/experimental/pvocfreq.c
new file mode 100755
index 0000000..4eb30ca
--- /dev/null
+++ b/experimental/pvocfreq.c
@@ -0,0 +1,114 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ shuffle ----------------------------- */
+
+static t_class *shuffle_class;
+
+
+typedef struct _shuffle
+{
+ t_object x_obj;
+ t_float x;
+} t_shuffle;
+
+
+void shuffle_float(t_shuffle *x, t_floatarg f)
+{
+ post("float %f",f);
+ x->x = f;
+}
+
+
+
+static t_int *shuffle_perform(t_int *w)
+{
+ t_shuffle* x = (t_shuffle*)(w[1]);
+ t_float* in1 = (t_float*) w[2];
+ t_float* in2 = (t_float*) w[3];
+ t_float* out = (t_float*) w[4];
+ int n = w[5];
+
+ if (x->x <= 0) {
+ while (n--) {
+ *out++ = *in1++;
+ }
+ return w+6;
+ }
+
+ if (x->x < 0.5) {
+ t_int index = 1/x->x;
+ while (n--) {
+ if (n%index){
+ *out++ = *in1++;
+ in2++;
+ }
+ else {
+ *out++ = *in2++;
+ in1++;
+ }
+ }
+ return w+6;
+ }
+
+ if (x->x > 1.0) {
+ while (n--) {
+ *out++ = *in2++;
+ }
+ return w+6;
+ }
+
+ if (x->x >= 0.5) {
+ t_int index = 1/(1.0- x->x);
+ while (n--) {
+ if (n%index) {
+ *out++ = *in2++;
+ in1++;
+ }
+ else {
+ *out++ = *in1++;
+ in2++;
+ }
+ }
+ }
+
+ return w+6;
+}
+
+
+static void shuffle_dsp(t_shuffle *x, t_signal **sp)
+{
+ dsp_add(shuffle_perform, 5, x, sp[0]->s_vec,
+ sp[1]->s_vec,sp[2]->s_vec, sp[0]->s_n);
+
+}
+
+static void *shuffle_new()
+{
+ t_shuffle *x = (t_shuffle *)pd_new(shuffle_class);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+
+
+ outlet_new(&x->x_obj, gensym("signal"));
+ return (x);
+}
+
+void shuffle_setup(void)
+{
+ shuffle_class = class_new(gensym("shuffle~"), (t_newmethod)shuffle_new, 0,
+ sizeof(t_shuffle), 0,0);
+
+ class_addmethod(shuffle_class, nullfn, gensym("signal"), 0);
+ class_addmethod(shuffle_class, (t_method) shuffle_dsp, gensym("dsp"), 0);
+
+ class_addfloat(shuffle_class,shuffle_float);
+}
+
+
diff --git a/experimental/stk.cpp b/experimental/stk.cpp
new file mode 100755
index 0000000..e6229f7
--- /dev/null
+++ b/experimental/stk.cpp
@@ -0,0 +1,207 @@
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* STK includes */
+
+#include "stk.h"
+
+/* ------------------------ stk ----------------------------- */
+
+static t_class *stk_class;
+
+typedef struct _stk
+{
+ t_object x_obj;
+ Instrmnt *instrument;
+ t_float x_velo;
+} t_stk;
+
+
+char* stk_instruments[255];
+
+void stk_print(t_stk* x) {
+ int i=0;
+
+ while (strncmp(stk_instruments[i],"LastInst",8)) {
+ post("%s",stk_instruments[i]);
+ i++;
+ }
+}
+
+
+#define DECL_INST(name) if ((stk_instruments[i++] = #name) && !strcmp(s->s_name, #name )) \
+{ x->instrument = new name;}
+
+#define DECL_INST2(name) if ((stk_instruments[i++] = #name) && !strcmp(s->s_name, #name )) \
+{ x->instrument = new name(80.);}
+
+
+static void stk_set_instrument(t_stk* x,t_symbol* s)
+{
+ int i = 0;
+ if (!strcmp(s->s_name,"Simple")) x->instrument = new Simple;
+ DECL_INST2(Plucked)
+ DECL_INST2(Plucked2)
+ DECL_INST2(Mandolin)
+ DECL_INST2(Bowed)
+ DECL_INST2(Brass)
+ DECL_INST2(Clarinet)
+ DECL_INST2(BlowHole)
+ DECL_INST2(Flute)
+ DECL_INST(BowedBar)
+ DECL_INST(Modal4)
+ DECL_INST(ModalBar)
+ DECL_INST(FM4Op)
+ DECL_INST(FM4Alg3)
+ DECL_INST(FM4Alg4)
+ DECL_INST(FM4Alg5)
+ DECL_INST(FM4Alg6)
+ DECL_INST(FM4Alg8)
+ DECL_INST(HeavyMtl)
+ DECL_INST(PercFlut)
+ DECL_INST(Rhodey)
+ DECL_INST(Wurley)
+ DECL_INST(TubeBell)
+ DECL_INST(FMVoices)
+ DECL_INST(BeeThree)
+ DECL_INST(Sampler)
+ DECL_INST(SamplFlt)
+ DECL_INST(Moog1)
+ // DECL_INST(VoicForm)
+ DECL_INST(DrumSynt)
+ DECL_INST(Shakers)
+ DECL_INST2(Sitar1)
+ DECL_INST2(StrDrone)
+ else {
+ error("No such instrument %s",s->s_name);
+ }
+ stk_instruments[i] = "LastInst";
+}
+
+
+static void stk_bang(t_stk *x)
+{
+ post("bang");
+}
+
+
+static t_int *stk_perform(t_int *w)
+{
+ t_stk* x = (t_stk*)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ int n = (int)(w[3]);
+
+ while (n--) {
+ *out++ = x->instrument->tick();
+ }
+
+
+ return (w+4);
+}
+
+
+static void stk_dsp(t_stk *x, t_signal **sp)
+{
+ dsp_add(stk_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
+}
+
+
+static void stk_noteOn(t_stk *x,t_float f)
+{
+ x->instrument->noteOn(f,x->x_velo);
+}
+
+
+static void stk_noteOff(t_stk *x)
+{
+ x->instrument->noteOff(0);
+}
+
+
+static void stk_control(t_stk *x,t_floatarg f1,t_floatarg f2)
+{
+ x->instrument->controlChange(f1,f2);
+}
+
+static void stk_control1(t_stk *x,t_floatarg f1)
+{
+ x->instrument->controlChange(1,f1);
+}
+
+static void stk_control2(t_stk *x,t_floatarg f1)
+{
+ x->instrument->controlChange(2,f1);
+}
+
+static void stk_control3(t_stk *x,t_floatarg f1)
+{
+ x->instrument->controlChange(3,f1);
+}
+
+static void stk_control4(t_stk *x,t_floatarg f1)
+{
+ x->instrument->controlChange(4,f1);
+}
+
+static void stk_aftertouch(t_stk *x,t_floatarg f1)
+{
+ x->instrument->controlChange(128,f1);
+}
+
+static void stk_pitchbend(t_stk *x,t_floatarg f1)
+{
+ x->instrument->setFreq(f1);
+}
+
+static void stk_float(t_stk* x,t_floatarg f)
+{
+ if (f > 20) stk_noteOn(x,f);
+ else stk_noteOff(x);
+
+}
+
+
+static void *stk_new(t_symbol* s)
+{
+ t_stk *x = (t_stk *)pd_new(stk_class);
+
+ stk_set_instrument(x,s);
+
+ if (x->instrument == NULL) {
+ post("stk: %s no such instrument",s->s_name);
+ return NULL;
+ }
+ floatinlet_new(&x->x_obj, &x->x_velo);
+ x->x_velo = 0.1;
+
+ outlet_new(&x->x_obj, gensym("signal"));
+
+ return (x);
+}
+
+
+
+extern "C" {
+ void stk_setup(void)
+ {
+ stk_class = class_new(gensym("stk"), (t_newmethod)stk_new, 0,
+ sizeof(t_stk), 0,A_DEFSYM,A_NULL);
+ class_addmethod(stk_class, nullfn, gensym("signal"), A_NULL);
+ class_addmethod(stk_class, (t_method) stk_dsp, gensym("dsp"), A_NULL);
+
+ class_addbang(stk_class,stk_bang);
+ class_addfloat(stk_class,stk_float);
+ class_addmethod(stk_class,(t_method) stk_control,gensym("control"),A_DEFFLOAT,A_DEFFLOAT,A_NULL);
+ class_addmethod(stk_class,(t_method) stk_control1,gensym("control1"),A_DEFFLOAT,A_NULL);
+ class_addmethod(stk_class,(t_method) stk_control2,gensym("control2"),A_DEFFLOAT,A_NULL);
+ class_addmethod(stk_class,(t_method) stk_control3,gensym("control3"),A_DEFFLOAT,A_NULL);
+ class_addmethod(stk_class,(t_method) stk_control4,gensym("control4"),A_DEFFLOAT,A_NULL);
+ class_addmethod(stk_class,(t_method) stk_aftertouch,gensym("aftertouch"),A_DEFFLOAT,A_NULL);
+ class_addmethod(stk_class,(t_method) stk_pitchbend,gensym("pitchbend"),A_DEFFLOAT,A_NULL);
+ class_addmethod(stk_class,(t_method) stk_print,gensym("print"),A_NULL);
+
+ }
+}
diff --git a/experimental/stk.h b/experimental/stk.h
new file mode 100755
index 0000000..2fa1ec0
--- /dev/null
+++ b/experimental/stk.h
@@ -0,0 +1,91 @@
+#include <ADSR.h>
+#include <AifWvIn.h>
+#include <AifWvOut.h>
+#include <BeeThree.h>
+#include <BiQuad.h>
+#include <BlowHole.h>
+#include <BowTabl.h>
+#include <Bowed.h>
+#include <BowedBar.h>
+#include <Brass.h>
+#include <ByteSwap.h>
+#include <Clarinet.h>
+#include <Controller.h>
+#include <DCBlock.h>
+#include <DLineA.h>
+#include <DLineL.h>
+#include <DLineN.h>
+#include <DrumSynt.h>
+#include <Envelope.h>
+#include <FIR.h>
+#include <FM4Alg3.h>
+#include <FM4Alg4.h>
+#include <FM4Alg5.h>
+#include <FM4Alg6.h>
+#include <FM4Alg8.h>
+#include <FM4Op.h>
+#include <FMVoices.h>
+#include <Filter.h>
+#include <Flute.h>
+#include <FormSwep.h>
+#include <HeavyMtl.h>
+#include <Instrmnt.h>
+#include <JCRev.h>
+#include <JetTabl.h>
+//#include <LipFilt.h>
+#include <Mandolin.h>
+#include <MatWvIn.h>
+#include <MatWvOut.h>
+#include <Modal4.h>
+#include <ModalBar.h>
+#include <Modulatr.h>
+#include <Moog1.h>
+#include <NRev.h>
+#include <Noise.h>
+#include <Object.h>
+#include <OnePole.h>
+#include <OneZero.h>
+#include <PRCRev.h>
+#include <PercFlut.h>
+#include <Plucked.h>
+#include <Plucked2.h>
+#include <PoleZero.h>
+#include <RawWvIn.h>
+#include <RawWvOut.h>
+#include <ReedTabl.h>
+#include <Reverb.h>
+#include <Rhodey.h>
+#include <RtAudio.h>
+#include <RtDuplex.h>
+#include <RtMidi.h>
+#include <RtWvIn.h>
+#include <RtWvOut.h>
+#include <SKINI11.h>
+#include <SKINI11.msg>
+#include <SamplFlt.h>
+#include <Sampler.h>
+#include <Shakers.h>
+#include <Simple.h>
+#include <SingWave.h>
+#include <SndWvIn.h>
+#include <SndWvOut.h>
+#include <StkError.h>
+#include <StrmWvIn.h>
+#include <StrmWvOut.h>
+#include <SubNoise.h>
+#include <TablLook.h>
+#include <TubeBell.h>
+#include <TwoPole.h>
+#include <TwoZero.h>
+#include <VoicForm.h>
+#include <VoicMang.h>
+#include <WavWvIn.h>
+#include <WavWvOut.h>
+#include <Wurley.h>
+#include <WvIn.h>
+#include <WvOut.h>
+#include <mandplyr.h>
+#include <miditabl.h>
+#include <phontabl.h>
+#include <Sitar1.h>
+#include <StrDrone.h>
diff --git a/experimental/stk.pd b/experimental/stk.pd
new file mode 100755
index 0000000..85c161c
--- /dev/null
+++ b/experimental/stk.pd
@@ -0,0 +1,76 @@
+#N canvas 226 44 704 495 12;
+#X obj 50 422 dac~;
+#X obj 19 295 stk Rhodey;
+#X obj 19 321 throw~ out1;
+#X obj 61 379 catch~ out1;
+#X obj 19 246 mtof;
+#X floatatom 19 87 0 0 0;
+#X msg 56 247 0;
+#X floatatom 100 112 0 0 0;
+#X msg 56 112 bang;
+#X obj 56 134 pipe 600;
+#X floatatom 97 230 0 0 0;
+#X obj 97 254 * 0.01;
+#X text 95 211 velocity;
+#X obj 380 383 stk Flute;
+#X obj 380 350 mtof;
+#X floatatom 380 277 0 0 0;
+#X msg 417 351 0;
+#X floatatom 461 302 0 0 0;
+#X msg 417 302 bang;
+#X obj 417 324 pipe 600;
+#X floatatom 483 331 0 0 0;
+#X obj 483 355 * 0.01;
+#X text 481 312 velocity;
+#X obj 380 411 throw~ out1;
+#X floatatom 557 299 0 0 0;
+#X obj 130 319 throw~ out1;
+#X floatatom 208 242 0 0 0;
+#X obj 208 266 * 0.01;
+#X text 206 223 velocity;
+#X obj 130 293 stk BeeThree;
+#X msg 557 323 control 1 \$1;
+#X msg 161 97 print;
+#X text 233 96 print: prints out all available stk instruments;
+#X text 232 113 control f1 f2: sets the control channel f1 to the;
+#X text 255 129 value of f2;
+#X text 230 150 control1: short for control 1 f2;
+#X text 28 14 PD interface to Perry Cook's STK;
+#X text 231 48 Messages;
+#X text 229 63 ===========;
+#X text 231 79 float number: sets the frequency in Hz;
+#X text 230 171 aftertouch \, pitchbend: MIDI values for aftertouch
+and pitchbend;
+#X msg 319 248 print;
+#X text 317 224 click to see available instruments;
+#X connect 1 0 2 0;
+#X connect 3 0 0 0;
+#X connect 3 0 0 1;
+#X connect 4 0 1 0;
+#X connect 4 0 29 0;
+#X connect 5 0 4 0;
+#X connect 5 0 8 0;
+#X connect 6 0 1 0;
+#X connect 6 0 29 0;
+#X connect 7 0 9 1;
+#X connect 8 0 9 0;
+#X connect 9 0 6 0;
+#X connect 10 0 11 0;
+#X connect 11 0 1 1;
+#X connect 13 0 23 0;
+#X connect 14 0 13 0;
+#X connect 15 0 14 0;
+#X connect 15 0 18 0;
+#X connect 16 0 13 0;
+#X connect 17 0 19 1;
+#X connect 18 0 19 0;
+#X connect 19 0 16 0;
+#X connect 20 0 21 0;
+#X connect 21 0 13 1;
+#X connect 24 0 30 0;
+#X connect 26 0 27 0;
+#X connect 27 0 29 1;
+#X connect 29 0 25 0;
+#X connect 30 0 13 0;
+#X connect 31 0 1 0;
+#X connect 41 0 13 0;
diff --git a/filters/Makefile b/filters/Makefile
new file mode 100755
index 0000000..f002498
--- /dev/null
+++ b/filters/Makefile
@@ -0,0 +1,50 @@
+current: nt
+
+
+# TARGETS += stk
+
+VERSION = \"0.24\"
+
+.SUFFIXES: .dll .obj
+# ----------------------- NT ----------------------------
+
+NTOBJECTS = *.obj
+NTDLLS = *.dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+
+PDNTINCLUDE = /I. /I..\..\pd\src
+ProgramFiles = C:\Program Files
+PDNTLDIR = "$(ProgramFiles)\Microsoft Visual Studio\Vc98\lib"
+#PDNTLDIR = "C:\Programme\Msdev\Vc98\lib"
+
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\wsock32.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ $(PDNTLDIR)\uuid.lib \
+ ..\..\pd\bin\pd.lib
+
+nt: $(NTOBJECTS)
+ -link /dll $(PDNTLIB) bandpass.obj /export:bandpass_setup
+ -link /dll $(PDNTLIB) highpass.obj /export:highpass_setup
+ -link /dll $(PDNTLIB) highshelf.obj /export:highshelf_setup
+ -link /dll $(PDNTLIB) hlshelf.obj /export:hlshelf_setup
+ -link /dll $(PDNTLIB) lowpass.obj /export:lowpass_setup
+ -link /dll $(PDNTLIB) notch.obj /export:notch_setup
+ -link /dll $(PDNTLIB) equalizer.obj /export:equalizer_setup
+
+
+clean:
+ del *.obj
+ del *.dll
+
+
+.c.obj:
+ -cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+
+.obj.dll:
+
+
+
+
diff --git a/filters/bandpass.c b/filters/bandpass.c
new file mode 100755
index 0000000..c4c2e13
--- /dev/null
+++ b/filters/bandpass.c
@@ -0,0 +1,86 @@
+
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+/* ------------------- bandpass ----------------------------*/
+
+static t_class *bandpass_class;
+
+void bandpass_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float alpha = e_alpha(x->x_bw* 0.01,omega);
+ t_float b1 = 0.;
+ t_float b0 = alpha;
+ t_float b2 = -alpha;
+ t_float a0 = 1 + alpha;
+ t_float a1 = -2.*cos(omega);
+ t_float a2 = 1 - alpha;
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("bandpass: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void bandpass_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ bandpass_bang(x);
+}
+
+
+static void *bandpass_new(t_floatarg f,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(bandpass_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+/* floatinlet_new(&x->x_obj, &x->x_gain); */
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ return (x);
+}
+
+
+void bandpass_setup(void)
+{
+ bandpass_class = class_new(gensym("bandpass"), (t_newmethod)bandpass_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(bandpass_class,bandpass_bang);
+ class_addfloat(bandpass_class,bandpass_float);
+}
+
+
+
diff --git a/filters/bandpass.pd b/filters/bandpass.pd
new file mode 100755
index 0000000..73cace4
--- /dev/null
+++ b/filters/bandpass.pd
@@ -0,0 +1,38 @@
+#N canvas 295 68 622 469 10;
+#X obj 77 199 print;
+#X floatatom 77 114 0 0 0;
+#X floatatom 139 114 0 0 0;
+#X msg 360 109 \; paint 0;
+#X obj 164 196 filtgain;
+#X msg 91 138 bang;
+#X text 139 93 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which
+is expressed in octaves. A bandwidth of 100 is equivalent to one octave.
+;
+#X text 358 25 click first;
+#X text 186 159 click on filtgain to view frequency plot;
+#X text 76 12 Bandpass coefficients for biquad~;
+#X text 70 26 ===================================;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients
+for biquad~;
+#X obj 77 160 bandpass 4000 33;
+#X obj 33 114 r doit;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X connect 1 0 24 0;
+#X connect 2 0 24 1;
+#X connect 2 0 5 0;
+#X connect 5 0 24 0;
+#X connect 24 0 0 0;
+#X connect 24 0 4 0;
+#X connect 25 0 5 0;
diff --git a/filters/equalizer.c b/filters/equalizer.c
new file mode 100755
index 0000000..80d8410
--- /dev/null
+++ b/filters/equalizer.c
@@ -0,0 +1,89 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+
+/* ------------------- equ ----------------------------*/
+static t_class *equ_class;
+
+void equ_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float alpha = e_alpha(x->x_bw*0.01,omega);
+ t_float b0 = 1 + alpha*e_A(x->x_gain);
+ t_float b1 = -2.*cos(omega);
+ t_float b2 = 1;
+ t_float a0 = 1 + alpha;
+ t_float a1 = -2.*cos(omega);
+ t_float a2 = 1 - alpha;
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("equ: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void equ_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ equ_bang(x);
+}
+
+
+static void *equ_new(t_floatarg f,t_floatarg g,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(equ_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+ floatinlet_new(&x->x_obj, &x->x_gain);
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ if (g != 0.) x->x_gain = g;
+ return (x);
+}
+
+
+void equalizer_setup(void)
+{
+ equ_class = class_new(gensym("equalizer"), (t_newmethod)equ_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(equ_class,equ_bang);
+ class_addfloat(equ_class,equ_float);
+}
+
+
+
+
+
diff --git a/filters/equalizer.pd b/filters/equalizer.pd
new file mode 100755
index 0000000..05f7c56
--- /dev/null
+++ b/filters/equalizer.pd
@@ -0,0 +1,39 @@
+#N canvas 561 126 620 459 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 186 112;
+#X msg 360 117 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 186 91 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 200 158 click on filtgain to view frequency plot;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X floatatom 129 113;
+#X text 138 92 gain;
+#X text 71 26 ==============================================;
+#X text 76 12 Parametric Equalizer coefficients for biquad~;
+#X obj 77 160 equalizer 5000 70 8;
+#X obj 31 114 r doit;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X connect 1 0 26 0;
+#X connect 2 0 5 0;
+#X connect 2 0 26 2;
+#X connect 5 0 26 0;
+#X connect 22 0 5 0;
+#X connect 22 0 26 1;
+#X connect 26 0 0 0;
+#X connect 26 0 4 0;
+#X connect 27 0 26 0;
diff --git a/filters/filters.h b/filters/filters.h
new file mode 100755
index 0000000..6ff7962
--- /dev/null
+++ b/filters/filters.h
@@ -0,0 +1,74 @@
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+
+#ifndef __GGEE_FILTERS_H__
+#define __GGEE_FILTERS_H__
+
+
+
+#ifndef M_PI
+#define M_PI 3.141593f
+#endif
+
+
+#include <math.h>
+#define LN2 0.69314718
+#define e_A(g) (pow(10,(g/40.)))
+#define e_omega(f,r) (2.0*M_PI*f/r)
+#define e_alpha(bw,omega) (sin(omega)*sinh(LN2/2. * bw * omega/sin(omega)))
+#define e_beta(a,S) (sqrt((a*a + 1)/(S) - (a-1)*(a-1)))
+
+
+
+
+typedef struct _rbjfilter
+{
+ t_object x_obj;
+ t_float x_rate;
+ t_float x_freq;
+ t_float x_gain;
+ t_float x_bw;
+} t_rbjfilter;
+
+
+static int check_stability(t_float fb1,
+ t_float fb2,
+ t_float ff1,
+ t_float ff2,
+ t_float ff3)
+{
+ float discriminant = fb1 * fb1 + 4 * fb2;
+
+ if (discriminant < 0) /* imaginary roots -- resonant filter */
+ {
+ /* they're conjugates so we just check that the product
+ is less than one */
+ if (fb2 >= -1.0f) goto stable;
+ }
+ else /* real roots */
+ {
+ /* check that the parabola 1 - fb1 x - fb2 x^2 has a
+ vertex between -1 and 1, and that it's nonnegative
+ at both ends, which implies both roots are in [1-,1]. */
+ if (fb1 <= 2.0f && fb1 >= -2.0f &&
+ 1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
+ goto stable;
+ }
+ return 0;
+stable:
+ return 1;
+}
+
+
+
+
+
+
+#endif
diff --git a/filters/filtgain.pd b/filters/filtgain.pd
new file mode 100755
index 0000000..b276a52
--- /dev/null
+++ b/filters/filtgain.pd
@@ -0,0 +1,74 @@
+#N canvas 178 144 702 459 10;
+#X obj 38 342 biquad~;
+#X obj 38 316 osc~ 220;
+#X obj 118 340 env~;
+#X floatatom 38 297;
+#X obj 38 419 dac~;
+#X obj 193 428 tabwrite array1;
+#X obj 325 400 int;
+#X obj 350 401 + 1;
+#X msg 296 399 0;
+#X obj 193 410 float;
+#X obj 218 372 t b f;
+#X obj 38 398 *~;
+#X obj 61 399 dbtorms;
+#X floatatom 368 359;
+#X obj 296 418 sel 500;
+#X obj 38 277 * 40;
+#X obj 325 380 metro 10;
+#X obj 325 359 r paint;
+#X obj 61 381 r volume;
+#X obj 38 7 inlet;
+#X floatatom 194 368;
+#X floatatom 279 360;
+#X obj 118 360 - 100;
+#X obj 118 382 * 0.01;
+#X graph graph2 0 -1 500 1 148 253 648 113;
+#X array array1 500 float;
+#X pop;
+#X msg 273 272 5000;
+#X msg 273 82 5000;
+#X msg 398 82 10000;
+#X msg 398 272 10000;
+#X msg 173 83 1000;
+#X msg 173 271 1000;
+#X text 105 6 subpatch used in filter externals see;
+#X obj 347 12 bandpass;
+#X obj 414 13 notch;
+#X obj 470 14 lowpass;
+#X obj 522 13 highpass;
+#X obj 522 35 equalizer;
+#X obj 347 34 highshelf;
+#X obj 414 34 lowshelf;
+#X obj 470 34 hlshelf;
+#X connect 0 0 2 0;
+#X connect 0 0 11 0;
+#X connect 1 0 0 0;
+#X connect 2 0 22 0;
+#X connect 3 0 1 0;
+#X connect 6 0 7 0;
+#X connect 6 0 10 0;
+#X connect 6 0 14 0;
+#X connect 6 0 15 0;
+#X connect 7 0 6 1;
+#X connect 8 0 6 0;
+#X connect 9 0 5 0;
+#X connect 10 0 9 0;
+#X connect 10 1 5 1;
+#X connect 11 0 4 0;
+#X connect 11 0 4 1;
+#X connect 12 0 11 1;
+#X connect 13 0 16 1;
+#X connect 14 0 8 0;
+#X connect 15 0 3 0;
+#X connect 16 0 6 0;
+#X connect 17 0 16 0;
+#X connect 18 0 12 0;
+#X connect 19 0 0 0;
+#X connect 20 0 5 0;
+#X connect 21 0 5 1;
+#X connect 22 0 23 0;
+#X connect 23 0 9 1;
+#X connect 26 0 25 0;
+#X connect 27 0 28 0;
+#X connect 29 0 30 0;
diff --git a/filters/highpass.c b/filters/highpass.c
new file mode 100755
index 0000000..e7e0443
--- /dev/null
+++ b/filters/highpass.c
@@ -0,0 +1,87 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+/* ------------------- highpass ----------------------------*/
+
+static t_class *highpass_class;
+
+void highpass_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float alpha = e_alpha(x->x_bw* 0.01,omega);
+ t_float b1 = -(1 + cos(omega));
+ t_float b0 = -b1/2.;
+ t_float b2 = b0;
+ t_float a0 = 1 + alpha;
+ t_float a1 = -2.*cos(omega);
+ t_float a2 = 1 - alpha;
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("highpass: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void highpass_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ highpass_bang(x);
+}
+
+
+static void *highpass_new(t_floatarg f,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(highpass_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+/* floatinlet_new(&x->x_obj, &x->x_gain); */
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ return (x);
+}
+
+
+void highpass_setup(void)
+{
+ highpass_class = class_new(gensym("highpass"), (t_newmethod)highpass_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(highpass_class,highpass_bang);
+ class_addfloat(highpass_class,highpass_float);
+}
+
+
+
+
diff --git a/filters/highpass.pd b/filters/highpass.pd
new file mode 100755
index 0000000..e953888
--- /dev/null
+++ b/filters/highpass.pd
@@ -0,0 +1,35 @@
+#N canvas 365 183 620 463 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 168 115;
+#X msg 360 109 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 168 94 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 182 148 click on filtgain to view frequency plot;
+#X text 70 26 ===================================;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X text 76 12 Highpass coefficients for biquad~;
+#X obj 77 160 highpass 4000 33;
+#X obj 34 113 r doit;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X connect 1 0 24 0;
+#X connect 2 0 5 0;
+#X connect 2 0 24 1;
+#X connect 5 0 24 0;
+#X connect 24 0 0 0;
+#X connect 24 0 4 0;
+#X connect 25 0 24 0;
diff --git a/filters/highshelf.c b/filters/highshelf.c
new file mode 100755
index 0000000..ee6006c
--- /dev/null
+++ b/filters/highshelf.c
@@ -0,0 +1,90 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+/* ------------------- highshelf ----------------------------*/
+
+static t_class *highshelf_class;
+
+void highshelf_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float A = e_A(x->x_gain);
+ t_float cs = cos(omega);
+ t_float sn = sin(omega);
+ t_float beta = e_beta(A,x->x_bw* 0.01);
+
+ t_float b0 = A*((A+1) + (A-1)*cs + beta*sn);
+ t_float b1 =-2.*A*((A-1) + (A+1)*cs);
+ t_float b2 = A*((A+1) + (A-1)*cs - beta*sn);
+ t_float a0 = ((A+1) - (A-1)*cs + beta*sn);
+ t_float a1 = 2.*((A-1) - (A+1)*cs);
+ t_float a2 = ((A+1) - (A-1)*cs - beta*sn);
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("highshelf: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void highshelf_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ highshelf_bang(x);
+}
+
+
+static void *highshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(highshelf_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+ floatinlet_new(&x->x_obj, &x->x_gain);
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ if (g != 0.) x->x_gain = g;
+ return (x);
+}
+
+
+void highshelf_setup(void)
+{
+ highshelf_class = class_new(gensym("highshelf"), (t_newmethod)highshelf_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(highshelf_class,highshelf_bang);
+ class_addfloat(highshelf_class,highshelf_float);
+}
+
+
diff --git a/filters/highshelf.pd b/filters/highshelf.pd
new file mode 100755
index 0000000..be2a577
--- /dev/null
+++ b/filters/highshelf.pd
@@ -0,0 +1,39 @@
+#N canvas 310 193 620 455 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 186 112;
+#X msg 360 117 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 208 159 click on filtgain to view frequency plot;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X floatatom 129 113;
+#X text 138 92 gain;
+#X text 71 26 ==============================================;
+#X text 186 91 slope (0 - 100);
+#X text 76 12 Highshelf coefficients for biquad~;
+#X obj 77 160 highshelf 5000 70 100;
+#X obj 30 113 r doit;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X connect 1 0 26 0;
+#X connect 2 0 5 0;
+#X connect 2 0 26 2;
+#X connect 5 0 26 0;
+#X connect 21 0 5 0;
+#X connect 21 0 26 1;
+#X connect 26 0 0 0;
+#X connect 26 0 4 0;
+#X connect 27 0 26 0;
diff --git a/filters/hlshelf.c b/filters/hlshelf.c
new file mode 100755
index 0000000..a2189d7
--- /dev/null
+++ b/filters/hlshelf.c
@@ -0,0 +1,226 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include <math.h>
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ hlshelf ----------------------------- */
+
+
+#ifndef M_PI
+#define M_PI 3.141593f
+#endif
+
+#define SRATE 44100.0
+#define MAX_GAIN 120.0f
+
+static t_class *hlshelf_class;
+
+
+typedef struct _hlshelf
+{
+ t_object x_obj;
+ float s_rate;
+ float s_gain0;
+ float s_gain1;
+ float s_gain2;
+ float s_ltransfq;
+ float s_htransfq;
+ float s_lradians;
+ float s_hradians;
+} t_hlshelf;
+
+
+int hlshelf_check_stability(t_float fb1,
+ t_float fb2,
+ t_float ff1,
+ t_float ff2,
+ t_float ff3)
+{
+ float discriminant = fb1 * fb1 + 4 * fb2;
+
+ if (discriminant < 0) /* imaginary roots -- resonant filter */
+ {
+ /* they're conjugates so we just check that the product
+ is less than one */
+ if (fb2 >= -1.0f) goto stable;
+ }
+ else /* real roots */
+ {
+ /* check that the parabola 1 - fb1 x - fb2 x^2 has a
+ vertex between -1 and 1, and that it's nonnegative
+ at both ends, which implies both roots are in [1-,1]. */
+ if (fb1 <= 2.0f && fb1 >= -2.0f &&
+ 1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
+ goto stable;
+ }
+ return 0;
+stable:
+ return 1;
+}
+
+
+void hlshelf_check(t_hlshelf *x)
+{
+
+ if(x->s_gain0 - x->s_gain1 > MAX_GAIN) {
+ x->s_gain0 = x->s_gain1 + MAX_GAIN;
+ post("setting gain0 to %f",x->s_gain0);
+ }
+
+
+ if(x->s_gain1 > MAX_GAIN) {
+ x->s_gain1 = MAX_GAIN;
+ post("setting gain1 to %f",x->s_gain1);
+ }
+
+ if(x->s_gain2 - x->s_gain1 > MAX_GAIN) {
+ x->s_gain2 = x->s_gain1 + MAX_GAIN;
+ post("setting gain2 to %f",x->s_gain2);
+ }
+
+ /* constrain: 0 <= x->s_ltransfq < x->s_htransfq. */
+ x->s_ltransfq = (x->s_ltransfq < x->s_htransfq) ? x->s_ltransfq : x->s_htransfq - 0.5f;
+
+ if (x->s_ltransfq < 0) x->s_ltransfq = 0.0f;
+
+ x->s_lradians = M_PI * x->s_ltransfq / x->s_rate;
+ x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate));
+
+}
+
+
+void hlshelf_bang(t_hlshelf *x)
+{
+ t_atom at[6];
+ float c0, c1, c2, d0, d1, d2; /* output coefs */
+ float a1, a2, b1, b2, g1, g2; /* temp coefs */
+ double xf;
+
+ hlshelf_check(x);
+
+ /* low shelf */
+ xf = 0.5 * 0.115129255 * (double)(x->s_gain0 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */
+ if(xf < -200.) /* exp(x) -> 0 */
+ {
+ a1 = 1.0f;
+ b1 = -1.0f;
+ g1 = 0.0f;
+ }
+ else
+ {
+ double t = tan(x->s_lradians);
+ double e = exp(xf);
+ double r = t / e;
+ double kr = t * e;
+
+ a1 = (r - 1) / (r + 1);
+ b1 = (kr - 1) / (kr + 1);
+ g1 = (kr + 1) / (r + 1);
+ }
+
+ /* high shelf */
+ xf = 0.5 * 0.115129255 * (double)(x->s_gain2 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */
+ if(xf < -200.) /* exp(x) -> 0 */
+ {
+ a2 = -1.0f;
+ b2 = 1.0f;
+ g2 = 0.0f;
+ }
+ else
+ {
+ double t = tan(x->s_hradians);
+ double e = exp(xf);
+ double r = t / e;
+ double kr = t * e;
+
+ a2 = (1 - r) / (1 + r);
+ b2 = (1 - kr) / (1 + kr);
+ g2 = (1 + kr) / (1 + r);
+ }
+
+ /* form product */
+ c0 = g1 * g2 * (float)(exp((double)(x->s_gain1) * 0.05f * 2.302585093f)); ;
+ c1 = a1 + a2;
+ c2 = a1 * a2;
+ d0 = 1.0f;
+ d1 = b1 + b2;
+ d2 = b1 * b2;
+
+ if (!hlshelf_check_stability(-c1/d0,-c2/d0,d0/d0,d1/d0,d2/d0)) {
+ post("hlshelf: filter unstable -> resetting");
+ c0=1.;c1=0.;c2=0.;
+ d0=1.;d1=0.;d2=0.;
+ }
+
+ SETFLOAT(at,-c1/d0);
+ SETFLOAT(at+1,-c2/d0);
+ SETFLOAT(at+2,d0/d0);
+ SETFLOAT(at+3,d1/d0);
+ SETFLOAT(at+4,d2/d0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+void hlshelf_float(t_hlshelf *x,t_floatarg f)
+{
+ x->s_gain0 = f;
+ hlshelf_bang(x);
+}
+
+
+static void *hlshelf_new(t_symbol* s,t_int argc, t_atom* at)
+{
+ t_hlshelf *x = (t_hlshelf *)pd_new(hlshelf_class);
+ t_float k0 = atom_getfloat(at);
+ t_float k1 = atom_getfloat(at+1);
+ t_float k2 = atom_getfloat(at+2);
+ t_float f1 = atom_getfloat(at+3);
+ t_float f2 = atom_getfloat(at+4);
+
+
+ f1 = atom_getfloat(at);
+ f2 = atom_getfloat(at);
+
+ if ((f1 == 0.0f && f2 == 0.0f) || f1 > f2){ /* all gains = 0db */
+ f1 = 150.0f;
+ f2 = 5000.0f;
+ }
+
+ if (f1 < 0) f1 = 0.0f;
+ if (f2 > SRATE) f2 = .5f*SRATE;
+
+ x->s_rate = SRATE; /* srate default */
+ x->s_gain0 = k0;
+ x->s_gain1 = k1;
+ x->s_gain2 = k2;
+
+ x->s_ltransfq = 0.0f;
+ x->s_htransfq = SRATE/2;
+
+ x->s_lradians = M_PI * x->s_ltransfq / x->s_rate;
+ x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate));
+
+ floatinlet_new(&x->x_obj, &x->s_gain1);
+ floatinlet_new(&x->x_obj, &x->s_gain2);
+ floatinlet_new(&x->x_obj, &x->s_ltransfq);
+ floatinlet_new(&x->x_obj, &x->s_htransfq);
+ outlet_new(&x->x_obj, &s_list);
+
+ return (x);
+}
+
+void hlshelf_setup(void)
+{
+ hlshelf_class = class_new(gensym("hlshelf"), (t_newmethod)hlshelf_new, 0,
+ sizeof(t_hlshelf), 0, A_GIMME, 0);
+ class_addbang(hlshelf_class,hlshelf_bang);
+ class_addfloat(hlshelf_class,hlshelf_float);
+}
+
+
diff --git a/filters/hlshelf.pd b/filters/hlshelf.pd
new file mode 100755
index 0000000..0e5251d
--- /dev/null
+++ b/filters/hlshelf.pd
@@ -0,0 +1,34 @@
+#N canvas 365 183 620 471 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 139 114;
+#X msg 360 109 \; paint 0;
+#X obj 159 175 filtgain;
+#X text 139 93 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 158 159 click on filtgain to view frequency plot;
+#X text 76 12 Bandpass coefficients for biquad~;
+#X text 70 26 ===================================;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X obj 77 61 r freq;
+#X obj 139 61 r bw;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; freq 4000 \; bw 33;
+#X obj 77 160 hlshelf;
+#X connect 1 0 26 0;
+#X connect 2 0 26 1;
+#X connect 23 0 1 0;
+#X connect 24 0 2 0;
+#X connect 26 0 0 0;
+#X connect 26 0 4 0;
diff --git a/filters/lowpass.c b/filters/lowpass.c
new file mode 100755
index 0000000..4e1b2b9
--- /dev/null
+++ b/filters/lowpass.c
@@ -0,0 +1,89 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+
+/* ------------------- lowpass ----------------------------*/
+
+static t_class *lowpass_class;
+
+void lowpass_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float alpha = e_alpha(x->x_bw*0.01,omega);
+ t_float b1 = 1 - cos(omega);
+ t_float b0 = b1/2.;
+ t_float b2 = b0;
+ t_float a0 = 1 + alpha;
+ t_float a1 = -2.*cos(omega);
+ t_float a2 = 1 - alpha;
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("lowpass: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void lowpass_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ lowpass_bang(x);
+}
+
+
+static void *lowpass_new(t_floatarg f,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(lowpass_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+/* floatinlet_new(&x->x_obj, &x->x_gain); */
+ floatinlet_new(&x->x_obj, &x->x_bw);
+
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ return (x);
+}
+
+
+void lowpass_setup(void)
+{
+ lowpass_class = class_new(gensym("lowpass"), (t_newmethod)lowpass_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(lowpass_class,lowpass_bang);
+ class_addfloat(lowpass_class,lowpass_float);
+}
+
+
+
+
diff --git a/filters/lowpass.pd b/filters/lowpass.pd
new file mode 100755
index 0000000..9d15c16
--- /dev/null
+++ b/filters/lowpass.pd
@@ -0,0 +1,35 @@
+#N canvas 365 183 620 467 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 162 114;
+#X msg 360 109 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 139 93 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 175 159 click on filtgain to view frequency plot;
+#X text 70 26 ===================================;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X text 71 12 Lowpass coefficients for biquad~;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X obj 32 114 r doit;
+#X obj 77 160 lowpass 4000 33;
+#X connect 1 0 26 0;
+#X connect 2 0 5 0;
+#X connect 2 0 26 1;
+#X connect 5 0 26 0;
+#X connect 25 0 26 0;
+#X connect 26 0 0 0;
+#X connect 26 0 4 0;
diff --git a/filters/lowshelf.c b/filters/lowshelf.c
new file mode 100755
index 0000000..dd925dc
--- /dev/null
+++ b/filters/lowshelf.c
@@ -0,0 +1,91 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+
+/* ------------------- lowshelf ----------------------------*/
+
+static t_class *lowshelf_class;
+
+void lowshelf_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float A = e_A(x->x_gain);
+ t_float cs = cos(omega);
+ t_float sn = sin(omega);
+ t_float beta = e_beta(A,x->x_bw*0.01);
+
+ t_float b0 = A*((A+1) - (A-1)*cs + beta*sn);
+ t_float b1 = 2.*A*((A-1) - (A+1)*cs);
+ t_float b2 = A*((A+1) - (A-1)*cs - beta*sn);
+ t_float a0 = ((A+1) + (A-1)*cs + beta*sn);
+ t_float a1 = -2.*((A-1) + (A+1)*cs);
+ t_float a2 = ((A+1) + (A-1)*cs - beta*sn);
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("lowshelf: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void lowshelf_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ lowshelf_bang(x);
+}
+
+
+static void *lowshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(lowshelf_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+ floatinlet_new(&x->x_obj, &x->x_gain);
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ if (g != 0.) x->x_gain = g;
+ return (x);
+}
+
+
+void lowshelf_setup(void)
+{
+ lowshelf_class = class_new(gensym("lowshelf"), (t_newmethod)lowshelf_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(lowshelf_class,lowshelf_bang);
+ class_addfloat(lowshelf_class,lowshelf_float);
+}
+
+
diff --git a/filters/lowshelf.pd b/filters/lowshelf.pd
new file mode 100755
index 0000000..140c754
--- /dev/null
+++ b/filters/lowshelf.pd
@@ -0,0 +1,39 @@
+#N canvas 365 183 620 459 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 192 113;
+#X msg 360 117 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 211 159 click on filtgain to view frequency plot;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X floatatom 129 113;
+#X text 138 92 gain;
+#X text 71 26 ==============================================;
+#X text 192 92 slope (0 - 100);
+#X text 76 12 Lowshelf coefficients for biquad~;
+#X obj 31 113 r doit;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X obj 77 160 lowshelf 4000 50 100;
+#X connect 1 0 28 0;
+#X connect 2 0 5 0;
+#X connect 2 0 28 2;
+#X connect 5 0 28 0;
+#X connect 21 0 5 0;
+#X connect 21 0 28 1;
+#X connect 26 0 28 0;
+#X connect 28 0 0 0;
+#X connect 28 0 4 0;
diff --git a/filters/moog~.c b/filters/moog~.c
new file mode 100755
index 0000000..924ff31
--- /dev/null
+++ b/filters/moog~.c
@@ -0,0 +1,182 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include "math.h"
+#include <m_pd.h>
+
+/* ----------------------------- moog ----------------------------- */
+static t_class *moog_class;
+
+
+typedef struct _moog
+{
+ t_object x_obj;
+ t_pd in2;
+ t_float x_1,x_2,x_3,x_4;
+ t_float y_1,y_2,y_3,y_4;
+} t_moog;
+
+static void moog_reset(t_moog *x)
+{
+ x->x_1 = x->x_2 = x->x_3 = x->x_4 = 0.0;
+ x->y_1 = x->y_2 = x->y_3 = x->y_4 = 0.0;
+
+}
+
+
+
+static void *moog_new(t_symbol *s, int argc, t_atom *argv)
+{
+ if (argc > 1) post("moog~: extra arguments ignored");
+ {
+ t_moog *x = (t_moog *)pd_new(moog_class);
+ outlet_new(&x->x_obj, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->in2, &s_signal, &s_signal);
+ moog_reset(x);
+ return (x);
+ }
+
+
+}
+
+
+
+static t_float calc_k(t_float f,t_float k) {
+ if (k>4.) k =4.;
+ if (k < 0.) k = 0.;
+ if (f <= 3800) return k;
+ k = k - 0.5*((f-3800)/4300);
+ return k;
+}
+
+t_int *moog_perform(t_int *w)
+{
+ t_moog* x = (t_moog*) (w[1]);
+ t_float *in1 = (t_float *)(w[2]);
+ t_float *p = (t_float *)(w[3]);
+ t_float *k = (t_float *)(w[4]);
+
+ t_float *out = (t_float *)(w[5]);
+ int n = (int)(w[6]);
+ float in;
+ float pt,pt1;
+
+ float x1 = x->x_1;
+ float x2 = x->x_2;
+ float x3 = x->x_3;
+ float x4 = x->x_4;
+ float y1 = x->y_1;
+ float y2 = x->y_2;
+ float y3 = x->y_3;
+ float y4 = x->y_4;
+
+
+ while (n--) {
+ if (*p > 8140) *p = 8140.;
+ *k = calc_k(*p,*k);
+ pt =*p;
+ pt1=(pt+1)*0.76923077;
+ in = *in1++ - *k*y4;
+ y1 = (pt1)*in + 0.3*x1 - pt*y1;
+ x1 = in;
+ y2 = (pt1)*y1 + 0.3*x2 - pt*y2;
+ x2 = y1;
+ y3 = (pt1)*y2 + 0.3 *x3 - pt*y3;
+ x3 = y2;
+ y4 = (pt1)*y3 + 0.3*x4 - pt*y4;
+ x4 = y3;
+ *out++ = y4;
+ }
+
+
+ x->y_1 = y1;
+ x->y_2 = y2;
+ x->y_3 = y3;
+ x->y_4 = y4;
+ x->x_1 = x1;
+ x->x_2 = x2;
+ x->x_3 = x3;
+ x->x_4 = x4;
+
+ return (w+7);
+}
+
+
+#define CLIP(x) x = ((x) > 1.0 ? (1.0) : (x))
+
+t_int *moog_perf8(t_int *w)
+{
+ t_moog* x = (t_moog*) (w[1]);
+ t_float *in1 = (t_float *)(w[2]);
+ t_float *p = (t_float *)(w[3]);
+ t_float *k = (t_float *)(w[4]);
+ t_float *out = (t_float *)(w[5]);
+ int n = (int)(w[6]);
+
+ t_float x1 = x->x_1;
+ t_float x2 = x->x_2;
+ t_float x3 = x->x_3;
+ t_float x4 = x->x_4;
+ t_float y1 = x->y_1;
+ t_float y2 = x->y_2;
+ t_float y3 = x->y_3;
+ t_float y4 = x->y_4;
+ t_float temp,temp2;
+ t_float pt,pt1;
+ t_float in;
+
+ while (n--) {
+ if (*p > 8140.) *p = 8140.;
+ *k = calc_k(*p,*k);
+
+ pt =*p* 0.01*0.0140845 - 0.9999999f;
+ pt1=(pt+1.0)*0.76923077;
+ in = *in1++ - *k*y4;
+ y1 = pt1*(in + 0.3*x1) - pt*y1;
+ x1 = in;
+ y2 = pt1*(y1 + 0.3*x2) - pt*y2;
+ x2 = y1;
+ y3 = pt1*(y2 + 0.3*x3) - pt*y3;
+ x3 = y2;
+ y4 = pt1*(y3 + 0.3*x4) - pt*y4;
+ x4 = y3;
+ *out++ = y4;
+
+ p++;k++;
+ }
+
+ x->y_1 = y1;
+ x->y_2 = y2;
+ x->y_3 = y3;
+ x->y_4 = y4;
+ x->x_1 = x1;
+ x->x_2 = x2;
+ x->x_3 = x3;
+ x->x_4 = x4;
+
+ return (w+7);
+}
+
+void dsp_add_moog(t_moog *x, t_sample *in1, t_sample *in2, t_sample *in3, t_sample *out, int n)
+{
+ if (n&7)
+ dsp_add(moog_perform, 6,(t_int)x, in1,in2,in3, out, n);
+ else
+ dsp_add(moog_perf8, 6,(t_int) x, in1, in2, in3, out, n);
+}
+
+static void moog_dsp(t_moog *x, t_signal **sp)
+{
+ dsp_add_moog(x,sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,sp[0]->s_n);
+}
+
+
+void moog_tilde_setup(void)
+{
+ moog_class = class_new(gensym("moog~"), (t_newmethod)moog_new, 0,
+ sizeof(t_moog), 0, A_GIMME, 0);
+ class_addmethod(moog_class, nullfn, gensym("signal"), 0);
+ class_addmethod(moog_class, (t_method)moog_reset, gensym("reset"), 0);
+ class_addmethod(moog_class, (t_method)moog_dsp, gensym("dsp"), A_NULL);
+}
diff --git a/filters/moog~.pd b/filters/moog~.pd
new file mode 100755
index 0000000..7e0139b
--- /dev/null
+++ b/filters/moog~.pd
@@ -0,0 +1,39 @@
+#N canvas 225 113 568 397 10;
+#X obj 186 210 moog~;
+#X obj 178 288 dac~;
+#X floatatom 226 163 5 0 0;
+#X floatatom 183 104 5 0 0;
+#X floatatom 25 113 5 0 0;
+#X obj 238 237 env~;
+#X floatatom 238 257 5 0 0;
+#X obj 186 257 *~ 0.1;
+#X msg 182 163 reset;
+#X obj 116 105 +~ 1;
+#X floatatom 116 63 5 0 0;
+#X floatatom 180 128 5 0 0;
+#X obj 116 146 +~ 100;
+#X obj 116 84 osc~ 0.25;
+#X obj 116 125 *~ 2000;
+#X obj 226 182 sig~ 3;
+#X obj 25 139 phasor~ 110;
+#X msg 249 52 \; pd dsp 1 \;;
+#X text 17 7 A signal controlled "moog" resonant lowpass;
+#X text 272 163 Q (1-4);
+#X text 61 46 resonance freq modulation;
+#X connect 0 0 5 0;
+#X connect 0 0 7 0;
+#X connect 2 0 15 0;
+#X connect 3 0 14 1;
+#X connect 4 0 16 0;
+#X connect 5 0 6 0;
+#X connect 7 0 1 0;
+#X connect 7 0 1 1;
+#X connect 8 0 0 0;
+#X connect 9 0 14 0;
+#X connect 10 0 13 0;
+#X connect 11 0 12 1;
+#X connect 12 0 0 1;
+#X connect 13 0 9 0;
+#X connect 14 0 12 0;
+#X connect 15 0 0 2;
+#X connect 16 0 0 0;
diff --git a/filters/notch.c b/filters/notch.c
new file mode 100755
index 0000000..ab11a7a
--- /dev/null
+++ b/filters/notch.c
@@ -0,0 +1,89 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+
+/* ------------------- notch ----------------------------*/
+
+static t_class *notch_class;
+
+void notch_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float alpha = e_alpha(x->x_bw* 0.01,omega);
+ t_float b1 = -2.*cos(omega);
+ t_float b0 = 1;
+ t_float b2 = b0;
+ t_float a0 = 1 + alpha;
+ t_float a1 = -2.*cos(omega);
+ t_float a2 = 1 - alpha;
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("notch: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void notch_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ notch_bang(x);
+}
+
+
+static void *notch_new(t_floatarg f,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(notch_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+/* floatinlet_new(&x->x_obj, &x->x_gain); */
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ return (x);
+}
+
+
+void notch_setup(void)
+{
+ notch_class = class_new(gensym("notch"), (t_newmethod)notch_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(notch_class,notch_bang);
+ class_addfloat(notch_class,notch_float);
+}
+
+
+
+
+
diff --git a/filters/notch.pd b/filters/notch.pd
new file mode 100755
index 0000000..a65d9c4
--- /dev/null
+++ b/filters/notch.pd
@@ -0,0 +1,35 @@
+#N canvas 363 47 620 467 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 150 114;
+#X msg 360 109 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 150 93 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 165 159 click on filtgain to view frequency plot;
+#X text 70 26 ===================================;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X text 72 13 Notch coefficients for biquad~;
+#X msg 360 46 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X obj 35 114 r doit;
+#X obj 77 160 notch 4000 33;
+#X connect 1 0 26 0;
+#X connect 2 0 5 0;
+#X connect 2 0 26 1;
+#X connect 5 0 26 0;
+#X connect 25 0 26 0;
+#X connect 26 0 0 0;
+#X connect 26 0 4 0;
diff --git a/ggee.c b/ggee.c
new file mode 100644
index 0000000..4d762d9
--- /dev/null
+++ b/ggee.c
@@ -0,0 +1,134 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#ifndef VERSION
+#define VERSION "unknown"
+#endif
+
+#include <m_pd.h>
+
+#define EXPERIMENTAL
+
+#ifndef __DATE__
+#define __DATE__ "without using a gnu compiler"
+#endif
+
+typedef struct _ggext
+{
+ t_object x_obj;
+} t_ggext;
+
+static t_class* ggext_class;
+
+void sfplay_setup();
+void streamin_tilde_setup();
+void streamout_tilde_setup();
+void fofsynth_setup();
+void sfread_tilde_setup();
+void sfwrite_tilde_setup();
+void state_setup();
+void slider_setup();
+void hslider_setup();
+void toddle_setup();
+void envgen_setup();
+void ticker_setup();
+void unwonk_setup();
+void atan2_tilde_setup(void);
+void log_tilde_setup(void);
+void exp_tilde_setup(void);
+void sinh_setup(void);
+void inv_setup();
+void scalarinv_setup();
+void rtout_setup(void);
+void fasor_tilde_setup(void);
+void sl_setup();
+void rl_setup();
+void trsync_tilde_setup();
+void serialize_setup();
+void vbap_setup();
+void hlshelf_setup();
+void lowpass_setup();
+void highpass_setup();
+void bandpass_setup();
+void notch_setup();
+void lowshelf_setup();
+void highshelf_setup();
+void equalizer_setup();
+void constant_setup(void );
+void mixer_tilde_setup();
+void stripdir_setup();
+void qread_setup();
+void joystick_setup();
+
+#ifdef HAVE_LIBSTK
+void stk_setup();
+#endif
+void serialctl_setup();
+void serial_ms_setup();
+void serial_bird_setup();
+void shell_setup();
+
+static void* ggext_new(t_symbol* s) {
+ t_ggext *x = (t_ggext *)pd_new(ggext_class);
+ return (x);
+}
+
+void ggext_setup(void)
+{
+ ggext_class = class_new(gensym("ggext"), (t_newmethod)ggext_new, 0,
+ sizeof(t_ggext), 0,0);
+
+ streamin_tilde_setup();
+ streamout_tilde_setup();
+ fofsynth_tilde_setup();
+#ifdef unix
+ sfread_tilde_setup();
+ sfwrite_tilde_setup();
+ serialctl_setup();
+ serial_ms_setup();
+ serial_bird_setup();
+ rtout_setup();
+ shell_setup();
+#endif
+ serialize_setup();
+ sfplay_tilde_setup();
+ state_setup();
+ slider_setup();
+ hslider_setup();
+ toddle_setup();
+ envgen_setup();
+ ticker_setup();
+ unwonk_setup();
+ atan2_tilde_setup();
+ log_tilde_setup();
+ exp_tilde_setup();
+ sinh_setup();
+ inv_setup();
+ scalarinv_setup();
+ fasor_tilde_setup();
+ sl_setup();
+ rl_setup();
+#ifdef HAVE_LIBSTK
+ stk_setup();
+#endif
+ vbap_setup();
+ hlshelf_setup();
+ lowpass_setup();
+ highpass_setup();
+ bandpass_setup();
+ notch_setup();
+ lowshelf_setup();
+ highshelf_setup();
+ equalizer_setup();
+ qread_setup();
+ joystick_setup();
+#ifdef EXPERIMENTAL
+ constant_setup();
+ mixer_tilde_setup();
+ stripdir_setup();
+#endif
+
+ post("GGEXT: Guenter Geiger");
+ post("GGEXT: ver: "VERSION);
+ post("GGEXT: compiled: "__DATE__);
+}
diff --git a/gui/Makefile b/gui/Makefile
new file mode 100755
index 0000000..469c06d
--- /dev/null
+++ b/gui/Makefile
@@ -0,0 +1,49 @@
+current: nt
+
+
+# TARGETS += stk
+
+VERSION = \"0.16\"
+
+.SUFFIXES: .dll .obj
+# ----------------------- NT ----------------------------
+
+NTOBJECTS = *.obj
+NTDLLS = *.dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+
+PDNTINCLUDE = /I. /I..\..\pd\src /I../include
+
+ProgramFiles = C:\Program Files
+PDNTLDIR = "$(ProgramFiles)\Microsoft Visual Studio\Vc98\lib"
+#PDNTLDIR = "C:\Programme\Msdev\Vc98\lib"
+
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\wsock32.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ $(PDNTLDIR)\uuid.lib \
+ ..\..\pd\bin\pd.lib
+
+nt: $(NTOBJECTS)
+ -link /dll $(PDNTLIB) envgen.obj /export:envgen_setup
+ -link /dll $(PDNTLIB) slider.obj /export:slider_setup
+ -link /dll $(PDNTLIB) state.obj /export:state_setup
+ -link /dll $(PDNTLIB) ticker.obj /export:ticker_setup
+ -link /dll $(PDNTLIB) toddle.obj /export:toddle_setup
+ -copy slider.dll hslider.dll
+
+clean:
+ del *.obj
+ del *.dll
+
+
+.c.obj:
+ -cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+
+.obj.dll:
+
+
+
+
diff --git a/gui/envgen.c b/gui/envgen.c
new file mode 100755
index 0000000..aa644d0
--- /dev/null
+++ b/gui/envgen.c
@@ -0,0 +1,296 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ envgen~ ----------------------------- */
+
+#define NONE 0
+#define ATTACK 1
+#define SUSTAIN 3
+#define STATES 100
+
+#include "envgen.h"
+#include "w_envgen.h"
+
+static t_class *envgen_class;
+
+
+char dumpy[2000];
+
+/* initialize envelope with argument vector */
+
+#include <stdio.h>
+
+/*
+ envgen crashes frequently when reallocating memory ....
+ I really don't know why, it crashes during resizebytes,
+ which means it is unable to realloc() the memory ?????
+ the pointer seems to be ok, I don't know what else could
+ cause the problem. for the moment we prevent from reallocating
+ by setting the STATES variable to 100 */
+
+void envgen_resize(t_envgen* x,int ns)
+{
+ if (ns > x->args) {
+ int newargs = ns*sizeof(t_float);
+
+ x->duration = resizebytes(x->duration,x->args*sizeof(t_float),newargs);
+ x->finalvalues = resizebytes(x->finalvalues,x->args*sizeof(t_float),newargs);
+ x->args = ns;
+ }
+}
+
+
+
+void envgen_totaldur(t_envgen* x,t_float dur)
+{
+ int i;
+ float f = dur/x->duration[x->last_state];
+
+ if (dur < 10) {
+ post("envgen: duration too small %f",dur);
+ return;
+ }
+
+ for (i=1;i<=x->last_state;i++)
+ x->duration[i]*=f;
+}
+
+
+static void envgen_dump(t_envgen* e)
+{
+ t_atom argv[50];
+ int argc= 0;
+ t_atom* a = argv;
+ int i;
+
+ SETFLOAT(a,e->finalvalues[0]);argc++;
+ for (i=1;i <= e->last_state;i++) {
+ SETFLOAT(argv+argc,e->duration[i] - e->duration[i-1]);
+ argc++;
+ SETFLOAT(argv+argc,e->finalvalues[i]);
+ argc++;
+ }
+ outlet_list(e->out2,&s_list,argc,(t_atom*)&argv);
+
+}
+
+void envgen_init(t_envgen *x,int argc,t_atom* argv)
+{
+ t_float* dur;
+ t_float* val;
+ t_float tdur = 0;
+
+ if (!argc) return;
+
+ x->duration[0] = 0;
+
+ x->last_state = argc>>1;
+ envgen_resize(x,argc>>1);
+
+ dur = x->duration;
+ val = x->finalvalues;
+
+ if (argc) {
+ *val = atom_getfloat(argv++);
+ *dur = 0.0;
+ }
+ dur++;val++;argc--;
+ for (;argc > 0;argc--) {
+ tdur += atom_getfloat(argv++);
+#ifdef DEBUG
+ post("dur =%f",tdur);
+#endif
+ *dur++ = tdur;
+ argc--;
+ if (argc > 0)
+ *val++ = atom_getfloat(argv++);
+ else
+ *val++ = 0;
+#ifdef DEBUG
+ post("val =%f",*(val-1));
+#endif
+
+ }
+
+}
+
+
+
+
+
+void envgen_list(t_envgen *x,t_symbol* s, int argc,t_atom* argv)
+{
+ envgen_init(x,argc,argv);
+ if (glist_isvisible(x->w.glist)) {
+ envgen_drawme(x, x->w.glist, 0);
+ }
+}
+
+
+void envgen_float(t_envgen *x, t_floatarg f)
+{
+ int state = 0;
+ while (x->duration[state] < f && state < x->last_state) state++;
+
+ if (state == 0 || f >= x->duration[x->last_state]) {
+ outlet_float(x->x_obj.ob_outlet,x->finalvalues[state]);
+ return;
+ }
+ outlet_float(x->x_obj.ob_outlet,x->finalvalues[state-1] +
+ (f - x->duration[state-1])*
+ (x->finalvalues[state] - x->finalvalues[state-1])/
+ (x->duration[state] - x->duration[state-1]));
+}
+
+
+void envgen_bang(t_envgen *x)
+{
+ t_atom a[2];
+ x->x_time = 0.0;
+
+
+ SETFLOAT(a,x->finalvalues[NONE]);
+ SETFLOAT(a+1,0);
+ outlet_list(x->x_obj.ob_outlet,&s_list,2,(t_atom*)&a);
+
+/* we don't force the first value anymore, so the first value
+ is actually with what we have left off at the end ...
+ this reduces clicks
+*/
+ x->x_state = ATTACK;
+ x->x_val = x->finalvalues[NONE];
+
+ SETFLOAT(a,x->finalvalues[x->x_state]);
+ SETFLOAT(a+1,x->duration[x->x_state]);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,2,(t_atom*)&a);
+ clock_delay(x->x_clock,x->duration[x->x_state]);
+}
+
+
+static void envgen_sustain(t_envgen *x, t_floatarg f)
+{
+ if (f > 0 && f < x->last_state)
+ x->sustain_state = f;
+}
+
+
+static void envgen_tick(t_envgen* x)
+{
+ t_atom a[2];
+ x->x_state++;
+ if (x->x_state <= x->last_state) {
+ float del = x->duration[x->x_state] - x->duration[x->x_state-1];
+ clock_delay(x->x_clock,del);
+ SETFLOAT(a,x->finalvalues[x->x_state]);
+ SETFLOAT(a+1,del);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,2,(t_atom*)&a);
+ }
+ else
+ clock_unset(x->x_clock);
+}
+
+static void envgen_freeze(t_envgen* x, t_floatarg f)
+{
+ x->x_freeze = f;
+}
+
+static void *envgen_new(t_symbol *s,int argc,t_atom* argv)
+{
+ t_envgen *x = (t_envgen *)pd_new(envgen_class);
+
+ x->args = STATES;
+ x->finalvalues = getbytes( x->args*sizeof(t_float));
+ x->duration = getbytes( x->args*sizeof(t_float));
+#ifdef DEBUG
+ post("finalvalues %x",x->finalvalues);
+#endif
+ /* widget */
+
+ x->w.glist = (t_glist*) canvas_getcurrent();
+ if (argc) {
+ x->w.width = atom_getfloat(argv++);
+ argc--;
+ }
+ else
+ x->w.width = 140;
+
+ if (argc) {
+ x->w.height = atom_getfloat(argv++);
+ argc--;
+ }
+ else
+ x->w.height = 200;
+
+
+
+ x->w.grabbed = 0;
+ x->resizing = 0;
+ /* end widget */
+
+ if (argc)
+ envgen_init(x,argc,argv);
+ else {
+ t_atom a[5];
+ SETFLOAT(a,0);
+ SETFLOAT(a+1,50);
+ SETFLOAT(a+2,1);
+ SETFLOAT(a+3,50);
+ SETFLOAT(a+4,0);
+ envgen_init(x,5,a);
+ }
+
+ x->x_val = 0.0;
+ x->x_state = NONE;
+ x->sustain_state = SUSTAIN;
+ x->x_freeze = 0;
+
+ outlet_new(&x->x_obj, &s_float);
+ x->out2 = outlet_new(&x->x_obj, &s_float);
+
+ x->x_clock = clock_new(x, (t_method) envgen_tick);
+ return (x);
+}
+
+
+void envgen_motion(t_envgen *x, t_floatarg dx, t_floatarg dy);
+void envgen_click(t_envgen *x,
+ t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
+ t_floatarg alt);
+void envgen_key(t_envgen *x, t_floatarg f);
+
+
+void envgen_setup(void)
+{
+ envgen_class = class_new(gensym("envgen"), (t_newmethod)envgen_new, 0,
+ sizeof(t_envgen), 0,A_GIMME,0);
+
+ class_addcreator((t_newmethod)envgen_new,gensym("envgen~"),A_GIMME,0);
+ class_addfloat(envgen_class, envgen_float);
+
+ class_addbang(envgen_class,envgen_bang);
+ class_addlist(envgen_class,envgen_list);
+ class_addmethod(envgen_class,(t_method)envgen_sustain,gensym("sustain"),A_FLOAT);
+
+ class_addmethod(envgen_class, (t_method)envgen_click, gensym("click"),
+ A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
+ class_addmethod(envgen_class, (t_method)envgen_motion, gensym("motion"),
+ A_FLOAT, A_FLOAT, 0);
+ class_addmethod(envgen_class, (t_method)envgen_key, gensym("key"),
+ A_FLOAT, 0);
+
+ class_addmethod(envgen_class,(t_method)envgen_totaldur,gensym("duration"),A_FLOAT,NULL);
+ class_addmethod(envgen_class,(t_method)envgen_freeze,gensym("freeze"),A_FLOAT,NULL);
+
+
+ envgen_setwidget();
+ class_setwidget(envgen_class,&envgen_widgetbehavior);
+ class_addmethod(envgen_class,(t_method)envgen_dump,gensym("dump"),A_NULL);
+}
diff --git a/gui/envgen.h b/gui/envgen.h
new file mode 100755
index 0000000..8db6b43
--- /dev/null
+++ b/gui/envgen.h
@@ -0,0 +1,50 @@
+#ifndef __GG_ENVGEN_H__
+#define __GG_ENVGEN_H__
+
+#include "g_canvas.h"
+
+typedef struct _wenvgen {
+ t_glist* glist;
+ int width;
+ int height;
+ int numdoodles;
+ int grabbed; /* for moving points */
+ int pointerx;
+ int pointery;
+} t_wenvgen;
+
+typedef struct _envgen
+{
+ t_object x_obj;
+
+ t_float x_val;
+
+ t_float x_slevel;
+ t_float x_time;
+ int x_state;
+ int last_state;
+ int sustain_state;
+ int envchanged;
+
+ t_float* finalvalues;
+ t_float* duration;
+ t_float totaldur;
+ t_int args; /* get rid of that */
+ t_int resizing;
+
+
+ t_clock* x_clock;
+ t_float x_freeze;
+
+ t_outlet* out2;
+ /* widget parameters */
+ t_wenvgen w;
+} t_envgen;
+
+
+t_widgetbehavior envgen_widgetbehavior;
+void envgen_drawme(t_envgen *x, t_glist *glist, int firsttime);
+int envgen_set_values(t_envgen * x);
+void envgen_resize(t_envgen* x,int ns);
+
+#endif
diff --git a/gui/envgen.pd b/gui/envgen.pd
new file mode 100755
index 0000000..8c537f9
--- /dev/null
+++ b/gui/envgen.pd
@@ -0,0 +1,70 @@
+#N canvas 289 62 893 565 12;
+#X obj 21 239 osc~;
+#X obj 21 214 sig~ 220;
+#X obj 21 269 *~;
+#X floatatom 18 178 0 0 0;
+#X graph graph2 0 -1 44100 1 440 522 840 222;
+#X array array1 44100 float 0;
+#X pop;
+#X obj 21 299 tabwrite~ array1;
+#X msg 695 174 \; array1 resize 44100;
+#X msg 213 123 0 200 1 200 0;
+#X msg 213 67 -1 500 0.7 200;
+#X text 102 4 envgen - A (not so) simple envelope generator;
+#X obj 178 193 envgen 247 144;
+#X msg 213 45 1 100 0.5 100 0.7 100 0.1 100 1;
+#X msg 213 88 0 50 1 10 0 10 1 10 0 10 1 10 0 10 1 10 0 10 1 10 0 10
+1 10 0 10 1 10 0 10 1 10 0 10 1 10 0 10 1 10 0 10 1;
+#X msg 346 156 duration 1000;
+#X msg 448 156 duration 300;
+#X msg 213 155 freeze 1;
+#X msg 279 156 freeze 0;
+#X obj 97 63 metro 2000;
+#X obj 149 345 line~;
+#X obj 97 32 ticker 15 15;
+#X floatatom 36 83 0 0 0;
+#X floatatom 207 346 0 0 0;
+#X text 13 59 indexing;
+#X obj 691 107 state env;
+#X msg 701 45 1;
+#X msg 634 44 save;
+#X msg 736 45 2;
+#X text 21 357 Messages:;
+#X text 20 375 freeze: addition of new breakpoints on/off;
+#X text 21 391 duration: duration in ms;
+#X text 21 407 bang: output pairs suitable for line~;
+#X text 18 446 <float>: output value at time (in ms);
+#X text 20 465 <list>: set breakpoints in;
+#X text 74 481 <val> <dur> <val> <dur> ... <val> format;
+#X msg 448 187 dump;
+#X text 20 426 dump: output a list suitable to input in other envgen
+;
+#X text 19 498 hitting backspace deletes the selected point;
+#X obj 338 346 print dump;
+#X text 19 514 NEW ! clicking in the lower right corner resizes (in
+run mode ????);
+#X text 18 546 (C) 1999 - 2002 Guenter Geiger;
+#X connect 0 0 2 0;
+#X connect 1 0 0 0;
+#X connect 2 0 5 0;
+#X connect 3 0 1 0;
+#X connect 7 0 10 0;
+#X connect 8 0 10 0;
+#X connect 10 0 21 0;
+#X connect 10 0 18 0;
+#X connect 10 1 37 0;
+#X connect 11 0 10 0;
+#X connect 12 0 10 0;
+#X connect 13 0 10 0;
+#X connect 14 0 10 0;
+#X connect 15 0 10 0;
+#X connect 16 0 10 0;
+#X connect 17 0 10 0;
+#X connect 17 0 5 0;
+#X connect 18 0 2 1;
+#X connect 19 0 17 0;
+#X connect 20 0 10 0;
+#X connect 24 0 23 0;
+#X connect 25 0 23 0;
+#X connect 26 0 23 0;
+#X connect 34 0 10 0;
diff --git a/gui/hslider.pd b/gui/hslider.pd
new file mode 100755
index 0000000..dddb288
--- /dev/null
+++ b/gui/hslider.pd
@@ -0,0 +1,10 @@
+#N canvas 330 157 516 263 12;
+#X floatatom 54 83;
+#X text 203 10 Same as slider;
+#X floatatom 54 131;
+#X obj 54 59 hslider 127 0 15;
+#X obj 54 107 hslider 400 0 15;
+#X text 20 226 (C) 1999 - 2000 Guenter Geiger;
+#X connect 0 0 4 0;
+#X connect 3 0 0 0;
+#X connect 4 0 2 0;
diff --git a/gui/slider.c b/gui/slider.c
new file mode 100755
index 0000000..22b3c69
--- /dev/null
+++ b/gui/slider.c
@@ -0,0 +1,62 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/* ------------------------ slider ----------------------------- */
+
+#include "slider.h"
+
+static t_class *slider_class;
+
+
+static void *slider_new(t_floatarg h,t_floatarg o,t_floatarg w,t_floatarg n,t_floatarg horiz)
+{
+ t_slider *x = (t_slider *)pd_new(slider_class);
+ x->x_glist = (t_glist*) canvas_getcurrent();
+
+ if (w) x->x_width = w;
+ else x->x_width = 15;
+ if (h) x->x_height = h - o;
+ else
+ x->x_height = 127;
+ x->x_offset = o;
+ x->x_pos = o;
+ x->x_pos2 = o;
+ x->a_pos.a_type = A_FLOAT;
+ if (n) x->x_num = n;
+ else x->x_num = 1;
+ outlet_new(&x->x_obj, &s_float);
+
+/* make us think we're an atom .. we are one ... this doesn work,
+ because the object resets it .. so we will have to create our own menu entry later */
+/* x->x_obj.te_type = T_ATOM; */
+ x->x_horizontal = horiz;
+
+ return (x);
+}
+
+
+
+void slider_setup(void)
+{
+ slider_class = class_new(gensym("slider"), (t_newmethod)slider_new, 0,
+ sizeof(t_slider), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(slider_class,slider_bang);
+ class_addfloat(slider_class,slider_float);
+
+ class_addmethod(slider_class, (t_method)slider_mark, gensym("mark"),
+ A_FLOAT, 0);
+
+
+ class_addmethod(slider_class, (t_method)slider_click, gensym("click"),
+ A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
+ class_addmethod(slider_class, (t_method)slider_motion, gensym("motion"),
+ A_FLOAT, A_FLOAT, 0);
+ class_addmethod(slider_class, (t_method)slider_set, gensym("set"),
+A_FLOAT, 0);
+ class_addmethod(slider_class, (t_method)slider_type, gensym("type"),A_FLOAT,0);
+
+
+ slider_setwidget();
+ class_setwidget(slider_class,&slider_widgetbehavior);
+}
+
diff --git a/gui/slider.h b/gui/slider.h
new file mode 100755
index 0000000..69c44dd
--- /dev/null
+++ b/gui/slider.h
@@ -0,0 +1,439 @@
+#ifndef __SLIDER_H__
+#define __SLIDER_H__
+
+/* changes for setting width by <dieter@rhiz.org>
+ set message by <dieter@klingt.org>
+*/
+
+#include "ggee.h"
+#include "m_imp.h"
+#include "g_canvas.h"
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#define SPOSITIONS
+#define te_xpos te_xpix
+#define te_ypos te_ypix
+
+typedef struct _slider
+{
+ t_object x_obj;
+ t_atom a_pos;
+ t_atom a_pos2;
+ t_glist * x_glist;
+ int x_width;
+ int x_height;
+ int x_offset;
+ int x_mpos;
+ int x_num;
+ int x_horizontal;
+} t_slider;
+
+#define x_pos a_pos.a_w.w_float
+#define x_pos2 a_pos2.a_w.w_float
+
+
+/* widget helper functions */
+
+static void draw_inlets(t_slider *x, t_glist *glist, int firsttime, int nin, int nout)
+{
+ int n = nin;
+ int nplus, i;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpos + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypos + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypos + x->x_height,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypos + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypos + x->x_height);
+ }
+ n = nout;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpos + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypos,
+ onset + IOWIDTH, x->x_obj.te_ypos + 1,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypos,
+ onset + IOWIDTH, x->x_obj.te_ypos + 1);
+
+ }
+}
+
+
+
+static void slider_update(t_slider *x, t_glist *glist)
+{
+ if (glist_isvisible(glist)) {
+ if (!x->x_horizontal) {
+ sys_vgui(".x%x.c coords %xP \
+%d %d %d %d\n",glist_getcanvas(glist),x,
+ x->x_obj.te_xpos,x->x_obj.te_ypos + x->x_height - (int)x->x_pos + x->x_offset,
+ x->x_obj.te_xpos + x->x_width,x->x_obj.te_ypos + x->x_height - (int)x->x_pos + x->x_offset);
+ sys_vgui(".x%x.c coords %xP2 \
+%d %d %d %d\n",glist_getcanvas(glist),x,
+ x->x_obj.te_xpos,x->x_obj.te_ypos + x->x_height - (int)x->x_pos2 + x->x_offset,
+ x->x_obj.te_xpos + x->x_width,x->x_obj.te_ypos + x->x_height - (int)x->x_pos2 + x->x_offset);
+ }
+ else {
+ sys_vgui(".x%x.c coords %xP \
+%d %d %d %d\n",glist_getcanvas(glist),x,
+ x->x_obj.te_xpos +(int)x->x_pos - x->x_offset ,x->x_obj.te_ypos,
+ x->x_obj.te_xpos +(int)x->x_pos - x->x_offset ,x->x_obj.te_ypos + x->x_height);
+ sys_vgui(".x%x.c coords %xP2 \
+%d %d %d %d\n",glist_getcanvas(glist),x,
+ x->x_obj.te_xpos +(int)x->x_pos2 - x->x_offset ,x->x_obj.te_ypos,
+ x->x_obj.te_xpos +(int)x->x_pos2 - x->x_offset ,x->x_obj.te_ypos + x->x_height);
+ }
+ }
+}
+
+
+static void slider_drawme(t_slider *x, t_glist *glist, int firsttime)
+{
+ if (firsttime) {
+ sys_vgui(".x%x.c create rectangle \
+%d %d %d %d -tags %xS "BACKGROUND"\n",
+ glist_getcanvas(glist),
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height,
+ x);
+ if (!x->x_horizontal) {
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -width 3 -tags %xP\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos,x->x_obj.te_ypos + x->x_height - (int)x->x_pos + x->x_offset,
+ x->x_obj.te_xpos + x->x_width,
+ x->x_obj.te_ypos + x->x_height - (int)x->x_pos + x->x_offset,x);
+
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -width 3 -tags %xP2\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos,x->x_obj.te_ypos + x->x_height - (int)x->x_pos2 + x->x_offset,
+ x->x_obj.te_xpos + x->x_width,
+ x->x_obj.te_ypos + x->x_height - (int)x->x_pos2 + x->x_offset,x);
+ }
+ else {
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -width 3 -tags %xP\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos + (int)x->x_pos + x->x_offset ,x->x_obj.te_ypos,
+ x->x_obj.te_xpos + (int)x->x_pos + x->x_offset,
+ x->x_obj.te_ypos + x->x_height,x );
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -width 3 -tags %xP2\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos + (int)x->x_pos2 + x->x_offset ,x->x_obj.te_ypos,
+ x->x_obj.te_xpos + (int)x->x_pos2 + x->x_offset,
+ x->x_obj.te_ypos + x->x_height,x );
+ }
+ }
+ else {
+ sys_vgui(".x%x.c coords %xS \
+%d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height);
+ slider_update(x, glist);
+ }
+
+ draw_inlets(x, glist, firsttime, 1,1);
+
+}
+
+
+
+
+static void slider_erase(t_slider* x,t_glist* glist)
+{
+ int n;
+ sys_vgui(".x%x.c delete %xS\n",
+ glist_getcanvas(glist), x);
+
+ sys_vgui(".x%x.c delete %xP\n",
+ glist_getcanvas(glist), x);
+
+ sys_vgui(".x%x.c delete %xP2\n",
+ glist_getcanvas(glist), x);
+
+ n = x->x_num;
+
+ while (n--) {
+ sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,n);
+ sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
+ }
+}
+
+
+
+/* ------------------------ slider widgetbehaviour----------------------------- */
+
+
+static void slider_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ int width, height;
+ t_slider* s = (t_slider*)z;
+
+
+ width = s->x_width;
+ height = s->x_height;
+ *xp1 = s->x_obj.te_xpos;
+ *yp1 = s->x_obj.te_ypos;
+ *xp2 = s->x_obj.te_xpos + width;
+ *yp2 = s->x_obj.te_ypos + height;
+}
+
+static void slider_displace(t_gobj *z, t_glist *glist,
+ int dx, int dy)
+{
+ t_slider *x = (t_slider *)z;
+ x->x_obj.te_xpos += dx;
+ x->x_obj.te_ypos += dy;
+ slider_drawme(x, glist, 0);
+ canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
+}
+
+static void slider_select(t_gobj *z, t_glist *glist, int state)
+{
+ t_slider *x = (t_slider *)z;
+ sys_vgui(".x%x.c itemconfigure %xS -fill %s\n", glist,
+ x, (state? "blue" : BACKGROUNDCOLOR));
+}
+
+
+static void slider_activate(t_gobj *z, t_glist *glist, int state)
+{
+/* t_text *x = (t_text *)z;
+ t_rtext *y = glist_findrtext(glist, x);
+ if (z->g_pd != gatom_class) rtext_activate(y, state);*/
+}
+
+static void slider_delete(t_gobj *z, t_glist *glist)
+{
+ t_text *x = (t_text *)z;
+ canvas_deletelinesfor(glist_getcanvas(glist), x);
+}
+
+
+static void slider_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_slider* s = (t_slider*)z;
+ if (vis)
+ slider_drawme(s, glist, 1);
+ else
+ slider_erase(s,glist);
+}
+
+/* can we use the normal text save function ?? */
+
+static void slider_save(t_gobj *z, t_binbuf *b)
+{
+ t_slider *x = (t_slider *)z;
+ t_symbol* sname;
+ int maxlen,maxwidth;
+
+/* if (!x->x_horizontal) {*/
+ sname = gensym("slider");
+ maxlen = x->x_height + x->x_offset;
+ maxwidth = x->x_width;
+/* }*/
+
+ /* forget hsliders ...
+ else {
+ sname = gensym("hslider");
+ maxlen = x->x_width + x->x_offset;
+ maxwidth = x->x_height;
+ }
+*/
+
+
+ binbuf_addv(b, "ssiisiiii", gensym("#X"),gensym("obj"),
+ (t_int)x->x_obj.te_xpos, (t_int)x->x_obj.te_ypos, sname,maxlen,
+ x->x_offset,maxwidth,x->x_num,x->x_horizontal);
+/* binbuf_addbinbuf(b, x->te_binbuf); */
+ binbuf_addv(b, ";");
+}
+
+
+t_widgetbehavior slider_widgetbehavior;
+
+
+static void slider_motion(t_slider *x, t_floatarg dx, t_floatarg dy)
+{
+ int max;
+
+ if (!x->x_horizontal) {
+ x->x_mpos -= dy;
+ max = (x->x_offset + x->x_height);
+ }
+ else {
+ x->x_mpos += dx;
+ max = (x->x_offset + x->x_width);
+ }
+
+ if (x->x_mpos < x->x_offset)
+ x->x_pos = x->x_offset;
+ else if (x->x_mpos > (max))
+ x->x_pos = (max);
+ else
+ x->x_pos = x->x_mpos;
+
+
+ slider_update(x, x->x_glist);
+ outlet_float(x->x_obj.ob_outlet, x->x_pos);
+
+}
+
+
+static void slider_click(t_slider *x,
+ t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
+ t_floatarg alt)
+{
+
+ if (!x->x_horizontal)
+ x->x_mpos = x->x_pos = x->x_obj.te_ypos + x->x_height + x->x_offset - ypos;
+ else
+ x->x_mpos = x->x_pos = xpos - x->x_obj.te_xpos + x->x_offset;
+
+ slider_update(x, x->x_glist);
+ outlet_float(x->x_obj.ob_outlet, x->x_pos);
+#if (PD_VERSION_MINOR > 31)
+ glist_grab(x->x_glist, &x->x_obj.te_g, slider_motion, 0,xpos, ypos);
+#else
+ glist_grab(x->x_glist, &x->x_obj.te_g, xpos, ypos);
+#endif
+}
+
+
+#if (PD_VERSION_MINOR > 31)
+static int slider_newclick(t_gobj *z, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit)
+{
+ t_slider* x = (t_slider *)z;
+ if (doit)
+ slider_click( x, (t_floatarg)xpix, (t_floatarg)ypix,
+ (t_floatarg)shift, 0, (t_floatarg)alt);
+ return (1);
+}
+#endif
+
+static void slider_setwidget()
+{
+ slider_widgetbehavior.w_getrectfn = slider_getrect;
+ slider_widgetbehavior.w_displacefn = slider_displace;
+ slider_widgetbehavior.w_selectfn = slider_select;
+ slider_widgetbehavior.w_activatefn = slider_activate;
+ slider_widgetbehavior.w_deletefn = slider_delete;
+ slider_widgetbehavior.w_visfn = slider_vis;
+#if (PD_VERSION_MINOR > 31)
+ slider_widgetbehavior.w_clickfn = slider_newclick;
+ slider_widgetbehavior.w_propertiesfn = NULL;
+#endif
+ slider_widgetbehavior.w_savefn = slider_save;
+}
+
+
+
+static void slider_float(t_slider *x,t_floatarg f)
+{
+ if (!x->x_horizontal) {
+ if (f >= x->x_offset && f <= (x->x_offset + x->x_height))
+ x->x_pos = (int)f;
+ }
+ else
+ if (f >= x->x_offset && f <= (x->x_offset + x->x_width))
+ x->x_pos = (int)f;
+
+
+ slider_update(x, x->x_glist);
+ outlet_float(x->x_obj.ob_outlet, x->x_pos);
+
+}
+
+
+static void slider_mark(t_slider *x,t_floatarg val)
+{
+ if (!x->x_horizontal) {
+ if (val >= x->x_offset && val <= (x->x_offset + x->x_height))
+ x->x_pos2 = (int)val;
+ }
+ else
+ if (val >= x->x_offset && val <= (x->x_offset + x->x_width))
+ x->x_pos2 = (int)val;
+
+ slider_update(x, x->x_glist);
+}
+
+
+static void slider_type(t_slider *x,t_floatarg val)
+{
+ x->x_horizontal=val;
+ slider_vis((struct _gobj*)x,x->x_glist,0);
+ slider_vis((struct _gobj*)x,x->x_glist,1);
+}
+
+static void slider_list(t_slider *x,t_symbol* s,t_int argc, t_atom* argv)
+{
+ t_float num;
+ t_float val;
+
+ if (argc != 2) return;
+
+ num = atom_getfloat(argv++);
+ val = atom_getfloat(argv);
+ if (!x->x_horizontal) {
+ if (val >= x->x_offset && val <= (x->x_offset + x->x_height))
+ if (num)
+ x->x_pos2 = (int)val;
+ else
+ x->x_pos = (int)val;
+ }
+ else
+ if (val >= x->x_offset && val <= (x->x_offset + x->x_width))
+ if (num)
+ x->x_pos2 = (int)val;
+ else
+ x->x_pos = (int)val;
+
+ slider_update(x, x->x_glist);
+ outlet_float(x->x_obj.ob_outlet, x->x_pos);
+
+}
+
+
+
+static void slider_bang(t_slider *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_pos);
+}
+
+
+static void slider_set(t_slider *x,t_floatarg f)
+{
+ if (!x->x_horizontal) {
+ if (f >= x->x_offset && f <= (x->x_offset + x->x_height))
+ x->x_pos = (int)f;
+ }
+ else{
+ if (f >= x->x_offset && f <= (x->x_offset + x->x_width))
+ x->x_pos = (int)f;
+ }
+
+ slider_update(x, x->x_glist);
+}
+
+#endif
diff --git a/gui/slider.pd b/gui/slider.pd
new file mode 100755
index 0000000..23af752
--- /dev/null
+++ b/gui/slider.pd
@@ -0,0 +1,32 @@
+#N canvas 552 205 602 446 12;
+#X obj 14 121 slider 127 0 15 1;
+#X floatatom 12 42 0 0 0;
+#X floatatom 14 319 0 0 0;
+#X obj 12 64 metro 200;
+#X floatatom 121 253 0 0 0;
+#X text 11 23 Alt-Click on number box to toggle between 0 and non-0
+state;
+#X obj 118 142 slider 200 100 15 1;
+#X text 141 139 This was instantiated with "slider 200 100";
+#X obj 14 85 random 127;
+#X obj 304 257 state sl;
+#X msg 304 197 save;
+#X msg 356 197 1;
+#X obj 191 239 slider 100 0 30 1;
+#X text 118 49 Instantiate a new slider with Put->Object and type slider
+into the object. The slider takes up to 3 parameters \, the first is
+the maximum value \, the second is the minimum. The third is the width
+of the slider (contributed by Dieter <dieter@rhiz.org>. Currently only
+integer values are supported.;
+#X msg 178 192 mark 120;
+#X msg 257 285 type 1;
+#X obj 257 315 slider 127 0 15 1;
+#X connect 0 0 2 0;
+#X connect 1 0 3 0;
+#X connect 3 0 8 0;
+#X connect 6 0 4 0;
+#X connect 8 0 0 0;
+#X connect 10 0 9 0;
+#X connect 11 0 9 0;
+#X connect 14 0 6 0;
+#X connect 15 0 16 0;
diff --git a/gui/state.0 b/gui/state.0
new file mode 100755
index 0000000..95acef8
--- /dev/null
+++ b/gui/state.0
@@ -0,0 +1,5 @@
+33.000000
+83.000000
+-49.000000
+0.000000
+2 0.000000 86.500000 0.980000 13.500000 0.000000
diff --git a/gui/state.1 b/gui/state.1
new file mode 100755
index 0000000..9348e8a
--- /dev/null
+++ b/gui/state.1
@@ -0,0 +1,4 @@
+26.000000
+76.000000
+10.000000
+4 0.000000 8.500000 0.770000 52.000000 0.410000 26.000000 0.980000 13.500000 0.000000
diff --git a/gui/state.2 b/gui/state.2
new file mode 100755
index 0000000..31d1cc2
--- /dev/null
+++ b/gui/state.2
@@ -0,0 +1,4 @@
+66.000000
+35.000000
+-27.000000
+2 0.000000 8.500000 0.770000 91.500000 0.000000
diff --git a/gui/state.3 b/gui/state.3
new file mode 100755
index 0000000..5f642cc
--- /dev/null
+++ b/gui/state.3
@@ -0,0 +1,2 @@
+66.000000
+0.000000
diff --git a/gui/state.c b/gui/state.c
new file mode 100755
index 0000000..22abdd2
--- /dev/null
+++ b/gui/state.c
@@ -0,0 +1,384 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+/*
+ * The iem stuff doesn't work yet !!!
+*/
+
+typedef struct _iem_fstyle_flags
+{
+ unsigned int x_font_style:6;
+ unsigned int x_rcv_able:1;
+ unsigned int x_snd_able:1;
+ unsigned int x_lab_is_unique:1;
+ unsigned int x_rcv_is_unique:1;
+ unsigned int x_snd_is_unique:1;
+ unsigned int x_lab_arg_tail_len:6;
+ unsigned int x_lab_is_arg_num:6;
+ unsigned int x_shiftdown:1;
+ unsigned int x_selected:1;
+ unsigned int x_finemoved:1;
+ unsigned int x_put_in2out:1;
+ unsigned int x_change:1;
+ unsigned int x_thick:1;
+ unsigned int x_lin0_log1:1;
+ unsigned int x_steady:1;
+ unsigned int dummy:1;
+} t_iem_fstyle_flags;
+
+typedef struct _iem_init_symargs
+{
+ unsigned int x_loadinit:1;
+ unsigned int x_rcv_arg_tail_len:6;
+ unsigned int x_snd_arg_tail_len:6;
+ unsigned int x_rcv_is_arg_num:6;
+ unsigned int x_snd_is_arg_num:6;
+ unsigned int x_scale:1;
+ unsigned int x_flashed:1;
+ unsigned int x_locked:1;
+ unsigned int dummy:4;
+} t_iem_init_symargs;
+
+
+typedef struct _iemgui
+{
+ t_object x_obj;
+ void *x_glist;
+ void* x_draw;
+ int x_h;
+ int x_w;
+ int x_ldx;
+ int x_ldy;
+ char x_font[16];
+ t_iem_fstyle_flags x_fsf;
+ int x_fontsize;
+ t_iem_init_symargs x_isa;
+ int x_fcol;
+ int x_bcol;
+ int x_lcol;
+ int x_unique_num;
+ t_symbol *x_snd;
+ t_symbol *x_rcv;
+ t_symbol *x_lab;
+} t_iemgui;
+
+
+
+/* hacks .... this duplicates definitions in pd and must be
+ * adjusted if something changes there !!!! */
+
+#define EMPTYSYMBOL "emptysymbol"
+
+typedef struct _mygatom
+{
+ t_text a_text;
+ t_atom a_atom;
+} t_mygatom; /* this is not !! the real t_atom ...*/
+
+#define TATOM(a) (&((t_mygatom*)a)->a_atom)
+
+
+/* glist's are not visible, but the only thing we need is to
+ get the list link from them */
+
+typedef struct _myglist
+{
+ t_object gl_gobj;
+ t_gobj* g_list;
+} t_myglist;
+
+#define FIRSTOBJECT(a) (((t_myglist*)a)->g_list)
+
+
+#ifndef vmess
+#define vmess pd_vmess
+#endif
+
+
+/* ------------------------ State ----------------------------- */
+
+#include "envgen.h"
+
+
+static t_class *state_class;
+
+
+typedef struct _state
+{
+ t_object x_obj;
+ t_canvas* x_canvas;
+ t_symbol* x_name;
+ int x_slot;
+ t_symbol* x_symslot;
+ int x_save;
+ int x_loading;
+ t_clock* x_clock;
+} t_state;
+
+
+
+
+void state_dosave(t_state *x)
+{
+ char name[255];
+ FILE* fp;
+ t_text* a;
+ t_symbol* dir;
+ char dirstr[255];
+
+#ifdef NT
+ dir = gensym("");
+#else
+ dir = canvas_getdir(x->x_canvas);
+#endif
+
+ strcpy(dirstr,dir->s_name);
+
+#ifndef NT
+ strcat(dirstr,"/");
+#endif
+
+ if (x->x_symslot)
+ sprintf(name,"%s%s.%s",dirstr,x->x_name->s_name,x->x_symslot->s_name);
+ else
+ sprintf(name,"%s%s.%d",dirstr,x->x_name->s_name,x->x_slot);
+
+ fp = fopen(name,"w");
+ if (!fp) {
+ post("state: unable to open %s",name);
+ return;
+ }
+
+ a = (t_text*)FIRSTOBJECT(x->x_canvas);
+
+ do {
+ if (a->te_type == T_ATOM) {
+ if (TATOM(a)->a_type == A_SYMBOL) {
+ if (strlen(TATOM(a)->a_w.w_symbol->s_name))
+/* fprintf(fp,"%s\n",TATOM(a)->a_w.w_symbol->s_name);*/
+ fprintf(fp,"%s\n",atom_getsymbol(TATOM(a))->s_name);
+ else
+ fprintf(fp,EMPTYSYMBOL"\n");
+ }
+ else {
+ fprintf(fp,"%f\n",atom_getfloat(TATOM(a)));
+ fprintf(stderr,"%f\n",atom_getfloat(TATOM(a)));
+ }
+ }
+
+ /* slider should be an atom as well ... how to do it ? */
+
+ if (!strcmp(class_getname(a->te_pd),"slider")) {
+ float val = atom_getfloat(TATOM(a));
+ fprintf(fp,"%f\n",val);
+ fprintf(stderr,"slider %f\n",atom_getfloat(TATOM(a)));
+ }
+#if 0
+ if (!strcmp(class_getname(a->te_pd),"vsl")) {
+ /* float val = atom_getfloat(TATOM(a));*/
+ float val = *((float*) (((char*)a) + sizeof(t_iemgui) + sizeof(int)));
+ fprintf(fp,"%f\n",val);
+ fprintf(stderr,"vslider %f\n",val);
+ }
+ if (!strcmp(class_getname(a->te_pd),"hsl")) {
+ float val = *((float*) (((char*)a) + sizeof(t_iemgui) + sizeof(int)));
+ fprintf(fp,"%f\n",val);
+ fprintf(stderr,"hslider %f\n",val);
+ }
+#endif
+ if (!strncmp(class_getname(a->te_pd),"envgen",6)) {
+ int i;
+ t_envgen* e = (t_envgen*) a;
+
+ fprintf(fp,"%d ",e->last_state);
+ fprintf(fp,"%f ",e->finalvalues[0]);
+ for (i=1;i <= e->last_state;i++)
+ fprintf(fp,"%f %f ",e->duration[i] - e->duration[i-1],e->finalvalues[i]);
+ fprintf(fp,"\n");
+ }
+
+
+
+ } while ((a = (t_text*)((t_gobj*)a)->g_next));
+ post("state saved to: %s",name);
+
+ fclose(fp);
+
+}
+
+void state_save(t_state *x)
+{
+ x->x_save = 1;
+ clock_delay(x->x_clock,2000);
+}
+
+
+void state_saveoff(t_state *x)
+{
+ x->x_save = 0;
+}
+
+void state_load(t_state *x)
+{
+ char name[255];
+ FILE* fp;
+ t_text* a;
+ t_float in;
+ t_symbol* dir;
+ char dirstr[255];
+
+#ifdef NT
+ dir = gensym("");
+#else
+ dir = canvas_getdir(x->x_canvas);
+#endif
+
+ strcpy(dirstr,dir->s_name);
+
+#ifndef NT
+ strcat(dirstr,"/");
+#endif
+
+
+ if (x->x_symslot)
+ sprintf(name,"%s%s.%s",dirstr,x->x_name->s_name,x->x_symslot->s_name);
+ else
+ sprintf(name,"%s%s.%d",dirstr,x->x_name->s_name,x->x_slot);
+
+ fp = fopen(name,"r");
+ if (!fp) {
+ post("state: unable to open %s",name);
+ return;
+ }
+
+ a = (t_text*) FIRSTOBJECT(x->x_canvas);
+
+ x->x_loading = 1;
+ post("state loading from: %s",name);
+ *name = 0;
+ do {
+ if (a->te_type == T_ATOM ||
+ !strcmp(class_getname(a->te_pd),"slider")
+ /* ||
+ !strcmp(class_getname(a->te_pd),"vsl") ||
+ !strcmp(class_getname(a->te_pd),"hsl" ) */
+ ) {
+ if (TATOM(a)->a_type == A_SYMBOL) {
+ fscanf(fp,"%s",name);
+ if (strcmp(name,EMPTYSYMBOL))
+ vmess((t_pd*)a,gensym("set"),"s",gensym(name));
+ }
+ else {
+ fscanf(fp,"%f",&in);
+ vmess((t_pd*)a,&s_float,"f",in);
+ }
+ }
+
+ if (!strncmp(class_getname(a->te_pd),"envgen",6)) {
+ int i;
+ int end;
+ float val;
+ float dur;
+ t_atom ilist[255];
+
+ fscanf(fp,"%f",&in);
+ end = in;
+
+ fscanf(fp,"%f",&val);
+ SETFLOAT(ilist,val);
+ for (i=1 ;i <= end;i++) {
+ fscanf(fp,"%f",&dur);
+ fscanf(fp,"%f",&val);
+ SETFLOAT(ilist +2*i-1,dur);
+ SETFLOAT(ilist+2*i,val);
+ }
+ pd_typedmess((t_pd*)a,&s_list,2*end+1,ilist);
+ post("ok %d",end);
+ }
+
+
+ } while ((a = (t_text*)((t_gobj*)a)->g_next) && !feof(fp));
+
+ x->x_loading = 0;
+ fclose(fp);
+
+}
+
+void state_float(t_state *x,t_floatarg f)
+{
+ if (x->x_loading) return;
+ x->x_symslot = NULL;
+ x->x_slot = f;
+ if (x->x_save) {
+ x->x_save = 0;
+ state_dosave(x);
+ return;
+ }
+
+ state_load(x);
+}
+
+
+void state_anything(t_state *x,t_symbol* s,t_int argc,t_atom* argv)
+{
+ x->x_symslot = s;
+ if (x->x_save) {
+ x->x_save = 0;
+ state_dosave(x);
+ return;
+ }
+
+ state_load(x);
+}
+
+
+
+void state_bang(t_state *x)
+{
+ if (x->x_symslot) outlet_symbol(x->x_obj.ob_outlet,x->x_symslot);
+ else
+ outlet_float(x->x_obj.ob_outlet,x->x_slot);
+}
+
+
+static void *state_new(t_symbol* name)
+{
+ t_state *x = (t_state *)pd_new(state_class);
+ x->x_canvas = canvas_getcurrent();
+ if (name != &s_)
+ x->x_name = name;
+ else
+ x->x_name = gensym("state");
+
+ x->x_clock = clock_new(x, (t_method)state_saveoff);
+ x->x_slot = 0;
+ x->x_symslot = NULL;
+ x->x_loading = 0;
+ x->x_save = 0;
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+
+
+void state_setup(void)
+{
+ state_class = class_new(gensym("state"), (t_newmethod)state_new, 0,
+ sizeof(t_state), 0,A_DEFSYM,0);
+ class_addfloat(state_class,state_float);
+ class_addmethod(state_class,(t_method) state_save, gensym("save"), 0);
+ class_addanything(state_class,(t_method) state_anything);
+ class_addbang(state_class,state_bang);
+/* class_addmethod(state_class, (t_method)state_load, gensym("load"), 0);*/
+}
+
+
diff --git a/gui/state.list b/gui/state.list
new file mode 100755
index 0000000..5f642cc
--- /dev/null
+++ b/gui/state.list
@@ -0,0 +1,2 @@
+66.000000
+0.000000
diff --git a/gui/state.pd b/gui/state.pd
new file mode 100755
index 0000000..1575e48
--- /dev/null
+++ b/gui/state.pd
@@ -0,0 +1,44 @@
+#N canvas 182 231 789 437 10;
+#X obj 20 393 state;
+#X msg 20 322 save;
+#X floatatom 405 85 5 0 0;
+#X obj 371 291 ticker 15 15;
+#X obj 684 31 slider 127 0 15 1;
+#X obj 654 165 float;
+#X obj 654 136 toddle black 15 15;
+#X floatatom 654 194 5 0 0;
+#X text 87 10 The state object;
+#X text 7 37 With the state object settings within a patch;
+#X text 7 51 can be saved to a file. You can add a name to;
+#X text 7 66 the state (if you have several states in your;
+#X text 7 81 system this might be a good idea).;
+#X text 9 120 Note that the state object has several problems:;
+#X text 8 146 1) you can not delete "saveable objects" without;
+#X text 10 164 making the already saved states bogus;
+#X text 9 190 2) Not all the gui objects are saveable (Which is;
+#X text 8 208 good in some situations \, you might for example not
+;
+#X text 9 226 save the state selecting widget ....;
+#X text 373 8 saveable:;
+#X text 374 66 Numberboxes:;
+#X text 544 10 This is the "slider" object !!:;
+#X text 545 28 (not vslider);
+#X text 369 269 Not saveable:;
+#X obj 396 293 vsl 15 128 0 127 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 0 1;
+#X text 422 292 ...etc (everything from the menu exept "number");
+#X obj 418 315 hdl 15 1 0 8 empty empty empty 20 8 0 8 -262144 -1 -1
+0;
+#X text 605 410 (C) Guenter Geiger 2002;
+#X obj 373 141 envgen;
+#X msg 29 346 1;
+#X msg 60 346 2;
+#X msg 90 346 3;
+#X text 370 118 envgen;
+#X connect 1 0 0 0;
+#X connect 4 0 5 1;
+#X connect 5 0 7 0;
+#X connect 6 0 5 0;
+#X connect 29 0 0 0;
+#X connect 30 0 0 0;
+#X connect 31 0 0 0;
diff --git a/gui/testsave.1 b/gui/testsave.1
new file mode 100755
index 0000000..da6c429
--- /dev/null
+++ b/gui/testsave.1
@@ -0,0 +1,9 @@
+60.000000
+30.000000
+20.000000
+1800.000000
+6.000000
+symbol
+symbol
+0.000000
+0.000000
diff --git a/gui/testsave.2 b/gui/testsave.2
new file mode 100755
index 0000000..a9cc15c
--- /dev/null
+++ b/gui/testsave.2
@@ -0,0 +1,9 @@
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+symbol
+symbol
+0.000000
+0.000000
diff --git a/gui/ticker.c b/gui/ticker.c
new file mode 100755
index 0000000..b40b1d7
--- /dev/null
+++ b/gui/ticker.c
@@ -0,0 +1,337 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <ggee.h>
+#include <m_pd.h>
+#include "g_canvas.h"
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ ticker ----------------------------- */
+
+#define DEFAULTSIZE 15
+#define DEFAULTCOLOR "black"
+
+static t_class *ticker_class;
+
+typedef struct _ticker
+{
+ t_object x_obj;
+ t_glist * x_glist;
+ int x_width;
+ int x_height;
+ t_float x_on;
+} t_ticker;
+
+/* widget helper functions */
+
+
+static void draw_inlets(t_ticker *x, t_glist *glist, int firsttime, int nin, int nout)
+{
+ int n = nin;
+ int nplus, i;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypix + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypix + x->x_height,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypix + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypix + x->x_height);
+ }
+ n = nout;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypix,
+ onset + IOWIDTH, x->x_obj.te_ypix + 1,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypix,
+ onset + IOWIDTH, x->x_obj.te_ypix + 1);
+
+ }
+}
+
+
+
+void ticker_draw(t_ticker *x,t_glist *glist)
+{
+ if (x->x_on) {
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -tags %xB\n",glist_getcanvas(glist),
+ x->x_obj.te_xpix+1,x->x_obj.te_ypix+1,
+ x->x_obj.te_xpix + x->x_width -1,
+ x->x_obj.te_ypix + x->x_height -1,x);
+ sys_vgui(".x%x.c create line \
+%d %d %d %d -tags %xC\n",glist_getcanvas(glist),
+ x->x_obj.te_xpix+1,x->x_obj.te_ypix + x->x_height -1,
+ x->x_obj.te_xpix + x->x_width -1,x->x_obj.te_ypix+1,
+ x);
+
+ }
+ else {
+ sys_vgui(".x%x.c delete %xB\n",
+ glist_getcanvas(glist), x);
+ sys_vgui(".x%x.c delete %xC\n",
+ glist_getcanvas(glist), x);
+ }
+}
+
+
+void ticker_update(t_ticker *x,t_glist *glist)
+{
+ if (glist_isvisible(glist)) {
+ if (x->x_on) {
+ sys_vgui(".x%x.c coords %xB \
+%d %d %d %d\n",glist_getcanvas(glist),
+ x,x->x_obj.te_xpix+1,x->x_obj.te_ypix+1,
+ x->x_obj.te_xpix + x->x_width -1,
+ x->x_obj.te_ypix + x->x_height -1);
+ sys_vgui(".x%x.c coords %xC \
+%d %d %d %d\n",glist_getcanvas(glist),
+ x,x->x_obj.te_xpix+1,x->x_obj.te_ypix + x->x_height -1,
+ x->x_obj.te_xpix + x->x_width -1,x->x_obj.te_ypix+1);
+
+ }
+ }
+}
+
+
+
+void ticker_drawme(t_ticker *x, t_glist *glist, int firsttime)
+{
+ if (firsttime) {
+ sys_vgui(".x%x.c create rectangle \
+%d %d %d %d -tags %xS "BACKGROUND"\n",
+ glist_getcanvas(glist),
+ x->x_obj.te_xpix, x->x_obj.te_ypix,
+ x->x_obj.te_xpix + x->x_width, x->x_obj.te_ypix + x->x_height,
+ x);
+ ticker_draw(x,glist);
+ }
+ else {
+ sys_vgui(".x%x.c coords %xS \
+%d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ x->x_obj.te_xpix, x->x_obj.te_ypix,
+ x->x_obj.te_xpix + x->x_width, x->x_obj.te_ypix + x->x_height);
+ ticker_update(x,glist);
+ }
+
+ draw_inlets(x, glist, firsttime, 1,1);
+
+}
+
+
+
+
+void ticker_erase(t_ticker* x,t_glist* glist)
+{
+ int n;
+ sys_vgui(".x%x.c delete %xS\n",
+ glist_getcanvas(glist), x);
+
+ sys_vgui(".x%x.c delete %xP\n",
+ glist_getcanvas(glist), x);
+
+ n = 1;
+ sys_vgui(".x%x.c delete %xB\n",
+ glist_getcanvas(glist), x);
+ sys_vgui(".x%x.c delete %xC\n",
+ glist_getcanvas(glist), x);
+
+ while (n--) {
+ sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,n);
+ sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
+ }
+}
+
+
+
+/* ------------------------ ticker widgetbehaviour----------------------------- */
+
+
+static void ticker_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ int width, height;
+ t_ticker* s = (t_ticker*)z;
+
+
+ width = s->x_width;
+ height = s->x_height;
+ *xp1 = s->x_obj.te_xpix;
+ *yp1 = s->x_obj.te_ypix;
+ *xp2 = s->x_obj.te_xpix + width;
+ *yp2 = s->x_obj.te_ypix + height;
+}
+
+static void ticker_displace(t_gobj *z, t_glist *glist,
+ int dx, int dy)
+{
+ t_ticker *x = (t_ticker *)z;
+ x->x_obj.te_xpix += dx;
+ x->x_obj.te_ypix += dy;
+ ticker_drawme(x, glist, 0);
+ canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
+}
+
+static void ticker_select(t_gobj *z, t_glist *glist, int state)
+{
+ t_ticker *x = (t_ticker *)z;
+ sys_vgui(".x%x.c itemconfigure %xS -fill %s\n", glist,
+ x, (state? "blue" : BACKGROUNDCOLOR));
+}
+
+
+static void ticker_activate(t_gobj *z, t_glist *glist, int state)
+{
+/* t_text *x = (t_text *)z;
+ t_rtext *y = glist_findrtext(glist, x);
+ if (z->g_pd != gatom_class) rtext_activate(y, state);*/
+}
+
+static void ticker_delete(t_gobj *z, t_glist *glist)
+{
+ t_text *x = (t_text *)z;
+ canvas_deletelinesfor(glist_getcanvas(glist), x);
+}
+
+
+static void ticker_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_ticker* s = (t_ticker*)z;
+ if (vis)
+ ticker_drawme(s, glist, 1);
+ else
+ ticker_erase(s,glist);
+}
+
+/* can we use the normal text save function ?? */
+
+static void ticker_save(t_gobj *z, t_binbuf *b)
+{
+ t_ticker *x = (t_ticker *)z;
+ binbuf_addv(b, "ssiisii", gensym("#X"),gensym("obj"),
+ (t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
+ gensym("ticker"),x->x_width,x->x_height);
+ binbuf_addv(b, ";");
+}
+
+
+static void ticker_click(t_ticker *x,
+ t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
+ t_floatarg alt)
+{
+ x->x_on = x->x_on == 0.0 ? 1.0:0.0;
+ ticker_draw(x,x->x_glist);
+ outlet_float(x->x_obj.ob_outlet,x->x_on);
+}
+
+#if (PD_VERSION_MINOR > 31)
+static int ticker_newclick(t_gobj *z, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit)
+{
+ if (doit)
+ ticker_click((t_ticker *)z, (t_floatarg)xpix, (t_floatarg)ypix,
+ (t_floatarg)shift, 0, (t_floatarg)alt);
+ return (1);
+}
+#endif
+
+t_widgetbehavior ticker_widgetbehavior;
+
+
+void ticker_size(t_ticker* x,t_floatarg w,t_floatarg h) {
+ x->x_width = w;
+ x->x_height = h;
+ ticker_drawme(x, x->x_glist, 0);
+}
+
+
+static void ticker_bang(t_ticker* x)
+{
+ x->x_on = x->x_on == 0.0 ? 1.0:0.0;
+ if (glist_isvisible(x->x_glist))
+ ticker_draw(x,x->x_glist);
+ outlet_float(x->x_obj.ob_outlet,x->x_on);
+}
+
+static void ticker_float(t_ticker* x,t_floatarg f)
+{
+ x->x_on = f;
+ if (glist_isvisible(x->x_glist))
+ ticker_draw(x,x->x_glist);
+ outlet_float(x->x_obj.ob_outlet,x->x_on);
+}
+
+static void ticker_set(t_ticker* x,t_floatarg f)
+{
+ x->x_on = f;
+}
+
+static void *ticker_new(t_floatarg h,t_floatarg o)
+{
+ t_ticker *x = (t_ticker *)pd_new(ticker_class);
+
+ x->x_glist = (t_glist*) canvas_getcurrent();
+ if (h) x->x_width = h;
+ else
+ x->x_width = DEFAULTSIZE;
+
+ if (o) x->x_height = o;
+ else
+ x->x_height = DEFAULTSIZE;
+
+ x->x_on = 0;
+
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void ticker_setup(void)
+{
+ ticker_class = class_new(gensym("ticker"), (t_newmethod)ticker_new, 0,
+ sizeof(t_ticker),0, A_DEFFLOAT,A_DEFFLOAT,0);
+
+
+ class_addmethod(ticker_class, (t_method)ticker_click, gensym("click"),
+ A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
+ class_addmethod(ticker_class, (t_method)ticker_size, gensym("size"),
+ A_FLOAT, A_FLOAT, 0);
+
+ class_addfloat(ticker_class, ticker_float);
+ class_addbang(ticker_class,ticker_bang);
+ class_addmethod(ticker_class,(t_method) ticker_set,gensym("set"),A_FLOAT,0);
+ class_setwidget(ticker_class,&ticker_widgetbehavior);
+
+ ticker_widgetbehavior.w_getrectfn = ticker_getrect;
+ ticker_widgetbehavior.w_displacefn = ticker_displace;
+ ticker_widgetbehavior.w_selectfn = ticker_select;
+ ticker_widgetbehavior.w_activatefn = ticker_activate;
+ ticker_widgetbehavior.w_deletefn = ticker_delete;
+ ticker_widgetbehavior.w_visfn = ticker_vis;
+#if (PD_VERSION_MINOR > 31)
+ ticker_widgetbehavior.w_clickfn = ticker_newclick;
+ ticker_widgetbehavior.w_propertiesfn = NULL;
+#endif
+ ticker_widgetbehavior.w_savefn = ticker_save;
+}
+
+
diff --git a/gui/ticker.pd b/gui/ticker.pd
new file mode 100755
index 0000000..b094910
--- /dev/null
+++ b/gui/ticker.pd
@@ -0,0 +1,11 @@
+#N canvas 209 91 456 299 12;
+#X obj 40 154 ticker 15 15;
+#X floatatom 40 184;
+#X obj 40 125 metro 200;
+#X obj 40 16 ticker 100 100;
+#X obj 75 151 ticker 30 50;
+#X text 43 245 (C) 1999 - 2000 Guenter Geiger;
+#X connect 0 0 1 0;
+#X connect 2 0 0 0;
+#X connect 2 0 4 0;
+#X connect 3 0 2 0;
diff --git a/gui/toddle.c b/gui/toddle.c
new file mode 100755
index 0000000..4b46e8d
--- /dev/null
+++ b/gui/toddle.c
@@ -0,0 +1,382 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include "g_canvas.h"
+#include <ggee.h>
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#define te_xpos te_xpix
+#define te_ypos te_ypix
+
+/* ------------------------ toddle ----------------------------- */
+
+
+
+#define DEFAULTSIZE 15
+#define DEFAULTCOLOR "black"
+
+static t_class *toddle_class;
+
+typedef struct _toddle
+{
+ t_object x_obj;
+ t_glist * x_glist;
+ int x_width;
+ int x_height;
+ t_symbol* x_color;
+ t_clock* x_clock;
+} t_toddle;
+
+/* widget helper functions */
+
+
+void toddle_drawbang(t_toddle *x,t_glist *glist,int on)
+{
+ if (glist_isvisible(glist)) {
+ if (on)
+ sys_vgui(".x%x.c create oval \
+%d %d %d %d -fill %s -tags %xB\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos+1,x->x_obj.te_ypos+1,
+ x->x_obj.te_xpos + x->x_width -1,
+ x->x_obj.te_ypos + x->x_height -1,x->x_color->s_name,x);
+ else
+ sys_vgui(".x%x.c delete %xB\n",
+ glist_getcanvas(glist), x);
+ }
+}
+
+
+
+
+void toddle_drawme(t_toddle *x, t_glist *glist, int firsttime)
+{
+ if (firsttime) {
+#if 0
+ sys_vgui(".x%x.c create line \
+%d %d %d %d %d %d %d %d %d %d -tags %xS\n",
+ glist_getcanvas(glist),
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height,
+ x->x_obj.te_xpos, x->x_obj.te_ypos + x->x_height,
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x);
+#endif
+
+ sys_vgui(".x%x.c create rectangle \
+%d %d %d %d -tags %xS "BACKGROUND"\n",
+ glist_getcanvas(glist),
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height,
+ x);
+ sys_vgui(".x%x.c create oval \
+%d %d %d %d -tags %xP\n",glist_getcanvas(glist),
+ x->x_obj.te_xpos+1,x->x_obj.te_ypos+1,
+ x->x_obj.te_xpos + x->x_width -1,
+ x->x_obj.te_ypos + x->x_height -1,x);
+
+ }
+ else {
+#if 0
+ sys_vgui(".x%x.c coords %xS \
+%d %d %d %d %d %d %d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height,
+ x->x_obj.te_xpos, x->x_obj.te_ypos + x->x_height,
+ x->x_obj.te_xpos, x->x_obj.te_ypos);
+#endif
+ sys_vgui(".x%x.c coords %xS \
+%d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ x->x_obj.te_xpos, x->x_obj.te_ypos,
+ x->x_obj.te_xpos + x->x_width, x->x_obj.te_ypos + x->x_height);
+
+
+ sys_vgui(".x%x.c coords %xP \
+%d %d %d %d\n",glist_getcanvas(glist),x,
+ x->x_obj.te_xpos+1,x->x_obj.te_ypos+1,
+ x->x_obj.te_xpos + x->x_width-1,
+ x->x_obj.te_ypos + x->x_height-1);
+ }
+
+
+ {
+ int n = 1;
+ int nplus, i;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpos + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypos + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypos + x->x_height,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypos + x->x_height - 1,
+ onset + IOWIDTH, x->x_obj.te_ypos + x->x_height);
+ }
+ n = 1;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpos + (x->x_width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypos,
+ onset + IOWIDTH, x->x_obj.te_ypos + 1,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypos,
+ onset + IOWIDTH, x->x_obj.te_ypos + 1);
+
+ }
+ }
+
+}
+
+
+
+
+void toddle_erase(t_toddle* x,t_glist* glist)
+{
+ int n;
+ sys_vgui(".x%x.c delete %xS\n",
+ glist_getcanvas(glist), x);
+
+ sys_vgui(".x%x.c delete %xP\n",
+ glist_getcanvas(glist), x);
+
+ n = 1;
+
+ while (n--) {
+ sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,n);
+ sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
+ }
+}
+
+
+
+/* ------------------------ toddle widgetbehaviour----------------------------- */
+
+
+static void toddle_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ int width, height;
+ t_toddle* s = (t_toddle*)z;
+
+
+ width = s->x_width;
+ height = s->x_height;
+ *xp1 = s->x_obj.te_xpos;
+ *yp1 = s->x_obj.te_ypos;
+ *xp2 = s->x_obj.te_xpos + width;
+ *yp2 = s->x_obj.te_ypos + height;
+}
+
+static void toddle_displace(t_gobj *z, t_glist *glist,
+ int dx, int dy)
+{
+ t_toddle *x = (t_toddle *)z;
+ x->x_obj.te_xpos += dx;
+ x->x_obj.te_ypos += dy;
+ toddle_drawme(x, glist, 0);
+ canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
+}
+
+static void toddle_select(t_gobj *z, t_glist *glist, int state)
+{
+ t_toddle *x = (t_toddle *)z;
+ sys_vgui(".x%x.c itemconfigure %xS -fill %s\n", glist,
+ x, (state? "blue" : BACKGROUNDCOLOR));
+}
+
+
+static void toddle_activate(t_gobj *z, t_glist *glist, int state)
+{
+/* t_text *x = (t_text *)z;
+ t_rtext *y = glist_findrtext(glist, x);
+ if (z->g_pd != gatom_class) rtext_activate(y, state);*/
+}
+
+static void toddle_delete(t_gobj *z, t_glist *glist)
+{
+ t_text *x = (t_text *)z;
+ canvas_deletelinesfor(glist_getcanvas(glist), x);
+}
+
+
+static void toddle_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_toddle* s = (t_toddle*)z;
+ if (vis)
+ toddle_drawme(s, glist, 1);
+ else
+ toddle_erase(s,glist);
+}
+
+/* can we use the normal text save function ?? */
+
+static void toddle_save(t_gobj *z, t_binbuf *b)
+{
+ t_toddle *x = (t_toddle *)z;
+ binbuf_addv(b, "ssiissii", gensym("#X"),gensym("obj"),
+ (t_int)x->x_obj.te_xpos, (t_int)x->x_obj.te_ypos,
+ gensym("toddle"),x->x_color,x->x_width,x->x_height);
+ binbuf_addv(b, ";");
+}
+
+
+t_widgetbehavior toddle_widgetbehavior;
+
+
+void toddle_bang(t_toddle *x)
+{
+ toddle_drawbang(x,x->x_glist,1);
+ outlet_bang(x->x_obj.ob_outlet);
+ clock_delay(x->x_clock, 100);
+}
+
+
+static void toddle_click(t_toddle *x,
+ t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
+ t_floatarg alt)
+{
+ toddle_bang(x);
+}
+
+#if (PD_VERSION_MINOR > 31)
+static int toddle_newclick(t_gobj *z, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit)
+{
+ if (doit)
+ toddle_click((t_toddle *)z, (t_floatarg)xpix, (t_floatarg)ypix,
+ (t_floatarg)shift, 0, (t_floatarg)alt);
+ return (1);
+}
+#endif
+
+void toddle_float(t_toddle *x,t_floatarg f)
+{
+
+ toddle_drawbang(x,x->x_glist,1);
+
+ clock_delay(x->x_clock, 100);
+ outlet_float(x->x_obj.ob_outlet,f);
+}
+
+void toddle_on(t_toddle* x)
+{
+ toddle_drawbang(x,x->x_glist,1);
+}
+
+void toddle_off(t_toddle* x)
+{
+ toddle_drawbang(x,x->x_glist,0);
+}
+
+void toddle_tick(t_toddle* x)
+{
+ toddle_drawbang(x,x->x_glist,0);
+ clock_unset(x->x_clock);
+}
+
+
+void toddle_size(t_toddle* x,t_floatarg w,t_floatarg h) {
+ x->x_width = w;
+ x->x_height = h;
+ toddle_drawme(x, x->x_glist, 0);
+}
+
+void toddle_color(t_toddle* x,t_symbol* col)
+{
+ x->x_color = col;
+ toddle_drawbang(x,x->x_glist,1);
+ clock_delay(x->x_clock, 100);
+/* outlet_bang(x->x_obj.ob_outlet); only bang if there was a bang ..
+ so color black does the same as bang, but doesn't forward the bang
+*/
+}
+
+static void toddle_setwidget()
+{
+ toddle_widgetbehavior.w_getrectfn = toddle_getrect;
+ toddle_widgetbehavior.w_displacefn = toddle_displace;
+ toddle_widgetbehavior.w_selectfn = toddle_select;
+ toddle_widgetbehavior.w_activatefn = toddle_activate;
+ toddle_widgetbehavior.w_deletefn = toddle_delete;
+ toddle_widgetbehavior.w_visfn = toddle_vis;
+#if (PD_VERSION_MINOR > 31)
+ toddle_widgetbehavior.w_clickfn = toddle_newclick;
+ toddle_widgetbehavior.w_propertiesfn = NULL;
+#endif
+ toddle_widgetbehavior.w_savefn = toddle_save;
+}
+
+
+static void *toddle_new(t_symbol* col,t_floatarg h,t_floatarg o)
+{
+ t_toddle *x = (t_toddle *)pd_new(toddle_class);
+
+ x->x_glist = (t_glist*) canvas_getcurrent();
+ if (h) x->x_width = h;
+ else
+ x->x_width = DEFAULTSIZE;
+
+ if (o) x->x_height = o;
+ else
+ x->x_height = DEFAULTSIZE;
+
+ if (col != &s_)
+ x->x_color = col;
+ else
+ x->x_color = gensym(DEFAULTCOLOR);
+ x->x_clock = clock_new(x, (t_method)toddle_tick);
+
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void toddle_setup(void)
+{
+ toddle_class = class_new(gensym("toddle"), (t_newmethod)toddle_new, 0,
+ sizeof(t_toddle),0, A_DEFSYM,A_DEFFLOAT,A_DEFFLOAT,0);
+
+ class_addcreator((t_newmethod)toddle_new,gensym("bng"),A_DEFSYM,A_DEFFLOAT,A_DEFFLOAT,A_GIMME,0);
+ class_addbang(toddle_class,toddle_bang);
+ class_addfloat(toddle_class,toddle_float);
+
+ class_addmethod(toddle_class, (t_method)toddle_click, gensym("click"),
+ A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
+
+ class_addmethod(toddle_class, (t_method)toddle_size, gensym("size"),
+ A_FLOAT, A_FLOAT, 0);
+
+ class_addmethod(toddle_class, (t_method)toddle_color, gensym("color"),
+ A_SYMBOL, 0);
+
+ class_addmethod(toddle_class, (t_method)toddle_on, gensym("on"), 0);
+
+ class_addmethod(toddle_class, (t_method)toddle_off, gensym("off"), 0);
+
+
+ toddle_setwidget();
+ class_setwidget(toddle_class,&toddle_widgetbehavior);
+}
+
+
diff --git a/gui/toddle.pd b/gui/toddle.pd
new file mode 100755
index 0000000..2c56c53
--- /dev/null
+++ b/gui/toddle.pd
@@ -0,0 +1,50 @@
+#N canvas 194 167 644 497 12;
+#X obj 21 258 toddle blue 50 50;
+#X obj 254 397 toddle magenta 62 67;
+#X obj 21 315 print;
+#X msg 21 232 bang;
+#X msg 254 251 size 15 15;
+#X obj 22 57 toddle black 15 15;
+#X text 333 250 set the size;
+#X text 42 54 default toddle;
+#X obj 22 92 toddle black 40 40;
+#X text 72 105 toddle black 40 40;
+#X obj 22 149 toddle red 15 15;
+#X text 46 148 toddle red;
+#X obj 22 180 toddle green 10 40;
+#X text 43 193 toddle green 10 40;
+#X text 19 460 (C) 1999 Guenter Geiger;
+#X text 232 9 The Toddle object;
+#X text 232 24 ==================;
+#X msg 460 248 size \$1 \$2;
+#X floatatom 460 206 0 0 0;
+#X obj 460 227 pack 1 2;
+#X floatatom 511 206 0 0 0;
+#X msg 460 183 bang;
+#X text 254 155 wow .....;
+#X msg 460 285 color magenta \, bang;
+#X msg 459 306 color red \, bang;
+#X msg 459 328 color slategrey \, bang;
+#X msg 460 350 color darkgreen \, bang;
+#X text 199 52 To create: Put->Object and type in the "toddle";
+#X floatatom 75 231 0 0 0;
+#X text 75 263 toddle is not a "bang";
+#X text 75 278 converter \, but routes;
+#X text 76 294 messages through;
+#X connect 0 0 2 0;
+#X connect 3 0 0 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 8 0 10 0;
+#X connect 10 0 12 0;
+#X connect 17 0 1 0;
+#X connect 18 0 19 0;
+#X connect 19 0 17 0;
+#X connect 20 0 19 1;
+#X connect 20 0 21 0;
+#X connect 21 0 18 0;
+#X connect 23 0 1 0;
+#X connect 24 0 1 0;
+#X connect 25 0 1 0;
+#X connect 26 0 1 0;
+#X connect 28 0 0 0;
diff --git a/gui/w_envgen.h b/gui/w_envgen.h
new file mode 100755
index 0000000..b815d6c
--- /dev/null
+++ b/gui/w_envgen.h
@@ -0,0 +1,452 @@
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#define abs fabs
+#endif
+
+#include "ggee.h"
+#define BORDER 2
+
+#if 0 /* backwards compatiblity */
+#define text_xpix(a,b) a.te_xpos
+#define text_ypix(a,b) a.te_ypos
+#endif
+
+static void draw_inlets(t_envgen *x, t_glist *glist, int firsttime, int nin, int nout)
+{
+ int n = nin;
+ int nplus, i;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpix + (x->w.width - IOWIDTH) * i / nplus - BORDER;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypix + x->w.height - 1 + 2*BORDER,
+ onset + IOWIDTH, x->x_obj.te_ypix + x->w.height + 2*BORDER,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypix + x->w.height - 1 + 2*BORDER,
+ onset + IOWIDTH, x->x_obj.te_ypix + x->w.height + 2*BORDER);
+ }
+ n = nout;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = x->x_obj.te_xpix + (x->w.width - IOWIDTH) * i / nplus - BORDER;
+ if (firsttime)
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
+ glist_getcanvas(glist),
+ onset, x->x_obj.te_ypix - BORDER,
+ onset + IOWIDTH, x->x_obj.te_ypix + 1 - BORDER,
+ x, i);
+ else
+ sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, x->x_obj.te_ypix - BORDER,
+ onset + IOWIDTH, x->x_obj.te_ypix + 1 - BORDER);
+
+ }
+}
+
+
+
+static int envgen_next_doodle(t_envgen *x, int xpos,int ypos)
+{
+ int ret = -1;
+ float xscale,yscale;
+ int dxpos,dypos;
+ float minval = 1000000.0;
+ float tval;
+ int i;
+ int insertpos = -1;
+
+
+ xscale = x->w.width/x->duration[x->last_state];
+ yscale = x->w.height;
+
+ dxpos = x->x_obj.te_xpix;/* + BORDER */;
+ dypos = x->x_obj.te_ypix + BORDER;
+
+ for (i=0;i<=x->last_state;i++) {
+ float dx2 = (dxpos + (x->duration[i] * xscale)) - xpos;
+ float dy2 = (dypos + yscale - (x->finalvalues[i] * yscale)) - ypos;
+
+ dx2*=dx2;
+ dy2*=dy2;
+ tval = dx2+dy2;
+/* post("%i: dist = %f dx=%f dy=%f",i,tval,dx2,dy2);*/
+ if ((dxpos + (x->duration[i] * xscale)) < xpos)
+ insertpos = i;
+ if (abs(tval) < minval) {
+ minval = abs(tval);
+ }
+ }
+
+ /* decide if we want to make a new one */
+/* post("insertpos %d",insertpos); */
+ if (minval > /*5*/ 16 && insertpos >= 0 && !x->x_freeze) {
+
+ if (((dxpos + (x->duration[insertpos] * xscale)) - xpos) < 0)
+ insertpos++;
+/* post("minval = %f, insertpos = %d",minval,insertpos);*/
+
+ if (x->last_state+1 >= x->args)
+ envgen_resize(x,x->args+1);
+
+ for (i=x->last_state;i>=insertpos;i--) {
+ x->duration[i+1] = x->duration[i];
+ x->finalvalues[i+1] = x->finalvalues[i];
+ }
+
+ x->duration[insertpos] = (float)(xpos-dxpos)/x->w.width*x->duration[x->last_state++];
+
+ x->w.grabbed = insertpos;
+ }
+
+ return insertpos;
+}
+
+static void envgen_create_doodles(t_envgen *x, t_glist *glist)
+{
+ float xscale,yscale;
+ int xpos,ypos;
+ int i;
+ char guistr[255];
+
+ xscale = x->w.width/x->duration[x->last_state];
+ yscale = x->w.height;
+
+ xpos = x->x_obj.te_xpix;
+ ypos = (int) (x->x_obj.te_ypix + x->w.height);
+ for (i=0;i<=x->last_state;i++) {
+ sprintf(guistr,".x%x.c create oval %d %d %d %d -tags %xD%d",glist_getcanvas(glist),
+ (int) (xpos+(x->duration[i] * xscale) - 2),
+ (int) (ypos - x->finalvalues[i]*yscale - 2),
+ (int) (xpos+(x->duration[i] * xscale)+2),
+ (int) (ypos - x->finalvalues[i]*yscale + 2),
+ x,i);
+
+ if (i == x->w.grabbed) strcat(guistr," -fill red\n");
+ else strcat(guistr,"\n");
+ sys_vgui("%s",guistr);
+ }
+ x->w.numdoodles = i;
+}
+
+
+static void envgen_delete_doodles(t_envgen *x, t_glist *glist)
+{
+ int i;
+ for (i=0;i<=x->w.numdoodles;i++)
+ sys_vgui(".x%x.c delete %xD%d\n",glist_getcanvas(glist),x,i);
+}
+
+static void envgen_update_doodles(t_envgen *x, t_glist *glist)
+{
+
+ envgen_delete_doodles(x,glist);
+/* LATER only create new doodles if necessary */
+ envgen_create_doodles(x, glist);
+}
+
+
+static void envgen_create(t_envgen *x, t_glist *glist)
+{
+ int i;
+ static char buf[1024];
+ float xscale,yscale;
+ int xpos,ypos;
+ char num[40];
+
+ sys_vgui(".x%x.c create rectangle \
+%d %d %d %d -tags %xS "BACKGROUND"\n",
+ glist_getcanvas(glist),
+ x->x_obj.te_xpix-BORDER, x->x_obj.te_ypix-BORDER,
+ x->x_obj.te_xpix + x->w.width+2*BORDER, x->x_obj.te_ypix + x->w.height+2*BORDER,
+ x);
+
+ xscale = x->w.width/x->duration[x->last_state];
+ yscale = x->w.height;
+
+ sprintf(buf,".x%x.c create line",glist_getcanvas(glist));
+ xpos = x->x_obj.te_xpix;
+ ypos = (int) (x->x_obj.te_ypix + x->w.height);
+ for (i=0;i<=x->last_state;i++) {
+ sprintf(num," %d %d ",(int)(xpos + x->duration[i]*xscale),
+ (int)(ypos - x->finalvalues[i]*yscale));
+ strcat(buf,num);
+ }
+
+ sprintf(num,"-tags %xP\n",x);
+ strcat(buf,num);
+/* post("sending %s",buf); */
+ sys_vgui("%s",buf);
+ envgen_create_doodles(x,glist);
+}
+
+
+static void envgen_update(t_envgen *x, t_glist *glist)
+{
+int i;
+ static char buf[1024];
+ float xscale,yscale;
+ int xpos,ypos;
+ char num[40];
+
+ sys_vgui(".x%x.c coords %xS \
+%d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ x->x_obj.te_xpix - BORDER, x->x_obj.te_ypix -BORDER,
+ x->x_obj.te_xpix + x->w.width+2*BORDER, x->x_obj.te_ypix + x->w.height+2*BORDER);
+
+
+ xscale = x->w.width/x->duration[x->last_state];
+ yscale = x->w.height;
+
+ sprintf(buf,".x%x.c coords %xP",glist_getcanvas(glist),x);
+ xpos = x->x_obj.te_xpix;
+ ypos = (int) (x->x_obj.te_ypix + x->w.height);
+ for (i=0;i<=x->last_state;i++) {
+ sprintf(num," %d %d ",(int)(xpos + x->duration[i]*xscale),
+ (int) (ypos - x->finalvalues[i]*yscale));
+ strcat(buf,num);
+ }
+ strcat(buf,"\n");
+/* post("sending %s",buf); */
+ sys_vgui("%s",buf);
+ envgen_update_doodles(x,glist);
+}
+
+
+
+void envgen_drawme(t_envgen *x, t_glist *glist, int firsttime)
+{
+
+ if (firsttime) envgen_create(x,glist);
+ else envgen_update(x,glist);
+
+ draw_inlets(x, glist, firsttime, 1,1);
+}
+
+
+
+
+void envgen_erase(t_envgen* x,t_glist* glist)
+{
+ int n;
+ sys_vgui(".x%x.c delete %xS\n",
+ glist_getcanvas(glist), x);
+
+ sys_vgui(".x%x.c delete %xP\n",
+ glist_getcanvas(glist), x);
+
+ n = 1;
+
+ while (n--) {
+ sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,n);
+ sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
+ }
+
+ envgen_delete_doodles(x,glist);
+}
+
+
+
+/* ------------------------ envgen widgetbehaviour----------------------------- */
+
+
+static void envgen_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ int width, height;
+ t_envgen* s = (t_envgen*)z;
+
+
+ width = s->w.width + 2*BORDER;
+ height = s->w.height + 2*BORDER;
+ *xp1 = s->x_obj.te_xpix-BORDER;
+ *yp1 = s->x_obj.te_ypix-BORDER;
+ *xp2 = s->x_obj.te_xpix + width;
+ *yp2 = s->x_obj.te_ypix + height;
+}
+
+static void envgen_displace(t_gobj *z, t_glist *glist,
+ int dx, int dy)
+{
+ t_envgen *x = (t_envgen *)z;
+ x->x_obj.te_xpix += dx;
+ x->x_obj.te_ypix += dy;
+
+ envgen_drawme(x, glist, 0);
+ canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
+}
+
+static void envgen_select(t_gobj *z, t_glist *glist, int state)
+{
+ t_envgen *x = (t_envgen *)z;
+ sys_vgui(".x%x.c itemconfigure %xS -fill %s\n", glist,
+ x, (state? "blue" : BACKGROUNDCOLOR));
+}
+
+
+static void envgen_activate(t_gobj *z, t_glist *glist, int state)
+{
+/* t_text *x = (t_text *)z;
+ t_rtext *y = glist_findrtext(glist, x);
+ if (z->g_pd != gatom_class) rtext_activate(y, state);*/
+}
+
+static void envgen_delete(t_gobj *z, t_glist *glist)
+{
+ t_text *x = (t_text *)z;
+ canvas_deletelinesfor(glist_getcanvas(glist), x);
+}
+
+
+static void envgen_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_envgen* s = (t_envgen*)z;
+ if (vis)
+ envgen_drawme(s, glist, 1);
+ else
+ envgen_erase(s,glist);
+}
+
+/* can we use the normal text save function ?? */
+
+static void envgen_save(t_gobj *z, t_binbuf *b)
+{
+ t_envgen *x = (t_envgen *)z;
+ binbuf_addv(b, "ssiisii", gensym("#X"),gensym("obj"),
+ (t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
+ gensym("envgen"),x->w.width,x->w.height);
+ binbuf_addv(b, ";");
+}
+
+
+
+static void envgen_followpointer(t_envgen* x)
+{
+ float dur;
+
+ float xscale = x->duration[x->last_state]/x->w.width;
+
+ if ((x->w.grabbed > 0) && (x->w.grabbed < x->last_state)) {
+
+ dur = (x->w.pointerx - x->x_obj.te_xpix)*xscale;
+ if (dur < x->duration[x->w.grabbed-1])
+ dur = x->duration[x->w.grabbed-1] + 1.0;
+ if (dur > x->duration[x->w.grabbed+1])
+ dur = x->duration[x->w.grabbed+1] - 0.2;
+
+ x->duration[x->w.grabbed] = dur;
+ }
+
+
+ x->finalvalues[x->w.grabbed] = 1.0f - (float)(x->w.pointery - x->x_obj.te_ypix)/(float)x->w.height;
+ if (x->finalvalues[x->w.grabbed] < 0.0)
+ x->finalvalues[x->w.grabbed]= 0.0;
+ else if (x->finalvalues[x->w.grabbed] > 1.0)
+ x->finalvalues[x->w.grabbed]= 1.0;
+
+}
+
+
+void envgen_motion(t_envgen *x, t_floatarg dx, t_floatarg dy)
+{
+ x->w.pointerx+=dx;
+ x->w.pointery+=dy;
+
+ if (!x->resizing)
+ envgen_followpointer(x);
+ else {
+ x->w.width+=dx;
+ x->w.height+=dy;
+ }
+ envgen_update(x,x->w.glist);
+}
+
+void envgen_key(t_envgen *x, t_floatarg f)
+{
+ if (f == 8.0 && x->w.grabbed < x->last_state && x->w.grabbed > 0) {
+ int i;
+
+ for (i=x->w.grabbed;i<=x->last_state;i++) {
+ x->duration[i] = x->duration[i+1];
+ x->finalvalues[i] = x->finalvalues[i+1];
+ }
+
+ x->last_state--;
+ x->w.grabbed--;
+ envgen_update(x,x->w.glist);
+ }
+}
+
+
+
+void envgen_click(t_envgen *x,
+ t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
+ t_floatarg alt)
+{
+ /* check if user wants to resize */
+ float wxpos = x->x_obj.te_xpix;
+ float wypos = (int) (x->x_obj.te_ypix + x->w.height);
+
+ x->w.grabbed = envgen_next_doodle(x,xpos,ypos);
+#if (PD_VERSION_MINOR > 31)
+ glist_grab(x->w.glist, &x->x_obj.te_g, envgen_motion, envgen_key, xpos, ypos);
+#else
+ glist_grab(x->w.glist, &x->x_obj.te_g, xpos, ypos);
+#endif
+ x->resizing = 0;
+ if ((xpos > wxpos + x->w.width - 3) &&
+ (fabs(ypos -2 - wypos) < 3.)) {
+ x->resizing = 1;
+ return;
+ }
+
+ x->w.pointerx = xpos;
+ x->w.pointery = ypos;
+ envgen_followpointer(x);
+ envgen_update(x,x->w.glist);
+}
+
+
+#if (PD_VERSION_MINOR > 31)
+static int envgen_newclick(t_gobj *z, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit)
+{
+ if (doit)
+ envgen_click((t_envgen *)z, (t_floatarg)xpix, (t_floatarg)ypix,
+ (t_floatarg)shift, 0, (t_floatarg)alt);
+ return (1);
+}
+#endif
+
+
+
+t_widgetbehavior envgen_widgetbehavior;
+
+void envgen_setwidget()
+{
+ envgen_widgetbehavior.w_getrectfn = envgen_getrect;
+ envgen_widgetbehavior.w_displacefn = envgen_displace;
+ envgen_widgetbehavior.w_selectfn = envgen_select;
+ envgen_widgetbehavior.w_activatefn = envgen_activate;
+ envgen_widgetbehavior.w_deletefn = envgen_delete;
+ envgen_widgetbehavior.w_visfn = envgen_vis;
+#if (PD_VERSION_MINOR > 31)
+ envgen_widgetbehavior.w_clickfn = envgen_newclick;
+ envgen_widgetbehavior.w_propertiesfn = NULL;
+#endif
+ envgen_widgetbehavior.w_savefn = envgen_save;
+
+}
+
diff --git a/include/g_canvas.h b/include/g_canvas.h
new file mode 100755
index 0000000..5cc4df1
--- /dev/null
+++ b/include/g_canvas.h
@@ -0,0 +1,560 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* this file defines the structure for "glists" and related structures and
+functions. "Glists" and "canvases" and "graphs" used to be different
+structures until being unified in version 0.35.
+
+A glist occupies its own window if the "gl_havewindow" flag is set. Its
+appearance on its "parent" or "owner" (if it has one) is as a graph if
+"gl_isgraph" is set, and otherwise as a text box.
+
+A glist is "root" if it has no owner, i.e., a document window. In this
+case "gl_havewindow" is always set.
+
+We maintain a list of root windows, so that we can traverse the whole
+collection of everything in a Pd process.
+
+If a glist has a window it may still not be "mapped." Miniaturized
+windows aren't mapped, for example, but a window is also not mapped
+immediately upon creation. In either case gl_havewindow is true but
+gl_mapped is false.
+
+Closing a non-root window makes it invisible; closing a root destroys it.
+
+A glist that's just a text object on its parent is always "toplevel." An
+embedded glist can switch back and forth to appear as a toplevel by double-
+clicking on it. Single-clicking a text box makes the toplevel become visible
+and raises the window it's in.
+
+If a glist shows up as a graph on its parent, the graph is blanked while the
+glist has its own window, even if miniaturized.
+
+*/
+
+/* --------------------- geometry ---------------------------- */
+#define IOWIDTH 7 /* width of an inlet/outlet in pixels */
+#define IOMIDDLE ((IOWIDTH-1)/2)
+#define GLIST_DEFGRAPHWIDTH 200
+#define GLIST_DEFGRAPHHEIGHT 140
+/* ----------------------- data ------------------------------- */
+
+typedef struct _updateheader
+{
+ struct _updateheader *upd_next;
+ unsigned int upd_array:1; /* true if array, false if glist */
+ unsigned int upd_queued:1; /* true if we're queued */
+} t_updateheader;
+
+ /* types to support glists grabbing mouse motion or keys from parent */
+typedef void (*t_glistmotionfn)(void *z, t_floatarg dx, t_floatarg dy);
+typedef void (*t_glistkeyfn)(void *z, t_floatarg key);
+
+EXTERN_STRUCT _rtext;
+#define t_rtext struct _rtext
+
+EXTERN_STRUCT _gtemplate;
+#define t_gtemplate struct _gtemplate
+
+EXTERN_STRUCT _guiconnect;
+#define t_guiconnect struct _guiconnect
+
+EXTERN_STRUCT _tscalar;
+#define t_tscalar struct _tscalar
+
+EXTERN_STRUCT _canvasenvironment;
+#define t_canvasenvironment struct _canvasenvironment
+
+EXTERN_STRUCT _linetraverser;
+#define t_linetraverser struct _linetraverser
+
+typedef struct _selection
+{
+ t_gobj *sel_what;
+ struct _selection *sel_next;
+} t_selection;
+
+ /* this structure is instantiated whenever a glist becomes visible. */
+typedef struct _editor
+{
+ t_updateheader e_upd; /* update header structure */
+ t_selection *e_updlist; /* list of objects to update */
+ t_rtext *e_rtext; /* text responder linked list */
+ t_selection *e_selection; /* head of the selection list */
+ t_rtext *e_textedfor; /* the rtext if any that we are editing */
+ t_gobj *e_grab; /* object being "dragged" */
+ t_glistmotionfn e_motionfn; /* ... motion callback */
+ t_glistkeyfn e_keyfn; /* ... keypress callback */
+ t_binbuf *e_connectbuf; /* connections to deleted objects */
+ t_binbuf *e_deleted; /* last stuff we deleted */
+ t_guiconnect *e_guiconnect; /* GUI connection for filtering messages */
+ struct _glist *e_glist; /* glist which owns this */
+ int e_xwas; /* xpos on last mousedown or motion event */
+ int e_ywas; /* ypos, similarly */
+ unsigned int e_onmotion: 3; /* action to take on motion */
+ unsigned int e_lastmoved: 1; /* one if mouse has moved since click */
+ unsigned int e_textdirty: 1; /* one if e_textedfor has changed */
+} t_editor;
+
+#define MA_NONE 0 /* e_onmotion: do nothing on mouse motion */
+#define MA_MOVE 1 /* drag the selection around */
+#define MA_CONNECT 2 /* make a connection */
+#define MA_REGION 3 /* selection region */
+#define MA_PASSOUT 4 /* send on to e_grab */
+#define MA_DRAGTEXT 5 /* drag in text editor to alter selection */
+
+/* editor structure for "garrays". We don't bother to delete and regenerate
+this structure when the "garray" becomes invisible or visible, although we
+could do so if the structure gets big (like the "editor" above.) */
+
+typedef struct _arrayvis
+{
+ t_updateheader av_upd; /* update header structure */
+ t_garray *av_garray; /* owning structure */
+} t_arrayvis;
+
+/* the t_tick structure describes where to draw x and y "ticks" for a glist */
+
+typedef struct _tick /* where to put ticks on x or y axes */
+{
+ float k_point; /* one point to draw a big tick at */
+ float k_inc; /* x or y increment per little tick */
+ int k_lperb; /* little ticks per big; 0 if no ticks to draw */
+} t_tick;
+
+/* the t_glist structure, which describes a list of elements that live on an
+area of a window.
+
+*/
+
+struct _glist
+{
+ t_object gl_obj; /* header in case we're a glist */
+ t_gobj *gl_list; /* the actual data */
+ struct _gstub *gl_stub; /* safe pointer handler */
+ int gl_valid; /* incremented when pointers might be stale */
+ struct _glist *gl_owner; /* parent glist, supercanvas, or 0 if none */
+ int gl_pixwidth; /* width in pixels (on parent, if a graph) */
+ int gl_pixheight;
+ float gl_x1; /* bounding rectangle in our own coordinates */
+ float gl_y1;
+ float gl_x2;
+ float gl_y2;
+ int gl_screenx1; /* screen coordinates when toplevel */
+ int gl_screeny1;
+ int gl_screenx2;
+ int gl_screeny2;
+ t_tick gl_xtick; /* ticks marking X values */
+ int gl_nxlabels; /* number of X coordinate labels */
+ t_symbol **gl_xlabel; /* ... an array to hold them */
+ float gl_xlabely; /* ... and their Y coordinates */
+ t_tick gl_ytick; /* same as above for Y ticks and labels */
+ int gl_nylabels;
+ t_symbol **gl_ylabel;
+ float gl_ylabelx;
+ t_editor *gl_editor; /* editor structure when visible */
+ t_symbol *gl_name; /* symbol bound here */
+ int gl_font; /* nominal font size in points, e.g., 10 */
+ struct _glist *gl_next; /* link in list of toplevels */
+ t_canvasenvironment *gl_env; /* root canvases and abstractions only */
+ unsigned int gl_havewindow:1; /* true if we own a window */
+ unsigned int gl_mapped:1; /* true if, moreover, it's "mapped" */
+ unsigned int gl_dirty:1; /* (root canvas only:) patch has changed */
+ unsigned int gl_loading:1; /* am now loading from file */
+ unsigned int gl_willvis:1; /* make me visible after loading */
+ unsigned int gl_edit:1; /* edit mode */
+ unsigned int gl_imatemplate:1; /* someone needs me as template */
+ unsigned int gl_isdeleting:1; /* we're inside glist_delete -- hack! */
+ unsigned int gl_protect:1; /* don't delete connections on click */
+ unsigned int gl_stretch:1; /* stretch contents on resize */
+ unsigned int gl_isgraph:1; /* show as graph on parent */
+};
+
+#define gl_gobj gl_obj.te_g
+#define gl_pd gl_gobj.g_pd
+
+/* a data structure to describe a field in a pure datum */
+
+#define DT_FLOAT 0
+#define DT_SYMBOL 1
+#define DT_LIST 2
+#define DT_ARRAY 3
+
+typedef struct _dataslot
+{
+ int ds_type;
+ t_symbol *ds_name;
+ t_symbol *ds_arraytemplate; /* filled in for arrays only */
+} t_dataslot;
+
+typedef struct _template
+{
+ t_pd t_pd; /* header */
+ struct _gtemplate *t_list; /* list of "struct"/gtemplate objects */
+ t_symbol *t_sym; /* name */
+ int t_n; /* number of dataslots (fields) */
+ t_dataslot *t_vec; /* array of dataslots */
+} t_template;
+
+struct _array
+{
+ int a_n; /* number of elements */
+ int a_elemsize; /* size in bytes; LATER get this from template */
+ char *a_vec; /* array of elements */
+ t_symbol *a_templatesym; /* template for elements */
+ int a_valid; /* protection against stale pointers into array */
+ t_gpointer a_gp; /* pointer to scalar or array element we're in */
+ t_gstub *a_stub;
+};
+
+ /* structure for traversing all the connections in a glist */
+struct _linetraverser
+{
+ t_canvas *tr_x;
+ t_object *tr_ob;
+ int tr_nout;
+ int tr_outno;
+ t_object *tr_ob2;
+ t_outlet *tr_outlet;
+ t_inlet *tr_inlet;
+ int tr_nin;
+ int tr_inno;
+ int tr_x11, tr_y11, tr_x12, tr_y12;
+ int tr_x21, tr_y21, tr_x22, tr_y22;
+ int tr_lx1, tr_ly1, tr_lx2, tr_ly2;
+ t_outconnect *tr_nextoc;
+ int tr_nextoutno;
+};
+
+/* function types used to define graphical behavior for gobjs, a bit like X
+widgets. We don't use Pd methods because Pd's typechecking can't specify the
+types of pointer arguments. Also it's more convenient this way, since
+every "patchable" object can just get the "text" behaviors. */
+
+ /* Call this to get a gobj's bounding rectangle in pixels */
+typedef void (*t_getrectfn)(t_gobj *x, struct _glist *glist,
+ int *x1, int *y1, int *x2, int *y2);
+ /* and this to displace a gobj: */
+typedef void (*t_displacefn)(t_gobj *x, struct _glist *glist, int dx, int dy);
+ /* change color to show selection: */
+typedef void (*t_selectfn)(t_gobj *x, struct _glist *glist, int state);
+ /* change appearance to show activation/deactivation: */
+typedef void (*t_activatefn)(t_gobj *x, struct _glist *glist, int state);
+ /* warn a gobj it's about to be deleted */
+typedef void (*t_deletefn)(t_gobj *x, struct _glist *glist);
+ /* making visible or invisible */
+typedef void (*t_visfn)(t_gobj *x, struct _glist *glist, int flag);
+ /* field a mouse click (when not in "edit" mode) */
+typedef int (*t_clickfn)(t_gobj *x, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit);
+ /* save to a binbuf */
+typedef void (*t_savefn)(t_gobj *x, t_binbuf *b);
+ /* open properties dialog */
+typedef void (*t_propertiesfn)(t_gobj *x, struct _glist *glist);
+ /* ... and later, resizing; getting/setting font or color... */
+
+struct _widgetbehavior
+{
+ t_getrectfn w_getrectfn;
+ t_displacefn w_displacefn;
+ t_selectfn w_selectfn;
+ t_activatefn w_activatefn;
+ t_deletefn w_deletefn;
+ t_visfn w_visfn;
+ t_clickfn w_clickfn;
+ t_savefn w_savefn;
+ t_propertiesfn w_propertiesfn;
+};
+
+/* -------- behaviors for scalars defined by objects in template --------- */
+/* these are set by "drawing commands" in g_template.c which add appearance to
+scalars, which live in some other window. If the scalar is just included
+in a canvas the "parent" is a misnomer. There is also a text scalar object
+which really does draw the scalar on the parent window; see g_scalar.c. */
+
+/* note how the click function wants the whole scalar, not the "data", so
+doesn't work on array elements... LATER reconsider this */
+
+ /* bounding rectangle: */
+typedef void (*t_parentgetrectfn)(t_gobj *x, struct _glist *glist,
+ t_word *data, t_template *template, float basex, float basey,
+ int *x1, int *y1, int *x2, int *y2);
+ /* displace it */
+typedef void (*t_parentdisplacefn)(t_gobj *x, struct _glist *glist,
+ t_word *data, t_template *template, float basex, float basey,
+ int dx, int dy);
+ /* change color to show selection */
+typedef void (*t_parentselectfn)(t_gobj *x, struct _glist *glist,
+ t_word *data, t_template *template, float basex, float basey,
+ int state);
+ /* change appearance to show activation/deactivation: */
+typedef void (*t_parentactivatefn)(t_gobj *x, struct _glist *glist,
+ t_word *data, t_template *template, float basex, float basey,
+ int state);
+ /* making visible or invisible */
+typedef void (*t_parentvisfn)(t_gobj *x, struct _glist *glist,
+ t_word *data, t_template *template, float basex, float basey,
+ int flag);
+ /* field a mouse click */
+typedef int (*t_parentclickfn)(t_gobj *x, struct _glist *glist,
+ t_scalar *sc, t_template *template, float basex, float basey,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit);
+
+struct _parentwidgetbehavior
+{
+ t_parentgetrectfn w_parentgetrectfn;
+ t_parentdisplacefn w_parentdisplacefn;
+ t_parentselectfn w_parentselectfn;
+ t_parentactivatefn w_parentactivatefn;
+ t_parentvisfn w_parentvisfn;
+ t_parentclickfn w_parentclickfn;
+};
+
+ /* cursor definitions; used as return value for t_parentclickfn */
+#define CURSOR_RUNMODE_NOTHING 0
+#define CURSOR_RUNMODE_CLICKME 1
+#define CURSOR_RUNMODE_THICKEN 2
+#define CURSOR_RUNMODE_ADDPOINT 3
+#define CURSOR_EDITMODE_NOTHING 4
+#define CURSOR_EDITMODE_CONNECT 5
+#define CURSOR_EDITMODE_DISCONNECT 6
+EXTERN void canvas_setcursor(t_glist *x, unsigned int cursornum);
+
+extern t_canvas *canvas_editing; /* last canvas to start text edting */
+extern t_canvas *canvas_whichfind; /* last canvas we did a find in */
+extern t_canvas *canvas_list; /* list of all root canvases */
+extern t_class *vinlet_class, *voutlet_class;
+extern int glist_valid; /* incremented when pointers might be stale */
+
+/* ------------------- functions on any gobj ----------------------------- */
+EXTERN void gobj_getrect(t_gobj *x, t_glist *owner, int *x1, int *y1,
+ int *x2, int *y2);
+EXTERN void gobj_displace(t_gobj *x, t_glist *owner, int dx, int dy);
+EXTERN void gobj_select(t_gobj *x, t_glist *owner, int state);
+EXTERN void gobj_activate(t_gobj *x, t_glist *owner, int state);
+EXTERN void gobj_delete(t_gobj *x, t_glist *owner);
+EXTERN void gobj_vis(t_gobj *x, t_glist *glist, int flag);
+EXTERN int gobj_click(t_gobj *x, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit);
+EXTERN void gobj_save(t_gobj *x, t_binbuf *b);
+EXTERN void gobj_properties(t_gobj *x, struct _glist *glist);
+
+/* -------------------- functions on glists --------------------- */
+EXTERN t_glist *glist_new( void);
+EXTERN void glist_init(t_glist *x);
+EXTERN void glist_add(t_glist *x, t_gobj *g);
+EXTERN void glist_cleanup(t_glist *x);
+EXTERN void glist_free(t_glist *x);
+
+EXTERN void glist_clear(t_glist *x);
+EXTERN t_canvas *glist_getcanvas(t_glist *x);
+EXTERN int glist_isselected(t_glist *x, t_gobj *y);
+EXTERN void glist_select(t_glist *x, t_gobj *y);
+EXTERN void glist_deselect(t_glist *x, t_gobj *y);
+EXTERN void glist_noselect(t_glist *x);
+EXTERN void glist_selectall(t_glist *x);
+EXTERN void glist_delete(t_glist *x, t_gobj *y);
+EXTERN void glist_retext(t_glist *x, t_text *y);
+EXTERN void glist_grab(t_glist *x, t_gobj *y, t_glistmotionfn motionfn,
+ t_glistkeyfn keyfn, int xpos, int ypos);
+EXTERN int glist_isvisible(t_glist *x);
+EXTERN int glist_istoplevel(t_glist *x);
+EXTERN t_glist *glist_findgraph(t_glist *x);
+EXTERN int glist_getfont(t_glist *x);
+EXTERN void glist_sort(t_glist *canvas);
+EXTERN void glist_read(t_glist *x, t_symbol *filename, t_symbol *format);
+EXTERN void glist_mergefile(t_glist *x, t_symbol *filename, t_symbol *format);
+
+EXTERN float glist_pixelstox(t_glist *x, float xpix);
+EXTERN float glist_pixelstoy(t_glist *x, float ypix);
+EXTERN float glist_xtopixels(t_glist *x, float xval);
+EXTERN float glist_ytopixels(t_glist *x, float yval);
+EXTERN float glist_dpixtodx(t_glist *x, float dxpix);
+EXTERN float glist_dpixtody(t_glist *x, float dypix);
+
+EXTERN void glist_redrawitem(t_glist *owner, t_gobj *gobj);
+EXTERN void glist_getnextxy(t_glist *gl, int *xval, int *yval);
+EXTERN void glist_glist(t_glist *g, t_symbol *s, int argc, t_atom *argv);
+EXTERN t_glist *glist_addglist(t_glist *g, t_symbol *sym,
+ float x1, float y1, float x2, float y2,
+ float px1, float py1, float px2, float py2);
+EXTERN void glist_arraydialog(t_glist *parent, t_symbol *name,
+ t_floatarg size, t_floatarg saveit, t_floatarg newgraph);
+EXTERN t_binbuf *glist_writetobinbuf(t_glist *x, int wholething);
+EXTERN int glist_isgraph(t_glist *x);
+EXTERN void glist_redraw(t_glist *x);
+EXTERN void glist_drawiofor(t_glist *glist, t_object *ob, int firsttime,
+ char *tag, int x1, int y1, int x2, int y2);
+EXTERN void glist_eraseiofor(t_glist *glist, t_object *ob, char *tag);
+EXTERN void canvas_create_editor(t_glist *x, int createit);
+
+/* -------------------- functions on texts ------------------------- */
+EXTERN void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize);
+EXTERN void text_drawborder(t_text *x, t_glist *glist, char *tag,
+ int width, int height, int firsttime);
+EXTERN void text_eraseborder(t_text *x, t_glist *glist, char *tag);
+EXTERN int text_xcoord(t_text *x, t_glist *glist);
+EXTERN int text_ycoord(t_text *x, t_glist *glist);
+EXTERN int text_xpix(t_text *x, t_glist *glist);
+EXTERN int text_ypix(t_text *x, t_glist *glist);
+EXTERN int text_shouldvis(t_text *x, t_glist *glist);
+
+/* -------------------- functions on rtexts ------------------------- */
+#define RTEXT_DOWN 1
+#define RTEXT_DRAG 2
+#define RTEXT_DBL 3
+#define RTEXT_SHIFT 4
+
+EXTERN t_rtext *rtext_new(t_glist *glist, t_text *who, t_rtext *next,
+ int sendipup);
+EXTERN t_rtext *rtext_remove(t_rtext *first, t_rtext *x);
+EXTERN t_rtext *glist_findrtext(t_glist *gl, t_text *who);
+EXTERN int rtext_height(t_rtext *x);
+EXTERN void rtext_displace(t_rtext *x, int dx, int dy);
+EXTERN void rtext_select(t_rtext *x, int state);
+EXTERN void rtext_activate(t_rtext *x, int state);
+EXTERN void rtext_free(t_rtext *x);
+EXTERN void rtext_key(t_rtext *x, int n, t_symbol *s);
+EXTERN void rtext_mouse(t_rtext *x, int xval, int yval, int flag);
+EXTERN void rtext_retext(t_rtext *x);
+EXTERN int rtext_width(t_rtext *x);
+EXTERN int rtext_height(t_rtext *x);
+EXTERN char *rtext_gettag(t_rtext *x);
+EXTERN void rtext_gettext(t_rtext *x, char **buf, int *bufsize);
+
+/* -------------------- functions on canvases ------------------------ */
+EXTERN t_class *canvas_class;
+
+EXTERN t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv);
+EXTERN t_symbol *canvas_makebindsym(t_symbol *s);
+EXTERN void canvas_vistext(t_canvas *x, t_text *y);
+EXTERN void canvas_fixlinesfor(t_canvas *x, t_text *text);
+EXTERN void canvas_deletelinesfor(t_canvas *x, t_text *text);
+EXTERN void canvas_stowconnections(t_canvas *x);
+EXTERN void canvas_restoreconnections(t_canvas *x);
+EXTERN void canvas_redraw(t_canvas *x);
+
+EXTERN t_inlet *canvas_addinlet(t_canvas *x, t_pd *who, t_symbol *sym);
+EXTERN void canvas_rminlet(t_canvas *x, t_inlet *ip);
+EXTERN t_outlet *canvas_addoutlet(t_canvas *x, t_pd *who, t_symbol *sym);
+EXTERN void canvas_rmoutlet(t_canvas *x, t_outlet *op);
+EXTERN void canvas_redrawallfortemplate(t_canvas *template);
+EXTERN void canvas_zapallfortemplate(t_canvas *template);
+EXTERN void canvas_setusedastemplate(t_canvas *x);
+EXTERN t_canvas *canvas_getcurrent(void);
+EXTERN void canvas_setcurrent(t_canvas *x);
+EXTERN void canvas_unsetcurrent(t_canvas *x);
+EXTERN t_canvas *canvas_getrootfor(t_canvas *x);
+EXTERN void canvas_dirty(t_canvas *x, t_int n);
+EXTERN int canvas_getfont(t_canvas *x);
+typedef int (*t_canvasapply)(t_canvas *x, t_int x1, t_int x2, t_int x3);
+
+EXTERN t_int *canvas_recurapply(t_canvas *x, t_canvasapply *fn,
+ t_int x1, t_int x2, t_int x3);
+
+EXTERN void canvas_resortinlets(t_canvas *x);
+EXTERN void canvas_resortoutlets(t_canvas *x);
+EXTERN void canvas_free(t_canvas *x);
+EXTERN void canvas_updatewindowlist( void);
+EXTERN void canvas_editmode(t_canvas *x, t_floatarg yesplease);
+EXTERN int canvas_isabstraction(t_canvas *x);
+EXTERN void canvas_vis(t_canvas *x, t_floatarg f);
+EXTERN t_canvasenvironment *canvas_getenv(t_canvas *x);
+EXTERN void canvas_rename(t_canvas *x, t_symbol *s, t_symbol *dir);
+EXTERN void canvas_loadbang(t_canvas *x);
+EXTERN int canvas_hitbox(t_canvas *x, t_gobj *y, int xpos, int ypos,
+ int *x1p, int *y1p, int *x2p, int *y2p);
+
+/* ---- functions on canvasses as objects --------------------- */
+
+EXTERN void canvas_fattenforscalars(t_canvas *x,
+ int *x1, int *y1, int *x2, int *y2);
+EXTERN void canvas_visforscalars(t_canvas *x, t_glist *glist, int vis);
+EXTERN int canvas_clicksub(t_canvas *x, int xpix, int ypix, int shift,
+ int alt, int dbl, int doit);
+EXTERN t_glist *canvas_getglistonsuper(void);
+
+EXTERN void linetraverser_start(t_linetraverser *t, t_canvas *x);
+EXTERN t_outconnect *linetraverser_next(t_linetraverser *t);
+EXTERN void linetraverser_skipobject(t_linetraverser *t);
+
+/* --------------------- functions on tscalars --------------------- */
+
+EXTERN void tscalar_getrect(t_tscalar *x, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2);
+EXTERN void tscalar_vis(t_tscalar *x, t_glist *owner, int flag);
+EXTERN int tscalar_click(t_tscalar *x, int xpix, int ypix, int shift,
+ int alt, int dbl, int doit);
+
+/* --------- functions on garrays (graphical arrays) -------------------- */
+
+EXTERN t_template *garray_template(t_garray *x);
+
+/* -------------------- arrays --------------------- */
+EXTERN t_garray *graph_array(t_glist *gl, t_symbol *s, t_symbol *template,
+ t_floatarg f, t_floatarg saveit);
+EXTERN t_array *array_new(t_symbol *templatesym, t_gpointer *parent);
+EXTERN void array_resize(t_array *x, t_template *template, int n);
+EXTERN void array_free(t_array *x);
+
+/* --------------------- gpointers and stubs ---------------- */
+EXTERN t_gstub *gstub_new(t_glist *gl, t_array *a);
+EXTERN void gstub_cutoff(t_gstub *gs);
+EXTERN void gpointer_setglist(t_gpointer *gp, t_glist *glist, t_scalar *x);
+
+/* --------------------- scalars ------------------------- */
+EXTERN void word_init(t_word *wp, t_template *template, t_gpointer *gp);
+EXTERN void word_restore(t_word *wp, t_template *template,
+ int argc, t_atom *argv);
+EXTERN t_scalar *scalar_new(t_glist *owner,
+ t_symbol *templatesym);
+EXTERN void scalar_getbasexy(t_scalar *x, float *basex, float *basey);
+
+/* ------helper routines for "garrays" and "plots" -------------- */
+EXTERN int array_doclick(t_array *array, t_glist *glist, t_gobj *gobj,
+ t_symbol *elemtemplatesym,
+ float linewidth, float xloc, float xinc, float yloc,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit);
+
+EXTERN void array_getcoordinate(t_glist *glist,
+ char *elem, int xonset, int yonset, int wonset, int indx,
+ float basex, float basey, float xinc,
+ float *xp, float *yp, float *wp);
+
+EXTERN int array_getfields(t_symbol *elemtemplatesym,
+ t_canvas **elemtemplatecanvasp,
+ t_template **elemtemplatep, int *elemsizep,
+ int *xonsetp, int *yonsetp, int *wonsetp);
+
+/* --------------------- templates ------------------------- */
+EXTERN t_template *template_new(t_symbol *sym, int argc, t_atom *argv);
+EXTERN void template_free(t_template *x);
+EXTERN int template_match(t_template *x1, t_template *x2);
+EXTERN int template_find_field(t_template *x, t_symbol *name, int *p_onset,
+ int *p_type, t_symbol **p_arraytype);
+EXTERN t_float template_getfloat(t_template *x, t_symbol *fieldname, t_word *wp,
+ int loud);
+EXTERN void template_setfloat(t_template *x, t_symbol *fieldname, t_word *wp,
+ t_float f, int loud);
+EXTERN t_symbol *template_getsymbol(t_template *x, t_symbol *fieldname,
+ t_word *wp, int loud);
+EXTERN void template_setsymbol(t_template *x, t_symbol *fieldname,
+ t_word *wp, t_symbol *s, int loud);
+
+EXTERN t_template *gtemplate_get(t_gtemplate *x);
+EXTERN t_template *template_findbyname(t_symbol *s);
+EXTERN t_canvas *template_findcanvas(t_template *template);
+
+EXTERN t_float template_getfloat(t_template *x, t_symbol *fieldname,
+ t_word *wp, int loud);
+EXTERN void template_setfloat(t_template *x, t_symbol *fieldname,
+ t_word *wp, t_float f, int loud);
+EXTERN t_symbol *template_getsymbol(t_template *x, t_symbol *fieldname,
+ t_word *wp, int loud);
+EXTERN void template_setsymbol(t_template *x, t_symbol *fieldname,
+ t_word *wp, t_symbol *s, int loud);
+
+/* ----------------------- guiconnects, g_guiconnect.c --------- */
+EXTERN t_guiconnect *guiconnect_new(t_pd *who, t_symbol *sym);
+EXTERN void guiconnect_notarget(t_guiconnect *x, double timedelay);
diff --git a/include/ggee.h b/include/ggee.h
new file mode 100755
index 0000000..6882454
--- /dev/null
+++ b/include/ggee.h
@@ -0,0 +1,13 @@
+#ifndef __GGEXT_H__
+#define __GGEXT_H__
+
+
+
+#define BACKGROUND "-fill grey"
+#define BACKGROUNDCOLOR "grey"
+
+#ifndef PD_VERSION_MINOR
+#define PD_VERSION_MINOR 32
+#endif
+
+#endif
diff --git a/include/m_imp.h b/include/m_imp.h
new file mode 100755
index 0000000..9a76379
--- /dev/null
+++ b/include/m_imp.h
@@ -0,0 +1,222 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* This file contains function prototypes and data types used to implement
+Pd, but not shared with Pd objects. */
+
+#include "m_pd.h"
+
+/* LATER consider whether to use 'char' for method arg types to save space */
+
+/* the structure for a method handler ala Max */
+typedef struct _methodentry
+{
+ t_symbol *me_name;
+ t_gotfn me_fun;
+ t_atomtype me_arg[MAXPDARG+1];
+} t_methodentry;
+
+EXTERN_STRUCT _widgetbehavior;
+
+typedef void (*t_bangmethod)(t_pd *x);
+typedef void (*t_pointermethod)(t_pd *x, t_gpointer *gp);
+typedef void (*t_floatmethod)(t_pd *x, t_float f);
+typedef void (*t_symbolmethod)(t_pd *x, t_symbol *s);
+typedef void (*t_listmethod)(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+typedef void (*t_anymethod)(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+
+struct _class
+{
+ t_symbol *c_name; /* name (mostly for error reporting) */
+ t_symbol *c_helpname; /* name of help file */
+ size_t c_size; /* size of an instance */
+ t_methodentry *c_methods; /* methods other than bang, etc below */
+ int c_nmethod; /* number of methods */
+ t_method c_freemethod; /* function to call before freeing */
+ t_bangmethod c_bangmethod; /* common methods */
+ t_pointermethod c_pointermethod;
+ t_floatmethod c_floatmethod;
+ t_symbolmethod c_symbolmethod;
+ t_listmethod c_listmethod;
+ t_anymethod c_anymethod;
+ struct _widgetbehavior *c_wb; /* "gobjs" only */
+ struct _parentwidgetbehavior *c_pwb;/* widget behavior in parent */
+ int c_floatsignalin; /* onset to float for signal input */
+ char c_gobj; /* true if is a gobj */
+ char c_patchable; /* true if we have a t_object header */
+ char c_firstin; /* if patchable, true if draw first inlet */
+ char c_drawcommand; /* a drawing command for a template */
+};
+
+/* s_file.c */
+typedef struct _namelist
+{
+ struct _namelist *nl_next;
+ char *nl_string;
+} t_namelist;
+
+t_namelist *namelist_append(t_namelist *listwas, const char *s);
+void namelist_free(t_namelist *listwas);
+
+extern int sys_debuglevel;
+extern int sys_verbose;
+
+#define DEBUG_MESSUP 1 /* messages up from pd to pd-gui */
+#define DEBUG_MESSDOWN 2 /* messages down from pd-gui to pd */
+
+extern int sys_noloadbang;
+extern int sys_nogui;
+extern char *sys_guicmd;
+
+/* in s_main.c */
+EXTERN int sys_nearestfontsize(int fontsize);
+EXTERN int sys_hostfontsize(int fontsize);
+
+extern int sys_defaultfont;
+extern t_symbol *sys_libdir; /* library directory for auxilliary files */
+/* s_loader.c */
+int sys_load_lib(char *dirname, char *filename);
+
+/* s_unix.c */
+EXTERN void sys_microsleep(int microsec);
+EXTERN double sys_getrealtime(void);
+
+/* s_sgi.c, s_nt.c, s_linux.c each implement the same API for audio
+and MIDI I/O as follows: */
+
+#define DACBLKSIZE 64
+
+#define SENDDACS_NO 0 /* return values for sys_send_dacs() */
+#define SENDDACS_YES 1
+#define SENDDACS_SLEPT 2
+
+#define API_OSS 0 /* API choices */
+#define API_ALSA 1
+#define API_RME 2
+#define API_MMIO 3
+#define API_PORTAUDIO 4
+
+
+ /* MIDI input and output */
+#define MAXMIDIINDEV 16 /* max. number of input ports */
+#define MAXMIDIOUTDEV 16 /* max. number of output ports */
+extern int sys_nmidiin;
+extern int sys_nmidiout;
+extern int sys_midiindevlist[];
+extern int sys_midioutdevlist[];
+
+EXTERN void sys_putmidimess(int portno, int a, int b, int c);
+EXTERN void sys_putmidibyte(int portno, int a);
+EXTERN void sys_poll_midi(void);
+EXTERN void sys_setmiditimediff(double inbuftime, double outbuftime);
+EXTERN void sys_midibytein(int portno, int byte);
+
+extern int sys_hipriority; /* real-time flag, true if priority boosted */
+extern t_sample *sys_soundout;
+extern t_sample *sys_soundin;
+extern float sys_dacsr;
+extern int sys_schedadvance;
+extern int sys_sleepgrain;
+EXTERN void sys_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev,
+ int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev,
+ int srate); /* IOhannes */
+
+EXTERN void sys_close_audio(void);
+
+EXTERN void sys_open_midi(int nmidiin, int *midiinvec,
+ int nmidiout, int *midioutvec);
+EXTERN void sys_close_midi(void);
+
+EXTERN int sys_send_dacs(void);
+EXTERN void sys_reportidle(void);
+EXTERN void sys_set_priority(int higher);
+EXTERN void sys_audiobuf(int nbufs);
+EXTERN void sys_getmeters(float *inmax, float *outmax);
+
+ /* for NT and Linux, there are additional bits of fluff as follows. */
+#ifdef NT
+EXTERN void nt_listdevs(void);
+EXTERN void nt_soundindev(int which);
+EXTERN void nt_soundoutdev(int which);
+EXTERN void nt_midiindev(int which);
+EXTERN void nt_midioutdev(int which);
+EXTERN void nt_noresync( void);
+EXTERN void nt_set_sound_api(int which);
+#endif
+
+#ifdef __linux__
+ /* the following definitions allow you to switch at run time
+ between audio APIs in Linux and later in NT. */
+void linux_set_sound_api(int which);
+
+void linux_setfrags(int n);
+void linux_setfragsize(int n);
+void linux_streammode( void);
+void rme_soundindev(int which);
+void rme_soundoutdev(int which);
+void linux_alsa_queue_size(int size);
+#ifdef ALSA99 /* old fashioned ALSA */
+void linux_alsa_devno(int devno);
+#else
+void linux_alsa_devname(char *devname);
+#endif
+#endif /* __linux__ */
+
+/* portaudio, used in Windows and Mac versions... */
+
+int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin,
+ t_sample *soundout, int framesperbuf, int nbuffers, int deviceno);
+void pa_close_audio(void);
+int pa_send_dacs(void);
+void pa_reportidle(void);
+
+
+/* m_sched.c */
+EXTERN void sys_log_error(int type);
+#define ERR_NOTHING 0
+#define ERR_ADCSLEPT 1
+#define ERR_DACSLEPT 2
+#define ERR_RESYNC 3
+#define ERR_DATALATE 4
+
+/* s_inter.c */
+
+EXTERN void sys_bail(int exitcode);
+EXTERN int sys_pollgui(void);
+
+EXTERN_STRUCT _socketreceiver;
+#define t_socketreceiver struct _socketreceiver
+
+typedef void (*t_socketnotifier)(void *x);
+typedef void (*t_socketreceivefn)(void *x, t_binbuf *b);
+
+EXTERN t_socketreceiver *socketreceiver_new(void *owner,
+ t_socketnotifier notifier, t_socketreceivefn socketreceivefn, int udp);
+EXTERN void socketreceiver_read(t_socketreceiver *x, int fd);
+EXTERN void sys_sockerror(char *s);
+EXTERN void sys_closesocket(int fd);
+
+typedef void (*t_fdpollfn)(void *ptr, int fd);
+EXTERN void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr);
+EXTERN void sys_rmpollfn(int fd);
+#ifdef UNIX
+void sys_setalarm(int microsec);
+void sys_setvirtualalarm( void);
+#endif
+
+/* m_obj.c */
+EXTERN int obj_noutlets(t_object *x);
+EXTERN int obj_ninlets(t_object *x);
+EXTERN t_outconnect *obj_starttraverseoutlet(t_object *x, t_outlet **op,
+ int nout);
+EXTERN t_outconnect *obj_nexttraverseoutlet(t_outconnect *lastconnect,
+ t_object **destp, t_inlet **inletp, int *whichp);
+EXTERN t_outconnect *obj_connect(t_object *source, int outno,
+ t_object *sink, int inno);
+EXTERN void obj_disconnect(t_object *source, int outno, t_object *sink,
+ int inno);
+EXTERN void outlet_setstacklim(void);
+/* misc */
+EXTERN void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir);
+EXTERN void glob_initfromgui(void *dummy, t_symbol *s, int argc, t_atom *argv);
diff --git a/include/m_pd.h b/include/m_pd.h
new file mode 100755
index 0000000..ae53cfd
--- /dev/null
+++ b/include/m_pd.h
@@ -0,0 +1,592 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifdef NT
+// #pragma warning( disable : 4091 )
+#pragma warning( disable : 4305 ) /* uncast const double to float */
+#pragma warning( disable : 4244 ) /* uncast float/int conversion etc. */
+#pragma warning( disable : 4101 ) /* unused automatic variables */
+#endif /* NT */
+
+ /* the external storage class is "extern" in UNIX; in NT it's ugly. */
+#ifdef NT
+#ifdef PD_INTERNAL
+#define EXTERN __declspec(dllexport) extern
+#else
+#define EXTERN __declspec(dllimport) extern
+#endif /* PD_INTERNAL */
+#else
+#define EXTERN extern
+#endif /* NT */
+
+ /* and depending on the compiler, hidden data structures are
+ declared differently: */
+#ifdef __GNUC__
+#define EXTERN_STRUCT struct
+#else
+#define EXTERN_STRUCT extern struct
+#endif
+
+
+#if !defined(_SIZE_T) && !defined(_SIZE_T_)
+#include <stddef.h> /* just for size_t -- how lame! */
+#endif
+
+#define MAXPDSTRING 1000 /* use this for anything you want */
+#define MAXPDARG 5 /* max number of args we can typecheck today */
+
+ /* signed and unsigned integer types the size of a pointer: */
+#ifdef __alpha__
+typedef long t_int;
+#else
+typedef int t_int;
+#endif
+
+typedef float t_float; /* a floating-point number at most the same size */
+typedef float t_floatarg; /* floating-point type for function calls */
+
+typedef struct _symbol
+{
+ char *s_name;
+ struct _class **s_thing;
+ struct _symbol *s_next;
+} t_symbol;
+
+EXTERN_STRUCT _array;
+#define t_array struct _array /* g_canvas.h */
+
+/* pointers to glist and array elements go through a "stub" which sticks
+around after the glist or array is freed. The stub itself is deleted when
+both the glist/array is gone and the refcount is zero, ensuring that no
+gpointers are pointing here. */
+
+#define GP_NONE 0 /* the stub points nowhere (has been cut off) */
+#define GP_GLIST 1 /* the stub points to a glist element */
+#define GP_ARRAY 2 /* ... or array */
+
+typedef struct _gstub
+{
+ union
+ {
+ struct _glist *gs_glist; /* glist we're in */
+ struct _array *gs_array; /* array we're in */
+ } gs_un;
+ int gs_which; /* GP_GLIST/GP_ARRAY */
+ int gs_refcount; /* number of gpointers pointing here */
+} t_gstub;
+
+typedef struct _gpointer /* pointer to a gobj in a glist */
+{
+ union
+ {
+ struct _scalar *gp_scalar; /* scalar we're in (if glist) */
+ union word *gp_w; /* raw data (if array) */
+ } gp_un;
+ int gp_valid; /* number which must match gpointee */
+ t_gstub *gp_stub; /* stub which points to glist/array */
+} t_gpointer;
+
+typedef union word
+{
+ t_float w_float;
+ t_symbol *w_symbol;
+ t_gpointer *w_gpointer;
+ t_array *w_array;
+ struct _glist *w_list;
+ int w_index;
+} t_word;
+
+typedef enum
+{
+ A_NULL,
+ A_FLOAT,
+ A_SYMBOL,
+ A_POINTER,
+ A_SEMI,
+ A_COMMA,
+ A_DEFFLOAT,
+ A_DEFSYM,
+ A_DOLLAR,
+ A_DOLLSYM,
+ A_GIMME,
+ A_CANT
+} t_atomtype;
+
+#define A_DEFSYMBOL A_DEFSYM /* better name for this */
+
+typedef struct _atom
+{
+ t_atomtype a_type;
+ union word a_w;
+} t_atom;
+
+EXTERN_STRUCT _class;
+#define t_class struct _class
+
+EXTERN_STRUCT _outlet;
+#define t_outlet struct _outlet
+
+EXTERN_STRUCT _inlet;
+#define t_inlet struct _inlet
+
+EXTERN_STRUCT _binbuf;
+#define t_binbuf struct _binbuf
+
+EXTERN_STRUCT _clock;
+#define t_clock struct _clock
+
+EXTERN_STRUCT _outconnect;
+#define t_outconnect struct _outconnect
+
+EXTERN_STRUCT _glist;
+#define t_glist struct _glist
+#define t_canvas struct _glist /* LATER lose this */
+
+typedef t_class *t_pd; /* pure datum: nothing but a class pointer */
+
+typedef struct _gobj /* a graphical object */
+{
+ t_pd g_pd; /* pure datum header (class) */
+ struct _gobj *g_next; /* next in list */
+} t_gobj;
+
+typedef struct _scalar /* a graphical object holding data */
+{
+ t_gobj sc_gobj; /* header for graphical object */
+ t_symbol *sc_template; /* template name (LATER replace with pointer) */
+ t_word sc_vec[1]; /* indeterminate-length array of words */
+} t_scalar;
+
+typedef struct _text /* patchable object - graphical, with text */
+{
+ t_gobj te_g; /* header for graphical object */
+ t_binbuf *te_binbuf; /* holder for the text */
+ t_outlet *te_outlet; /* linked list of outlets */
+ t_inlet *te_inlet; /* linked list of inlets */
+ short te_xpix; /* x&y location (within the toplevel) */
+ short te_ypix;
+ short te_width; /* requested width in chars, 0 if auto */
+ unsigned int te_type:2; /* from defs below */
+} t_text;
+
+#define T_TEXT 0 /* just a textual comment */
+#define T_OBJECT 1 /* a MAX style patchable object */
+#define T_MESSAGE 2 /* a MAX stype message */
+#define T_ATOM 3 /* a cell to display a number or symbol */
+
+#define te_pd te_g.g_pd
+
+ /* t_object is synonym for t_text (LATER unify them) */
+
+typedef struct _text t_object;
+
+#define ob_outlet te_outlet
+#define ob_inlet te_inlet
+#define ob_binbuf te_binbuf
+#define ob_pd te_g.g_pd
+#define ob_g te_g
+
+typedef void (*t_method)(void);
+typedef void *(*t_newmethod)( void);
+typedef void (*t_gotfn)(void *x, ...);
+
+/* ---------------- pre-defined objects and symbols --------------*/
+EXTERN t_pd pd_objectmaker; /* factory for creating "object" boxes */
+EXTERN t_pd pd_canvasmaker; /* factory for creating canvases */
+EXTERN t_symbol s_pointer;
+EXTERN t_symbol s_float;
+EXTERN t_symbol s_symbol;
+EXTERN t_symbol s_bang;
+EXTERN t_symbol s_list;
+EXTERN t_symbol s_anything;
+EXTERN t_symbol s_signal;
+EXTERN t_symbol s__N;
+EXTERN t_symbol s__X;
+EXTERN t_symbol s_x;
+EXTERN t_symbol s_y;
+EXTERN t_symbol s_;
+
+/* --------- prototypes from the central message system ----------- */
+EXTERN void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void pd_forwardmess(t_pd *x, int argc, t_atom *argv);
+EXTERN t_symbol *gensym(char *s);
+EXTERN t_gotfn getfn(t_pd *x, t_symbol *s);
+EXTERN t_gotfn zgetfn(t_pd *x, t_symbol *s);
+EXTERN void nullfn(void);
+EXTERN void pd_vmess(t_pd *x, t_symbol *s, char *fmt, ...);
+#define mess0(x, s) ((*getfn((x), (s)))((x)))
+#define mess1(x, s, a) ((*getfn((x), (s)))((x), (a)))
+#define mess2(x, s, a,b) ((*getfn((x), (s)))((x), (a),(b)))
+#define mess3(x, s, a,b,c) ((*getfn((x), (s)))((x), (a),(b),(c)))
+#define mess4(x, s, a,b,c,d) ((*getfn((x), (s)))((x), (a),(b),(c),(d)))
+#define mess5(x, s, a,b,c,d,e) ((*getfn((x), (s)))((x), (a),(b),(c),(d),(e)))
+void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv);
+
+/* --------------- memory management -------------------- */
+EXTERN void *getbytes(size_t nbytes);
+EXTERN void *getzbytes(size_t nbytes);
+EXTERN void *copybytes(void *src, size_t nbytes);
+EXTERN void freebytes(void *x, size_t nbytes);
+EXTERN void *resizebytes(void *x, size_t oldsize, size_t newsize);
+
+/* -------------------- atoms ----------------------------- */
+
+#define SETSEMI(atom) ((atom)->a_type = A_SEMI, (atom)->a_w.w_index = 0)
+#define SETCOMMA(atom) ((atom)->a_type = A_COMMA, (atom)->a_w.w_index = 0)
+#define SETPOINTER(atom, gp) ((atom)->a_type = A_POINTER, \
+ (atom)->a_w.w_gpointer = (gp))
+#define SETFLOAT(atom, f) ((atom)->a_type = A_FLOAT, (atom)->a_w.w_float = (f))
+#define SETSYMBOL(atom, s) ((atom)->a_type = A_SYMBOL, \
+ (atom)->a_w.w_symbol = (s))
+#define SETDOLLAR(atom, n) ((atom)->a_type = A_DOLLAR, \
+ (atom)->a_w.w_index = (n))
+#define SETDOLLSYM(atom, s) ((atom)->a_type = A_DOLLSYM, \
+ (atom)->a_w.w_symbol= (s))
+
+EXTERN t_float atom_getfloat(t_atom *a);
+EXTERN t_int atom_getint(t_atom *a);
+EXTERN t_symbol *atom_getsymbol(t_atom *a);
+EXTERN t_symbol *atom_gensym(t_atom *a);
+EXTERN t_float atom_getfloatarg(int which, int argc, t_atom *argv);
+EXTERN t_int atom_getintarg(int which, int argc, t_atom *argv);
+EXTERN t_symbol *atom_getsymbolarg(int which, int argc, t_atom *argv);
+
+EXTERN void atom_string(t_atom *a, char *buf, unsigned int bufsize);
+
+/* ------------------ binbufs --------------- */
+
+EXTERN t_binbuf *binbuf_new(void);
+EXTERN void binbuf_free(t_binbuf *x);
+
+EXTERN void binbuf_text(t_binbuf *x, char *text, size_t size);
+EXTERN void binbuf_gettext(t_binbuf *x, char **bufp, int *lengthp);
+EXTERN void binbuf_clear(t_binbuf *x);
+EXTERN void binbuf_add(t_binbuf *x, int argc, t_atom *argv);
+EXTERN void binbuf_addv(t_binbuf *x, char *fmt, ...);
+EXTERN void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y);
+EXTERN void binbuf_addsemi(t_binbuf *x);
+EXTERN void binbuf_restore(t_binbuf *x, int argc, t_atom *argv);
+EXTERN void binbuf_print(t_binbuf *x);
+EXTERN int binbuf_getnatom(t_binbuf *x);
+EXTERN t_atom *binbuf_getvec(t_binbuf *x);
+EXTERN void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv);
+EXTERN int binbuf_read(t_binbuf *b, char *filename, char *dirname,
+ int crflag);
+EXTERN int binbuf_read_via_path(t_binbuf *b, char *filename, char *dirname,
+ int crflag);
+EXTERN int binbuf_write(t_binbuf *x, char *filename, char *dir,
+ int crflag);
+EXTERN void binbuf_evalfile(t_symbol *name, t_symbol *dir);
+
+/* ------------------ clocks --------------- */
+
+EXTERN t_clock *clock_new(void *owner, t_method fn);
+EXTERN void clock_set(t_clock *x, double systime);
+EXTERN void clock_delay(t_clock *x, double delaytime);
+EXTERN void clock_unset(t_clock *x);
+EXTERN double clock_getlogicaltime(void);
+EXTERN double clock_getsystime(void); /* OBSOLETE; use clock_getlogicaltime() */
+EXTERN double clock_gettimesince(double prevsystime);
+EXTERN double clock_getsystimeafter(double delaytime);
+EXTERN void clock_free(t_clock *x);
+
+/* ----------------- pure data ---------------- */
+EXTERN t_pd *pd_new(t_class *cls);
+EXTERN void pd_free(t_pd *x);
+EXTERN void pd_bind(t_pd *x, t_symbol *s);
+EXTERN void pd_unbind(t_pd *x, t_symbol *s);
+EXTERN t_pd *pd_findbyclass(t_symbol *s, t_class *c);
+EXTERN void pd_pushsym(t_pd *x);
+EXTERN void pd_popsym(t_pd *x);
+EXTERN t_symbol *pd_getfilename(void);
+EXTERN t_symbol *pd_getdirname(void);
+EXTERN void pd_bang(t_pd *x);
+EXTERN void pd_pointer(t_pd *x, t_gpointer *gp);
+EXTERN void pd_float(t_pd *x, t_float f);
+EXTERN void pd_symbol(t_pd *x, t_symbol *s);
+EXTERN void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void pd_anything(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+#define pd_class(x) (*(x))
+
+/* ----------------- pointers ---------------- */
+EXTERN void gpointer_init(t_gpointer *gp);
+EXTERN void gpointer_copy(const t_gpointer *gpfrom, t_gpointer *gpto);
+EXTERN void gpointer_unset(t_gpointer *gp);
+EXTERN int gpointer_check(const t_gpointer *gp, int headok);
+
+/* ----------------- patchable "objects" -------------- */
+EXTERN_STRUCT _inlet;
+#define t_inlet struct _inlet
+EXTERN_STRUCT _outlet;
+#define t_outlet struct _outlet
+
+EXTERN t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1,
+ t_symbol *s2);
+EXTERN t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp);
+EXTERN t_inlet *floatinlet_new(t_object *owner, t_float *fp);
+EXTERN t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp);
+EXTERN void inlet_free(t_inlet *x);
+
+EXTERN t_outlet *outlet_new(t_object *owner, t_symbol *s);
+EXTERN void outlet_bang(t_outlet *x);
+EXTERN void outlet_pointer(t_outlet *x, t_gpointer *gp);
+EXTERN void outlet_float(t_outlet *x, t_float f);
+EXTERN void outlet_symbol(t_outlet *x, t_symbol *s);
+EXTERN void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void outlet_free(t_outlet *x);
+EXTERN t_object *pd_checkobject(t_pd *x);
+
+
+/* -------------------- canvases -------------- */
+
+EXTERN void glob_setfilename(void *dummy, t_symbol *name, t_symbol *dir);
+
+EXTERN void canvas_setargs(int argc, t_atom *argv);
+EXTERN t_atom *canvas_getarg(int which);
+EXTERN t_symbol *canvas_getcurrentdir(void);
+EXTERN t_glist *canvas_getcurrent(void);
+EXTERN void canvas_makefilename(t_glist *c, char *file,
+ char *result,int resultsize);
+EXTERN t_symbol *canvas_getdir(t_glist *x);
+EXTERN int sys_fontwidth(int fontsize);
+EXTERN int sys_fontheight(int fontsize);
+EXTERN void canvas_dataproperties(t_glist *x, t_scalar *sc, t_binbuf *b);
+
+/* ---------------- widget behaviors ---------------------- */
+
+EXTERN_STRUCT _widgetbehavior;
+#define t_widgetbehavior struct _widgetbehavior
+
+EXTERN_STRUCT _parentwidgetbehavior;
+#define t_parentwidgetbehavior struct _parentwidgetbehavior
+EXTERN t_parentwidgetbehavior *pd_getparentwidget(t_pd *x);
+
+/* -------------------- classes -------------- */
+
+#define CLASS_DEFAULT 0 /* flags for new classes below */
+#define CLASS_PD 1
+#define CLASS_GOBJ 2
+#define CLASS_PATCHABLE 3
+#define CLASS_NOINLET 8
+
+#define CLASS_TYPEMASK 3
+
+
+EXTERN t_class *class_new(t_symbol *name, t_newmethod newmethod,
+ t_method freemethod, size_t size, int flags, t_atomtype arg1, ...);
+EXTERN void class_addcreator(t_newmethod newmethod, t_symbol *s,
+ t_atomtype type1, ...);
+EXTERN void class_addmethod(t_class *c, t_method fn, t_symbol *sel,
+ t_atomtype arg1, ...);
+EXTERN void class_addbang(t_class *c, t_method fn);
+EXTERN void class_addpointer(t_class *c, t_method fn);
+EXTERN void class_doaddfloat(t_class *c, t_method fn);
+EXTERN void class_addsymbol(t_class *c, t_method fn);
+EXTERN void class_addlist(t_class *c, t_method fn);
+EXTERN void class_addanything(t_class *c, t_method fn);
+EXTERN void class_sethelpsymbol(t_class *c, t_symbol *s);
+EXTERN void class_setwidget(t_class *c, t_widgetbehavior *w);
+EXTERN void class_setparentwidget(t_class *c, t_parentwidgetbehavior *w);
+EXTERN t_parentwidgetbehavior *class_parentwidget(t_class *c);
+EXTERN char *class_getname(t_class *c);
+EXTERN char *class_gethelpname(t_class *c);
+EXTERN void class_setdrawcommand(t_class *c);
+EXTERN int class_isdrawcommand(t_class *c);
+EXTERN void class_domainsignalin(t_class *c, int onset);
+#define CLASS_MAINSIGNALIN(c, type, field) \
+ class_domainsignalin(c, (char *)(&((type *)0)->field) - (char *)0)
+
+#ifndef PD_CLASS_DEF
+#define class_addbang(x, y) class_addbang((x), (t_method)(y))
+#define class_addpointer(x, y) class_addpointer((x), (t_method)(y))
+#define class_addfloat(x, y) class_doaddfloat((x), (t_method)(y))
+#define class_addsymbol(x, y) class_addsymbol((x), (t_method)(y))
+#define class_addlist(x, y) class_addlist((x), (t_method)(y))
+#define class_addanything(x, y) class_addanything((x), (t_method)(y))
+#endif
+
+/* ------------ printing --------------------------------- */
+EXTERN void post(char *fmt, ...);
+EXTERN void startpost(char *fmt, ...);
+EXTERN void poststring(char *s);
+EXTERN void postfloat(float f);
+EXTERN void postatom(int argc, t_atom *argv);
+EXTERN void endpost(void);
+EXTERN void error(char *fmt, ...);
+EXTERN void bug(char *fmt, ...);
+EXTERN void pd_error(void *object, char *fmt, ...);
+EXTERN void sys_logerror(char *object, char *s);
+EXTERN void sys_unixerror(char *object);
+EXTERN void sys_ouch(void);
+
+#ifdef __linux__
+EXTERN char* sys_get_path( void);
+#endif
+EXTERN void sys_addpath(const char* p);
+
+
+/* ------------ system interface routines ------------------- */
+EXTERN int sys_isreadablefile(const char *name);
+EXTERN void sys_bashfilename(const char *from, char *to);
+EXTERN void sys_unbashfilename(const char *from, char *to);
+EXTERN int open_via_path(const char *name, const char *ext, const char *dir,
+ char *dirresult, char **nameresult, unsigned int size, int bin);
+
+/* --------------- signals ----------------------------------- */
+
+typedef float t_sample;
+#define MAXLOGSIG 32
+#define MAXSIGSIZE (1 << MAXLOGSIG)
+
+typedef struct _signal
+{
+ int s_n; /* number of points in the array */
+ t_sample *s_vec; /* the array */
+ float s_sr; /* sample rate */
+ int s_refcount; /* number of times used */
+ int s_isborrowed; /* whether we're going to borrow our array */
+ struct _signal *s_borrowedfrom; /* signal to borrow it from */
+ struct _signal *s_nextfree; /* next in freelist */
+ struct _signal *s_nextused; /* next in used list */
+} t_signal;
+
+
+typedef t_int *(*t_perfroutine)(t_int *args);
+
+EXTERN t_int *plus_perform(t_int *args);
+EXTERN t_int *zero_perform(t_int *args);
+EXTERN t_int *copy_perform(t_int *args);
+
+EXTERN void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n);
+EXTERN void dsp_add_copy(t_sample *in, t_sample *out, int n);
+EXTERN void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n);
+EXTERN void dsp_add_zero(t_sample *out, int n);
+
+EXTERN int sys_getblksize(void);
+EXTERN float sys_getsr(void);
+EXTERN int sys_get_inchannels(void);
+EXTERN int sys_get_outchannels(void);
+
+EXTERN void dsp_add(t_perfroutine f, int n, ...);
+EXTERN void dsp_addv(t_perfroutine f, int n, t_int *vec);
+EXTERN void pd_fft(float *buf, int npoints, int inverse);
+EXTERN int ilog2(int n);
+
+EXTERN void mayer_fht(float *fz, int n);
+EXTERN void mayer_fft(int n, float *real, float *imag);
+EXTERN void mayer_ifft(int n, float *real, float *imag);
+EXTERN void mayer_realfft(int n, float *real);
+EXTERN void mayer_realifft(int n, float *real);
+
+EXTERN float *cos_table;
+#define LOGCOSTABSIZE 9
+#define COSTABSIZE (1<<LOGCOSTABSIZE)
+
+EXTERN int canvas_suspend_dsp(void);
+EXTERN void canvas_resume_dsp(int oldstate);
+EXTERN void canvas_update_dsp(void);
+
+/* IOhannes { (up/downsampling) */
+typedef struct _resample
+{
+ int method; /* up/downsampling method ID */
+
+ t_int downsample; /* downsampling factor */
+ t_int upsample; /* upsampling factor */
+
+ t_float *s_vec; /* here we hold the resampled data */
+ int s_n;
+
+ t_float *coeffs; /* coefficients for filtering... */
+ int coefsize;
+
+ t_float *buffer; /* buffer for filtering */
+ int bufsize;
+} t_resample;
+
+EXTERN void resample_init(t_resample *x);
+EXTERN void resample_free(t_resample *x);
+
+EXTERN void resample_dsp(t_resample *x, t_sample *in, int insize, t_sample *out, int outsize, int method);
+EXTERN void resamplefrom_dsp(t_resample *x, t_sample *in, int insize, int outsize, int method);
+EXTERN void resampleto_dsp(t_resample *x, t_sample *out, int insize, int outsize, int method);
+/* } IOhannes */
+
+/* ----------------------- utility functions for signals -------------- */
+EXTERN float mtof(float);
+EXTERN float ftom(float);
+EXTERN float rmstodb(float);
+EXTERN float powtodb(float);
+EXTERN float dbtorms(float);
+EXTERN float dbtopow(float);
+
+EXTERN float q8_sqrt(float);
+EXTERN float q8_rsqrt(float);
+#ifndef N32
+EXTERN float qsqrt(float); /* old names kept for extern compatibility */
+EXTERN float qrsqrt(float);
+#endif
+/* --------------------- data --------------------------------- */
+
+ /* graphical arrays */
+EXTERN_STRUCT _garray;
+#define t_garray struct _garray
+
+EXTERN t_class *garray_class;
+EXTERN int garray_getfloatarray(t_garray *x, int *size, t_float **vec);
+EXTERN float garray_get(t_garray *x, t_symbol *s, t_int indx);
+EXTERN void garray_redraw(t_garray *x);
+EXTERN int garray_npoints(t_garray *x);
+EXTERN char *garray_vec(t_garray *x);
+EXTERN void garray_resize(t_garray *x, t_floatarg f);
+EXTERN void garray_usedindsp(t_garray *x);
+EXTERN void garray_setsaveit(t_garray *x, int saveit);
+EXTERN t_class *scalar_class;
+
+EXTERN t_float *value_get(t_symbol *s);
+EXTERN void value_release(t_symbol *s);
+EXTERN int value_getfloat(t_symbol *s, t_float *f);
+EXTERN int value_setfloat(t_symbol *s, t_float f);
+
+/* ------- GUI interface - functions to send strings to TK --------- */
+EXTERN void sys_vgui(char *fmt, ...);
+EXTERN void sys_gui(char *s);
+
+EXTERN void gfxstub_new(t_pd *owner, void *key, const char *cmd);
+EXTERN void gfxstub_deleteforkey(void *key);
+
+/*------------- Max 0.26 compatibility --------------------*/
+
+/* the following reflects the new way classes are laid out, with the class
+ pointing to the messlist and not vice versa. Externs shouldn't feel it. */
+typedef t_class *t_externclass;
+
+EXTERN void c_extern(t_externclass *cls, t_newmethod newroutine,
+ t_method freeroutine, t_symbol *name, size_t size, int tiny, \
+ t_atomtype arg1, ...);
+EXTERN void c_addmess(t_method fn, t_symbol *sel, t_atomtype arg1, ...);
+
+#define t_getbytes getbytes
+#define t_freebytes freebytes
+#define t_resizebytes resizebytes
+#define typedmess pd_typedmess
+#define vmess pd_vmess
+
+#ifdef MACOSX
+#define cabs() smerdyakov(void)
+#endif
+
+/* A definition to help gui objects straddle 0.34-0.35 changes. If this is
+defined, there is a "te_xpix" field in objects, not a "te_xpos" as before: */
+
+#define PD_USE_TE_XPIX
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif
diff --git a/install b/install
new file mode 100644
index 0000000..bf92264
--- /dev/null
+++ b/install
@@ -0,0 +1,77 @@
+
+
+For the copyright notice read the file LICENCE.txt.
+I would like to be notified if you use this code, change it for your own
+project or would like to have some improvement. I will even accept patches
+if the don't break anything.
+
+
+Installation Instructions for ggee
+===================================
+
+To compile ggee under Linux and IRIX:
+
+Unpack ggee.**.tar.gz (you have already done that).
+
+cd to the ggee directory and type
+
+"configure" followed by
+"make" for building single externals
+"make ggext" for building the "classical" ggext library.
+
+that should do it for Linux. Any other platform I haven't tested
+yet, and I would like to hear how the compilation works there.
+
+For building on NT, use the build.bat script.
+Before doing that, take a look if there are some dll's hanging around,
+I may have included them.
+
+
+*****NEW****
+ggee now comes with support for pd-0.32. If you want to compile ggee for
+earlier versions of pd, copy the files m_pd.h, m_imp.h and !! g_canvas.h
+to the ggee "include" directory and configure with
+
+./configure --with-minor-version=30
+
+
+
+STK external (with STK 3.2)
+=============
+
+Get the STK toolkit from:
+
+<http://www-ccrma.stanford.edu/CCRMA/Software/STK/>
+
+To use the stk object, you have to download Perry Cooks STK toolkit.
+Unpack it besides ggee.
+
+Then you have to remove the file stk/include/Object.h
+
+call configure with
+ configure --with-stk=../stk
+
+and then do a make.
+
+ and finally, as stk needs some sound samples, you have to call
+
+make install_stk
+
+ as root.
+
+
+Usage
+======
+
+To use the ggext library within pd you have to load it with the "-lib" switch. (see pd -help)
+If you built the single externals you can copy them either to a common place and use the
+"-path" option for pd (e.g. copy them to /usr/lib/pd/externs and call pd like
+"pd -path /usr/lib/pd/externs". Or, you can just put them into the same
+directory as you put the patches which use them.
+
+make install by default puts either ggext.pd_linux or all the single externals into /usr/lib/pd/externs.
+
+You can put these default options into your ".pdrc" file.
+
+
+Guenter <geiger@epy.co.at>
diff --git a/install-sh b/install-sh
new file mode 100644
index 0000000..7dc2f28
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/license.txt b/license.txt
new file mode 100644
index 0000000..36d724e
--- /dev/null
+++ b/license.txt
@@ -0,0 +1,31 @@
+This software is copyrighted by Guenter Geiger and others. The following
+terms apply to all files associated with the software unless explicitly
+disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+RESTRICTED RIGHTS: Use, duplication or disclosure by the government
+is subject to the restrictions as set forth in subparagraph (c) (1) (ii)
+of the Rights in Technical Data and Computer Software Clause as DFARS
+252.227-7013 and FAR 52.227-19.
diff --git a/m_pd.h b/m_pd.h
new file mode 100644
index 0000000..f85aae6
--- /dev/null
+++ b/m_pd.h
@@ -0,0 +1,592 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifdef NT
+// #pragma warning( disable : 4091 )
+#pragma warning( disable : 4305 ) /* uncast const double to float */
+#pragma warning( disable : 4244 ) /* uncast float/int conversion etc. */
+#pragma warning( disable : 4101 ) /* unused automatic variables */
+#endif /* NT */
+
+ /* the external storage class is "extern" in UNIX; in NT it's ugly. */
+#ifdef NT
+#ifdef PD_INTERNAL
+#define EXTERN __declspec(dllexport) extern
+#else
+#define EXTERN __declspec(dllimport) extern
+#endif /* PD_INTERNAL */
+#else
+#define EXTERN extern
+#endif /* NT */
+
+ /* and depending on the compiler, hidden data structures are
+ declared differently: */
+#ifdef __GNUC__
+#define EXTERN_STRUCT struct
+#else
+#define EXTERN_STRUCT extern struct
+#endif
+
+
+#if !defined(_SIZE_T) && !defined(_SIZE_T_)
+#include <stddef.h> /* just for size_t -- how lame! */
+#endif
+
+#define MAXPDSTRING 1000 /* use this for anything you want */
+#define MAXPDARG 5 /* max number of args we can typecheck today */
+
+ /* signed and unsigned integer types the size of a pointer: */
+#ifdef __alpha__
+typedef long t_int;
+#else
+typedef int t_int;
+#endif
+
+typedef float t_float; /* a floating-point number at most the same size */
+typedef float t_floatarg; /* floating-point type for function calls */
+
+typedef struct _symbol
+{
+ char *s_name;
+ struct _class **s_thing;
+ struct _symbol *s_next;
+} t_symbol;
+
+EXTERN_STRUCT _array;
+#define t_array struct _array /* g_canvas.h */
+
+/* pointers to glist and array elements go through a "stub" which sticks
+around after the glist or array is freed. The stub itself is deleted when
+both the glist/array is gone and the refcount is zero, ensuring that no
+gpointers are pointing here. */
+
+#define GP_NONE 0 /* the stub points nowhere (has been cut off) */
+#define GP_GLIST 1 /* the stub points to a glist element */
+#define GP_ARRAY 2 /* ... or array */
+
+typedef struct _gstub
+{
+ union
+ {
+ struct _glist *gs_glist; /* glist we're in */
+ struct _array *gs_array; /* array we're in */
+ } gs_un;
+ int gs_which; /* GP_GLIST/GP_ARRAY */
+ int gs_refcount; /* number of gpointers pointing here */
+} t_gstub;
+
+typedef struct _gpointer /* pointer to a gobj in a glist */
+{
+ union
+ {
+ struct _scalar *gp_scalar; /* scalar we're in (if glist) */
+ union word *gp_w; /* raw data (if array) */
+ } gp_un;
+ int gp_valid; /* number which must match gpointee */
+ t_gstub *gp_stub; /* stub which points to glist/array */
+} t_gpointer;
+
+typedef union word
+{
+ t_float w_float;
+ t_symbol *w_symbol;
+ t_gpointer *w_gpointer;
+ t_array *w_array;
+ struct _glist *w_list;
+ int w_index;
+} t_word;
+
+typedef enum
+{
+ A_NULL,
+ A_FLOAT,
+ A_SYMBOL,
+ A_POINTER,
+ A_SEMI,
+ A_COMMA,
+ A_DEFFLOAT,
+ A_DEFSYM,
+ A_DOLLAR,
+ A_DOLLSYM,
+ A_GIMME,
+ A_CANT
+} t_atomtype;
+
+#define A_DEFSYMBOL A_DEFSYM /* better name for this */
+
+typedef struct _atom
+{
+ t_atomtype a_type;
+ union word a_w;
+} t_atom;
+
+EXTERN_STRUCT _class;
+#define t_class struct _class
+
+EXTERN_STRUCT _outlet;
+#define t_outlet struct _outlet
+
+EXTERN_STRUCT _inlet;
+#define t_inlet struct _inlet
+
+EXTERN_STRUCT _binbuf;
+#define t_binbuf struct _binbuf
+
+EXTERN_STRUCT _clock;
+#define t_clock struct _clock
+
+EXTERN_STRUCT _outconnect;
+#define t_outconnect struct _outconnect
+
+EXTERN_STRUCT _glist;
+#define t_glist struct _glist
+#define t_canvas struct _glist /* LATER lose this */
+
+typedef t_class *t_pd; /* pure datum: nothing but a class pointer */
+
+typedef struct _gobj /* a graphical object */
+{
+ t_pd g_pd; /* pure datum header (class) */
+ struct _gobj *g_next; /* next in list */
+} t_gobj;
+
+typedef struct _scalar /* a graphical object holding data */
+{
+ t_gobj sc_gobj; /* header for graphical object */
+ t_symbol *sc_template; /* template name (LATER replace with pointer) */
+ t_word sc_vec[1]; /* indeterminate-length array of words */
+} t_scalar;
+
+typedef struct _text /* patchable object - graphical, with text */
+{
+ t_gobj te_g; /* header for graphical object */
+ t_binbuf *te_binbuf; /* holder for the text */
+ t_outlet *te_outlet; /* linked list of outlets */
+ t_inlet *te_inlet; /* linked list of inlets */
+ short te_xpix; /* x&y location (within the toplevel) */
+ short te_ypix;
+ short te_width; /* requested width in chars, 0 if auto */
+ unsigned int te_type:2; /* from defs below */
+} t_text;
+
+#define T_TEXT 0 /* just a textual comment */
+#define T_OBJECT 1 /* a MAX style patchable object */
+#define T_MESSAGE 2 /* a MAX stype message */
+#define T_ATOM 3 /* a cell to display a number or symbol */
+
+#define te_pd te_g.g_pd
+
+ /* t_object is synonym for t_text (LATER unify them) */
+
+typedef struct _text t_object;
+
+#define ob_outlet te_outlet
+#define ob_inlet te_inlet
+#define ob_binbuf te_binbuf
+#define ob_pd te_g.g_pd
+#define ob_g te_g
+
+typedef void (*t_method)(void);
+typedef void *(*t_newmethod)( void);
+typedef void (*t_gotfn)(void *x, ...);
+
+/* ---------------- pre-defined objects and symbols --------------*/
+EXTERN t_pd pd_objectmaker; /* factory for creating "object" boxes */
+EXTERN t_pd pd_canvasmaker; /* factory for creating canvases */
+EXTERN t_symbol s_pointer;
+EXTERN t_symbol s_float;
+EXTERN t_symbol s_symbol;
+EXTERN t_symbol s_bang;
+EXTERN t_symbol s_list;
+EXTERN t_symbol s_anything;
+EXTERN t_symbol s_signal;
+EXTERN t_symbol s__N;
+EXTERN t_symbol s__X;
+EXTERN t_symbol s_x;
+EXTERN t_symbol s_y;
+EXTERN t_symbol s_;
+
+/* --------- prototypes from the central message system ----------- */
+EXTERN void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void pd_forwardmess(t_pd *x, int argc, t_atom *argv);
+EXTERN t_symbol *gensym(char *s);
+EXTERN t_gotfn getfn(t_pd *x, t_symbol *s);
+EXTERN t_gotfn zgetfn(t_pd *x, t_symbol *s);
+EXTERN void nullfn(void);
+EXTERN void pd_vmess(t_pd *x, t_symbol *s, char *fmt, ...);
+#define mess0(x, s) ((*getfn((x), (s)))((x)))
+#define mess1(x, s, a) ((*getfn((x), (s)))((x), (a)))
+#define mess2(x, s, a,b) ((*getfn((x), (s)))((x), (a),(b)))
+#define mess3(x, s, a,b,c) ((*getfn((x), (s)))((x), (a),(b),(c)))
+#define mess4(x, s, a,b,c,d) ((*getfn((x), (s)))((x), (a),(b),(c),(d)))
+#define mess5(x, s, a,b,c,d,e) ((*getfn((x), (s)))((x), (a),(b),(c),(d),(e)))
+void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv);
+
+/* --------------- memory management -------------------- */
+EXTERN void *getbytes(size_t nbytes);
+EXTERN void *getzbytes(size_t nbytes);
+EXTERN void *copybytes(void *src, size_t nbytes);
+EXTERN void freebytes(void *x, size_t nbytes);
+EXTERN void *resizebytes(void *x, size_t oldsize, size_t newsize);
+
+/* -------------------- atoms ----------------------------- */
+
+#define SETSEMI(atom) ((atom)->a_type = A_SEMI, (atom)->a_w.w_index = 0)
+#define SETCOMMA(atom) ((atom)->a_type = A_COMMA, (atom)->a_w.w_index = 0)
+#define SETPOINTER(atom, gp) ((atom)->a_type = A_POINTER, \
+ (atom)->a_w.w_gpointer = (gp))
+#define SETFLOAT(atom, f) ((atom)->a_type = A_FLOAT, (atom)->a_w.w_float = (f))
+#define SETSYMBOL(atom, s) ((atom)->a_type = A_SYMBOL, \
+ (atom)->a_w.w_symbol = (s))
+#define SETDOLLAR(atom, n) ((atom)->a_type = A_DOLLAR, \
+ (atom)->a_w.w_index = (n))
+#define SETDOLLSYM(atom, s) ((atom)->a_type = A_DOLLSYM, \
+ (atom)->a_w.w_symbol= (s))
+
+EXTERN t_float atom_getfloat(t_atom *a);
+EXTERN t_int atom_getint(t_atom *a);
+EXTERN t_symbol *atom_getsymbol(t_atom *a);
+EXTERN t_symbol *atom_gensym(t_atom *a);
+EXTERN t_float atom_getfloatarg(int which, int argc, t_atom *argv);
+EXTERN t_int atom_getintarg(int which, int argc, t_atom *argv);
+EXTERN t_symbol *atom_getsymbolarg(int which, int argc, t_atom *argv);
+
+EXTERN void atom_string(t_atom *a, char *buf, unsigned int bufsize);
+
+/* ------------------ binbufs --------------- */
+
+EXTERN t_binbuf *binbuf_new(void);
+EXTERN void binbuf_free(t_binbuf *x);
+
+EXTERN void binbuf_text(t_binbuf *x, char *text, size_t size);
+EXTERN void binbuf_gettext(t_binbuf *x, char **bufp, int *lengthp);
+EXTERN void binbuf_clear(t_binbuf *x);
+EXTERN void binbuf_add(t_binbuf *x, int argc, t_atom *argv);
+EXTERN void binbuf_addv(t_binbuf *x, char *fmt, ...);
+EXTERN void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y);
+EXTERN void binbuf_addsemi(t_binbuf *x);
+EXTERN void binbuf_restore(t_binbuf *x, int argc, t_atom *argv);
+EXTERN void binbuf_print(t_binbuf *x);
+EXTERN int binbuf_getnatom(t_binbuf *x);
+EXTERN t_atom *binbuf_getvec(t_binbuf *x);
+EXTERN void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv);
+EXTERN int binbuf_read(t_binbuf *b, char *filename, char *dirname,
+ int crflag);
+EXTERN int binbuf_read_via_path(t_binbuf *b, char *filename, char *dirname,
+ int crflag);
+EXTERN int binbuf_write(t_binbuf *x, char *filename, char *dir,
+ int crflag);
+EXTERN void binbuf_evalfile(t_symbol *name, t_symbol *dir);
+
+/* ------------------ clocks --------------- */
+
+EXTERN t_clock *clock_new(void *owner, t_method fn);
+EXTERN void clock_set(t_clock *x, double systime);
+EXTERN void clock_delay(t_clock *x, double delaytime);
+EXTERN void clock_unset(t_clock *x);
+EXTERN double clock_getlogicaltime(void);
+EXTERN double clock_getsystime(void); /* OBSOLETE; use clock_getlogicaltime() */
+EXTERN double clock_gettimesince(double prevsystime);
+EXTERN double clock_getsystimeafter(double delaytime);
+EXTERN void clock_free(t_clock *x);
+
+/* ----------------- pure data ---------------- */
+EXTERN t_pd *pd_new(t_class *cls);
+EXTERN void pd_free(t_pd *x);
+EXTERN void pd_bind(t_pd *x, t_symbol *s);
+EXTERN void pd_unbind(t_pd *x, t_symbol *s);
+EXTERN t_pd *pd_findbyclass(t_symbol *s, t_class *c);
+EXTERN void pd_pushsym(t_pd *x);
+EXTERN void pd_popsym(t_pd *x);
+EXTERN t_symbol *pd_getfilename(void);
+EXTERN t_symbol *pd_getdirname(void);
+EXTERN void pd_bang(t_pd *x);
+EXTERN void pd_pointer(t_pd *x, t_gpointer *gp);
+EXTERN void pd_float(t_pd *x, t_float f);
+EXTERN void pd_symbol(t_pd *x, t_symbol *s);
+EXTERN void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void pd_anything(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+#define pd_class(x) (*(x))
+
+/* ----------------- pointers ---------------- */
+EXTERN void gpointer_init(t_gpointer *gp);
+EXTERN void gpointer_copy(const t_gpointer *gpfrom, t_gpointer *gpto);
+EXTERN void gpointer_unset(t_gpointer *gp);
+EXTERN int gpointer_check(const t_gpointer *gp, int headok);
+
+/* ----------------- patchable "objects" -------------- */
+EXTERN_STRUCT _inlet;
+#define t_inlet struct _inlet
+EXTERN_STRUCT _outlet;
+#define t_outlet struct _outlet
+
+EXTERN t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1,
+ t_symbol *s2);
+EXTERN t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp);
+EXTERN t_inlet *floatinlet_new(t_object *owner, t_float *fp);
+EXTERN t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp);
+EXTERN void inlet_free(t_inlet *x);
+
+EXTERN t_outlet *outlet_new(t_object *owner, t_symbol *s);
+EXTERN void outlet_bang(t_outlet *x);
+EXTERN void outlet_pointer(t_outlet *x, t_gpointer *gp);
+EXTERN void outlet_float(t_outlet *x, t_float f);
+EXTERN void outlet_symbol(t_outlet *x, t_symbol *s);
+EXTERN void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void outlet_free(t_outlet *x);
+EXTERN t_object *pd_checkobject(t_pd *x);
+
+
+/* -------------------- canvases -------------- */
+
+EXTERN void glob_setfilename(void *dummy, t_symbol *name, t_symbol *dir);
+
+EXTERN void canvas_setargs(int argc, t_atom *argv);
+EXTERN t_atom *canvas_getarg(int which);
+EXTERN t_symbol *canvas_getcurrentdir(void);
+EXTERN t_glist *canvas_getcurrent(void);
+EXTERN void canvas_makefilename(t_glist *c, char *file,
+ char *result,int resultsize);
+EXTERN t_symbol *canvas_getdir(t_glist *x);
+EXTERN int sys_fontwidth(int fontsize);
+EXTERN int sys_fontheight(int fontsize);
+EXTERN void canvas_dataproperties(t_glist *x, t_scalar *sc, t_binbuf *b);
+
+/* ---------------- widget behaviors ---------------------- */
+
+EXTERN_STRUCT _widgetbehavior;
+#define t_widgetbehavior struct _widgetbehavior
+
+EXTERN_STRUCT _parentwidgetbehavior;
+#define t_parentwidgetbehavior struct _parentwidgetbehavior
+EXTERN t_parentwidgetbehavior *pd_getparentwidget(t_pd *x);
+
+/* -------------------- classes -------------- */
+
+#define CLASS_DEFAULT 0 /* flags for new classes below */
+#define CLASS_PD 1
+#define CLASS_GOBJ 2
+#define CLASS_PATCHABLE 3
+#define CLASS_NOINLET 8
+
+#define CLASS_TYPEMASK 3
+
+
+EXTERN t_class *class_new(t_symbol *name, t_newmethod newmethod,
+ t_method freemethod, size_t size, int flags, t_atomtype arg1, ...);
+EXTERN void class_addcreator(t_newmethod newmethod, t_symbol *s,
+ t_atomtype type1, ...);
+EXTERN void class_addmethod(t_class *c, t_method fn, t_symbol *sel,
+ t_atomtype arg1, ...);
+EXTERN void class_addbang(t_class *c, t_method fn);
+EXTERN void class_addpointer(t_class *c, t_method fn);
+EXTERN void class_doaddfloat(t_class *c, t_method fn);
+EXTERN void class_addsymbol(t_class *c, t_method fn);
+EXTERN void class_addlist(t_class *c, t_method fn);
+EXTERN void class_addanything(t_class *c, t_method fn);
+EXTERN void class_sethelpsymbol(t_class *c, t_symbol *s);
+EXTERN void class_setwidget(t_class *c, t_widgetbehavior *w);
+EXTERN void class_setparentwidget(t_class *c, t_parentwidgetbehavior *w);
+EXTERN t_parentwidgetbehavior *class_parentwidget(t_class *c);
+EXTERN char *class_getname(t_class *c);
+EXTERN char *class_gethelpname(t_class *c);
+EXTERN void class_setdrawcommand(t_class *c);
+EXTERN int class_isdrawcommand(t_class *c);
+EXTERN void class_domainsignalin(t_class *c, int onset);
+#define CLASS_MAINSIGNALIN(c, type, field) \
+ class_domainsignalin(c, (char *)(&((type *)0)->field) - (char *)0)
+
+#ifndef PD_CLASS_DEF
+#define class_addbang(x, y) class_addbang((x), (t_method)(y))
+#define class_addpointer(x, y) class_addpointer((x), (t_method)(y))
+#define class_addfloat(x, y) class_doaddfloat((x), (t_method)(y))
+#define class_addsymbol(x, y) class_addsymbol((x), (t_method)(y))
+#define class_addlist(x, y) class_addlist((x), (t_method)(y))
+#define class_addanything(x, y) class_addanything((x), (t_method)(y))
+#endif
+
+/* ------------ printing --------------------------------- */
+EXTERN void post(char *fmt, ...);
+EXTERN void startpost(char *fmt, ...);
+EXTERN void poststring(char *s);
+EXTERN void postfloat(float f);
+EXTERN void postatom(int argc, t_atom *argv);
+EXTERN void endpost(void);
+EXTERN void error(char *fmt, ...);
+EXTERN void bug(char *fmt, ...);
+EXTERN void pd_error(void *object, char *fmt, ...);
+EXTERN void sys_logerror(char *object, char *s);
+EXTERN void sys_unixerror(char *object);
+EXTERN void sys_ouch(void);
+
+#ifdef __linux__
+EXTERN char* sys_get_path( void);
+#endif
+EXTERN void sys_addpath(const char* p);
+
+
+/* ------------ system interface routines ------------------- */
+EXTERN int sys_isreadablefile(const char *name);
+EXTERN void sys_bashfilename(const char *from, char *to);
+EXTERN void sys_unbashfilename(const char *from, char *to);
+EXTERN int open_via_path(const char *name, const char *ext, const char *dir,
+ char *dirresult, char **nameresult, unsigned int size, int bin);
+
+/* --------------- signals ----------------------------------- */
+
+typedef float t_sample;
+#define MAXLOGSIG 32
+#define MAXSIGSIZE (1 << MAXLOGSIG)
+
+typedef struct _signal
+{
+ int s_n; /* number of points in the array */
+ t_sample *s_vec; /* the array */
+ float s_sr; /* sample rate */
+ int s_refcount; /* number of times used */
+ int s_isborrowed; /* whether we're going to borrow our array */
+ struct _signal *s_borrowedfrom; /* signal to borrow it from */
+ struct _signal *s_nextfree; /* next in freelist */
+ struct _signal *s_nextused; /* next in used list */
+} t_signal;
+
+
+typedef t_int *(*t_perfroutine)(t_int *args);
+
+EXTERN t_int *plus_perform(t_int *args);
+EXTERN t_int *zero_perform(t_int *args);
+EXTERN t_int *copy_perform(t_int *args);
+
+EXTERN void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n);
+EXTERN void dsp_add_copy(t_sample *in, t_sample *out, int n);
+EXTERN void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n);
+EXTERN void dsp_add_zero(t_sample *out, int n);
+
+EXTERN int sys_getblksize(void);
+EXTERN float sys_getsr(void);
+EXTERN int sys_get_inchannels(void);
+EXTERN int sys_get_outchannels(void);
+
+EXTERN void dsp_add(t_perfroutine f, int n, ...);
+EXTERN void dsp_addv(t_perfroutine f, int n, t_int *vec);
+EXTERN void pd_fft(float *buf, int npoints, int inverse);
+EXTERN int ilog2(int n);
+
+EXTERN void mayer_fht(float *fz, int n);
+EXTERN void mayer_fft(int n, float *real, float *imag);
+EXTERN void mayer_ifft(int n, float *real, float *imag);
+EXTERN void mayer_realfft(int n, float *real);
+EXTERN void mayer_realifft(int n, float *real);
+
+EXTERN float *cos_table;
+#define LOGCOSTABSIZE 9
+#define COSTABSIZE (1<<LOGCOSTABSIZE)
+
+EXTERN int canvas_suspend_dsp(void);
+EXTERN void canvas_resume_dsp(int oldstate);
+EXTERN void canvas_update_dsp(void);
+
+/* IOhannes { (up/downsampling) */
+typedef struct _resample
+{
+ int method; /* up/downsampling method ID */
+
+ t_int downsample; /* downsampling factor */
+ t_int upsample; /* upsampling factor */
+
+ t_float *s_vec; /* here we hold the resampled data */
+ int s_n;
+
+ t_float *coeffs; /* coefficients for filtering... */
+ int coefsize;
+
+ t_float *buffer; /* buffer for filtering */
+ int bufsize;
+} t_resample;
+
+EXTERN void resample_init(t_resample *x);
+EXTERN void resample_free(t_resample *x);
+
+EXTERN void resample_dsp(t_resample *x, t_sample *in, int insize, t_sample *out, int outsize, int method);
+EXTERN void resamplefrom_dsp(t_resample *x, t_sample *in, int insize, int outsize, int method);
+EXTERN void resampleto_dsp(t_resample *x, t_sample *out, int insize, int outsize, int method);
+/* } IOhannes */
+
+/* ----------------------- utility functions for signals -------------- */
+EXTERN float mtof(float);
+EXTERN float ftom(float);
+EXTERN float rmstodb(float);
+EXTERN float powtodb(float);
+EXTERN float dbtorms(float);
+EXTERN float dbtopow(float);
+
+EXTERN float q8_sqrt(float);
+EXTERN float q8_rsqrt(float);
+#ifndef N32
+EXTERN float qsqrt(float); /* old names kept for extern compatibility */
+EXTERN float qrsqrt(float);
+#endif
+/* --------------------- data --------------------------------- */
+
+ /* graphical arrays */
+EXTERN_STRUCT _garray;
+#define t_garray struct _garray
+
+EXTERN t_class *garray_class;
+EXTERN int garray_getfloatarray(t_garray *x, int *size, t_float **vec);
+EXTERN float garray_get(t_garray *x, t_symbol *s, t_int indx);
+EXTERN void garray_redraw(t_garray *x);
+EXTERN int garray_npoints(t_garray *x);
+EXTERN char *garray_vec(t_garray *x);
+EXTERN void garray_resize(t_garray *x, t_floatarg f);
+EXTERN void garray_usedindsp(t_garray *x);
+EXTERN void garray_setsaveit(t_garray *x, int saveit);
+EXTERN t_class *scalar_class;
+
+EXTERN t_float *value_get(t_symbol *s);
+EXTERN void value_release(t_symbol *s);
+EXTERN int value_getfloat(t_symbol *s, t_float *f);
+EXTERN int value_setfloat(t_symbol *s, t_float f);
+
+/* ------- GUI interface - functions to send strings to TK --------- */
+EXTERN void sys_vgui(char *fmt, ...);
+EXTERN void sys_gui(char *s);
+
+EXTERN void gfxstub_new(t_pd *owner, void *key, const char *cmd);
+EXTERN void gfxstub_deleteforkey(void *key);
+
+/*------------- Max 0.26 compatibility --------------------*/
+
+/* the following reflects the new way classes are laid out, with the class
+ pointing to the messlist and not vice versa. Externs shouldn't feel it. */
+typedef t_class *t_externclass;
+
+EXTERN void c_extern(t_externclass *cls, t_newmethod newroutine,
+ t_method freeroutine, t_symbol *name, size_t size, int tiny, \
+ t_atomtype arg1, ...);
+EXTERN void c_addmess(t_method fn, t_symbol *sel, t_atomtype arg1, ...);
+
+#define t_getbytes getbytes
+#define t_freebytes freebytes
+#define t_resizebytes resizebytes
+#define typedmess pd_typedmess
+#define vmess pd_vmess
+
+#ifdef MACOSX
+#define cabs() smerdyakov(void)
+#endif
+
+/* A definition to help gui objects straddle 0.34-0.35 changes. If this is
+defined, there is a "te_xpix" field in objects, not a "te_xpos" as before: */
+
+#define PD_USE_TE_XPIX
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif
diff --git a/makefile.in b/makefile.in
new file mode 100644
index 0000000..b298fb4
--- /dev/null
+++ b/makefile.in
@@ -0,0 +1,68 @@
+
+EXT = @EXT@
+DEFS = @DEFS@ -DPD_VERSION_MINOR=@pd_minor_version@
+CC = @CC@
+CXX = @CXX@
+LD = @LD@
+AFLAGS = @AFLAGS@
+LFLAGS = @LFLAGS@
+WFLAGS =
+IFLAGS = -I./include
+INSTALL_PREFIX=@prefix@
+
+VERSION = \"$(shell cat VERSION)\"
+DISTVERSION = $(shell cat VERSION)
+
+.SUFFIXES: .$(EXT)
+
+PDCFLAGS = @CFLAGS@ $(DEFS) $(IFLAGS) $(WFLAGS) $(LFLAGS) $(AFLAGS) -DVERSION=$(VERSION)
+CFLAGS = @CFLAGS@ $(DEFS) $(IFLAGS) $(WFLAGS) -DVERSION=$(VERSION)
+CXXFLAGS = $(CFLAGS)
+
+STKPD= @STKPD@
+STK= @STK@
+BUILD_STK = @BUILDSTK@
+#LIBS = -lc -lm
+LIBS = @LIBS@
+SOURCES = @MYSOURCES@
+TARGETS = $(SOURCES:.c=.$(EXT)) $(STKPD)
+
+all: $(STK) $(TARGETS)
+
+ggext: $(STK) $(TARGETS)
+ cc -c $(CFLAGS) -DPD ggee.c
+ $(LD) -export_dynamic -shared -o ggext.pd_linux ggee.o */*.o $(LIBS)
+ strip --strip-unneeded ggext.pd_linux
+
+clean::
+ -rm */*.$(EXT) *.$(EXT) so_locations rm */*~ *~ *.o */*.o
+
+distclean: clean
+ -rm config.cache config.log config.status makefile
+
+
+distcleancvs:
+ -rm -r CVS reference/CVS
+
+
+.c.o:
+ $(CC) -c -o $@ $(CFLAGS) -DPD $*.c
+
+# cp $@ $*_stat.o
+
+.o.pd_linux:
+ $(CC) -o $@ $(PDCFLAGS) -DPD $*.o
+
+
+include makefile.stk
+
+
+install::
+ install -d $(INSTALL_PREFIX)/lib/pd/externs
+ install -m 644 */*.pd_linux $(INSTALL_PREFIX)/lib/pd/externs
+ -install -m 644 ggext.pd_linux $(INSTALL_PREFIX)/lib/pd/externs
+ install -m 644 */*.pd $(INSTALL_PREFIX)/lib/pd/doc/5.reference
+
+
+dist: distclean
+ (cd ..;tar czvf ggee-$(DISTVERSION).tgz ggee)
diff --git a/makefile.stk b/makefile.stk
new file mode 100644
index 0000000..7c57a09
--- /dev/null
+++ b/makefile.stk
@@ -0,0 +1,42 @@
+# The following definition indicates the relative location of
+# the core STK classes.
+
+
+STK_PATH = $(BUILD_STK)/src/
+INSTALL_DIR = $(INSTALL_PREFIX)/lib/pd/
+
+INCLUDE = -I$(BUILD_STK)/include -Iexperimental -I$(BUILD_STK)/projects/ragamatic
+
+CXXDEFINES = -O3 -I. -D__OS_Linux_ -DSRATE=44100.0 -DRAWWAVE_PATH=\"$(INSTALL_DIR)\" $(INCLUDE)
+
+CC_FILES = $(shell ls --ignore "*.tbl" --ignore "*.a" --ignore "*.o" $(BUILD_STK)/src/)
+
+CC_FILES += Sitar1.cpp StrDrone.cpp
+
+O_FILES = $(CC_FILES:.cpp=.o)
+
+
+
+%.o : $(STK_PATH)%.cpp
+ $(CXX) $(CXXDEFINES) -c $(<) -o $@
+
+
+%.o : $(STK_PATH)/../projects/ragamatic/%.cpp
+ $(CXX) $(CXXDEFINES) -c $(<) -o $@
+
+
+libstk: $(O_FILES)
+ ar rc libstk.a $(O_FILES)
+
+.cpp.pd_linux:
+ $(CXX) -o $@ $(CFLAGS) $(LFLAGS) -O2 -DPD -fPIC $(INCLUDE) $*.cpp -L. -I$(STK_PATH) -lstk
+
+
+
+clean::
+ -rm libstk.a
+
+install-stk::
+ install -d $(DESTDIR)/$(INSTALL_DIR)/rawwaves
+ install $(BUILD_STK)/rawwaves/* $(DESTDIR)/$(INSTALL_DIR)/rawwaves
+
diff --git a/other/Makefile b/other/Makefile
new file mode 100755
index 0000000..acd7225
--- /dev/null
+++ b/other/Makefile
@@ -0,0 +1,44 @@
+current: nt
+
+
+# TARGETS += stk
+
+VERSION = \"0.24\"
+
+.SUFFIXES: .dll .obj
+# ----------------------- NT ----------------------------
+
+NTOBJECTS = *.obj
+NTDLLS = *.dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+
+PDNTINCLUDE = /I. /I..\..\pd\src
+ProgramFiles = C:\Program Files
+PDNTLDIR = "$(ProgramFiles)\Microsoft Visual Studio\Vc98\lib"
+#PDNTLDIR = "C:\Programme\Msdev\Vc98\lib"
+
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\wsock32.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ $(PDNTLDIR)\uuid.lib \
+ ..\..\pd\bin\pd.lib
+
+nt: $(NTOBJECTS)
+ -link /dll $(PDNTLIB) vbap.obj /export:vbap_setup
+
+
+clean:
+ del *.obj
+ del *.dll
+
+
+.c.obj:
+ -cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+
+.obj.dll:
+
+
+
+
diff --git a/other/ls_setup b/other/ls_setup
new file mode 100755
index 0000000..9fc3266
--- /dev/null
+++ b/other/ls_setup
@@ -0,0 +1,29 @@
+File: loudspeaker_hdm_3D Configured 28 sets in 3 dimensions:
+Triplet 0 Loudspeakers: 1 5 6 Matrix 4.456940 0.000000 -3.755852 -2.228470 -0.923062 2.655788 -2.228470 0.923062 2.655788
+Triplet 1 Loudspeakers: 1 5 9 Matrix 0.652704 1.575766 0.777862 0.000000 -1.846125 -0.000000 0.652704 -0.270359 -0.777862
+Triplet 2 Loudspeakers: 1 6 9 Matrix 0.652704 -1.575766 0.777862 -0.000000 1.846125 0.000000 0.652704 0.270359 -0.777862
+Triplet 3 Loudspeakers: 2 6 8 Matrix 0.000002 4.456941 -3.755853 0.923062 -2.228471 2.655789 -0.923063 -2.228470 2.655789
+Triplet 4 Loudspeakers: 2 6 10 Matrix -1.575766 0.652704 0.777862 1.846125 -0.000001 -0.000000 0.270359 0.652703 -0.777862
+Triplet 5 Loudspeakers: 2 8 10 Matrix 1.575766 0.652703 0.777862 -1.846125 0.000001 0.000000 -0.270358 0.652704 -0.777862
+Triplet 6 Loudspeakers: 3 5 7 Matrix 0.000002 -4.456941 -3.755853 0.923062 2.228471 2.655789 -0.923063 2.228470 2.655789
+Triplet 7 Loudspeakers: 3 5 11 Matrix -1.575766 -0.652704 0.777862 1.846125 0.000001 0.000000 0.270359 -0.652703 -0.777862
+Triplet 8 Loudspeakers: 3 7 11 Matrix 1.575766 -0.652703 0.777862 -1.846125 -0.000001 -0.000000 -0.270358 -0.652704 -0.777862
+Triplet 9 Loudspeakers: 4 7 8 Matrix -4.456932 -0.000000 -3.755843 2.228464 -0.923062 2.655782 2.228468 0.923062 2.655785
+Triplet 10 Loudspeakers: 4 7 12 Matrix -0.652703 1.575764 0.777862 -0.000001 -1.846122 0.000000 -0.652704 -0.270359 -0.777862
+Triplet 11 Loudspeakers: 4 8 12 Matrix -0.652705 -1.575766 0.777862 0.000001 1.846125 -0.000000 -0.652703 0.270359 -0.777862
+Triplet 12 Loudspeakers: 5 6 7 Matrix 0.923063 -0.923062 -0.000001 -0.000000 0.923062 0.777862 -0.923062 -0.000000 0.777862
+Triplet 13 Loudspeakers: 5 9 13 Matrix 0.652704 -0.270359 0.777862 1.305407 1.305407 0.000000 -0.652704 -1.575766 -0.777862
+Triplet 14 Loudspeakers: 5 11 13 Matrix 0.270359 -0.652703 0.777862 -1.305407 -1.305407 -0.000000 1.575766 0.652704 -0.777862
+Triplet 15 Loudspeakers: 6 7 8 Matrix 0.923062 0.000000 0.777862 -0.000000 -0.923062 0.777862 -0.923062 0.923062 0.000001
+Triplet 16 Loudspeakers: 6 9 14 Matrix 0.652704 0.270359 0.777862 1.305407 -1.305407 -0.000000 -0.652704 1.575766 -0.777862
+Triplet 17 Loudspeakers: 6 10 14 Matrix 0.270359 0.652703 0.777862 -1.305407 1.305407 0.000000 1.575766 -0.652704 -0.777862
+Triplet 18 Loudspeakers: 7 11 15 Matrix -0.270358 -0.652704 0.777862 1.305408 -1.305407 0.000000 -1.575766 0.652703 -0.777862
+Triplet 19 Loudspeakers: 7 12 15 Matrix -0.652704 -0.270359 0.777862 -1.305406 1.305405 -0.000000 0.652703 -1.575764 -0.777862
+Triplet 20 Loudspeakers: 8 10 16 Matrix -0.270358 0.652704 0.777862 1.305408 1.305407 -0.000000 -1.575766 -0.652703 -0.777862
+Triplet 21 Loudspeakers: 8 12 16 Matrix -0.652703 0.270359 0.777862 -1.305408 -1.305407 0.000000 0.652705 1.575766 -0.777862
+Triplet 22 Loudspeakers: 9 13 14 Matrix 4.456940 -0.000000 3.755852 -2.228470 -0.923062 -2.655788 -2.228470 0.923062 -2.655788
+Triplet 23 Loudspeakers: 10 14 16 Matrix 0.000002 4.456941 3.755853 0.923062 -2.228471 -2.655789 -0.923063 -2.228470 -2.655789
+Triplet 24 Loudspeakers: 11 13 15 Matrix 0.000002 -4.456941 3.755853 0.923062 2.228471 -2.655789 -0.923063 2.228470 -2.655789
+Triplet 25 Loudspeakers: 12 15 16 Matrix -4.456932 0.000000 3.755843 2.228464 -0.923062 -2.655782 2.228468 0.923062 -2.655785
+Triplet 26 Loudspeakers: 13 14 15 Matrix 0.923063 -0.923062 0.000001 -0.000000 0.923062 -0.777862 -0.923062 0.000000 -0.777862
+Triplet 27 Loudspeakers: 14 15 16 Matrix 0.923062 -0.000000 -0.777862 -0.000000 -0.923062 -0.777862 -0.923062 0.923062 -0.000001
diff --git a/other/ls_setup16 b/other/ls_setup16
new file mode 100755
index 0000000..9fc3266
--- /dev/null
+++ b/other/ls_setup16
@@ -0,0 +1,29 @@
+File: loudspeaker_hdm_3D Configured 28 sets in 3 dimensions:
+Triplet 0 Loudspeakers: 1 5 6 Matrix 4.456940 0.000000 -3.755852 -2.228470 -0.923062 2.655788 -2.228470 0.923062 2.655788
+Triplet 1 Loudspeakers: 1 5 9 Matrix 0.652704 1.575766 0.777862 0.000000 -1.846125 -0.000000 0.652704 -0.270359 -0.777862
+Triplet 2 Loudspeakers: 1 6 9 Matrix 0.652704 -1.575766 0.777862 -0.000000 1.846125 0.000000 0.652704 0.270359 -0.777862
+Triplet 3 Loudspeakers: 2 6 8 Matrix 0.000002 4.456941 -3.755853 0.923062 -2.228471 2.655789 -0.923063 -2.228470 2.655789
+Triplet 4 Loudspeakers: 2 6 10 Matrix -1.575766 0.652704 0.777862 1.846125 -0.000001 -0.000000 0.270359 0.652703 -0.777862
+Triplet 5 Loudspeakers: 2 8 10 Matrix 1.575766 0.652703 0.777862 -1.846125 0.000001 0.000000 -0.270358 0.652704 -0.777862
+Triplet 6 Loudspeakers: 3 5 7 Matrix 0.000002 -4.456941 -3.755853 0.923062 2.228471 2.655789 -0.923063 2.228470 2.655789
+Triplet 7 Loudspeakers: 3 5 11 Matrix -1.575766 -0.652704 0.777862 1.846125 0.000001 0.000000 0.270359 -0.652703 -0.777862
+Triplet 8 Loudspeakers: 3 7 11 Matrix 1.575766 -0.652703 0.777862 -1.846125 -0.000001 -0.000000 -0.270358 -0.652704 -0.777862
+Triplet 9 Loudspeakers: 4 7 8 Matrix -4.456932 -0.000000 -3.755843 2.228464 -0.923062 2.655782 2.228468 0.923062 2.655785
+Triplet 10 Loudspeakers: 4 7 12 Matrix -0.652703 1.575764 0.777862 -0.000001 -1.846122 0.000000 -0.652704 -0.270359 -0.777862
+Triplet 11 Loudspeakers: 4 8 12 Matrix -0.652705 -1.575766 0.777862 0.000001 1.846125 -0.000000 -0.652703 0.270359 -0.777862
+Triplet 12 Loudspeakers: 5 6 7 Matrix 0.923063 -0.923062 -0.000001 -0.000000 0.923062 0.777862 -0.923062 -0.000000 0.777862
+Triplet 13 Loudspeakers: 5 9 13 Matrix 0.652704 -0.270359 0.777862 1.305407 1.305407 0.000000 -0.652704 -1.575766 -0.777862
+Triplet 14 Loudspeakers: 5 11 13 Matrix 0.270359 -0.652703 0.777862 -1.305407 -1.305407 -0.000000 1.575766 0.652704 -0.777862
+Triplet 15 Loudspeakers: 6 7 8 Matrix 0.923062 0.000000 0.777862 -0.000000 -0.923062 0.777862 -0.923062 0.923062 0.000001
+Triplet 16 Loudspeakers: 6 9 14 Matrix 0.652704 0.270359 0.777862 1.305407 -1.305407 -0.000000 -0.652704 1.575766 -0.777862
+Triplet 17 Loudspeakers: 6 10 14 Matrix 0.270359 0.652703 0.777862 -1.305407 1.305407 0.000000 1.575766 -0.652704 -0.777862
+Triplet 18 Loudspeakers: 7 11 15 Matrix -0.270358 -0.652704 0.777862 1.305408 -1.305407 0.000000 -1.575766 0.652703 -0.777862
+Triplet 19 Loudspeakers: 7 12 15 Matrix -0.652704 -0.270359 0.777862 -1.305406 1.305405 -0.000000 0.652703 -1.575764 -0.777862
+Triplet 20 Loudspeakers: 8 10 16 Matrix -0.270358 0.652704 0.777862 1.305408 1.305407 -0.000000 -1.575766 -0.652703 -0.777862
+Triplet 21 Loudspeakers: 8 12 16 Matrix -0.652703 0.270359 0.777862 -1.305408 -1.305407 0.000000 0.652705 1.575766 -0.777862
+Triplet 22 Loudspeakers: 9 13 14 Matrix 4.456940 -0.000000 3.755852 -2.228470 -0.923062 -2.655788 -2.228470 0.923062 -2.655788
+Triplet 23 Loudspeakers: 10 14 16 Matrix 0.000002 4.456941 3.755853 0.923062 -2.228471 -2.655789 -0.923063 -2.228470 -2.655789
+Triplet 24 Loudspeakers: 11 13 15 Matrix 0.000002 -4.456941 3.755853 0.923062 2.228471 -2.655789 -0.923063 2.228470 -2.655789
+Triplet 25 Loudspeakers: 12 15 16 Matrix -4.456932 0.000000 3.755843 2.228464 -0.923062 -2.655782 2.228468 0.923062 -2.655785
+Triplet 26 Loudspeakers: 13 14 15 Matrix 0.923063 -0.923062 0.000001 -0.000000 0.923062 -0.777862 -0.923062 0.000000 -0.777862
+Triplet 27 Loudspeakers: 14 15 16 Matrix 0.923062 -0.000000 -0.777862 -0.000000 -0.923062 -0.777862 -0.923062 0.923062 -0.000001
diff --git a/other/messages.c b/other/messages.c
new file mode 100755
index 0000000..f25f49e
--- /dev/null
+++ b/other/messages.c
@@ -0,0 +1,40 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ messages ----------------------------- */
+
+static t_class *messages_class;
+
+
+typedef struct _messages
+{
+ t_object x_obj;
+} t_messages;
+
+
+void messages_bang(t_messages *x)
+{
+ post("bang");
+}
+
+static void *messages_new()
+{
+ t_messages *x = (t_messages *)pd_new(messages_class);
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+void messages_setup(void)
+{
+ messages_class = class_new(gensym("messages"), (t_newmethod)messages_new, 0,
+ sizeof(t_messages), 0,0);
+ class_addbang(messages_class,messages_bang);
+}
+
+
diff --git a/other/vbap.c b/other/vbap.c
new file mode 100755
index 0000000..db36993
--- /dev/null
+++ b/other/vbap.c
@@ -0,0 +1,298 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+(C) Guenter Geiger
+
+
+based on code by:
+(c) Ville Pulkki 2.2.1999
+Helsinki University of Technology
+Laboratory of Acoustics and Audio Signal Processing
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include <math.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h> /* strtok */
+
+#define MAX_TRIPLET_AMOUNT 64
+
+/* this is related to the number of ls ..
+
+ and shoud be 3**(MAX_LS_AMOUNT / 4)
+
+*/
+
+#define MAX_LS_AMOUNT 16
+#define MAX_DIM_SQUARE 9
+
+
+/* ------------------------ vbap ----------------------------- */
+
+static t_class *vbap_class;
+
+
+typedef struct _vbap
+{
+ t_object x_ob;
+ t_outlet* x_out2;
+ t_outlet* x_out3;
+ t_float lsm[MAX_TRIPLET_AMOUNT][MAX_LS_AMOUNT+1]; /* loudspeaker triplet matrices */
+ int lstripl[MAX_TRIPLET_AMOUNT][3]; /* loudspeaker triplet ldspeaker numbers */
+ int lasttrip[3];
+ int triplet_amount;
+ int dimension;
+ int opened;
+} t_vbap;
+
+
+
+
+t_float *angle_to_cart(t_float azi, t_float ele);
+void vbap(t_vbap* x,t_float g[3], int ls[3], t_float azi, t_float ele) ;
+int read_ls_conf(t_vbap* x,FILE *fp );
+
+
+void vbap_list(t_vbap *x,t_symbol* s,t_int argc,t_atom* argv)
+{
+ t_float azi,ele;
+ t_float g[3];
+ int ls[3];
+ t_atom a[2];
+
+ if (argc != 2)
+ post("vbap: list message <azimuth> <elevation> required %d",argc);
+ else {
+ int i;
+ azi = atom_getfloat(argv++);
+ ele = atom_getfloat(argv++);
+
+ vbap(x,g,ls,azi,ele);
+
+ for (i=0;i<x->dimension;i++) {
+ if (x->lasttrip[i] != ls[i]) {
+ SETFLOAT(a,(t_float)x->lasttrip[i]);
+ SETFLOAT(a+1,0.0f);
+ outlet_list(x->x_ob.ob_outlet, &s_list,2 ,(t_atom*)&a);
+ x->lasttrip[i] = ls[i];
+ }
+ }
+
+ for (i=0;i<x->dimension;i++) {
+ SETFLOAT(a,(t_float)ls[i]);
+ SETFLOAT(a+1,g[i]);
+ outlet_list(x->x_ob.ob_outlet, &s_list,2 ,(t_atom*)&a);
+
+ }
+ }
+
+}
+
+
+void vbap_bang(t_vbap *x)
+{
+ post("vbap: bang");
+}
+
+
+
+static void *vbap_new(t_symbol* s)
+{
+ FILE *fp;
+ t_vbap *x = (t_vbap *)pd_new(vbap_class);
+ char fname[MAXPDSTRING];
+
+ if (s == &s_) {
+ post("vbap: Using default loudspeaker setup");
+ s = gensym("ls_setup");
+ }
+
+ /* opening the loudspeaker matrix file*/
+
+ canvas_makefilename(canvas_getcurrent(),s->s_name,
+ fname,MAXPDSTRING);
+
+ if((fp=fopen(fname,"r"))==NULL){
+ post("vbap: Could not open loudspeaker data file %s\n",fname);
+ x->opened = 0;
+ }
+ else {
+ if (!read_ls_conf(x,fp))
+ return NULL;
+ x->opened = 1;
+ fclose(fp);
+ }
+
+ x->lasttrip[0] = 0;
+ x->lasttrip[1] = 1;
+ x->lasttrip[2] = 2;
+
+ outlet_new(&x->x_ob, &s_list);
+
+ return (x);
+}
+
+void vbap_setup(void)
+{
+ vbap_class = class_new(gensym("vbap"), (t_newmethod)vbap_new, 0,
+ sizeof(t_vbap), 0,A_DEFSYM,0);
+/* class_addbang(vbap_class,vbap_bang);*/
+ class_addlist(vbap_class,vbap_list);
+}
+
+
+
+
+t_float *angle_to_cart(t_float azi, t_float ele)
+{
+ t_float *res;
+ t_float atorad = (2 * 3.1415927 / 360) ;
+ res = (t_float *) malloc(3*sizeof(t_float));
+ res[0] = (float) (cos((t_float) (azi * atorad)) * cos((t_float) (ele * atorad)));
+ res[1] = (float) (sin((t_float) (azi * atorad)) * cos((t_float) (ele * atorad)));
+ res[2] = (float) (sin((t_float) (ele * atorad)));
+ return res;
+}
+
+
+void vbap(t_vbap* x,t_float g[3], int ls[3], float azi, float ele)
+{
+ /* calculates gain factors using loudspeaker setup and given direction */
+ t_float *cartdir;
+ t_float power;
+ int i,j,k;
+ t_float small_g;
+ t_float big_sm_g, gtmp[3];
+ int winner_triplet;
+
+ cartdir=angle_to_cart(azi,ele);
+ big_sm_g = -100000.0;
+ for(i=0;i<x->triplet_amount;i++){
+ small_g = 10000000.0;
+ for(j=0;j<x->dimension;j++){
+ gtmp[j]=0.0;
+ for(k=0;k<x->dimension;k++)
+ gtmp[j]+=cartdir[k]*x->lsm[i][k+j*x->dimension];
+ if(gtmp[j] < small_g)
+ small_g = gtmp[j];
+ }
+ if(small_g > big_sm_g){
+ big_sm_g = small_g;
+ winner_triplet=i;
+ g[0]=gtmp[0]; g[1]=gtmp[1];
+ ls[0]=x->lstripl[i][0]; ls[1]=x->lstripl[i][1];
+ if(x->dimension==3){
+ g[2]=gtmp[2];
+ ls[2]=x->lstripl[i][2];
+ } else {
+ g[2]=0.0;
+ ls[2]=0;
+ }
+ }
+ }
+
+ /* this should probably be optimized somehow */
+
+ power=sqrt(g[0]*g[0] + g[1]*g[1] + g[2]*g[2]);
+ /* power=g[0]+g[1];*/
+
+ g[0] /= power;
+ g[1] /= power;
+ g[2] /= power;
+
+
+ free(cartdir);
+}
+
+int read_ls_conf(t_vbap* x,FILE *fp ){
+ /* reads from specified file the loudspeaker triplet setup */
+ int amount,i,j,a,b,d=0;
+ char *toke;
+ char c[1000];
+ t_float mx[MAX_DIM_SQUARE];
+ fgets(c,1000,fp);
+ toke = (char *) strtok(c, " ");
+ toke = (char *) strtok(NULL, " ");
+ toke = (char *) strtok(NULL, " ");
+ if((toke = (char *) strtok(NULL, " "))==NULL){
+ fprintf(stderr,"Wrong ls matrix file?\n");
+ return 0;
+ }
+ sscanf(toke, "%d",&amount);
+ toke = (char *) strtok(NULL, " ");
+ toke = (char *) strtok(NULL, " ");
+ if((toke = (char *) strtok(NULL, " "))==NULL){
+ fprintf(stderr,"Wrong ls matrix file?\n");
+ return 0;
+ }
+ sscanf(toke, "%d",&x->dimension);
+
+ x->triplet_amount = amount;
+
+ for(i=0;i<amount;i++){
+ fgets(c,1000,fp);
+ toke = (char *) strtok(c, " ");
+ if(strncmp(toke,"Trip",4)!=0 && x->dimension==3){
+ fprintf(stderr,"Something wrong in ls matrix file\n");
+ return 0;
+ }
+ if(strncmp(toke,"Pair",4)!=0 && x->dimension==2){
+ fprintf(stderr,"Something wrong in ls matrix file\n");
+ return 0;
+ }
+ toke = (char *) strtok(NULL, " ");
+ toke = (char *) strtok(NULL, " "); toke = (char *) strtok(NULL, " ");
+ sscanf(toke, "%d",&a);
+ x->lstripl[i][0]=a;
+ toke = (char *) strtok(NULL, " ");
+ sscanf(toke, "%d",&b);
+ x->lstripl[i][1]=b;
+ if (x->dimension==3){
+ toke = (char *) strtok(NULL, " ");
+ sscanf(toke, "%d",&d);
+ x->lstripl[i][2]=d;
+ }
+
+
+ toke = (char *) strtok(NULL, " ");
+ for(j=0;j<(x->dimension*x->dimension);j++){
+ toke = (char *) strtok(NULL, " ");
+ sscanf(toke, "%f",&(mx[j]));
+ x->lsm[i][j]=mx[j];
+ }
+
+ }
+ return 1;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/other/vbap.pd b/other/vbap.pd
new file mode 100755
index 0000000..d5047c0
--- /dev/null
+++ b/other/vbap.pd
@@ -0,0 +1,51 @@
+#N canvas 477 72 599 479 10;
+#X msg 82 109 20 0;
+#X obj 27 108 pack 1 2;
+#X floatatom 27 87 0 0 0;
+#X floatatom 70 88 0 0 0;
+#X obj 62 176 route 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18;
+#X floatatom 62 221 0 0 0;
+#X floatatom 78 251 0 0 0;
+#X floatatom 94 284 0 0 0;
+#X floatatom 111 316 0 0 0;
+#X floatatom 127 224 0 0 0;
+#X floatatom 143 251 0 0 0;
+#X floatatom 160 282 0 0 0;
+#X floatatom 176 317 0 0 0;
+#X floatatom 216 225 0 0 0;
+#X floatatom 239 251 0 0 0;
+#X floatatom 273 277 0 0 0;
+#X floatatom 334 247 0 0 0;
+#X floatatom 309 225 0 0 0;
+#X floatatom 308 314 0 0 0;
+#X floatatom 373 276 0 0 0;
+#X floatatom 415 315 0 0 0;
+#X floatatom 401 227 0 0 0;
+#X floatatom 476 295 0 0 0;
+#X floatatom 443 258 0 0 0;
+#X text 31 15 A VBAP (Vector Base Amplitude Panning) external;
+#X obj 82 144 vbap;
+#X connect 0 0 25 0;
+#X connect 1 0 25 0;
+#X connect 2 0 1 0;
+#X connect 3 0 1 1;
+#X connect 4 0 5 0;
+#X connect 4 1 6 0;
+#X connect 4 2 7 0;
+#X connect 4 3 8 0;
+#X connect 4 4 9 0;
+#X connect 4 5 10 0;
+#X connect 4 6 11 0;
+#X connect 4 7 12 0;
+#X connect 4 8 13 0;
+#X connect 4 9 14 0;
+#X connect 4 10 15 0;
+#X connect 4 11 16 0;
+#X connect 4 12 17 0;
+#X connect 4 13 18 0;
+#X connect 4 14 19 0;
+#X connect 4 15 20 0;
+#X connect 4 16 21 0;
+#X connect 4 17 22 0;
+#X connect 4 18 23 0;
+#X connect 25 0 4 0;
diff --git a/signal/Makefile b/signal/Makefile
new file mode 100755
index 0000000..ebf4c30
--- /dev/null
+++ b/signal/Makefile
@@ -0,0 +1,51 @@
+current: nt
+
+
+# TARGETS += stk
+
+VERSION = \"0.16\"
+
+.SUFFIXES: .dll .obj
+# ----------------------- NT ----------------------------
+
+NTOBJECTS = *.obj
+NTDLLS = *.dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+
+PDNTINCLUDE = /I. /I..\..\pd\src /I..\include
+ProgramFiles = C:\Program Files
+PDNTLDIR = "$(ProgramFiles)\Microsoft Visual Studio\Vc98\lib"
+#PDNTLDIR = "C:\Programme\Msdev\Vc98\lib"
+
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\wsock32.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ $(PDNTLDIR)\uuid.lib \
+ ..\..\pd\bin\pd.lib
+
+nt: $(NTOBJECTS)
+ -link /dll $(PDNTLIB) sfplay~.obj /export:sfplay_tilde_setup
+ -link /dll $(PDNTLIB) atan2~.obj /export:atan2_tilde_setup
+ -link /dll $(PDNTLIB) exp~.obj /export:exp_tilde_setup
+ -link /dll $(PDNTLIB) log~.obj /export:log_tilde_setup
+ -link /dll $(PDNTLIB) mixer~.obj /export:mixer_tilde_setup
+ -link /dll $(PDNTLIB) sfwrite~.obj /export:swrite_tilde_setup
+ -link /dll $(PDNTLIB) streamin~.obj /export:streamin_tilde_setup
+ -link /dll $(PDNTLIB) streamout~.obj /export:streamout_tilde_setup
+ -link /dll $(PDNTLIB) moog~.obj /export:moog_tilde_setup
+
+clean:
+ del *.obj
+ del *.dll
+
+
+.c.obj:
+ -cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+
+.obj.dll:
+
+
+
+
diff --git a/signal/apply~.c b/signal/apply~.c
new file mode 100644
index 0000000..7463383
--- /dev/null
+++ b/signal/apply~.c
@@ -0,0 +1,151 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include "math.h"
+#include <m_pd.h>
+
+/* ----------------------------- apply ----------------------------- */
+static t_class *apply_class;
+
+
+typedef double (*t_apply_onearg)(double);
+typedef double (*t_apply_twoarg)(double);
+
+static double nop(double f) {
+ return f;
+}
+
+typedef struct _funlist {
+ char* name;
+ t_int* fun;
+ int numarg;
+ char* desc;
+} t_funlist;
+
+#define MFUN1(x,d) {#x,(t_int*)x,1,d}
+
+static t_funlist funlist[] =
+ {
+ MFUN1(nop,"does nothing"),
+ MFUN1(sin,"calculate sine"),
+ MFUN1(asin,"calculate arcus sine"),
+ MFUN1(cos,"calculate cosine"),
+ MFUN1(acos,"calculate arcus cosine"),
+ MFUN1(tan,"calculate tangent"),
+ MFUN1(atan,"calculate arcus tangent"),
+
+ MFUN1(sinh,""),
+ MFUN1(asinh,""),
+ MFUN1(cosh,""),
+ MFUN1(acosh,""),
+ MFUN1(tanh,""),
+ MFUN1(atanh,""),
+
+ MFUN1(exp,""),
+ MFUN1(expm1,""),
+ // MFUN1(exp10),
+ // MFUN1(pow10),
+ MFUN1(log,""),
+ MFUN1(log1p,""),
+ MFUN1(log10,""),
+ // MFUN1(log2),
+ MFUN1(sqrt,""),
+ MFUN1(cbrt,""),
+
+
+ MFUN1(rint,""),
+ // MFUN1(round),
+ MFUN1(ceil,""),
+ MFUN1(floor,""),
+ // MFUN1(trunc),
+
+ MFUN1(erf,""),
+ MFUN1(erfc,""),
+ MFUN1(gamma,""),
+ MFUN1(lgamma,""),
+ // MFUN1(tgamma),
+
+ MFUN1(j0,""),
+ MFUN1(j1,""),
+ MFUN1(y0,""),
+ MFUN1(j1,"")
+ };
+
+
+
+typedef struct _apply
+{
+ t_object x_obj;
+ t_int* x_fun;
+} t_apply;
+
+static void *apply_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_symbol* fname;
+ int i;
+ int numfun = sizeof(funlist)/sizeof(t_funlist);
+ t_apply *x = (t_apply *)pd_new(apply_class);
+ outlet_new(&x->x_obj, &s_signal);
+
+ x->x_fun = (t_int*)nop;
+ if (argc < 1) {
+ post("nop operation requested");
+ }
+ else {
+ if (argv[0].a_type != A_SYMBOL)
+ goto nofun;
+ fname = atom_getsymbol(argv);
+ for (i=0;i<numfun;i++)
+ if (!strcmp(fname->s_name,funlist[i].name))
+ x->x_fun = funlist[i].fun;
+
+
+
+ }
+
+
+ return (x);
+ nofun:
+ post("apply first argument has to be a function");
+ return (x);
+}
+
+
+static void apply_what(t_apply* x)
+{
+ int i;
+ int numfun = sizeof(funlist)/sizeof(t_funlist);
+ for (i=0;i<numfun;i++)
+ post("function: %s: %s",funlist[i].name,funlist[i].desc);
+}
+
+t_int *apply_perform(t_int *w)
+{
+ t_apply* x = (t_apply*)(w[1]);
+ t_float *in1 = (t_float *)(w[2]);
+ t_float *out = (t_float *)(w[3]);
+
+ int n = (int)(w[4]);
+ while (n--) *out++ = (t_float) ((t_apply_onearg)x->x_fun)(*in1++);
+ return (w+5);
+}
+
+
+void dsp_add_apply(t_apply* x,t_sample *in1, t_sample *out, int n)
+{
+ dsp_add(apply_perform, 4,x, in1, out, n);
+}
+
+static void apply_dsp(t_apply *x, t_signal **sp)
+{
+ dsp_add_apply(x,sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+void apply_tilde_setup(void)
+{
+ apply_class = class_new(gensym("apply~"), (t_newmethod)apply_new, 0,
+ sizeof(t_apply), 0, A_GIMME, 0);
+ class_addmethod(apply_class, nullfn, gensym("signal"), 0);
+ class_addmethod(apply_class, (t_method)apply_dsp, gensym("dsp"), 0);
+ class_addmethod(apply_class, (t_method)apply_what, gensym("what"), 0);
+}
diff --git a/signal/apply~.pd b/signal/apply~.pd
new file mode 100644
index 0000000..b348a94
--- /dev/null
+++ b/signal/apply~.pd
@@ -0,0 +1,19 @@
+#N canvas 284 112 450 300 10;
+#X obj 33 88 sig~;
+#X obj 33 160 snapshot~;
+#X floatatom 33 183 10 0 0;
+#X msg 70 89 bang;
+#X floatatom 33 42 5 0 0;
+#X obj 148 112 apply~;
+#X msg 148 48 what;
+#X obj 33 118 apply~ rint;
+#X obj 295 41 loadbang;
+#X msg 295 63 \; pd dsp 1;
+#X connect 0 0 7 0;
+#X connect 1 0 2 0;
+#X connect 3 0 1 0;
+#X connect 4 0 0 0;
+#X connect 4 0 3 0;
+#X connect 6 0 5 0;
+#X connect 7 0 1 0;
+#X connect 8 0 9 0;
diff --git a/signal/atan2~.c b/signal/atan2~.c
new file mode 100755
index 0000000..0e1deb0
--- /dev/null
+++ b/signal/atan2~.c
@@ -0,0 +1,86 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+
+#include "math.h"
+#include <m_pd.h>
+
+/* ----------------------------- atan2 ----------------------------- */
+static t_class *atan2_class;
+
+
+#define INVTWOPI 0.15915494f
+
+typedef struct _atan2
+{
+ t_object x_obj;
+} t_atan2;
+
+static void *atan2_new(t_symbol *s, int argc, t_atom *argv)
+{
+ if (argc > 1) post("+~: extra arguments ignored");
+ {
+ t_atan2 *x = (t_atan2 *)pd_new(atan2_class);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ return (x);
+ }
+}
+
+t_int *atan2_perform(t_int *w)
+{
+ t_float *in1 = (t_float *)(w[1]);
+ t_float *in2 = (t_float *)(w[2]);
+ t_float *out = (t_float *)(w[3]);
+
+ int n = (int)(w[4]);
+ while (n--) *out++ = (t_float) atan2(*in1++,*in2++) *INVTWOPI;
+ return (w+5);
+}
+
+t_int *atan2_perf8(t_int *w)
+{
+ t_float *in1 = (t_float *)(w[1]);
+ t_float *in2 = (t_float *)(w[2]);
+ t_float *out = (t_float *)(w[3]);
+ int n = (int)(w[4]);
+ for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
+ {
+ float f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
+ float f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
+
+ float g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
+ float g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
+
+ out[0] = (t_float) atan2(f0,g0)*INVTWOPI;
+ out[1] = (t_float) atan2(f1,g1)*INVTWOPI;
+ out[2] = (t_float) atan2(f2,g2)*INVTWOPI;
+ out[3] = (t_float) atan2(f3,g3)*INVTWOPI;
+ out[4] = (t_float) atan2(f4,g4)*INVTWOPI;
+ out[5] = (t_float) atan2(f5,g5)*INVTWOPI;
+ out[6] = (t_float) atan2(f6,g6)*INVTWOPI;
+ out[7] = (t_float) atan2(f7,g7)*INVTWOPI;
+ }
+ return (w+5);
+}
+
+void dsp_add_atan2(t_sample *in1, t_sample *in2, t_sample *out, int n)
+{
+ if (n&7)
+ dsp_add(atan2_perform, 4, in1, in2, out, n);
+ else
+ dsp_add(atan2_perf8, 4, in1, in2, out, n);
+}
+
+static void atan2_dsp(t_atan2 *x, t_signal **sp)
+{
+ dsp_add_atan2(sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
+}
+
+void atan2_tilde_setup(void)
+{
+ atan2_class = class_new(gensym("atan2~"), (t_newmethod)atan2_new, 0,
+ sizeof(t_atan2), 0, A_GIMME, 0);
+ class_addmethod(atan2_class, nullfn, gensym("signal"), 0);
+ class_addmethod(atan2_class, (t_method)atan2_dsp, gensym("dsp"), 0);
+}
diff --git a/signal/atan2~.pd b/signal/atan2~.pd
new file mode 100755
index 0000000..e7ff494
--- /dev/null
+++ b/signal/atan2~.pd
@@ -0,0 +1,4 @@
+#N canvas 197 203 500 184 10;
+#X obj 33 88 atan2~;
+#X text 30 121 (C) Guenter Geiger;
+#X text 30 18 The atan2 function is used to get the phase from a imaginary value of the fft.;
diff --git a/signal/mixer~.c b/signal/mixer~.c
new file mode 100755
index 0000000..5d90285
--- /dev/null
+++ b/signal/mixer~.c
@@ -0,0 +1,107 @@
+/* (C) Oswald Berthold <opt@web.fm> */
+
+
+#include "math.h"
+#include <m_pd.h>
+
+/* ----------------------------- mixer ----------------------------- */
+static t_class *mixer_class;
+
+
+
+typedef struct _mixer
+{
+ t_object x_obj;
+ t_int x_n;
+ t_float* x_m;
+} t_mixer;
+
+static void *mixer_new(t_symbol *s, t_floatarg num)
+{
+ int i;
+ t_mixer *x = (t_mixer *)pd_new(mixer_class);
+ if (num < 1) x->x_n = 1;
+ else x->x_n = (int) num;
+
+ x->x_m = getbytes(sizeof(t_float)*x->x_n);
+
+ for (i=0;i<x->x_n /* - 1 */ ;i++) {
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ x->x_m[i] = 1.;
+ }
+
+
+
+ outlet_new(&x->x_obj, &s_signal);
+ return (x);
+}
+
+void mixer_list(t_mixer* x,t_symbol* s,t_int argc, t_atom* argv)
+{
+ int chan;
+ t_float val;
+
+ if (argc != 2) {
+ post("unknown");
+ return;
+ }
+
+ chan = (int) atom_getfloat(argv++);
+ val = atom_getfloat(argv++);
+
+
+ x->x_m[chan] = val;
+
+}
+
+
+t_int *mixer_perform(t_int *w)
+{
+ t_mixer* x = (t_mixer*) (w[1]);
+ int n = (int)(w[2]);
+ t_float **in = getbytes(sizeof(float)*x->x_n);
+ t_float *out;
+ int i,j;
+ int offset = 3;
+
+ for (i=0;i < x->x_n;i++) {
+ in[i] = (t_float *)(w[offset+i]);
+ }
+
+ out = (t_float *)(w[offset+i]);
+
+ while (n--) {
+ *out = 0.;
+ for (j=0;j<x->x_n;j++) {
+ *out += *(in[j]++) * x->x_m[j];
+ }
+ out++;
+ }
+ return (w+offset+1+i);
+}
+
+static void mixer_dsp(t_mixer *x, t_signal **sp)
+{
+ int i;
+ t_int** myvec = getbytes(sizeof(t_int)*(x->x_n + 3));
+
+ myvec[0] = (t_int*)x;
+ myvec[1] = (t_int*)sp[0]->s_n;
+
+ for (i=0;i < x->x_n+1;i++)
+ myvec[2 + i] = (t_int*)sp[i]->s_vec;
+
+ dsp_addv(mixer_perform, x->x_n + 3, (t_int*)myvec);
+ freebytes(myvec,sizeof(t_int)*(x->x_n + 3));
+}
+
+void mixer_tilde_setup(void)
+{
+ mixer_class = class_new(gensym("mixer~"), (t_newmethod)mixer_new, 0,
+ sizeof(t_mixer), 0, A_DEFFLOAT, A_DEFSYM,A_NULL);
+ class_addmethod(mixer_class, nullfn, gensym("signal"), 0);
+ class_addmethod(mixer_class, (t_method)mixer_dsp, gensym("dsp"), 0);
+
+ class_addlist(mixer_class,mixer_list);
+}
+
diff --git a/signal/mixer~.pd b/signal/mixer~.pd
new file mode 100755
index 0000000..1063de1
--- /dev/null
+++ b/signal/mixer~.pd
@@ -0,0 +1,87 @@
+#N canvas 205 153 590 395 10;
+#X obj 163 120 osc~ 220;
+#X obj 186 297 dac~;
+#X obj 163 140 *~ 0.1;
+#X obj 217 120 osc~ 220;
+#X obj 217 140 *~ 0.1;
+#X obj 272 120 osc~ 220;
+#X obj 272 140 *~ 0.1;
+#X obj 325 120 osc~ 220;
+#X obj 325 140 *~ 0.1;
+#X floatatom 217 97 0 0 0;
+#X floatatom 273 98 0 0 0;
+#X floatatom 326 95 0 0 0;
+#X floatatom 166 96 0 0 0;
+#X msg 106 175 1 \$1;
+#X msg 104 198 2 \$1;
+#X msg 104 221 3 \$1;
+#X floatatom 58 114 0 0 0;
+#X floatatom 58 153 0 0 0;
+#X floatatom 59 201 0 0 0;
+#X floatatom 59 84 0 0 0;
+#X msg 105 143 0 \$1;
+#X obj 196 246 mixer~ 20 --------------------------------------;
+#X obj 386 119 osc~ 220;
+#X obj 386 139 *~ 0.1;
+#X obj 440 119 osc~ 220;
+#X obj 440 139 *~ 0.1;
+#X obj 495 119 osc~ 220;
+#X obj 495 139 *~ 0.1;
+#X obj 548 119 osc~ 220;
+#X obj 548 139 *~ 0.1;
+#X floatatom 440 96 0 0 0;
+#X floatatom 496 97 0 0 0;
+#X floatatom 549 94 0 0 0;
+#X floatatom 389 95 0 0 0;
+#X floatatom 55 251 0 0 0;
+#X floatatom 55 290 0 0 0;
+#X floatatom 56 338 0 0 0;
+#X floatatom 56 221 0 0 0;
+#X msg 102 280 4 \$1;
+#X msg 103 312 5 \$1;
+#X msg 101 335 6 \$1;
+#X msg 101 358 7 \$1;
+#X text 57 7 The beginnig of a dynamic mixer matrix object \, implemented
+together with Oswald;
+#X connect 0 0 2 0;
+#X connect 2 0 21 0;
+#X connect 3 0 4 0;
+#X connect 4 0 21 1;
+#X connect 5 0 6 0;
+#X connect 6 0 21 2;
+#X connect 7 0 8 0;
+#X connect 8 0 21 3;
+#X connect 9 0 3 0;
+#X connect 10 0 5 0;
+#X connect 11 0 7 0;
+#X connect 12 0 0 0;
+#X connect 13 0 21 0;
+#X connect 14 0 21 0;
+#X connect 15 0 21 0;
+#X connect 16 0 13 0;
+#X connect 17 0 14 0;
+#X connect 18 0 15 0;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 1 0;
+#X connect 21 0 1 1;
+#X connect 22 0 23 0;
+#X connect 23 0 21 4;
+#X connect 24 0 25 0;
+#X connect 25 0 21 5;
+#X connect 26 0 27 0;
+#X connect 27 0 21 6;
+#X connect 28 0 29 0;
+#X connect 29 0 21 7;
+#X connect 30 0 24 0;
+#X connect 31 0 26 0;
+#X connect 32 0 28 0;
+#X connect 33 0 22 0;
+#X connect 34 0 39 0;
+#X connect 35 0 40 0;
+#X connect 36 0 41 0;
+#X connect 37 0 38 0;
+#X connect 38 0 21 0;
+#X connect 39 0 21 0;
+#X connect 40 0 21 0;
+#X connect 41 0 21 0;
diff --git a/signal/pipewrite~.c b/signal/pipewrite~.c
new file mode 100755
index 0000000..fe332f8
--- /dev/null
+++ b/signal/pipewrite~.c
@@ -0,0 +1,216 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include "m_imp.h"
+//#include <m_pd.h>
+#include "g_canvas.h"
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+/*
+ * -------------------------- pipewrite~ -------------------------------
+ */
+
+#define MAX_CHANS 4
+#define BLOCKTIME 0.001
+#define uint32 unsigned int
+#define uint16 unsigned short
+
+static t_class *pipewrite_class;
+
+typedef struct _pipewrite
+{
+ t_object x_obj;
+ t_symbol* filename;
+ int x_file;
+ t_int x_channels;
+ t_int size;
+ t_glist * x_glist;
+ t_int x_blocked;
+ t_int x_blockwarn;
+ short maxval;
+} t_pipewrite;
+
+static void pipewrite_close(t_pipewrite *x)
+{
+ if (x->x_file > 0) {
+ close(x->x_file);
+ }
+ x->x_file = -1;
+ x->size=0;
+}
+
+
+static void pipewrite_open(t_pipewrite *x,t_symbol *filename)
+{
+ char fname[MAXPDSTRING];
+
+ if (filename == &s_) {
+ post("pipewrite: open without filename");
+ return;
+ }
+
+ canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name,
+ fname, MAXPDSTRING);
+ x->x_blocked = 0;
+ x->filename = filename;
+ x->maxval=0;
+ x->size=0;
+ post("pipewrite: filename = %s",x->filename->s_name);
+
+ pipewrite_close(x);
+
+ if ((x->x_file = open(fname,O_WRONLY | O_NONBLOCK)) < 0)
+ {
+
+ error("can't open pipe %s: ",fname);
+ perror("system says");
+ return;
+ }
+}
+
+static void pipewrite_block(t_pipewrite *x, t_floatarg f)
+{
+ x->x_blockwarn = f;
+}
+
+
+static short out[4*64];
+
+static t_int *pipewrite_perform(t_int *w)
+{
+ t_pipewrite* x = (t_pipewrite*)(w[1]);
+ t_float * in[4];
+ int c = x->x_channels;
+ int i,num,n;
+ short* tout = out;
+ int ret;
+ double timebefore,timeafter;
+ double late;
+ struct sigaction action;
+ struct sigaction oldaction;
+
+
+ if (x->x_file < 0) {
+ pipewrite_open(x,x->filename);
+ }
+
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &action, &oldaction);
+
+ for (i=0;i < c;i++) {
+ in[i] = (t_float *)(w[2+i]);
+ }
+
+ n = num = (int)(w[2+c]);
+
+ /* loop */
+
+ if (x->x_file >= 0) {
+
+ while (n--) {
+ for (i=0;i<c;i++) {
+ if (*(in[i]) > 1. ) { *(in[i]) = 1. ; }
+ if (*(in[i]) < -1. ) { *(in[i]) = -1. ; }
+ *tout++ = (*(in[i])++ * 32768.);
+ }
+ }
+
+ timebefore = sys_getrealtime();
+ if ((ret = write(x->x_file,out,sizeof(short)*num*c)) < sizeof(short)*num*c) {
+ post("pipewrite: short write %d",ret);
+
+ }
+
+ timeafter = sys_getrealtime();
+ late = timeafter - timebefore;
+ x->size +=ret;
+ /* OK, we let only 10 ms block here */
+ if (late > BLOCKTIME && x->x_blockwarn) {
+ x->x_blocked++;
+ if (x->x_blocked > x->x_blockwarn) {
+ x->x_blocked=0;
+/* post("maximum blockcount %d reached",x->x_blockwarn); */
+ }
+ }
+ }
+
+ sigaction(SIGPIPE, &oldaction, NULL);
+
+ return (w+3+c);
+}
+
+
+
+static void pipewrite_dsp(t_pipewrite *x, t_signal **sp)
+{
+ switch (x->x_channels) {
+ case 1:
+ dsp_add(pipewrite_perform, 3, x, sp[0]->s_vec,
+ sp[0]->s_n);
+ break;
+ case 2:
+ dsp_add(pipewrite_perform, 4, x, sp[0]->s_vec,
+ sp[1]->s_vec, sp[0]->s_n);
+ break;
+ case 4:
+ dsp_add(pipewrite_perform, 6, x, sp[0]->s_vec,
+ sp[1]->s_vec,
+ sp[2]->s_vec,
+ sp[3]->s_vec,
+ sp[0]->s_n);
+ break;
+ }
+}
+
+static void pipewrite_free(t_pipewrite* x)
+{
+ pipewrite_close(x);
+}
+
+
+static void *pipewrite_new(t_symbol* name,t_floatarg chan)
+{
+ t_pipewrite *x = (t_pipewrite *)pd_new(pipewrite_class);
+ t_int c = chan;
+
+ if (c<1 || c > MAX_CHANS) c = 1;
+
+ x->x_glist = (t_glist*) canvas_getcurrent();
+ x->x_channels = c--;
+ post("channels:%d",x->x_channels);
+ x->x_file=0;
+ x->x_blocked = 0;
+ x->x_blockwarn = 10;
+ while (c--) {
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ }
+
+ if (name && name != &s_) { /* start the pipe */
+ pipewrite_open(x,name);
+ }
+
+ return (x);
+}
+
+void pipewrite_tilde_setup(void)
+{
+ pipewrite_class = class_new(gensym("pipewrite~"), (t_newmethod)pipewrite_new, (t_method)pipewrite_free,
+ sizeof(t_pipewrite), 0,A_DEFSYM,A_DEFFLOAT,A_NULL);
+ class_addmethod(pipewrite_class,nullfn,gensym("signal"), 0);
+ class_addmethod(pipewrite_class, (t_method) pipewrite_dsp, gensym("dsp"), 0);
+ class_addmethod(pipewrite_class, (t_method) pipewrite_open, gensym("open"), A_SYMBOL,A_NULL);
+ class_addmethod(pipewrite_class, (t_method) pipewrite_close, gensym("close"), 0);
+ class_addmethod(pipewrite_class, (t_method)pipewrite_block,gensym("block"),A_DEFFLOAT,0);
+
+}
diff --git a/signal/rtin~.c b/signal/rtin~.c
new file mode 100755
index 0000000..d086003
--- /dev/null
+++ b/signal/rtin~.c
@@ -0,0 +1,76 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <sys/time.h>
+ #include <unistd.h>
+
+// int gettimeofday(struct timeval *tv, struct timezone *tz);
+
+
+
+#include "math.h"
+#include <m_pd.h>
+
+
+/* ----------------------------- rtin ----------------------------- */
+static t_class *rtin_class;
+
+
+#define INVTWOPI 0.15915494f
+
+typedef struct _rtin
+{
+ t_object x_obj;
+ t_int fd;
+ t_int usec;
+} t_rtin;
+
+static void *rtin_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_rtin *x = (t_rtin *)pd_new(rtin_class);
+ /* inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);*/
+ outlet_new(&x->x_obj, &s_float);
+
+ x->usec=0;
+ x->fd = open("/dev/midi00",O_RDWR|O_NDELAY);
+
+ return (x);
+
+}
+
+t_int *rtin_perform(t_int *w)
+{
+ struct timeval tv;
+ long diff;
+ t_rtin* x = (t_rtin *)(w[1]);
+// int n = (int)(w[2]);
+ char c;
+
+
+ if (read(x->fd,&c,1) == 1) {
+ gettimeofday(&tv, NULL);
+ diff = tv.tv_usec - x->usec;
+ if (diff < 0) diff+=1000000;
+ if (diff > 10000) outlet_float(x->x_obj.ob_outlet,diff*0.001);
+ x->usec=tv.tv_usec;
+ }
+
+
+ return (w+2);
+}
+
+static void rtin_dsp(t_rtin *x, t_signal **sp)
+{
+ dsp_add(rtin_perform, 1, x);
+}
+
+void rtin_tilde_setup(void)
+{
+ rtin_class = class_new(gensym("rtin~"), (t_newmethod)rtin_new, 0,
+ sizeof(t_rtin), 0, A_GIMME, 0);
+ class_addmethod(rtin_class, nullfn, gensym("signal"), 0);
+ class_addmethod(rtin_class, (t_method)rtin_dsp, gensym("dsp"), 0);
+}
diff --git a/signal/rtin~.pd b/signal/rtin~.pd
new file mode 100755
index 0000000..176be1a
--- /dev/null
+++ b/signal/rtin~.pd
@@ -0,0 +1,32 @@
+#N canvas 321 9 450 300 10;
+#X obj 121 96 noise~;
+#X obj 139 202 dac~;
+#X obj 152 157 *~;
+#X obj 210 121 line~;
+#X msg 175 34 bang;
+#X obj 332 193 print;
+#X msg 141 69 1 \, 0 10;
+#X obj 270 89 int;
+#X obj 329 86 + 1;
+#X obj 263 141 sel 0;
+#X floatatom 274 167 5 0 0;
+#X obj 366 82 metro 20;
+#X floatatom 355 52 5 0 0;
+#X obj 270 110 % 8;
+#X obj 227 15 rtin~;
+#X msg 231 48 bang;
+#X connect 0 0 2 0;
+#X connect 2 0 1 0;
+#X connect 2 0 1 1;
+#X connect 3 0 2 1;
+#X connect 4 0 6 0;
+#X connect 6 0 3 0;
+#X connect 7 0 13 0;
+#X connect 8 0 7 1;
+#X connect 9 0 6 0;
+#X connect 12 0 11 1;
+#X connect 13 0 8 0;
+#X connect 13 0 9 0;
+#X connect 13 0 10 0;
+#X connect 14 0 15 0;
+#X connect 15 0 7 0;
diff --git a/signal/sfread~.c b/signal/sfread~.c
new file mode 100755
index 0000000..6cb97ab
--- /dev/null
+++ b/signal/sfread~.c
@@ -0,0 +1,317 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_imp.h>
+/*#include <m_pd.h>*/
+#include "g_canvas.h"
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#ifndef NT
+#include <unistd.h>
+#include <sys/mman.h>
+#else
+#include <io.h>
+#endif
+
+
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* ------------------------ sfread~ ----------------------------- */
+
+#ifdef NT
+#define BINREADMODE "rb"
+#else
+#define BINREADMODE "r"
+#endif
+
+static t_class *sfread_class;
+
+
+typedef struct _sfread
+{
+ t_object x_obj;
+ void* x_mapaddr;
+ int x_fd;
+
+ t_int x_play;
+ t_int x_channels;
+ t_int x_size;
+ t_int x_loop;
+ t_float x_offset;
+ t_float x_skip;
+ t_float x_speed;
+
+ t_glist * x_glist;
+ t_outlet *x_bangout;
+} t_sfread;
+
+
+void sfread_open(t_sfread *x,t_symbol *filename)
+{
+ struct stat fstate;
+ char fname[MAXPDSTRING];
+
+ if (filename == &s_) {
+ post("sfread: open without filename");
+ return;
+ }
+
+ canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name,
+ fname, MAXPDSTRING);
+
+
+ /* close the old file */
+
+ if (x->x_mapaddr) munmap(x->x_mapaddr,x->x_size);
+ if (x->x_fd >= 0) close(x->x_fd);
+
+ if ((x->x_fd = open(fname,O_RDONLY)) < 0)
+ {
+ error("can't open %s",fname);
+ x->x_play = 0;
+ x->x_mapaddr = NULL;
+ return;
+ }
+
+ /* get the size */
+
+ fstat(x->x_fd,&fstate);
+ x->x_size = fstate.st_size;
+
+ /* map the file into memory */
+
+ if (!(x->x_mapaddr = mmap(NULL,x->x_size,PROT_READ,MAP_PRIVATE,x->x_fd,0)))
+ {
+ error("can't mmap %s",fname);
+ return;
+ }
+}
+
+#define MAX_CHANS 4
+
+static t_int *sfread_perform(t_int *w)
+{
+ t_sfread* x = (t_sfread*)(w[1]);
+ short* buf = x->x_mapaddr;
+/* t_float *in = (t_float *)(w[2]); will we need this (indexing) ?*/
+ int c = x->x_channels;
+ t_float offset = x->x_offset*c;
+ t_float speed = x->x_speed;
+ int i,n;
+ int end = x->x_size/sizeof(short);
+ t_float* out[MAX_CHANS];
+
+ for (i=0;i<c;i++)
+ out[i] = (t_float *)(w[3+i]);
+ n = (int)(w[3+c]);
+
+ /* loop */
+
+ if (offset > end)
+ offset = end;
+
+ if (offset + n*c*speed > end) { // playing forward end
+ if (!x->x_loop) {
+ x->x_play=0;
+ offset = x->x_skip*c;
+ }
+ }
+
+ if (offset + n*c*speed < 0) { // playing backwards end
+ if (!x->x_loop) {
+ x->x_play=0;
+ offset = end;
+ }
+
+ }
+
+
+ if (x->x_play && x->x_mapaddr) {
+
+ if (speed != 1) { /* different speed */
+ float aoff = (((int)offset)>>1)<<1;
+ while (n--) {
+ for (i=0;i<c;i++) {
+ *out[i]++ = *(buf+(int)aoff+i)*3.052689e-05;
+ }
+ offset+=speed*c;
+ aoff = (((int)offset)>>1)<<1;
+ if (aoff > end) {
+ if (x->x_loop) aoff = x->x_skip;
+ else break;
+ }
+ if (aoff < 0) {
+ if (x->x_loop) aoff = end;
+ else break;
+ }
+ }
+ /* Fill with zero in case of end */
+ n++;
+ while (n--)
+ for (i=0;i<c;i++)
+ *out[i]++ = 0;
+ offset = aoff;
+ }
+ else { /* speed == 1 */
+ int aoff = (((int)offset)>>1)<<1;
+ while (n--) {
+ for (i=0;i<c;i++) {
+ *out[i]++ = *(buf+aoff+i)*3.052689e-05;
+ }
+ aoff+=c;
+ if (aoff > end) {
+ if (x->x_loop) aoff = x->x_skip;
+ else break;
+ }
+ }
+
+ /* Fill with zero in case of end */
+ n++;
+ while (n--)
+ for (i=0;i<c;i++)
+ *out[i]++ = 0.;
+ offset = aoff;
+ }
+
+ }
+ else {
+ while (n--) {
+ for (i=0;i<c;i++)
+ *out[i]++ = 0.;
+ }
+ }
+ x->x_offset = offset/c; /* this should always be integer !! */
+ return (w+c+4);
+}
+
+
+static void sfread_float(t_sfread *x, t_floatarg f)
+{
+ int t = f;
+ if (t && x->x_mapaddr) {
+ x->x_play=1;
+ }
+ else {
+ x->x_play=0;
+ }
+
+}
+
+static void sfread_loop(t_sfread *x, t_floatarg f)
+{
+ x->x_loop = f;
+}
+
+
+
+static void sfread_size(t_sfread* x)
+{
+ t_atom a;
+
+ SETFLOAT(&a,x->x_size*0.5/x->x_channels);
+ outlet_list(x->x_bangout, gensym("size"),1,&a);
+}
+
+static void sfread_state(t_sfread* x)
+{
+ t_atom a;
+
+ SETFLOAT(&a,x->x_play);
+ outlet_list(x->x_bangout, gensym("state"),1,&a);
+}
+
+
+
+
+static void sfread_bang(t_sfread* x)
+{
+ x->x_offset = x->x_skip*x->x_channels;
+ sfread_float(x,1.0);
+}
+
+
+static void sfread_dsp(t_sfread *x, t_signal **sp)
+{
+/* post("sfread: dsp"); */
+ switch (x->x_channels) {
+ case 1:
+ dsp_add(sfread_perform, 4, x, sp[0]->s_vec,
+ sp[1]->s_vec, sp[0]->s_n);
+ break;
+ case 2:
+ dsp_add(sfread_perform, 5, x, sp[0]->s_vec,
+ sp[1]->s_vec,sp[2]->s_vec, sp[0]->s_n);
+ break;
+ case 4:
+ dsp_add(sfread_perform, 6, x, sp[0]->s_vec,
+ sp[1]->s_vec,sp[2]->s_vec,
+ sp[3]->s_vec,sp[4]->s_vec,
+ sp[0]->s_n);
+ break;
+ }
+}
+
+
+static void *sfread_new(t_floatarg chan,t_floatarg skip)
+{
+ t_sfread *x = (t_sfread *)pd_new(sfread_class);
+ t_int c = chan;
+
+ x->x_glist = (t_glist*) canvas_getcurrent();
+
+ if (c<1 || c > MAX_CHANS) c = 1;
+ floatinlet_new(&x->x_obj, &x->x_offset);
+ floatinlet_new(&x->x_obj, &x->x_speed);
+
+
+ x->x_fd = -1;
+ x->x_mapaddr = NULL;
+
+ x->x_size = 0;
+ x->x_loop = 0;
+ x->x_channels = c;
+ x->x_mapaddr=NULL;
+ x->x_offset = skip;
+ x->x_skip = skip;
+ x->x_speed = 1.0;
+ x->x_play = 0;
+
+ while (c--) {
+ outlet_new(&x->x_obj, gensym("signal"));
+ }
+
+ x->x_bangout = outlet_new(&x->x_obj, &s_float);
+
+/* post("sfread: x_channels = %d, x_speed = %f",x->x_channels,x->x_speed);*/
+
+ return (x);
+}
+
+void sfread_tilde_setup(void)
+{
+ /* sfread */
+
+ sfread_class = class_new(gensym("sfread~"), (t_newmethod)sfread_new, 0,
+ sizeof(t_sfread), 0,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addmethod(sfread_class, nullfn, gensym("signal"), 0);
+ class_addmethod(sfread_class, (t_method) sfread_dsp, gensym("dsp"), 0);
+ class_addmethod(sfread_class, (t_method) sfread_open, gensym("open"), A_SYMBOL,A_NULL);
+ class_addmethod(sfread_class, (t_method) sfread_size, gensym("size"), 0);
+ class_addmethod(sfread_class, (t_method) sfread_state, gensym("state"), 0);
+ class_addfloat(sfread_class, sfread_float);
+ class_addbang(sfread_class,sfread_bang);
+ class_addmethod(sfread_class,(t_method)sfread_loop,gensym("loop"),A_FLOAT,A_NULL);
+
+}
+
+
+
+
+
+
diff --git a/signal/sfread~.pd b/signal/sfread~.pd
new file mode 100755
index 0000000..5cc1058
--- /dev/null
+++ b/signal/sfread~.pd
@@ -0,0 +1,44 @@
+#N canvas 89 114 600 456 8;
+#X msg 34 135 bang;
+#X obj 228 324 dac~;
+#X msg 70 218 1;
+#X floatatom 348 128;
+#X text 14 33 file to open;
+#X text 33 116 start playback;
+#X msg 70 240 0;
+#X text 34 10 SFREAD;
+#X text 34 21 =======;
+#X text 346 96 playback speed (defaults to 1);
+#X text 93 8 The file should have the systems samplerate (44100) and endianess matching the machine.;
+#X text 25 257 pause on/off during playback;
+#X text 277 46 resets sound to position;
+#X msg 322 63 200;
+#X text 288 164 instatiation: sfread <channels> <skip>;
+#X text 276 35 start position in samples (defaults to <skip>);
+#X floatatom 231 102;
+#X msg 172 114 loop 1;
+#X msg 152 94 loop 0;
+#X msg 364 224 size;
+#X floatatom 336 275;
+#X text 333 205 Get the size (in frames);
+#X obj 207 164 sfread~ 2 62;
+#X msg 14 85 open \$1;
+#X obj 14 66 openpanel;
+#X msg 69 66 bang;
+#X msg 365 249 state;
+#X connect 0 0 22 0;
+#X connect 2 0 22 0;
+#X connect 3 0 22 2;
+#X connect 6 0 22 0;
+#X connect 13 0 22 1;
+#X connect 16 0 22 1;
+#X connect 17 0 22 0;
+#X connect 18 0 22 0;
+#X connect 19 0 22 0;
+#X connect 22 0 1 0;
+#X connect 22 1 1 1;
+#X connect 22 2 20 0;
+#X connect 23 0 22 0;
+#X connect 24 0 23 0;
+#X connect 25 0 24 0;
+#X connect 26 0 22 0;
diff --git a/signal/sfwrite.pd b/signal/sfwrite.pd
new file mode 100755
index 0000000..1426cf3
--- /dev/null
+++ b/signal/sfwrite.pd
@@ -0,0 +1,45 @@
+#N canvas 340 71 600 460 12;
+#X obj 185 96 sfwrite~ 2;
+#X msg 65 16 open test.wav;
+#X floatatom 185 16;
+#X msg 147 308 0;
+#X obj 232 17 adc~;
+#X msg 91 278 0;
+#X msg 59 278 1;
+#X obj 142 222 table;
+#X msg 136 171 bang;
+#X msg 32 171 resize 441000;
+#X msg 181 172 read16 test.wav 200 l;
+#X obj 417 104 env~;
+#X obj 298 34 osc~ 220;
+#X obj 125 396 dac~;
+#X floatatom 411 10;
+#X obj 125 341 sfread~ 2;
+#X obj 281 379 dbtorms;
+#X obj 281 279 slider 96 0 15;
+#X obj 159 372 *~ 0;
+#X obj 125 372 *~ 0;
+#X msg 125 277 open test.wav \, bang;
+#X floatatom 417 129;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 15 1;
+#X connect 5 0 15 0;
+#X connect 6 0 15 0;
+#X connect 8 0 7 0;
+#X connect 9 0 7 0;
+#X connect 10 0 7 0;
+#X connect 11 0 21 0;
+#X connect 12 0 0 0;
+#X connect 12 0 0 1;
+#X connect 12 0 11 0;
+#X connect 12 0 19 0;
+#X connect 12 0 18 0;
+#X connect 14 0 12 0;
+#X connect 15 0 19 0;
+#X connect 15 1 18 0;
+#X connect 16 0 18 1;
+#X connect 16 0 19 1;
+#X connect 18 0 13 1;
+#X connect 19 0 13 0;
+#X connect 20 0 15 0;
diff --git a/signal/sfwrite~.c b/signal/sfwrite~.c
new file mode 100755
index 0000000..9a999c9
--- /dev/null
+++ b/signal/sfwrite~.c
@@ -0,0 +1,284 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_imp.h>
+/*#include <m_pd.h>*/
+#include "g_canvas.h"
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#ifndef NT
+#include <unistd.h>
+#include <sys/mman.h>
+#else
+#include <io.h>
+#endif
+#include <fcntl.h>
+#include <sys/stat.h>
+
+
+#ifdef NT
+#define BINREADMODE "rb"
+#define OPENPARAMS O_WRONLY | O_CREAT | O_TRUNC
+#else
+#define BINREADMODE "r"
+#define OPENPARAMS O_WRONLY | O_CREAT | O_NONBLOCK | O_TRUNC
+#endif
+#define MAX_CHANS 4
+
+
+/*
+ * ------------------------------------------- sfwrite~ -------------------------------
+ */
+
+#define BLOCKTIME 0.01
+#define uint32 unsigned int
+#define uint16 unsigned short
+
+static t_class *sfwrite_class;
+
+typedef struct _sfwrite
+{
+ t_object x_obj;
+ t_symbol* filename;
+ int x_file;
+
+ t_int rec;
+ t_int x_channels;
+ uint32 size;
+ t_glist * x_glist;
+ t_int x_blocked;
+ t_int x_blockwarn;
+} t_sfwrite;
+
+typedef struct _wave
+{
+ char w_fileid[4]; /* chunk id 'RIFF' */
+ uint32 w_chunksize; /* chunk size */
+ char w_waveid[4]; /* wave chunk id 'WAVE' */
+ char w_fmtid[4]; /* format chunk id 'fmt ' */
+ uint32 w_fmtchunksize; /* format chunk size */
+ uint16 w_fmttag; /* format tag, 1 for PCM */
+ uint16 w_nchannels; /* number of channels */
+ uint32 w_samplespersec; /* sample rate in hz */
+ uint32 w_navgbytespersec; /* average bytes per second */
+ uint16 w_nblockalign; /* number of bytes per sample */
+ uint16 w_nbitspersample; /* number of bits in a sample */
+ char w_datachunkid[4]; /* data chunk id 'data' */
+ uint32 w_datachunksize; /* length of data chunk */
+} t_wave;
+
+
+static void sfwrite_wave_setup(t_sfwrite* x,t_wave* w)
+{
+
+ strncpy(w->w_fileid,"RIFF",4); /* chunk id 'RIFF' */
+ w->w_chunksize = x->size + sizeof(t_wave) -8; /* chunk size */
+ strncpy(w->w_waveid,"WAVE",4); /* wave chunk id 'WAVE' */
+ strncpy(w->w_fmtid,"fmt ",4); /* format chunk id 'fmt '*/
+ w->w_fmtchunksize = 16; /* format chunk size */
+ w->w_fmttag = 1; /* format tag, 1 for PCM */
+ w->w_nchannels = x->x_channels; /* number of channels */
+ w->w_samplespersec = 44100; /* sample rate in hz */
+ w->w_navgbytespersec = 44100*x->x_channels*2; /* average bytes per second */
+ w->w_nblockalign = 4; /* number of bytes per sample */
+ w->w_nbitspersample = 16; /* number of bits in a sample */
+ strncpy(w->w_datachunkid,"data",4); /* data chunk id 'data'*/
+ w->w_datachunksize = x->size; /* length of data chunk */
+}
+
+
+
+static void sfwrite_close(t_sfwrite *x)
+{
+ if (x->x_file > 0) {
+ t_wave w;
+ sfwrite_wave_setup(x,&w);
+ lseek(x->x_file,0,SEEK_SET);
+ write(x->x_file,&w,sizeof(w));
+ close(x->x_file);
+ }
+ x->x_file = -1;
+}
+
+
+static void sfwrite_open(t_sfwrite *x,t_symbol *filename)
+{
+ char fname[MAXPDSTRING];
+
+ if (filename == &s_) {
+ post("sfwrite: open without filename");
+ return;
+ }
+
+ canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name,
+ fname, MAXPDSTRING);
+
+ x->x_blocked = 0;
+ x->filename = filename;
+ post("sfwrite: filename = %s",x->filename->s_name);
+
+ sfwrite_close(x);
+
+ if ((x->x_file = open(fname,OPENPARAMS,0664)) < 0)
+ {
+ error("can't create %s",fname);
+ return;
+ }
+
+ /* skip the header */
+
+ lseek(x->x_file,sizeof(t_wave),SEEK_SET);
+ x->size = 0;
+
+
+}
+
+static void sfwrite_block(t_sfwrite *x, t_floatarg f)
+{
+ x->x_blockwarn = f;
+}
+
+
+static void sfwrite_float(t_sfwrite *x, t_floatarg f)
+{
+ int t = f;
+ if (t) {
+ post("sfwrite: start", f);
+ x->rec=1;
+ }
+ else {
+ post("sfwrite: stop", f);
+ x->rec=0;
+ }
+
+}
+
+
+static short out[4*64];
+
+static t_int *sfwrite_perform(t_int *w)
+{
+ t_sfwrite* x = (t_sfwrite*)(w[1]);
+ t_float * in[4];
+ int c = x->x_channels;
+ int i,num,n;
+ short* tout = out;
+ int ret;
+ double timebefore,timeafter;
+ double late;
+
+ for (i=0;i < c;i++) {
+ in[i] = (t_float *)(w[2+i]);
+ }
+
+ n = num = (int)(w[2+c]);
+
+ /* loop */
+
+ if (x->rec && x->x_file) {
+
+ while (n--) {
+ for (i=0;i<c;i++) {
+ *tout++ = *(in[i])++ * 32768.;
+ }
+ }
+
+ timebefore = sys_getrealtime();
+ if ((ret =write(x->x_file,out,sizeof(short)*num*c)) < (signed int)sizeof(short)*num*c) {
+ post("sfwrite: short write %d",ret);
+
+ }
+ timeafter = sys_getrealtime();
+ late = timeafter - timebefore;
+
+ /* OK, we let only 10 ms block here */
+ if (late > BLOCKTIME && x->x_blockwarn) {
+ post("sfwrite blocked %f ms",late*1000);
+ x->x_blocked++;
+ if (x->x_blocked > x->x_blockwarn) {
+ x->rec = 0;
+ post("maximum blockcount %d reached, recording stopped (set blockcount with \"block <num>\"",x->x_blockwarn);
+ }
+ }
+ x->size +=64*x->x_channels*sizeof(short) ;
+ }
+
+ return (w+3+c);
+}
+
+
+
+static void sfwrite_dsp(t_sfwrite *x, t_signal **sp)
+{
+ switch (x->x_channels) {
+ case 1:
+ dsp_add(sfwrite_perform, 3, x, sp[0]->s_vec,
+ sp[0]->s_n);
+ break;
+ case 2:
+ dsp_add(sfwrite_perform, 4, x, sp[0]->s_vec,
+ sp[1]->s_vec, sp[0]->s_n);
+ break;
+ case 4:
+ dsp_add(sfwrite_perform, 6, x, sp[0]->s_vec,
+ sp[1]->s_vec,
+ sp[2]->s_vec,
+ sp[3]->s_vec,
+ sp[0]->s_n);
+ break;
+ }
+}
+
+static void sfwrite_free(t_sfwrite* x)
+{
+ sfwrite_close(x);
+}
+
+
+static void *sfwrite_new(t_floatarg chan)
+{
+ t_sfwrite *x = (t_sfwrite *)pd_new(sfwrite_class);
+ t_int c = chan;
+
+ if (c<1 || c > MAX_CHANS) c = 1;
+
+ x->x_glist = (t_glist*) canvas_getcurrent();
+ x->x_channels = c--;
+ x->x_file=0;
+ x->rec = 0;
+ x->size = 0;
+ x->x_blocked = 0;
+ x->x_blockwarn = 10;
+ while (c--) {
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ }
+
+
+ return (x);
+}
+
+void sfwrite_tilde_setup(void)
+{
+ sfwrite_class = class_new(gensym("sfwrite~"), (t_newmethod)sfwrite_new, (t_method)sfwrite_free,
+ sizeof(t_sfwrite), 0,A_DEFFLOAT,0);
+ class_addmethod(sfwrite_class,nullfn,gensym("signal"), 0);
+ class_addmethod(sfwrite_class, (t_method) sfwrite_dsp, gensym("dsp"), 0);
+ class_addmethod(sfwrite_class, (t_method) sfwrite_open, gensym("open"), A_SYMBOL,A_NULL);
+ class_addmethod(sfwrite_class, (t_method) sfwrite_close, gensym("close"), 0);
+ class_addmethod(sfwrite_class, (t_method)sfwrite_block,gensym("block"),A_DEFFLOAT,0);
+ class_addfloat(sfwrite_class, sfwrite_float);
+
+}
+
+
+
+
+
+
+
+
diff --git a/signal/stream.h b/signal/stream.h
new file mode 100755
index 0000000..331cf30
--- /dev/null
+++ b/signal/stream.h
@@ -0,0 +1,30 @@
+/* (C) Guenter Geiger 1999 */
+
+#define SF_FLOAT 1
+#define SF_DOUBLE 2
+#define SF_8BIT 10
+#define SF_16BIT 11
+#define SF_32BIT 12
+#define SF_ALAW 20
+#define SF_MP3 30
+
+#define SF_SIZEOF(a) (a == SF_FLOAT ? sizeof(t_float) : \
+ a == SF_16BIT ? sizeof(short) : 1)
+
+
+
+typedef struct _tag { /* size (bytes) */
+ char version; /* 1 */
+ char format; /* 1 */
+ int count; /* 4 */
+ char channels; /* 1 */
+ int framesize; /* 4 */
+ char extension[5]; /* 5 */
+} t_tag; /*--------------*/
+ /* 16 */
+
+
+typedef struct _frame {
+ t_tag tag;
+ char* data;
+} t_frame;
diff --git a/signal/streamin~.c b/signal/streamin~.c
new file mode 100755
index 0000000..54ab283
--- /dev/null
+++ b/signal/streamin~.c
@@ -0,0 +1,404 @@
+
+/* Written by Guenter Geiger <geiger@debian.org> (C) 1999 */
+
+#include <m_pd.h>
+#include "stream.h"
+
+#include <sys/types.h>
+#include <string.h>
+#ifdef unix
+#include <sys/socket.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#define SOCKET_ERROR -1
+#else
+#include <winsock.h>
+#endif
+
+
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#ifdef unix
+#define NONBLOCKED
+#endif
+#define INBUFSIZE 8192
+#define MAXFRAMES 128
+#define MAXFRAMESIZE 256
+#define AVERAGENUM 10
+
+/*#define DEBUGMESS(x) x*/
+#define DEBUGMESS(x)
+
+/* Utility functions */
+
+/* TODO !!!!
+ - check udp support
+*/
+
+
+#ifdef NT
+extern int close(int);
+extern void sys_rmpollfn(int fd);
+extern sys_addpollfn(int fd, void* fn, void *ptr);
+#endif
+
+static void sys_sockerror(char *s)
+{
+#ifdef unix
+ int err = errno;
+#else
+ int err = WSAGetLastError();
+ if (err == 10054) return;
+#endif
+ post("%s: %s (%d)\n", s, strerror(err), err);
+}
+
+
+static void sys_closesocket(int fd)
+{
+#ifdef UNIX
+ close(fd);
+#endif
+#ifdef NT
+ closesocket(fd);
+#endif
+}
+
+
+int setsocketoptions(int sockfd)
+{
+#ifdef unix
+ int sockopt = 1;
+ if (setsockopt(sockfd, SOL_TCP, TCP_NODELAY, (const char*) &sockopt, sizeof(int)) < 0)
+ DEBUGMESS(post("setsockopt NODELAY failed\n"));
+ else
+ DEBUGMESS(post("TCP_NODELAY set"));
+
+ /* if we don`t use REUSEADDR we have to wait under unix until the
+ address gets freed after a close ... this can be very annoying
+ when working with netsend/netreceive GG
+ */
+
+ sockopt = 1;
+ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int)) < 0)
+ post("setsockopt failed\n");
+#endif
+ return 0;
+}
+
+
+
+/* ------------------------ streamin~ ----------------------------- */
+
+
+static t_class *streamin_class;
+
+
+
+typedef struct _streamin
+{
+ t_object x_obj;
+ int x_socket;
+ int x_connectsocket;
+ int x_nconnections;
+ int x_ndrops;
+ int x_fd;
+ int x_tcp;
+
+ /* buffering */
+
+ int framein;
+ int frameout;
+ t_frame frames[MAXFRAMES];
+ int maxframes;
+
+ int nbytes;
+ int counter;
+ int average[AVERAGENUM];
+ int averagecur;
+ int underflow;
+} t_streamin;
+
+
+
+
+static void streamin_datapoll(t_streamin *x)
+{
+ int ret;
+ int n;
+ t_tag tag;
+ int i;
+
+ n = x->nbytes;
+ if (x->nbytes == 0) { /* get the new tag */
+ ret = recv(x->x_socket, (char*) &x->frames[x->framein].tag,sizeof(t_tag),MSG_PEEK);
+ if (ret != sizeof(t_tag)) return;
+ ret = recv(x->x_socket, (char*) &x->frames[x->framein].tag,sizeof(t_tag),0);
+
+ x->nbytes = n = x->frames[x->framein].tag.framesize;
+ }
+
+ ret = recv(x->x_socket, (char*) x->frames[x->framein].data + x->frames[x->framein].tag.framesize - n, n, 0);
+ if (ret > 0)
+ n-=ret;
+
+ x->nbytes = n;
+ if (n == 0) {
+ x->counter++;
+ x->framein++;
+ x->framein %= MAXFRAMES;
+ }
+}
+
+static void streamin_reset(t_streamin* x,t_floatarg frames)
+{
+ int i;
+ x->counter = 0;
+ x->nbytes = 0;
+ x->framein = 0;
+ x->frameout = 0;
+ for (i=0;i<AVERAGENUM;i++)
+ x->average[i] = x->maxframes;
+ x->averagecur=0;
+ if (frames == 0.0)
+ x->maxframes = MAXFRAMES/2;
+ else
+ x->maxframes = frames;
+ x->underflow = 0;
+}
+
+
+static void streamin_connectpoll(t_streamin *x)
+{
+ int fd = accept(x->x_connectsocket, 0, 0);
+
+#ifdef NONBLOCKED
+ fcntl(fd,F_SETFL,O_NONBLOCK);
+#endif
+ if (fd < 0) {
+ post("streamin~: accept failed");
+ return;
+ }
+
+ if (x->x_socket > 0) {
+ post("streamin~: new connection");
+ close(x->x_socket);
+ sys_rmpollfn(x->x_socket);
+ }
+
+ streamin_reset(x,0);
+ x->x_socket = fd;
+ sys_addpollfn(fd, streamin_datapoll, x);
+}
+
+
+static int streamin_createsocket(t_streamin* x, int portno,t_symbol* prot)
+{
+ struct sockaddr_in server;
+ int sockfd;
+ int tcp = x->x_tcp;
+
+ /* create a socket */
+ if (!tcp)
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ else
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (sockfd < 0)
+ {
+ sys_sockerror("socket");
+ return (0);
+ }
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+
+ /* assign server port number */
+
+ server.sin_port = htons((u_short)portno);
+ post("listening to port number %d", portno);
+
+
+ setsocketoptions(sockfd);
+
+
+ /* name the socket */
+
+ if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) {
+ sys_sockerror("bind");
+ sys_closesocket(sockfd);
+ return (0);
+ }
+
+
+ if (!tcp) {
+ x->x_socket = sockfd;
+ x->nbytes = 0;
+ sys_addpollfn(sockfd, streamin_datapoll, x);
+ }
+ else {
+ if (listen(sockfd, 5) < 0) {
+ sys_sockerror("listen");
+ sys_closesocket(sockfd);
+ }
+ else {
+ x->x_connectsocket = sockfd;
+ sys_addpollfn(sockfd, streamin_connectpoll, x);
+ }
+ }
+ return 1;
+}
+
+
+
+static void streamin_free(t_streamin *x)
+{
+ if (x->x_connectsocket > 0) {
+ sys_closesocket(x->x_connectsocket);
+ sys_rmpollfn(x->x_connectsocket);
+ }
+ sys_rmpollfn(x->x_socket);
+ sys_closesocket(x->x_socket);
+}
+
+
+#define QUEUESIZE ((x->framein + MAXFRAMES - x->frameout)%MAXFRAMES)
+
+static t_int *streamin_perform(t_int *w)
+{
+ t_streamin *x = (t_streamin*) (w[1]);
+ t_float *out = (t_float *)(w[2]);
+ int n = (int)(w[3]);
+ int ret;
+ int i = 0;
+
+ if (x->counter < x->maxframes) {
+ return (w+4);
+ }
+
+ if (x->framein == x->frameout) {
+ x->underflow++;
+ return w+4;
+ }
+
+
+ /* queue balancing */
+
+ x->average[x->averagecur] = QUEUESIZE;
+ x->averagecur++;
+ x->averagecur %= AVERAGENUM;
+
+ switch (x->frames[x->frameout].tag.format) {
+ case SF_FLOAT: {
+ t_float* buf = (t_float*)(x->frames[x->frameout].data);
+ while (n--)
+ *out++ = *buf++;
+ x->frameout++;
+ x->frameout %= MAXFRAMES;
+ break;
+ }
+ case SF_16BIT:
+ {
+ short* buf = (short*)(x->frames[x->frameout].data);
+
+ while (n--)
+ *out++ = (float) *buf++*3.051850e-05;
+ x->frameout++;
+ x->frameout %= MAXFRAMES;
+
+ break;
+ }
+ case SF_8BIT:
+ {
+ unsigned char* buf = (char*)(x->frames[x->frameout].data);
+
+ while (n--)
+ *out++ = (float) (0.0078125 * (*buf++)) - 1.0;
+ x->frameout++;
+ x->frameout %= MAXFRAMES;
+ break;
+ }
+ default:
+ post("unknown format %d",x->frames[x->frameout].tag.format);
+ break;
+ }
+
+ return (w+4);
+}
+
+
+
+static void streamin_dsp(t_streamin *x, t_signal **sp)
+{
+ dsp_add(streamin_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
+}
+
+
+static void streamin_print(t_streamin* x)
+{
+ int i;
+ int avg = 0;
+ for (i=0;i<AVERAGENUM;i++)
+ avg += x->average[i];
+ post("last size = %d, avg size = %d, %d underflows",
+ QUEUESIZE,avg,x->underflow);
+}
+
+
+
+
+static void *streamin_new(t_floatarg fportno, t_floatarg prot)
+{
+ t_streamin *x;
+ int i;
+
+ post("port %f",fportno);
+ x = (t_streamin *)pd_new(streamin_class);
+
+ x->x_connectsocket = -1;
+ x->x_socket = -1;
+ x->x_tcp = 1;
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_nconnections = 0;
+ x->x_ndrops = 0;
+
+ for (i=0;i<MAXFRAMES;i++) {
+ x->frames[i].data = getbytes(MAXFRAMESIZE);
+ }
+ x->framein = 0;
+ x->frameout = 0;
+ x->maxframes = MAXFRAMES/2;
+
+ if (prot)
+ x->x_tcp = 0;
+
+ streamin_createsocket(x, fportno, gensym("tcp"));
+
+ return (x);
+}
+
+
+
+
+
+void streamin_tilde_setup(void)
+{
+ streamin_class = class_new(gensym("streamin~"),
+ (t_newmethod) streamin_new, (t_method) streamin_free,
+ sizeof(t_streamin), 0, A_DEFFLOAT,A_DEFFLOAT, A_NULL);
+
+ class_addmethod(streamin_class, nullfn, gensym("signal"), 0);
+ class_addmethod(streamin_class, (t_method) streamin_dsp, gensym("dsp"), 0);
+ class_addmethod(streamin_class, (t_method) streamin_print,
+ gensym("print"), 0);
+ class_addmethod(streamin_class, (t_method) streamin_reset,
+ gensym("reset"),A_DEFFLOAT, 0);
+}
diff --git a/signal/streamin~.pd b/signal/streamin~.pd
new file mode 100755
index 0000000..e248f27
--- /dev/null
+++ b/signal/streamin~.pd
@@ -0,0 +1,41 @@
+#N canvas 248 65 623 459 12;
+#X obj 49 95 print~;
+#X msg 49 67 bang;
+#X obj 27 24 streamin~ 3000;
+#X obj 132 210 streamout~;
+#X msg 132 108 disconnect;
+#X obj 372 72 osc~;
+#X obj 372 47 sig~ 220;
+#X floatatom 372 20 0 0 0;
+#X msg 285 162 format float;
+#X msg 284 184 format 16bit;
+#X text 14 432 (C) 1999 Guenter Geiger;
+#X msg 286 204 format 8bit;
+#X floatatom 132 235 0 0 0;
+#X text 21 295 The streamin~ object just takes the portnumber it is
+listening to as it's argument.;
+#X text 23 334 For help on the streamout object \, see the streamout.pd
+patch.;
+#X obj 27 159 dac~;
+#X obj 355 115 *~ 0.1;
+#X floatatom 418 88 0 0 0;
+#X floatatom 149 159 0 0 0;
+#X msg 285 252 connect gige 3001;
+#X msg 132 86 connect localhost 3000;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 2 0 15 0;
+#X connect 2 0 15 1;
+#X connect 3 0 12 0;
+#X connect 4 0 3 0;
+#X connect 5 0 16 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 0;
+#X connect 8 0 3 0;
+#X connect 9 0 3 0;
+#X connect 11 0 3 0;
+#X connect 16 0 3 0;
+#X connect 17 0 16 1;
+#X connect 18 0 3 0;
+#X connect 19 0 3 0;
+#X connect 20 0 3 0;
diff --git a/signal/streamout~.c b/signal/streamout~.c
new file mode 100755
index 0000000..6e76b36
--- /dev/null
+++ b/signal/streamout~.c
@@ -0,0 +1,323 @@
+
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+#include <m_pd.h>
+#include "stream.h"
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef unix
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#define SOCKET_ERROR -1
+#else
+#include <winsock.h>
+#endif
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+/* Utility functions */
+
+static void sys_sockerror(char *s)
+{
+#ifdef unix
+ int err = errno;
+#else
+ int err = WSAGetLastError();
+ if (err == 10054) return;
+#endif
+ post("%s: %s (%d)\n", s, strerror(err), err);
+}
+
+
+
+static void sys_closesocket(int fd)
+{
+#ifdef UNIX
+ close(fd); /* shutdown() ?? */
+#endif
+#ifdef NT
+ closesocket(fd);
+#endif
+}
+
+
+/* ------------------------ streamout~ ----------------------------- */
+
+
+static t_class *streamout_class;
+
+typedef struct _streamout
+{
+ t_object x_obj;
+ int x_fd;
+ int x_protocol;
+ t_tag x_tag;
+ t_symbol* hostname;
+ int portno;
+ short* cbuf;
+ int nsamples;
+ int tbufsize;
+} t_streamout;
+
+
+
+static void streamout_tempbuf(t_streamout *x,int size) {
+
+ if (x->cbuf && x->tbufsize) freebytes(x->cbuf,x->tbufsize);
+ x->tbufsize=size;
+ if (!x->cbuf)
+ x->cbuf = getbytes(size*sizeof(short));
+ else
+ x->cbuf = resizebytes(x->cbuf,x->nsamples*sizeof(short),size*sizeof(short));
+ x->nsamples = size;
+}
+
+
+
+static void streamout_disconnect(t_streamout *x)
+{
+ if (x->x_fd >= 0)
+ {
+ sys_closesocket(x->x_fd);
+ x->x_fd = -1;
+ outlet_float(x->x_obj.ob_outlet, 0);
+ }
+}
+
+
+
+static void streamout_connect(t_streamout *x, t_symbol *hostname, t_floatarg fportno)
+{
+ struct sockaddr_in server;
+ struct hostent *hp;
+ int sockfd;
+ int portno = fportno;
+ x->hostname = hostname;
+ x->portno = (int) fportno;
+ x->x_tag.count = 0;
+
+
+ if (x->x_fd >= 0)
+ {
+ post("streamout~: already connected");
+ return;
+ }
+
+ /* create a socket */
+
+ sockfd = socket(AF_INET, x->x_protocol, 0);
+ if (sockfd < 0)
+ {
+ post("streamout: Connection to %s on port %d failed",hostname->s_name,portno);
+ sys_sockerror("socket");
+ return;
+ }
+
+ /* connect socket using hostname provided in command line */
+
+ server.sin_family = AF_INET;
+ hp = gethostbyname(x->hostname->s_name);
+ if (hp == 0)
+ {
+ post("bad host?\n");
+ return;
+ }
+ memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
+
+ /* assign client port number */
+ server.sin_port = htons((u_short)portno);
+
+ /* try to connect. LATER make a separate thread to do this
+ because it might block */
+ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0)
+ {
+ sys_sockerror("connecting stream socket");
+ sys_closesocket(sockfd);
+ return;
+ }
+
+ post("connected host %s on port %d",hostname->s_name, portno);
+
+ x->x_fd = sockfd;
+ outlet_float(x->x_obj.ob_outlet, 1);
+}
+
+
+
+static t_int *streamout_perform(t_int *w)
+{
+ t_streamout* x = (t_streamout*) (w[1]);
+ t_float *in = (t_float *)(w[2]);
+ char* bp;
+ int n = (int)(w[3]);
+ int length = n*SF_SIZEOF(x->x_tag.format);
+ int sent = 0;
+
+ if (n != x->nsamples)
+ streamout_tempbuf(x,n);
+
+ x->x_tag.framesize=length;
+ x->x_tag.count++;
+ /* format the buffer */
+ bp = (char*)in;
+ switch (x->x_tag.format) {
+ case SF_16BIT: {
+ short* cibuf =(short*) x->cbuf;
+ bp = (char*) x->cbuf;
+ while (n--)
+ *cibuf++ = (short) 32767.0 * *in++;
+ break;
+ }
+ case SF_8BIT: {
+ unsigned char* cbuf = (char*) x->cbuf;
+ bp = (char*) x->cbuf;
+ while (n--)
+ *cbuf++ = (unsigned char)(128. * (1.0 + *in++));
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (x->x_fd > 0) {
+ /* send the format tag */
+
+#ifdef unix
+ if (send(x->x_fd,(char*)&x->x_tag,sizeof(t_tag),/*MSG_DONTWAIT|*/MSG_NOSIGNAL) < 0)
+#else
+ if (send(x->x_fd,(char*)&x->x_tag,sizeof(t_tag),0) < 0)
+#endif
+ {
+ sys_sockerror("streamout");
+ streamout_disconnect(x);
+ return (w+4);
+ }
+
+ /* send the buffer */
+
+ for (sent = 0; sent < length;) {
+ int res = 0;
+#ifdef unix
+ res = send(x->x_fd, bp, length-sent, /*MSG_DONTWAIT|*/MSG_NOSIGNAL);
+#else
+ res = send(x->x_fd, bp, length-sent, 0);
+#endif
+ if (res <= 0)
+ {
+ sys_sockerror("streamout");
+ streamout_disconnect(x);
+ break;
+ }
+ else
+ {
+ sent += res;
+ bp += res;
+ }
+ }
+ }
+ return (w+4);
+}
+
+
+
+static void streamout_dsp(t_streamout *x, t_signal **sp)
+{
+ dsp_add(streamout_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
+}
+
+
+
+static void streamout_format(t_streamout *x,t_symbol* form)
+{
+ if (!strncmp(form->s_name,"float",5))
+ x->x_tag.format = (int) SF_FLOAT;
+
+ if (!strncmp(form->s_name,"16bit",5))
+ x->x_tag.format = (int) SF_16BIT;
+
+ if (!strncmp(form->s_name,"8bit",4))
+ x->x_tag.format = (int) SF_8BIT;
+
+
+ post ("format set to %s", form->s_name);
+}
+
+
+
+static void streamout_host(t_streamout *x,t_symbol* host)
+{
+ if (host != &s_)
+ x->hostname = host;
+
+ if (x->x_fd >= 0) {
+ streamout_connect(x,x->hostname,(float) x->portno);
+ }
+}
+
+
+
+
+static void streamout_float(t_streamout* x,t_float arg)
+{
+ if (arg == 0.0)
+ streamout_disconnect(x);
+ else
+ streamout_connect(x,x->hostname,(float) x->portno);
+}
+
+
+
+static void *streamout_new(t_symbol* prot)
+{
+ t_streamout *x = (t_streamout *)pd_new(streamout_class);
+ outlet_new(&x->x_obj, &s_float);
+
+ x->hostname = gensym("localhost");
+ x->portno = 3000;
+ x->x_fd = -1;
+ x->x_protocol = SOCK_STREAM;
+
+ if (prot != &s_)
+ if (!strncmp(prot->s_name,"udp",3))
+ x->x_protocol = SOCK_DGRAM;
+
+ x->x_tag.format = SF_FLOAT;
+ x->x_tag.channels = 1;
+ x->x_tag.version = 1;
+ x->cbuf = NULL;
+ streamout_tempbuf(x,64);
+ return (x);
+}
+
+
+
+static void streamout_free(t_streamout* x)
+{
+ if (x->cbuf && x->tbufsize) freebytes(x->cbuf,x->tbufsize);
+}
+
+
+
+void streamout_tilde_setup(void)
+{
+ streamout_class = class_new(gensym("streamout~"), (t_newmethod) streamout_new, (t_method) streamout_free,
+ sizeof(t_streamout), 0, A_DEFSYM, 0);
+ class_addmethod(streamout_class, (t_method) streamout_connect,
+ gensym("connect"), A_SYMBOL, A_DEFFLOAT, 0);
+ class_addmethod(streamout_class, (t_method) streamout_disconnect,
+ gensym("disconnect"), 0);
+ class_addfloat(streamout_class,streamout_float);
+ class_addmethod(streamout_class, nullfn, gensym("signal"), 0);
+ class_addmethod(streamout_class, (t_method) streamout_dsp, gensym("dsp"), 0);
+ class_addmethod(streamout_class, (t_method)streamout_format,gensym("format"),A_SYMBOL,0);
+ class_addmethod(streamout_class, (t_method)streamout_host,gensym("host"),A_DEFSYM,0);
+
+}
diff --git a/signal/streamout~.pd b/signal/streamout~.pd
new file mode 100755
index 0000000..56b2ece
--- /dev/null
+++ b/signal/streamout~.pd
@@ -0,0 +1,49 @@
+#N canvas 45 154 820 483 12;
+#X floatatom 227 194 0 0 0;
+#X msg 46 32 disconnect;
+#X obj 368 72 osc~;
+#X floatatom 368 20 0 0 0;
+#X obj 368 44 sig~ 220;
+#X text 13 239 The format message sets the transmission format;
+#X text 11 419 Hopefully we will sometimes have a version where we can compress it for transmission over the "real" net.;
+#X text 14 462 (C) 1999 Guenter Geiger;
+#X obj 455 21 streamin~ 3001;
+#X obj 448 78 dac~;
+#X msg 156 68 connect tritonus 3000;
+#X msg 20 113 format float;
+#X msg 20 144 format 16bit;
+#X text 13 256 format float: send float numbers;
+#X text 12 275 format 16bit: send 16 bit integers;
+#X msg 20 176 format 8bit;
+#X text 380 246 host:;
+#X text 13 219 format:;
+#X obj 227 162 streamout~ localhost 3000;
+#X text 379 193 connect:;
+#X text 378 210 connect sets the host and portnumber and immediatly tries to connect .;
+#X text 380 263 Set the host name and connect to the host \, if a connection was active.;
+#X msg 250 100 1;
+#X msg 284 100 0;
+#X text 379 298 disconnect (0);
+#X text 378 315 disconnect and 0 disconnect the object;
+#X text 379 335 1:;
+#X text 376 352 if the number 1 is sent to streamout \, the object connects to the stored host and portnumber. Default is localhost \, port number 3000;
+#X obj 366 107 *~ 0.01;
+#X msg 179 12 connect gige 15001;
+#X msg 156 37 connect localhost 3001;
+#X text 12 292 format 8bit: send 8 bit integers;
+#X connect 1 0 18 0;
+#X connect 2 0 28 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
+#X connect 8 0 9 0;
+#X connect 8 0 9 1;
+#X connect 10 0 18 0;
+#X connect 11 0 18 0;
+#X connect 12 0 18 0;
+#X connect 15 0 18 0;
+#X connect 18 0 0 0;
+#X connect 22 0 18 0;
+#X connect 23 0 18 0;
+#X connect 28 0 18 0;
+#X connect 29 0 18 0;
+#X connect 30 0 18 0;
diff --git a/tools/Makefile b/tools/Makefile
new file mode 100755
index 0000000..9e36fa1
--- /dev/null
+++ b/tools/Makefile
@@ -0,0 +1,19 @@
+all: define_loudspeakers
+
+CFLAGS = -O2 -g -I tich
+LFLAGS = -Ltich
+
+vbap.o: vbap.c
+ cc -c $(CFLAGS) vbap.c
+
+
+define_loudspeakers: define_loudspeakers.o define_louds_routines.o
+ cc define_loudspeakers.o define_louds_routines.o -o define_loudspeakers -lm
+define_loudspeakers.o: define_loudspeakers.c
+ cc -c define_loudspeakers.c
+define_loudsp_routines.o: define_louds_routines.c
+ cc -c -O2 define_louds_routines.c
+
+clean:
+ rm *.o
+ rm define_loudspeakers
diff --git a/tools/README.ggext b/tools/README.ggext
new file mode 100755
index 0000000..9e3f6f8
--- /dev/null
+++ b/tools/README.ggext
@@ -0,0 +1,22 @@
+This is a part of the vbap implementation from
+Ville Pulkki <Ville.Pulkki@hut.fi>
+
+Other parts of the code are folded into the "vbap" external.
+
+An example how to create a vbap file used by the "vabp" external:
+
+first type make to generate the "define_loudspeaker" program.
+
+write down the description of your loudspeaker positions, similar to
+the file
+
+loudspeaker_directions_3D
+
+then call
+
+./define_loudspeaker loudspeaker_directrions_3D > ls_setup
+
+lsi_setup can be used with the "vbap" object to spatialize the data.
+
+Guenter Geiger
+
diff --git a/tools/define_louds_routines.c b/tools/define_louds_routines.c
new file mode 100755
index 0000000..8a51308
--- /dev/null
+++ b/tools/define_louds_routines.c
@@ -0,0 +1,548 @@
+/* define_louds_rout.c
+(c) Ville Pulkki 10.11.1998 Helsinki University of Technology
+
+functions for loudspeaker table initialization */
+
+
+#include "define_loudspeakers.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+void angle_to_cart(ang_vec *from, cart_vec *to)
+ /* from angular to cartesian coordinates*/
+{
+ float ang2rad = 2 * 3.141592 / 360;
+ to->x= (float) (cos((double)(from->azi * ang2rad))
+ * cos((double) (from->ele * ang2rad)));
+ to->y= (float) (sin((double)(from->azi * ang2rad))
+ * cos((double) (from->ele * ang2rad)));
+ to->z= (float) (sin((double) (from->ele * ang2rad)));
+}
+
+
+void choose_ls_triplets(ls lss[MAX_LS_AMOUNT],
+ struct ls_triplet_chain **ls_triplets, int ls_amount)
+ /* Selects the loudspeaker triplets, and
+ calculates the inversion matrices for each selected triplet.
+ A line (connection) is drawn between each loudspeaker. The lines
+ denote the sides of the triangles. The triangles should not be
+ intersecting. All crossing connections are searched and the
+ longer connection is erased. This yields non-intesecting triangles,
+ which can be used in panning.*/
+{
+ int i,j,k,l,m,li, table_size;
+ int *i_ptr;
+ cart_vec vb1,vb2,tmp_vec;
+ int connections[MAX_LS_AMOUNT][MAX_LS_AMOUNT];
+ float angles[MAX_LS_AMOUNT];
+ int sorted_angles[MAX_LS_AMOUNT];
+ float distance_table[((MAX_LS_AMOUNT * (MAX_LS_AMOUNT - 1)) / 2)];
+ int distance_table_i[((MAX_LS_AMOUNT * (MAX_LS_AMOUNT - 1)) / 2)];
+ int distance_table_j[((MAX_LS_AMOUNT * (MAX_LS_AMOUNT - 1)) / 2)];
+ float distance;
+ struct ls_triplet_chain *trip_ptr, *prev, *tmp_ptr;
+
+ if (ls_amount == 0) {
+ fprintf(stderr,"Number of loudspeakers is zero\nExiting\n");
+ exit(-1);
+ }
+ for(i=0;i<ls_amount;i++)
+ for(j=i+1;j<ls_amount;j++)
+ for(k=j+1;k<ls_amount;k++){
+ if(vol_p_side_lgth(i,j, k, lss) > MIN_VOL_P_SIDE_LGTH){
+ connections[i][j]=1;
+ connections[j][i]=1;
+ connections[i][k]=1;
+ connections[k][i]=1;
+ connections[j][k]=1;
+ connections[k][j]=1;
+ add_ldsp_triplet(i,j,k,ls_triplets, lss);
+ }
+ }
+ /*calculate distancies between all lss and sorting them*/
+ table_size =(((ls_amount - 1) * (ls_amount)) / 2);
+ for(i=0;i<table_size; i++)
+ distance_table[i] = 100000.0;
+ for(i=0;i<ls_amount;i++){
+ for(j=(i+1);j<ls_amount; j++){
+ if(connections[i][j] == 1) {
+ distance = fabs(vec_angle(lss[i].coords,lss[j].coords));
+ k=0;
+ while(distance_table[k] < distance)
+ k++;
+ for(l=(table_size - 1);l > k ;l--){
+ distance_table[l] = distance_table[l-1];
+ distance_table_i[l] = distance_table_i[l-1];
+ distance_table_j[l] = distance_table_j[l-1];
+ }
+ distance_table[k] = distance;
+ distance_table_i[k] = i;
+ distance_table_j[k] = j;
+ } else
+ table_size--;
+ }
+ }
+
+ /* disconnecting connections which are crossing shorter ones,
+ starting from shortest one and removing all that cross it,
+ and proceeding to next shortest */
+ for(i=0; i<(table_size); i++){
+ int fst_ls = distance_table_i[i];
+ int sec_ls = distance_table_j[i];
+ if(connections[fst_ls][sec_ls] == 1)
+ for(j=0; j<ls_amount ; j++)
+ for(k=j+1; k<ls_amount; k++)
+ if( (j!=fst_ls) && (k != sec_ls) && (k!=fst_ls) && (j != sec_ls)){
+ if(lines_intersect(fst_ls, sec_ls, j,k,lss) == 1){
+ connections[j][k] = 0;
+ connections[k][j] = 0;
+ }
+ }
+ }
+
+ /* remove triangles which had crossing sides
+ with smaller triangles or include loudspeakers*/
+ trip_ptr = *ls_triplets;
+ prev = NULL;
+ while (trip_ptr != NULL){
+ i = trip_ptr->ls_nos[0];
+ j = trip_ptr->ls_nos[1];
+ k = trip_ptr->ls_nos[2];
+ if(connections[i][j] == 0 ||
+ connections[i][k] == 0 ||
+ connections[j][k] == 0 ||
+ any_ls_inside_triplet(i,j,k,lss,ls_amount) == 1 ){
+ if(prev != NULL) {
+ prev->next = trip_ptr->next;
+ tmp_ptr = trip_ptr;
+ trip_ptr = trip_ptr->next;
+ free(tmp_ptr);
+ } else {
+ *ls_triplets = trip_ptr->next;
+ tmp_ptr = trip_ptr;
+ trip_ptr = trip_ptr->next;
+ free(tmp_ptr);
+ }
+ } else {
+ prev = trip_ptr;
+ trip_ptr = trip_ptr->next;
+
+ }
+ }
+}
+
+
+int any_ls_inside_triplet(int a, int b, int c,ls lss[MAX_LS_AMOUNT],int ls_amount)
+ /* returns 1 if there is loudspeaker(s) inside given ls triplet */
+{
+ float invdet;
+ cart_vec *lp1, *lp2, *lp3;
+ float invmx[9];
+ int i,j,k;
+ float tmp;
+ int any_ls_inside, this_inside;
+
+ lp1 = &(lss[a].coords);
+ lp2 = &(lss[b].coords);
+ lp3 = &(lss[c].coords);
+
+ /* matrix inversion */
+ invdet = 1.0 / ( lp1->x * ((lp2->y * lp3->z) - (lp2->z * lp3->y))
+ - lp1->y * ((lp2->x * lp3->z) - (lp2->z * lp3->x))
+ + lp1->z * ((lp2->x * lp3->y) - (lp2->y * lp3->x)));
+
+ invmx[0] = ((lp2->y * lp3->z) - (lp2->z * lp3->y)) * invdet;
+ invmx[3] = ((lp1->y * lp3->z) - (lp1->z * lp3->y)) * -invdet;
+ invmx[6] = ((lp1->y * lp2->z) - (lp1->z * lp2->y)) * invdet;
+ invmx[1] = ((lp2->x * lp3->z) - (lp2->z * lp3->x)) * -invdet;
+ invmx[4] = ((lp1->x * lp3->z) - (lp1->z * lp3->x)) * invdet;
+ invmx[7] = ((lp1->x * lp2->z) - (lp1->z * lp2->x)) * -invdet;
+ invmx[2] = ((lp2->x * lp3->y) - (lp2->y * lp3->x)) * invdet;
+ invmx[5] = ((lp1->x * lp3->y) - (lp1->y * lp3->x)) * -invdet;
+ invmx[8] = ((lp1->x * lp2->y) - (lp1->y * lp2->x)) * invdet;
+
+ any_ls_inside = 0;
+ for(i=0; i< ls_amount; i++) {
+ if (i != a && i!=b && i != c){
+ this_inside = 1;
+ for(j=0; j< 3; j++){
+ tmp = lss[i].coords.x * invmx[0 + j*3];
+ tmp += lss[i].coords.y * invmx[1 + j*3];
+ tmp += lss[i].coords.z * invmx[2 + j*3];
+ if(tmp < -0.001)
+ this_inside = 0;
+ }
+ if(this_inside == 1)
+ any_ls_inside=1;
+ }
+ }
+ return any_ls_inside;
+}
+
+
+void add_ldsp_triplet(int i, int j, int k,
+ struct ls_triplet_chain **ls_triplets,
+ ls lss[MAX_LS_AMOUNT])
+ /* adds i,j,k triplet to triplet chain*/
+{
+ struct ls_triplet_chain *trip_ptr, *prev;
+ trip_ptr = *ls_triplets;
+ prev = NULL;
+
+ while (trip_ptr != NULL){
+ prev = trip_ptr;
+ trip_ptr = trip_ptr->next;
+ }
+ trip_ptr = (struct ls_triplet_chain*)
+ malloc (sizeof (struct ls_triplet_chain));
+ if(prev == NULL)
+ *ls_triplets = trip_ptr;
+ else
+ prev->next = trip_ptr;
+ trip_ptr->next = NULL;
+ trip_ptr->ls_nos[0] = i;
+ trip_ptr->ls_nos[1] = j;
+ trip_ptr->ls_nos[2] = k;
+}
+
+
+
+
+float vec_angle(cart_vec v1, cart_vec v2)
+{
+ float inner= ((v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)/
+ (vec_length(v1) * vec_length(v2)));
+ if(inner > 1.0)
+ inner= 1.0;
+ if (inner < -1.0)
+ inner = -1.0;
+ return fabsf((float) acos((double) inner));
+}
+
+float vec_length(cart_vec v1)
+{
+ return (sqrt(v1.x*v1.x + v1.y*v1.y + v1.z*v1.z));
+}
+
+float vec_prod(cart_vec v1, cart_vec v2)
+{
+ return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
+}
+
+
+float vol_p_side_lgth(int i, int j,int k, ls lss[MAX_LS_AMOUNT] ){
+ /* calculate volume of the parallelepiped defined by the loudspeaker
+ direction vectors and divide it with total length of the triangle sides.
+ This is used when removing too narrow triangles. */
+
+ float volper, lgth;
+ cart_vec xprod;
+ cross_prod(lss[i].coords, lss[j].coords, &xprod);
+ volper = fabsf(vec_prod(xprod, lss[k].coords));
+ lgth = (fabsf(vec_angle(lss[i].coords,lss[j].coords))
+ + fabsf(vec_angle(lss[i].coords,lss[k].coords))
+ + fabsf(vec_angle(lss[j].coords,lss[k].coords)));
+ if(lgth>0.00001)
+ return volper / lgth;
+ else
+ return 0.0;
+}
+
+void cross_prod(cart_vec v1,cart_vec v2,
+ cart_vec *res)
+{
+ float length;
+ res->x = (v1.y * v2.z ) - (v1.z * v2.y);
+ res->y = (v1.z * v2.x ) - (v1.x * v2.z);
+ res->z = (v1.x * v2.y ) - (v1.y * v2.x);
+
+ length= vec_length(*res);
+ res->x /= length;
+ res->y /= length;
+ res->z /= length;
+}
+
+
+int lines_intersect(int i,int j,int k,int l,ls lss[MAX_LS_AMOUNT])
+ /* checks if two lines intersect on 3D sphere
+ see theory in paper Pulkki, V. Lokki, T. "Creating Auditory Displays
+ with Multiple Loudspeakers Using VBAP: A Case Study with
+ DIVA Project" in International Conference on
+ Auditory Displays -98. E-mail Ville.Pulkki@hut.fi
+ if you want to have that paper.*/
+{
+ cart_vec v1;
+ cart_vec v2;
+ cart_vec v3, neg_v3;
+ float angle;
+ float dist_ij,dist_kl,dist_iv3,dist_jv3,dist_inv3,dist_jnv3;
+ float dist_kv3,dist_lv3,dist_knv3,dist_lnv3;
+
+ cross_prod(lss[i].coords,lss[j].coords,&v1);
+ cross_prod(lss[k].coords,lss[l].coords,&v2);
+ cross_prod(v1,v2,&v3);
+
+ neg_v3.x= 0.0 - v3.x;
+ neg_v3.y= 0.0 - v3.y;
+ neg_v3.z= 0.0 - v3.z;
+
+ dist_ij = (vec_angle(lss[i].coords,lss[j].coords));
+ dist_kl = (vec_angle(lss[k].coords,lss[l].coords));
+ dist_iv3 = (vec_angle(lss[i].coords,v3));
+ dist_jv3 = (vec_angle(v3,lss[j].coords));
+ dist_inv3 = (vec_angle(lss[i].coords,neg_v3));
+ dist_jnv3 = (vec_angle(neg_v3,lss[j].coords));
+ dist_kv3 = (vec_angle(lss[k].coords,v3));
+ dist_lv3 = (vec_angle(v3,lss[l].coords));
+ dist_knv3 = (vec_angle(lss[k].coords,neg_v3));
+ dist_lnv3 = (vec_angle(neg_v3,lss[l].coords));
+
+ /* if one of loudspeakers is close to crossing point, don't do anything*/
+
+
+ if(fabsf(dist_iv3) <= 0.01 || fabsf(dist_jv3) <= 0.01 ||
+ fabsf(dist_kv3) <= 0.01 || fabsf(dist_lv3) <= 0.01 ||
+ fabsf(dist_inv3) <= 0.01 || fabsf(dist_jnv3) <= 0.01 ||
+ fabsf(dist_knv3) <= 0.01 || fabsf(dist_lnv3) <= 0.01 )
+ return(0);
+
+
+
+ if (((fabsf(dist_ij - (dist_iv3 + dist_jv3)) <= 0.01 ) &&
+ (fabsf(dist_kl - (dist_kv3 + dist_lv3)) <= 0.01)) ||
+ ((fabsf(dist_ij - (dist_inv3 + dist_jnv3)) <= 0.01) &&
+ (fabsf(dist_kl - (dist_knv3 + dist_lnv3)) <= 0.01 ))) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+
+
+void calculate_3x3_matrixes(struct ls_triplet_chain *ls_triplets,
+ ls lss[MAX_LS_AMOUNT], int ls_amount)
+ /* Calculates the inverse matrices for 3D */
+{
+ float invdet;
+ cart_vec *lp1, *lp2, *lp3;
+ float *invmx;
+ float *ptr;
+ struct ls_triplet_chain *tr_ptr = ls_triplets;
+ int triplet_amount = 0, ftable_size,i,j,k;
+ float *ls_table;
+
+ if (tr_ptr == NULL){
+ fprintf(stderr,"Not valid 3-D configuration\n");
+ exit(-1);
+ }
+
+ /* counting triplet amount */
+ while(tr_ptr != NULL){
+ triplet_amount++;
+ tr_ptr = tr_ptr->next;
+ }
+
+ /* calculations and data storage to a global array */
+ ls_table = (float *) malloc( (triplet_amount*12 + 3) * sizeof (float));
+ ls_table[0] = 3.0; /*dimension*/
+ ls_table[1] = (float) ls_amount;
+ ls_table[2] = (float) triplet_amount;
+ tr_ptr = ls_triplets;
+ ptr = (float *) &(ls_table[3]);
+ while(tr_ptr != NULL){
+ lp1 = &(lss[tr_ptr->ls_nos[0]].coords);
+ lp2 = &(lss[tr_ptr->ls_nos[1]].coords);
+ lp3 = &(lss[tr_ptr->ls_nos[2]].coords);
+
+ /* matrix inversion */
+ invmx = tr_ptr->inv_mx;
+ invdet = 1.0 / ( lp1->x * ((lp2->y * lp3->z) - (lp2->z * lp3->y))
+ - lp1->y * ((lp2->x * lp3->z) - (lp2->z * lp3->x))
+ + lp1->z * ((lp2->x * lp3->y) - (lp2->y * lp3->x)));
+
+ invmx[0] = ((lp2->y * lp3->z) - (lp2->z * lp3->y)) * invdet;
+ invmx[3] = ((lp1->y * lp3->z) - (lp1->z * lp3->y)) * -invdet;
+ invmx[6] = ((lp1->y * lp2->z) - (lp1->z * lp2->y)) * invdet;
+ invmx[1] = ((lp2->x * lp3->z) - (lp2->z * lp3->x)) * -invdet;
+ invmx[4] = ((lp1->x * lp3->z) - (lp1->z * lp3->x)) * invdet;
+ invmx[7] = ((lp1->x * lp2->z) - (lp1->z * lp2->x)) * -invdet;
+ invmx[2] = ((lp2->x * lp3->y) - (lp2->y * lp3->x)) * invdet;
+ invmx[5] = ((lp1->x * lp3->y) - (lp1->y * lp3->x)) * -invdet;
+ invmx[8] = ((lp1->x * lp2->y) - (lp1->y * lp2->x)) * invdet;
+ for(i=0;i<3;i++){
+ *(ptr++) = (float) tr_ptr->ls_nos[i]+1;
+ }
+ for(i=0;i<9;i++){
+ *(ptr++) = (float) invmx[i];
+ }
+ tr_ptr = tr_ptr->next;
+ }
+
+ k=3;
+ printf("Configured %d sets in 3 dimensions:\n", triplet_amount);
+ for(i=0 ; i < triplet_amount ; i++) {
+ printf("Triplet %d Loudspeakers: ", i);
+ for (j=0 ; j < 3 ; j++) {
+ printf("%d ", (int) ls_table[k++]);
+ }
+ printf(" Matrix ");
+ for (j=0 ; j < 9; j++) {
+ printf("%f ", ls_table[k]);
+ k++;
+ }
+ printf("\n");
+ }
+}
+
+
+
+void choose_ls_tuplets( ls lss[MAX_LS_AMOUNT],
+ ls_triplet_chain **ls_triplets,
+ int ls_amount)
+ /* selects the loudspeaker pairs, calculates the inversion
+ matrices and stores the data to a global array*/
+{
+ float atorad = (2 * 3.1415927 / 360) ;
+ int i,j,k;
+ float w1,w2;
+ float p1,p2;
+ int sorted_lss[MAX_LS_AMOUNT];
+ int exist[MAX_LS_AMOUNT];
+ int amount=0;
+ float inv_mat[MAX_LS_AMOUNT][4], *ptr;
+ float *ls_table;
+
+ for(i=0;i<MAX_LS_AMOUNT;i++){
+ exist[i]=0;
+ }
+
+ /* sort loudspeakers according their aximuth angle */
+ sort_2D_lss(lss,sorted_lss,ls_amount);
+
+ /* adjacent loudspeakers are the loudspeaker pairs to be used.*/
+ for(i=0;i<(ls_amount-1);i++){
+ if((lss[sorted_lss[i+1]].angles.azi -
+ lss[sorted_lss[i]].angles.azi) <= (3.1415927 - 0.175)){
+ if (calc_2D_inv_tmatrix( lss[sorted_lss[i]].angles.azi,
+ lss[sorted_lss[i+1]].angles.azi,
+ inv_mat[i]) != 0){
+ exist[i]=1;
+ amount++;
+ }
+ }
+ }
+
+ if(((6.283 - lss[sorted_lss[ls_amount-1]].angles.azi)
+ +lss[sorted_lss[0]].angles.azi) <= (3.1415927 - 0.175)) {
+ if(calc_2D_inv_tmatrix(lss[sorted_lss[ls_amount-1]].angles.azi,
+ lss[sorted_lss[0]].angles.azi,
+ inv_mat[ls_amount-1]) != 0) {
+ exist[ls_amount-1]=1;
+ amount++;
+ }
+ }
+ ls_table = (float*) malloc ((amount * 6 + 3 + 100 ) * sizeof (float));
+ ls_table[0] = 2.0; /*dimension*/
+ ls_table[1] = (float) ls_amount;
+ ls_table[2] = (float) amount;
+ ptr = &(ls_table[3]);
+ for (i=0;i<ls_amount - 1;i++){
+ if(exist[i] == 1) {
+ *(ptr++) = sorted_lss[i]+1;
+ *(ptr++) = sorted_lss[i+1]+1;
+ for(j=0;j<4;j++) {
+ *(ptr++) = inv_mat[i][j];
+ }
+ }
+ }
+
+ if(exist[ls_amount-1] == 1) {
+ *(ptr++) = sorted_lss[ls_amount-1]+1;
+ *(ptr++) = sorted_lss[0]+1;
+ for(j=0;j<4;j++) {
+ *(ptr++) = inv_mat[ls_amount-1][j];
+ }
+ }
+ k=3;
+ printf("Configured %d pairs in 2 dimensions:\n",amount);
+ for(i=0 ; i < amount ; i++) {
+ printf("Pair %d Loudspeakers: ", i);
+ for (j=0 ; j < 2 ; j++) {
+ printf("%d ", (int) ls_table[k++]);
+ }
+ printf(" Matrix ");
+ for (j=0 ; j < 4; j++) {
+ printf("%f ", ls_table[k]);
+ k++;
+ }
+ printf("\n");
+ }
+}
+
+void sort_2D_lss(ls lss[MAX_LS_AMOUNT], int sorted_lss[MAX_LS_AMOUNT],
+ int ls_amount)
+{
+ int i,j,index;
+ float tmp, tmp_azi;
+ float rad2ang = 360.0 / ( 2 * 3.141592 );
+
+ float x,y;
+ /* Transforming angles between -180 and 180 */
+ for (i=0;i<ls_amount;i++) {
+ angle_to_cart(&lss[i].angles, &lss[i].coords);
+ lss[i].angles.azi = (float) acos((double) lss[i].coords.x);
+ if (fabsf(lss[i].coords.y) <= 0.001)
+ tmp = 1.0;
+ else
+ tmp = lss[i].coords.y / fabsf(lss[i].coords.y);
+ lss[i].angles.azi *= tmp;
+ }
+ for (i=0;i<ls_amount;i++){
+ tmp = 2000;
+ for (j=0 ; j<ls_amount;j++){
+ if (lss[j].angles.azi <= tmp){
+ tmp=lss[j].angles.azi;
+ index = j ;
+ }
+ }
+ sorted_lss[i]=index;
+ tmp_azi = (lss[index].angles.azi);
+ lss[index].angles.azi = (tmp_azi + (float) 4000.0);
+ }
+ for (i=0;i<ls_amount;i++) {
+ tmp_azi = (lss[i].angles.azi);
+ lss[i].angles.azi = (tmp_azi - (float) 4000.0);
+ }
+}
+
+
+int calc_2D_inv_tmatrix(float azi1,float azi2, float inv_mat[4])
+{
+ float x1,x2,x3,x4; /* x1 x3 */
+ float y1,y2,y3,y4; /* x2 x4 */
+ float det;
+ x1 = (float) cos((double) azi1 );
+ x2 = (float) sin((double) azi1 );
+ x3 = (float) cos((double) azi2 );
+ x4 = (float) sin((double) azi2 );
+ det = (x1 * x4) - ( x3 * x2 );
+ if(fabsf(det) <= 0.001) {
+
+ inv_mat[0] = 0.0;
+ inv_mat[1] = 0.0;
+ inv_mat[2] = 0.0;
+ inv_mat[3] = 0.0;
+ return 0;
+ } else {
+ inv_mat[0] = (float) (x4 / det);
+ inv_mat[1] = (float) (-x3 / det);
+ inv_mat[2] = (float) (-x2 / det);
+ inv_mat[3] = (float) (x1 / det);
+ return 1;
+ }
+}
+
+
diff --git a/tools/define_loudspeakers b/tools/define_loudspeakers
new file mode 100755
index 0000000..fcb2821
--- /dev/null
+++ b/tools/define_loudspeakers
Binary files differ
diff --git a/tools/define_loudspeakers.c b/tools/define_loudspeakers.c
new file mode 100755
index 0000000..14abe5c
--- /dev/null
+++ b/tools/define_loudspeakers.c
@@ -0,0 +1,142 @@
+/* define_loudspeakers.c 0.1
+(c) Ville Pulkki 2.2.1999 Helsinki University of Technology*/
+
+#include <stdio.h>
+#include "define_loudspeakers.h"
+
+
+void load_ls_triplets(ls lss[MAX_LS_AMOUNT],
+ struct ls_triplet_chain **ls_triplets,
+ int ls_amount, char *filename)
+{
+ struct ls_triplet_chain *trip_ptr, *prev;
+ int i,j,k;
+ FILE *fp;
+ char c[10000];
+ char *toke;
+
+ trip_ptr = *ls_triplets;
+ prev = NULL;
+ while (trip_ptr != NULL){
+ prev = trip_ptr;
+ trip_ptr = trip_ptr->next;
+ }
+
+ if((fp=fopen(filename,"r")) == NULL){
+ fprintf(stderr,"Could not open loudspeaker setup file.\n");
+ exit(-1);
+ }
+
+ while(1) {
+ if(fgets(c,10000,fp) == NULL)
+ break;
+ toke = (char *) strtok(c, " ");
+ if(sscanf(toke, "%d",&i)>0){
+ toke = (char *) strtok(NULL," ");
+ sscanf(toke, "%d",&j);
+ toke = (char *) strtok(NULL," ");
+ sscanf(toke, "%d",&k);
+ } else {
+ break;
+ }
+
+ trip_ptr = (struct ls_triplet_chain*)
+ malloc (sizeof (struct ls_triplet_chain));
+
+ if(prev == NULL)
+ *ls_triplets = trip_ptr;
+ else
+ prev->next = trip_ptr;
+
+ trip_ptr->next = NULL;
+ trip_ptr->ls_nos[0] = i-1;
+ trip_ptr->ls_nos[1] = j-1;
+ trip_ptr->ls_nos[2] = k-1;
+ prev=trip_ptr;
+ trip_ptr=NULL;
+ }
+}
+
+
+
+main(int argc,char **argv)
+ /* Inits the loudspeaker data. Calls choose_ls_tuplets or _triplets
+ according to current dimension. The inversion matrices are
+ stored in transposed form to ease calculation at run time.*/
+{
+ char *s;
+ int dim;
+ float tmp;
+ struct ls_triplet_chain *ls_triplets = NULL;
+ ls lss[MAX_LS_AMOUNT];
+ char c[10000];
+ char *toke;
+ ang_vec a_vector;
+ cart_vec c_vector;
+ int i=0,j;
+ float azi, ele;
+ int ls_amount;
+ FILE *fp;
+
+ if(argc != 2 && argc != 3){
+ fprintf(stderr,"Usage: define_loudspeakers loudspeaker_directions_file [loudspeaker_triplet_file]\n");
+ exit(-1);
+ }
+
+ if((fp=fopen(argv[1],"r")) == NULL){
+ fprintf(stderr,"Could not open loudspeaker setup file.%s\n",argv[1]);
+ exit(-1);
+ }
+
+
+ fgets(c,10000,fp);
+ toke = (char *) strtok(c, " ");
+ sscanf(toke, "%d",&dim);
+ if (!((dim==2) || (dim == 3))){
+ fprintf(stderr,"Error in loudspeaker dimension.\n");
+ exit (-1);
+ }
+ printf("File: %s ",argv[1]);
+ while(1) {
+ if(fgets(c,10000,fp) == NULL)
+ break;
+ toke = (char *) strtok(c, " ");
+ if(sscanf(toke, "%f",&azi)>0){
+ if(dim == 3) {
+ toke = (char *) strtok(NULL," ");
+ sscanf(toke, "%f",&ele);
+ } else if(dim == 2) {
+ ele=0.0;
+ }
+ } else {
+ break;
+ }
+
+ a_vector.azi = azi;
+ a_vector.ele = ele;
+ angle_to_cart(&a_vector,&c_vector);
+ lss[i].coords.x = c_vector.x;
+ lss[i].coords.y = c_vector.y;
+ lss[i].coords.z = c_vector.z;
+ lss[i].angles.azi = a_vector.azi;
+ lss[i].angles.ele = a_vector.ele;
+ lss[i].angles.length = 1.0;
+ i++;
+ }
+ ls_amount = i;
+ if(ls_amount < dim) {
+ fprintf(stderr,"Too few loudspeakers %d\n",ls_amount);
+ exit (-1);
+ }
+
+ if(dim == 3){
+ if(argc==2) /* select triplets */
+ choose_ls_triplets(lss, &ls_triplets,ls_amount);
+ else /* load triplets from a file */
+ load_ls_triplets(lss, &ls_triplets,ls_amount,argv[2]);
+ calculate_3x3_matrixes(ls_triplets,lss,ls_amount);
+ } else if (dim ==2) {
+ choose_ls_tuplets(lss, &ls_triplets,ls_amount);
+ }
+}
+
diff --git a/tools/define_loudspeakers.h b/tools/define_loudspeakers.h
new file mode 100755
index 0000000..2c7fb84
--- /dev/null
+++ b/tools/define_loudspeakers.h
@@ -0,0 +1,69 @@
+#define MAX_LS_AMOUNT 32
+#define MIN_VOL_P_SIDE_LGTH 0.01
+
+typedef struct {
+ float x;
+ float y;
+ float z;
+} cart_vec;
+
+
+typedef struct {
+ float azi;
+ float ele;
+ float length;
+} ang_vec;
+
+
+/* A struct for a loudspeaker triplet or pair (set) */
+typedef struct {
+ int ls_nos[3];
+ float ls_mx[9];
+ float set_weights[3];
+ float smallest_wt;
+} LS_SET;
+
+
+/* A struct for a loudspeaker instance */
+typedef struct {
+ cart_vec coords;
+ ang_vec angles;
+ int channel_nbr;
+} ls;
+
+/* A struct for all loudspeakers */
+typedef struct ls_triplet_chain {
+ int ls_nos[3];
+ float inv_mx[9];
+ struct ls_triplet_chain *next;
+} ls_triplet_chain;
+
+/* functions */
+
+void angle_to_cart( ang_vec *from, cart_vec *to);
+extern void choose_ls_triplets( ls lss[MAX_LS_AMOUNT],
+ ls_triplet_chain **ls_triplets,
+ int ls_amount);
+extern void choose_ls_tuplets( ls lss[MAX_LS_AMOUNT],
+ ls_triplet_chain **ls_triplets,
+ int ls_amount);
+int lines_intersect(int i,int j,int k,int l, ls lss[MAX_LS_AMOUNT]);
+int any_ls_inside_triplet(int a, int b, int c,ls lss[MAX_LS_AMOUNT], int ls_amount);
+float vec_angle(cart_vec v1, cart_vec v2);
+float vec_prod(cart_vec v1, cart_vec v2);
+float vec_length(cart_vec v1);
+void cross_prod(cart_vec v1,cart_vec v2,
+ cart_vec *res) ;
+extern void add_ldsp_triplet(int i, int j, int k,
+ ls_triplet_chain **ls_triplets,
+ ls *lss);
+
+extern void calculate_3x3_matrixes(ls_triplet_chain *ls_triplets,
+ ls lss[MAX_LS_AMOUNT], int ls_amount);
+int calc_2D_inv_tmatrix(float azi1,float azi2, float inv_mat[4]);
+extern void sort_2D_lss(ls lss[MAX_LS_AMOUNT], int sorted_lss[MAX_LS_AMOUNT],
+ int ls_amount);
+
+float vol_p_side_lgth(int i, int j,int k, ls lss[MAX_LS_AMOUNT] );
+
+
diff --git a/tools/loudspeaker_directions_2D b/tools/loudspeaker_directions_2D
new file mode 100755
index 0000000..addb5b7
--- /dev/null
+++ b/tools/loudspeaker_directions_2D
@@ -0,0 +1,6 @@
+2
+-45 0
+45 0
+135 0
+225 0
+
diff --git a/tools/loudspeaker_directions_3D b/tools/loudspeaker_directions_3D
new file mode 100755
index 0000000..61e4ba9
--- /dev/null
+++ b/tools/loudspeaker_directions_3D
@@ -0,0 +1,9 @@
+3 # dimensionality
+-30 0 # directions (azimuth elevation) of loudspeakers
+30 0
+-90 0
+90 0
+180 0
+180 40
+-30 40
+30 40
diff --git a/version b/version
new file mode 100644
index 0000000..8d83ccf
--- /dev/null
+++ b/version
@@ -0,0 +1 @@
+0.24