aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2013-01-17 22:54:00 +0000
committerIOhannes m zmölnig <zmoelnig@iem.at>2015-10-14 13:53:22 +0200
commit71b83fc040b848c98c5065d95ecbc72b0b4f8943 (patch)
treeb64020d616887a488f8304fc13f57ff4d6c4e313
parent2b487890477a2ad969a1694270cee19b1265f3f6 (diff)
merging maxlib v1.5.5 from branches/pd-extended/0.43HEADsvn2git-headmaster
svn path=/trunk/externals/maxlib/; revision=16897
-rw-r--r--Makefile122
-rw-r--r--allow.c224
-rw-r--r--arbran.c378
-rw-r--r--arraycopy.c50
-rw-r--r--average.c404
-rw-r--r--beat.c806
-rw-r--r--beta.c214
-rw-r--r--bilex.c174
-rw-r--r--borax.c476
-rw-r--r--cauchy.c170
-rw-r--r--chord.c3644
-rw-r--r--delta.c278
-rw-r--r--deny.c228
-rw-r--r--dist.c558
-rw-r--r--divide.c220
-rw-r--r--divmod.c200
-rw-r--r--edge.c164
-rw-r--r--examples/score.txt (renamed from examplescore.txt)0
-rw-r--r--expo.c172
-rw-r--r--fifo.c192
-rw-r--r--gauss.c168
-rw-r--r--gestalt.c246
-rw-r--r--history.c542
-rw-r--r--ignore.c238
-rw-r--r--iso.c438
-rw-r--r--lifo.c202
-rw-r--r--limit.c250
-rw-r--r--linear.c162
-rw-r--r--listfifo.c218
-rw-r--r--listfunnel.c184
-rw-r--r--manual/HISTORY.txt (renamed from HISTORY)0
-rw-r--r--manual/automata.txt (renamed from automata.txt)0
-rw-r--r--match.c548
-rw-r--r--maxlib-meta.pd2
-rw-r--r--maxlib.c384
-rw-r--r--minus.c222
-rw-r--r--mlife.c1030
-rw-r--r--multi.c220
-rw-r--r--nchange.c410
-rw-r--r--netclient.c764
-rw-r--r--netdist.c626
-rw-r--r--netrec.c894
-rw-r--r--netserver.c1340
-rw-r--r--nroute.c358
-rw-r--r--pitch.c228
-rw-r--r--plus.c220
-rw-r--r--poisson.c182
-rw-r--r--pong.c664
-rw-r--r--pulse.c602
-rw-r--r--remote.c216
-rw-r--r--rewrap.c310
-rw-r--r--rhythm.c686
-rw-r--r--scale.c276
-rw-r--r--score-help.pd2
-rw-r--r--score.c618
-rw-r--r--speedlim.c470
-rw-r--r--split.c190
-rw-r--r--step.c358
-rw-r--r--subst.c848
-rw-r--r--sync.c588
-rw-r--r--temperature.c240
-rw-r--r--tilt.c378
-rw-r--r--timebang.c348
-rw-r--r--triang.c160
-rw-r--r--unroute.c350
-rw-r--r--urn.c304
-rw-r--r--velocity.c224
-rw-r--r--weibull.c182
-rw-r--r--wrap.c284
69 files changed, 13563 insertions, 13485 deletions
diff --git a/Makefile b/Makefile
index 254ceff..7f8a16e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-## Pd library template version 1.0.11
+## Pd library template version 1.0.14
# For instructions on how to use this template, see:
# http://puredata.info/docs/developer/MakefileTemplate
LIBRARY_NAME = maxlib
@@ -12,16 +12,19 @@ SOURCES = allow.c arbran.c arraycopy.c average.c beat.c beta.c bilex.c borax.c c
PDOBJECTS =
# example patches and related files, in the 'examples' subfolder
-EXAMPLES =
+EXAMPLES = score.txt
# manuals and related files, in the 'manual' subfolder
-MANUAL =
+MANUAL = automata.txt HISTORY.txt
# if you want to include any other files in the source and binary tarballs,
# list them here. This can be anything from header files, test patches,
# documentation, etc. README.txt and LICENSE.txt are required and therefore
# automatically included
-EXTRA_DIST = HISTORY automata.txt examplescore.txt maxlib-help.pd maxlib.c maxlib.dsp maxlib.dsw
+EXTRA_DIST = maxlib-help.pd maxlib.c maxlib.dsp maxlib.dsw
+
+# unit tests and related files here, in the 'unittests' subfolder
+UNITTESTS =
@@ -105,13 +108,19 @@ ifeq ($(UNAME),Darwin)
ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8)
FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4
else
- FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
SOURCES += $(SOURCES_iphoneos)
+# Starting with Xcode 4.0, the PowerPC compiler is not installed by default
+ ifeq ($(wildcard /usr/llvm-gcc-4.2/libexec/gcc/powerpc*), )
+ FAT_FLAGS = -arch i386 -arch x86_64 -mmacosx-version-min=10.5
+ else
+ FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
+ endif
endif
ALL_CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include
# if the 'pd' binary exists, check the linking against it to aid with stripping
BUNDLE_LOADER = $(shell test ! -e $(PD_PATH)/bin/pd || echo -bundle_loader $(PD_PATH)/bin/pd)
- ALL_LDFLAGS += $(FAT_FLAGS) -bundle $(BUNDLE_LOADER) -undefined dynamic_lookup -L/sw/lib
+ ALL_LDFLAGS += $(FAT_FLAGS) -headerpad_max_install_names -bundle $(BUNDLE_LOADER) \
+ -undefined dynamic_lookup -L/sw/lib
SHARED_LDFLAGS += $(FAT_FLAGS) -dynamiclib -undefined dynamic_lookup \
-install_name @loader_path/$(SHARED_LIB) -compatibility_version 1 -current_version 1.0
ALL_LIBS += -lc $(LIBS_macosx)
@@ -126,35 +135,61 @@ endif
ifeq ($(UNAME),ANDROID)
CPU := arm
SOURCES += $(SOURCES_android)
- EXTENSION = pd_linux
+ EXTENSION = so
SHARED_EXTENSION = so
OS = android
PD_PATH = /usr
NDK_BASE := /usr/local/android-ndk
- NDK_PLATFORM_VERSION := 5
- NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_VERSION)/arch-arm
+ NDK_PLATFORM_LEVEL ?= 5
+ NDK_ABI=arm
+ NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_LEVEL)/arch-$(NDK_ABI)
NDK_UNAME := $(shell uname -s | tr '[A-Z]' '[a-z]')
- NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/$(NDK_UNAME)-x86
- CC := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-gcc --sysroot=$(NDK_SYSROOT)
+ NDK_COMPILER_VERSION=4.6
+ NDK_TOOLCHAIN=$(wildcard \
+ $(NDK_BASE)/toolchains/$(NDK_ABI)*-$(NDK_COMPILER_VERSION)/prebuilt/$(NDK_UNAME)-x86)
+ CC := $(wildcard $(NDK_TOOLCHAIN)/bin/*-linux-android*-gcc) --sysroot=$(NDK_SYSROOT)
OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
CFLAGS +=
LDFLAGS += -rdynamic -shared
SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared
LIBS += -lc $(LIBS_android)
- STRIP := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-strip \
+ STRIP := $(wildcard $(NDK_TOOLCHAIN)/bin/$(NDK_ABI)-linux-android*-strip) \
--strip-unneeded -R .note -R .comment
DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
endif
ifeq ($(UNAME),Linux)
CPU := $(shell uname -m)
- SOURCES += $(SOURCES_linux)
EXTENSION = pd_linux
+ ifeq ($(findstring arm,$(CPU)),arm)
+ EXTENSION = l_arm
+ endif
+ ifeq ($(CPU),i386)
+ EXTENSION = l_i386
+ endif
+ ifeq ($(CPU),i486)
+ EXTENSION = l_i386
+ endif
+ ifeq ($(CPU),i586)
+ EXTENSION = l_i386
+ endif
+ ifeq ($(CPU),i686)
+ EXTENSION = l_i386
+ endif
+ ifeq ($(CPU),amd64)
+ # amd64 and ia64 aren't the same thing, but that's how its done in pd...
+ EXTENSION = l_ia64
+ endif
+ ifeq ($(CPU),x86_64)
+ # x86_64 and ia64 aren't the same thing, but that's how its done in pd...
+ EXTENSION = l_ia64
+ endif
+ SOURCES += $(SOURCES_linux)
SHARED_EXTENSION = so
OS = linux
PD_PATH = /usr
OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
ALL_CFLAGS += -fPIC
- ALL_LDFLAGS += -rdynamic -shared -fPIC
+ ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared
ALL_LIBS += -lc $(LIBS_linux)
STRIP = strip --strip-unneeded -R .note -R .comment
@@ -170,7 +205,7 @@ ifeq ($(UNAME),GNU)
PD_PATH = /usr
OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
ALL_CFLAGS += -fPIC
- ALL_LDFLAGS += -rdynamic -shared -fPIC
+ ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
ALL_LIBS += -lc $(LIBS_linux)
STRIP = strip --strip-unneeded -R .note -R .comment
@@ -186,7 +221,7 @@ ifeq ($(UNAME),GNU/kFreeBSD)
PD_PATH = /usr
OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
ALL_CFLAGS += -fPIC
- ALL_LDFLAGS += -rdynamic -shared -fPIC
+ ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
ALL_LIBS += -lc $(LIBS_linux)
STRIP = strip --strip-unneeded -R .note -R .comment
@@ -218,9 +253,10 @@ ifeq (MINGW,$(findstring MINGW,$(UNAME)))
CC=gcc
OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer
ALL_CFLAGS += -mms-bitfields
- ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj"
+ ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import
SHARED_LDFLAGS += -shared
- ALL_LIBS += -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 $(LIBS_windows)
+ ALL_LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" \
+ -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 -liberty $(LIBS_windows)
STRIP = strip --strip-unneeded -R .note -R .comment
DISTBINDIR=$(DISTDIR)-$(OS)
endif
@@ -232,12 +268,12 @@ ALL_CFLAGS := $(ALL_CFLAGS) $(CFLAGS) $(OPT_CFLAGS)
ALL_LDFLAGS := $(LDFLAGS) $(ALL_LDFLAGS)
ALL_LIBS := $(LIBS) $(ALL_LIBS)
-SHARED_SOURCE ?= $(shell test ! -e lib$(LIBRARY_NAME).c || \
- echo lib$(LIBRARY_NAME).c )
+SHARED_SOURCE ?= $(wildcard lib$(LIBRARY_NAME).c)
SHARED_HEADER ?= $(shell test ! -e $(LIBRARY_NAME).h || echo $(LIBRARY_NAME).h)
-SHARED_LIB = $(SHARED_SOURCE:.c=.$(SHARED_EXTENSION))
+SHARED_LIB ?= $(SHARED_SOURCE:.c=.$(SHARED_EXTENSION))
+SHARED_TCL_LIB = $(wildcard lib$(LIBRARY_NAME).tcl)
-.PHONY = install libdir_install single_install install-doc install-examples install-manual clean distclean dist etags $(LIBRARY_NAME)
+.PHONY = install libdir_install single_install install-doc install-examples install-manual install-unittests clean distclean dist etags $(LIBRARY_NAME)
all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB)
@@ -249,18 +285,19 @@ all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB)
chmod a-x "$*.$(EXTENSION)"
# this links everything into a single binary file
-$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o
- $(CC) $(ALL_LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(ALL_LIBS)
+$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o lib$(LIBRARY_NAME).o
+ $(CC) $(ALL_LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) \
+ $(LIBRARY_NAME).o lib$(LIBRARY_NAME).o $(ALL_LIBS)
chmod a-x $(LIBRARY_NAME).$(EXTENSION)
$(SHARED_LIB): $(SHARED_SOURCE:.c=.o)
- $(CC) $(SHARED_LDFLAGS) -o $(SHARED_LIB) $(SHARED_SOURCE:.c=.o) $(LIBS)
+ $(CC) $(SHARED_LDFLAGS) -o $(SHARED_LIB) $(SHARED_SOURCE:.c=.o) $(ALL_LIBS)
install: libdir_install
# The meta and help files are explicitly installed to make sure they are
# actually there. Those files are not optional, then need to be there.
-libdir_install: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) install-doc install-examples install-manual
+libdir_install: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) install-doc install-examples install-manual install-unittests
$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \
$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
@@ -276,9 +313,12 @@ libdir_install: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) install-doc install-ex
test -z "$(strip $(PDOBJECTS))" || \
$(INSTALL_DATA) $(PDOBJECTS) \
$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ test -z "$(strip $(SHARED_TCL_LIB))" || \
+ $(INSTALL_DATA) $(SHARED_TCL_LIB) \
+ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
# install library linked as single binary
-single_install: $(LIBRARY_NAME) install-doc install-examples install-manual
+single_install: $(LIBRARY_NAME) install-doc install-examples install-manual install-unittests
$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
$(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
$(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION)
@@ -305,6 +345,12 @@ install-manual:
$(INSTALL_DATA) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \
done
+install-unittests:
+ test -z "$(strip $(UNITTESTS))" || \
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/unittests && \
+ for file in $(UNITTESTS); do \
+ $(INSTALL_DATA) unittests/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/unittests; \
+ done
clean:
-rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o) $(SHARED_SOURCE:.c=.o)
@@ -348,10 +394,14 @@ dist: $(DISTDIR)
$(INSTALL_DATA) $(ALLSOURCES) $(DISTDIR)
test -z "$(strip $(wildcard $(ALLSOURCES:.c=.tcl)))" || \
$(INSTALL_DATA) $(wildcard $(ALLSOURCES:.c=.tcl)) $(DISTDIR)
+ test -z "$(strip $(wildcard $(LIBRARY_NAME).c))" || \
+ $(INSTALL_DATA) $(LIBRARY_NAME).c $(DISTDIR)
test -z "$(strip $(SHARED_HEADER))" || \
$(INSTALL_DATA) $(SHARED_HEADER) $(DISTDIR)
test -z "$(strip $(SHARED_SOURCE))" || \
$(INSTALL_DATA) $(SHARED_SOURCE) $(DISTDIR)
+ test -z "$(strip $(SHARED_TCL_LIB))" || \
+ $(INSTALL_DATA) $(SHARED_TCL_LIB) $(DISTDIR)
test -z "$(strip $(PDOBJECTS))" || \
$(INSTALL_DATA) $(PDOBJECTS) $(DISTDIR)
test -z "$(strip $(HELPPATCHES))" || \
@@ -368,6 +418,11 @@ dist: $(DISTDIR)
for file in $(MANUAL); do \
$(INSTALL_DATA) manual/$$file $(DISTDIR)/manual; \
done
+ test -z "$(strip $(UNITTESTS))" || \
+ $(INSTALL_DIR) $(DISTDIR)/unittests && \
+ for file in $(UNITTESTS); do \
+ $(INSTALL_DATA) unittests/$$file $(DISTDIR)/unittests; \
+ done
tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR)
# make a Debian source package
@@ -380,8 +435,12 @@ dpkg-source:
rm -rf -- $(DISTDIR) $(ORIGDIR)
cd .. && dpkg-source -b $(LIBRARY_NAME)
-etags:
- etags *.h $(SOURCES) ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h
+etags: TAGS
+
+TAGS: $(wildcard $(PD_INCLUDE)/*.h) $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER)
+ etags $(wildcard $(PD_INCLUDE)/*.h)
+ etags -a *.h $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER)
+ etags -a --language=none --regex="/proc[ \t]+\([^ \t]+\)/\1/" *.tcl
showsetup:
@echo "CC: $(CC)"
@@ -397,9 +456,11 @@ showsetup:
@echo "LIBRARY_NAME: $(LIBRARY_NAME)"
@echo "LIBRARY_VERSION: $(LIBRARY_VERSION)"
@echo "SOURCES: $(SOURCES)"
+ @echo "EXTENSION: $(EXTENSION)"
@echo "SHARED_HEADER: $(SHARED_HEADER)"
@echo "SHARED_SOURCE: $(SHARED_SOURCE)"
@echo "SHARED_LIB: $(SHARED_LIB)"
+ @echo "SHARED_TCL_LIB: $(SHARED_TCL_LIB)"
@echo "PDOBJECTS: $(PDOBJECTS)"
@echo "ALLSOURCES: $(ALLSOURCES)"
@echo "ALLSOURCES TCL: $(wildcard $(ALLSOURCES:.c=.tcl))"
@@ -408,3 +469,6 @@ showsetup:
@echo "pkglibdir: $(pkglibdir)"
@echo "DISTDIR: $(DISTDIR)"
@echo "ORIGDIR: $(ORIGDIR)"
+ @echo "NDK_TOOLCHAIN: $(NDK_TOOLCHAIN)"
+ @echo "NDK_BASE: $(NDK_BASE)"
+ @echo "NDK_SYSROOT: $(NDK_SYSROOT)"
diff --git a/allow.c b/allow.c
index a8a6238..15b3803 100644
--- a/allow.c
+++ b/allow.c
@@ -1,112 +1,112 @@
-/* ---------------------------- allow --------------------------------------- */
-/* */
-/* Lets only floats/symbols through that are allowed to do so. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <string.h>
-
-static char *version = "allow v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct allow
-{
- t_object x_obj;
- t_outlet *x_out;
- t_atom *x_elem; // list of elemets that are allowed to pass
- t_int x_numelem; // the number of elemetns in our allow-list
-} t_allow;
-
- /* we got a symbol... */
-static void allow_symbol(t_allow *x, t_symbol *s)
-{
- int i;
- for(i = 0; i < x->x_numelem; i++)
- {
- if(x->x_elem[i].a_type == A_SYMBOL) // compare with all symbols in our list
- if(atom_getsymbolarg(i, x->x_numelem, x->x_elem) == s)
- {
- outlet_symbol(x->x_out, s);
- return;
- }
- }
-}
-
- /* we got a float... */
-static void allow_float(t_allow *x, t_floatarg f)
-{
- int i;
- for(i = 0; i < x->x_numelem; i++)
- {
- if(x->x_elem[i].a_type == A_FLOAT) // compare with all floats in our list
- if(atom_getfloatarg(i, x->x_numelem, x->x_elem) == f)
- {
- outlet_float(x->x_out, f);
- return;
- }
- }
-}
-
-static t_class *allow_class;
-
-static void allow_free(t_allow *x)
-{
- freebytes(x->x_elem, x->x_numelem*sizeof(t_atom));
-}
-
-static void *allow_new(t_symbol *s, int argc, t_atom *argv)
-{
- t_allow *x = (t_allow *)pd_new(allow_class);
-
- x->x_numelem = argc; // get the number of elements
- x->x_elem = getbytes(argc*sizeof(t_atom));
- memcpy(x->x_elem, argv, argc*sizeof(t_atom));
-
- x->x_out = outlet_new(&x->x_obj, gensym("anything"));
-
- // post("allow: got %d elements", x->x_numelem);
-
- return (x);
-}
-
-#ifndef MAXLIB
-void allow_setup(void)
-{
- /* the object's class: */
- allow_class = class_new(gensym("allow"), (t_newmethod)allow_new,
- (t_method)allow_free, sizeof(t_allow), 0, A_GIMME, 0);
-#else
-void maxlib_allow_setup(void)
-{
- /* the object's class: */
- allow_class = class_new(gensym("maxlib_allow"), (t_newmethod)allow_new,
- (t_method)allow_free, sizeof(t_allow), 0, A_GIMME, 0);
- class_addcreator((t_newmethod)allow_new, gensym("allow"), A_GIMME, 0);
-#endif
- class_addsymbol(allow_class, allow_symbol);
- class_addfloat(allow_class, allow_float);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_sethelpsymbol(allow_class, gensym("maxlib/allow-help.pd"));
-#endif
-}
+/* ---------------------------- allow --------------------------------------- */
+/* */
+/* Lets only floats/symbols through that are allowed to do so. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <string.h>
+
+static char *version = "allow v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct allow
+{
+ t_object x_obj;
+ t_outlet *x_out;
+ t_atom *x_elem; // list of elemets that are allowed to pass
+ t_int x_numelem; // the number of elemetns in our allow-list
+} t_allow;
+
+ /* we got a symbol... */
+static void allow_symbol(t_allow *x, t_symbol *s)
+{
+ int i;
+ for(i = 0; i < x->x_numelem; i++)
+ {
+ if(x->x_elem[i].a_type == A_SYMBOL) // compare with all symbols in our list
+ if(atom_getsymbolarg(i, x->x_numelem, x->x_elem) == s)
+ {
+ outlet_symbol(x->x_out, s);
+ return;
+ }
+ }
+}
+
+ /* we got a float... */
+static void allow_float(t_allow *x, t_floatarg f)
+{
+ int i;
+ for(i = 0; i < x->x_numelem; i++)
+ {
+ if(x->x_elem[i].a_type == A_FLOAT) // compare with all floats in our list
+ if(atom_getfloatarg(i, x->x_numelem, x->x_elem) == f)
+ {
+ outlet_float(x->x_out, f);
+ return;
+ }
+ }
+}
+
+static t_class *allow_class;
+
+static void allow_free(t_allow *x)
+{
+ freebytes(x->x_elem, x->x_numelem*sizeof(t_atom));
+}
+
+static void *allow_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_allow *x = (t_allow *)pd_new(allow_class);
+
+ x->x_numelem = argc; // get the number of elements
+ x->x_elem = getbytes(argc*sizeof(t_atom));
+ memcpy(x->x_elem, argv, argc*sizeof(t_atom));
+
+ x->x_out = outlet_new(&x->x_obj, gensym("anything"));
+
+ // post("allow: got %d elements", x->x_numelem);
+
+ return (x);
+}
+
+#ifndef MAXLIB
+void allow_setup(void)
+{
+ /* the object's class: */
+ allow_class = class_new(gensym("allow"), (t_newmethod)allow_new,
+ (t_method)allow_free, sizeof(t_allow), 0, A_GIMME, 0);
+#else
+void maxlib_allow_setup(void)
+{
+ /* the object's class: */
+ allow_class = class_new(gensym("maxlib_allow"), (t_newmethod)allow_new,
+ (t_method)allow_free, sizeof(t_allow), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)allow_new, gensym("allow"), A_GIMME, 0);
+#endif
+ class_addsymbol(allow_class, allow_symbol);
+ class_addfloat(allow_class, allow_float);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(allow_class, gensym("maxlib/allow-help.pd"));
+#endif
+}
diff --git a/arbran.c b/arbran.c
index d708e11..7dc68ac 100644
--- a/arbran.c
+++ b/arbran.c
@@ -1,189 +1,189 @@
-/* ---------------------------- rand_arbran ----------------------------------- */
-/* */
-/* rand_arbran generates a random variable that conforms to the */
-/* piecewise probability density in two arrays */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-#define fran() (t_float)rand()/(t_float)RAND_MAX
-#ifndef M_PI
-#define M_PI 3.1415927
-#endif
-
-static char *version = "arbran v0.1b, generates a random variable that conforms to the\n"
- " piecewise probability density in two arrays\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-/* -------------------------- rand_arbran ------------------------------ */
-
-static t_class *rand_arbran_class;
-
-typedef struct _rand_arbran
-{
- t_object x_obj;
- t_symbol *x_x;
- t_symbol *x_p;
- t_garray *x_bufx;
- t_garray *x_bufp;
-} t_rand_arbran;
-
-static void rand_arbran_pdfscale(t_rand_arbran *x)
-{
- t_garray *bx = x->x_bufx, *bp = x->x_bufp;
- t_float a = 0;
- t_int k = 0;
- t_float *tx, *tp;
- int ix, ip;
- if (!garray_getfloatarray(bx, &ix, &tx))
- {
- post("arbran: couldn't read from array!");
- return;
- }
- if (!garray_getfloatarray(bp, &ip, &tp))
- {
- post("arbran: couldn't read from array!");
- return;
- }
-
- for(k = 1; k < ix; k++)
- {
- a += (tx[k]-tx[k-1])*(tp[k]+tp[k-1])/2.0;
- }
- for(k = 0; k < ix; k++)
- {
- tp[k] = tp[k]/a;
- }
- garray_redraw(x->x_bufp);
-}
-
-static void rand_arbran_bang(t_rand_arbran *x)
-{
- t_garray *bx = x->x_bufx, *bp = x->x_bufp;
- t_float a, u, a0, slope, b, d, r;
- t_int k = 0;
- t_float *tx, *tp;
- int ix, ip;
- if (!garray_getfloatarray(bx, &ix, &tx))
- {
- post("arbran: couldn't read from array!");
- return;
- }
- if (!garray_getfloatarray(bp, &ip, &tp))
- {
- post("arbran: couldn't read from array!");
- return;
- }
-
- a = 0;
- a0 = 0;
- u = fran();
- while(u > a)
- {
- a0 = (tx[k+1]-tx[k])*(tp[k+1]+tp[k])/2.0;
- a += a0;
- k++;
- }
- k--;
- slope = (tp[k+1]-tp[k])/(tx[k+1]-tx[k]);
- if(slope == 0)
- {
- r = (u-a+a0)/tp[k]+tx[k];
- }
- else
- {
- b=tp[k]/slope-tx[k];
- d=b*b+tx[k]*tx[k]+2*b*tx[k]+2*(u-a+a0)/slope;
- if(slope > 0)
- r=-b+sqrt(d);
- else
- r=-b-sqrt(d);
- }
- outlet_float(x->x_obj.ob_outlet, r);
-}
-
-static void rand_arbran_set(t_rand_arbran *x)
-{
- t_garray *b, *b2;
-
- if ((b = (t_garray *)pd_findbyclass(x->x_x, garray_class)))
- {
- post("arbran: array set to \"%s\"", x->x_x->s_name);
- x->x_bufx = b;
- } else {
- post("arbran: no array \"%s\" (error %d)", x->x_x->s_name, b);
- x->x_bufx = 0;
- }
- if ((b2 = (t_garray *)pd_findbyclass(x->x_p, garray_class)))
- {
- post("arbran: array set to \"%s\"", x->x_p->s_name);
- x->x_bufp = b2;
- } else {
- post("arbran: no array \"%s\" (error %d)", x->x_p->s_name, b);
- x->x_bufp = 0;
- }
-}
-
-static void rand_arbran_setarrays(t_rand_arbran *x, t_symbol *s1, t_symbol *s2)
-{
- x->x_x = s1;
- x->x_p = s2;
- rand_arbran_set(x);
-}
-
-static void *rand_arbran_new(t_symbol *s1, t_symbol *s2)
-{
- t_rand_arbran *x = (t_rand_arbran *)pd_new(rand_arbran_class);
- srand( (unsigned)time( NULL ) );
- outlet_new(&x->x_obj, &s_float);
- x->x_x = s1;
- x->x_p = s2;
- rand_arbran_set(x);
- return (x);
-}
-
-#ifndef MAXLIB
-void arbran_setup(void)
-{
- rand_arbran_class = class_new(gensym("arbran"), (t_newmethod)rand_arbran_new, 0,
- sizeof(t_rand_arbran), 0, A_SYMBOL, A_SYMBOL, 0);
-#else
-void maxlib_arbran_setup(void)
-{
- rand_arbran_class = class_new(gensym("maxlib_arbran"), (t_newmethod)rand_arbran_new, 0,
- sizeof(t_rand_arbran), 0, A_SYMBOL, A_SYMBOL, 0);
-#endif
- class_addbang(rand_arbran_class, rand_arbran_bang);
- class_addmethod(rand_arbran_class, (t_method)rand_arbran_pdfscale, gensym("pdfscale"), 0);
- class_addmethod(rand_arbran_class, (t_method)rand_arbran_setarrays, gensym("set"), A_SYMBOL, A_SYMBOL, 0);
-#ifndef MAXLIB
- class_sethelpsymbol(rand_arbran_class, gensym("arbran-help.pd"));
- post(version);
-#else
- class_addcreator((t_newmethod)rand_arbran_new, gensym("arbran"), A_SYMBOL, A_SYMBOL, 0);
- class_sethelpsymbol(rand_arbran_class, gensym("maxlib/arbran-help.pd"));
-#endif
-}
+/* ---------------------------- rand_arbran ----------------------------------- */
+/* */
+/* rand_arbran generates a random variable that conforms to the */
+/* piecewise probability density in two arrays */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+
+#define fran() (t_float)rand()/(t_float)RAND_MAX
+#ifndef M_PI
+#define M_PI 3.1415927
+#endif
+
+static char *version = "arbran v0.1b, generates a random variable that conforms to the\n"
+ " piecewise probability density in two arrays\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- rand_arbran ------------------------------ */
+
+static t_class *rand_arbran_class;
+
+typedef struct _rand_arbran
+{
+ t_object x_obj;
+ t_symbol *x_x;
+ t_symbol *x_p;
+ t_garray *x_bufx;
+ t_garray *x_bufp;
+} t_rand_arbran;
+
+static void rand_arbran_pdfscale(t_rand_arbran *x)
+{
+ t_garray *bx = x->x_bufx, *bp = x->x_bufp;
+ t_float a = 0;
+ t_int k = 0;
+ t_float *tx, *tp;
+ int ix, ip;
+ if (!garray_getfloatarray(bx, &ix, &tx))
+ {
+ post("arbran: couldn't read from array!");
+ return;
+ }
+ if (!garray_getfloatarray(bp, &ip, &tp))
+ {
+ post("arbran: couldn't read from array!");
+ return;
+ }
+
+ for(k = 1; k < ix; k++)
+ {
+ a += (tx[k]-tx[k-1])*(tp[k]+tp[k-1])/2.0;
+ }
+ for(k = 0; k < ix; k++)
+ {
+ tp[k] = tp[k]/a;
+ }
+ garray_redraw(x->x_bufp);
+}
+
+static void rand_arbran_bang(t_rand_arbran *x)
+{
+ t_garray *bx = x->x_bufx, *bp = x->x_bufp;
+ t_float a, u, a0, slope, b, d, r;
+ t_int k = 0;
+ t_float *tx, *tp;
+ int ix, ip;
+ if (!garray_getfloatarray(bx, &ix, &tx))
+ {
+ post("arbran: couldn't read from array!");
+ return;
+ }
+ if (!garray_getfloatarray(bp, &ip, &tp))
+ {
+ post("arbran: couldn't read from array!");
+ return;
+ }
+
+ a = 0;
+ a0 = 0;
+ u = fran();
+ while(u > a)
+ {
+ a0 = (tx[k+1]-tx[k])*(tp[k+1]+tp[k])/2.0;
+ a += a0;
+ k++;
+ }
+ k--;
+ slope = (tp[k+1]-tp[k])/(tx[k+1]-tx[k]);
+ if(slope == 0)
+ {
+ r = (u-a+a0)/tp[k]+tx[k];
+ }
+ else
+ {
+ b=tp[k]/slope-tx[k];
+ d=b*b+tx[k]*tx[k]+2*b*tx[k]+2*(u-a+a0)/slope;
+ if(slope > 0)
+ r=-b+sqrt(d);
+ else
+ r=-b-sqrt(d);
+ }
+ outlet_float(x->x_obj.ob_outlet, r);
+}
+
+static void rand_arbran_set(t_rand_arbran *x)
+{
+ t_garray *b, *b2;
+
+ if ((b = (t_garray *)pd_findbyclass(x->x_x, garray_class)))
+ {
+ post("arbran: array set to \"%s\"", x->x_x->s_name);
+ x->x_bufx = b;
+ } else {
+ post("arbran: no array \"%s\" (error %d)", x->x_x->s_name, b);
+ x->x_bufx = 0;
+ }
+ if ((b2 = (t_garray *)pd_findbyclass(x->x_p, garray_class)))
+ {
+ post("arbran: array set to \"%s\"", x->x_p->s_name);
+ x->x_bufp = b2;
+ } else {
+ post("arbran: no array \"%s\" (error %d)", x->x_p->s_name, b);
+ x->x_bufp = 0;
+ }
+}
+
+static void rand_arbran_setarrays(t_rand_arbran *x, t_symbol *s1, t_symbol *s2)
+{
+ x->x_x = s1;
+ x->x_p = s2;
+ rand_arbran_set(x);
+}
+
+static void *rand_arbran_new(t_symbol *s1, t_symbol *s2)
+{
+ t_rand_arbran *x = (t_rand_arbran *)pd_new(rand_arbran_class);
+ srand( (unsigned)time( NULL ) );
+ outlet_new(&x->x_obj, &s_float);
+ x->x_x = s1;
+ x->x_p = s2;
+ rand_arbran_set(x);
+ return (x);
+}
+
+#ifndef MAXLIB
+void arbran_setup(void)
+{
+ rand_arbran_class = class_new(gensym("arbran"), (t_newmethod)rand_arbran_new, 0,
+ sizeof(t_rand_arbran), 0, A_SYMBOL, A_SYMBOL, 0);
+#else
+void maxlib_arbran_setup(void)
+{
+ rand_arbran_class = class_new(gensym("maxlib_arbran"), (t_newmethod)rand_arbran_new, 0,
+ sizeof(t_rand_arbran), 0, A_SYMBOL, A_SYMBOL, 0);
+#endif
+ class_addbang(rand_arbran_class, rand_arbran_bang);
+ class_addmethod(rand_arbran_class, (t_method)rand_arbran_pdfscale, gensym("pdfscale"), 0);
+ class_addmethod(rand_arbran_class, (t_method)rand_arbran_setarrays, gensym("set"), A_SYMBOL, A_SYMBOL, 0);
+#ifndef MAXLIB
+ class_sethelpsymbol(rand_arbran_class, gensym("arbran-help.pd"));
+ logpost(NULL, 4, version);
+#else
+ class_addcreator((t_newmethod)rand_arbran_new, gensym("arbran"), A_SYMBOL, A_SYMBOL, 0);
+ class_sethelpsymbol(rand_arbran_class, gensym("maxlib/arbran-help.pd"));
+#endif
+}
diff --git a/arraycopy.c b/arraycopy.c
index 50d4dd8..c5e2eb0 100644
--- a/arraycopy.c
+++ b/arraycopy.c
@@ -25,7 +25,7 @@
#include "m_pd.h"
#include <stdlib.h>
-static char *version = "arraycopy v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
+static char *version = "arraycopy v0.2.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
typedef struct arraycopy
{
@@ -80,7 +80,7 @@ static void arraycopy_setsourcearray(t_arraycopy *x, t_symbol *s)
/* get's called directly when we get a 'bang' */
static void arraycopy_docopy(t_arraycopy *x)
{
-
+ /* use new 64-bit compatible array API if available */
#if (defined PD_MAJOR_VERSION && defined PD_MINOR_VERSION) && (PD_MAJOR_VERSION > 0 || PD_MINOR_VERSION >= 41)
# define arraynumber_t t_word
# define array_getarray garray_getfloatwords
@@ -94,11 +94,10 @@ static void arraycopy_docopy(t_arraycopy *x)
#endif
t_garray *b; /* make local copy of array */
- arraynumber_t *tab; /* the content itselfe */
- int items;
+ arraynumber_t *tab; /* the content itself */
+ int sourcesize, destsize;
t_int i;
t_garray *A;
- int npoints;
arraynumber_t *vec;
if(!x->x_destarray)
@@ -123,40 +122,55 @@ static void arraycopy_docopy(t_arraycopy *x)
}
// read from our array
- if (!array_getarray(b, &items, &tab))
+ if (!array_getarray(b, &sourcesize, &tab))
{
- post("arraycopy: couldn't read from source array!");
+ pd_error(x, "arraycopy: couldn't read from source array '%s'!",
+ x->x_sourcearray->s_name);
return;
}
if (!(A = (t_garray *)pd_findbyclass(x->x_destarray, garray_class)))
error("arraycopy: %s: no such array", x->x_destarray->s_name);
- else if (!array_getarray(A, &npoints, &vec))
+ else if (!array_getarray(A, &destsize, &vec))
error("arraycopy: %s: bad template ", x->x_destarray->s_name);
else
{
- if(x->x_start > items) // check start point
+ if(x->x_start > sourcesize)
+ {
+ pd_error(x, "arraycopy: start point %i out of range for source '%s'",
+ (int)x->x_start, x->x_sourcearray->s_name);
+ return;
+ }
+ if(x->x_start > destsize)
{
- post("arraycopy: source start point out of range for the array given");
+ pd_error(x, "arraycopy: start point %i out of range for destination '%s'",
+ (int)x->x_start, x->x_destarray->s_name);
return;
}
if(x->x_end) // end point is specified
{
- if(x->x_end > items) // check start point
- {
- post("arraycopy: source end point out of range for the array given");
- x->x_end = items;
+ if(x->x_end > sourcesize)
+ {
+ logpost(x, 2, "arraycopy: end point %i out of range for source '%s', using %i",
+ (int)x->x_end, x->x_sourcearray->s_name, sourcesize);
+ x->x_end = sourcesize;
+ }
+ if(x->x_end > destsize)
+ {
+ logpost(x, 2, "arraycopy: end point %i out of range for destination '%s', using %i",
+ (int)x->x_end, x->x_destarray->s_name, destsize);
+ x->x_end = destsize;
}
}
- else x->x_end = items;
+ else
+ x->x_end = (sourcesize < destsize ? sourcesize : destsize);
if(x->x_pos)
vec += x->x_pos;
-
for(i = x->x_start; i < x->x_end; i++)
{
- array_set(vec, 0, array_get(tab, i));
+ array_set(vec, 0, array_get(tab, i));
vec++;
}
garray_redraw(A);
@@ -292,7 +306,7 @@ void maxlib_arraycopy_setup(void)
// class_addlist(arraycopy_class, arraycopy_list);
#ifndef MAXLIB
- post(version);
+ logpost(NULL, 4, version);
#else
class_sethelpsymbol(arraycopy_class, gensym("maxlib/arraycopy-help.pd"));
#endif
diff --git a/average.c b/average.c
index 2ce99ad..4e0f2d0 100644
--- a/average.c
+++ b/average.c
@@ -1,202 +1,202 @@
-/* -------------------------- average ----------------------------------------- */
-/* */
-/* Calculates the average value of the last N elements. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <math.h>
-
-#define MAX_ARG 128 /* maximum number of items to average */
-
-static char *version = "average v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct average
-{
- t_object x_ob;
- t_clock *x_clock;
- t_inlet *x_inindex;
- t_outlet *x_outfloat; /* output the average */
- t_outlet *x_outtendency; /* outputs the tendency of the average */
- t_int x_limit; /* indicates if input is 'blocked' (1) */
- t_int x_index; /* the number of elements to average */
- t_float x_input[MAX_ARG]; /* stores the input values we need for averaging */
- t_int x_inpointer; /* actual position in above array */
- t_float x_average; /* what do you guess ? */
- t_float x_lastaverage;
- t_int x_mode; /* how to average: linear or geometric */
-
-} t_average;
-
- /* there must be a function for this in math.h but how is the
- german 'Fakultät' called in english ???? */
-static int normalise(int i)
-{
- int ret = i;
- while(i--)
- {
- if(i == 0)break;
- ret += i;
- }
- return (ret);
-}
-
-static void average_float(t_average *x, t_floatarg f)
-{
- int i, j = 0;
- t_float tendency;
- t_float geo = 1.0;
-
- x->x_average = 0;
- /* put value into array */
- x->x_input[x->x_inpointer] = f;
- /* calulate average */
- for(i = 0; i < x->x_index; i++)
- {
- if(x->x_mode == 0) /* linear */
- {
- x->x_average += x->x_input[i] * (1.0 / (float)x->x_index);
- }
- else if(x->x_mode == 1) /* geometric */
- {
- if(x->x_input[i] == 0)x->x_input[i] = 0.001; /* need to cheat a bit... */
- geo *= x->x_input[i];
- if(i == x->x_index - 1)
- x->x_average = pow(geo, (1.0/(float)x->x_index));
- }
- else if(x->x_mode == 2) /* weighted */
- {
- x->x_average += x->x_input[(j + x->x_inpointer + x->x_index) % x->x_index] * (float)(x->x_index - (i + 1));
- j--; /* go back in array */
- /* normalise output */
- if(i == x->x_index - 1)
- x->x_average = x->x_average / (float)normalise(x->x_index - 1);
- } else post("average: internal error!");
- }
- if(++x->x_inpointer > x->x_index)
- {
- x->x_inpointer = 0;
- if(x->x_lastaverage < x->x_average)
- {
- tendency = 1; /* getting more */
- }
- else if(x->x_lastaverage > x->x_average)
- {
- tendency = -1; /* getting less */
- }
- else tendency = 0; /* nothing has changed */
- outlet_float(x->x_outtendency, tendency);
- x->x_lastaverage = x->x_average;
- }
- outlet_float(x->x_outfloat, x->x_average);
-}
-
-static void average_index(t_average *x, t_floatarg f)
-{
- x->x_index = (t_int)f;
- if(x->x_index > MAX_ARG)x->x_index = MAX_ARG;
-}
-
-static void average_reset(t_average *x)
-{
- int i;
- /* zeroe out the array */
- for(i = 0; i < MAX_ARG; i++)x->x_input[i] = 0.0;
- x->x_inpointer = 0;
- x->x_average = 0;
- x->x_lastaverage = 0;
- post("average: reset");
-}
-
-static void average_linear(t_average *x)
-{
- x->x_mode = 0;
- post("average: linear");
-}
-
-static void average_geometric(t_average *x)
-{
- x->x_mode = 1;
- post("average: geometric");
-}
-
-static void average_weight(t_average *x)
-{
- x->x_mode = 2;
- post("average: weighted");
-}
-
-static void average_free(t_average *x)
-{
- /* nothing to do */
-}
-
-static t_class *average_class;
-
-static void *average_new(t_floatarg f)
-{
- int i;
-
- t_average *x = (t_average *)pd_new(average_class);
- x->x_inindex = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("index"));
- x->x_outfloat = outlet_new(&x->x_ob, gensym("float"));
- x->x_outtendency = outlet_new(&x->x_ob, gensym("float"));
-
- /* zeroe out the array */
- for(i = 0; i < MAX_ARG; i++)x->x_input[i] = 0.0;
- x->x_index = (t_int)f;
- if(x->x_index > MAX_ARG)
- {
- x->x_index = MAX_ARG;
- post("average: set number of items to %d", x->x_index);
- }
- x->x_inpointer = 0;
- x->x_average = 0;
- x->x_mode = 0;
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void average_setup(void)
-{
- average_class = class_new(gensym("average"), (t_newmethod)average_new,
- (t_method)average_free, sizeof(t_average), 0, A_DEFFLOAT, 0);
-#else
-void maxlib_average_setup(void)
-{
- average_class = class_new(gensym("maxlib_average"), (t_newmethod)average_new,
- (t_method)average_free, sizeof(t_average), 0, A_DEFFLOAT, 0);
-#endif
- class_addmethod(average_class, (t_method)average_reset, gensym("reset"), 0);
- class_addmethod(average_class, (t_method)average_linear, gensym("linear"), 0);
- class_addmethod(average_class, (t_method)average_geometric, gensym("geometric"), 0);
- class_addmethod(average_class, (t_method)average_weight, gensym("weight"), 0);
- class_addfloat(average_class, average_float);
- class_addmethod(average_class, (t_method)average_index, gensym("index"), A_FLOAT, 0);
-#ifndef MAXLIB
- post(version);
-
-#else
- class_addcreator((t_newmethod)average_new, gensym("average"), A_DEFFLOAT, 0);
- class_sethelpsymbol(average_class, gensym("maxlib/average-help.pd"));
-#endif
-}
-
+/* -------------------------- average ----------------------------------------- */
+/* */
+/* Calculates the average value of the last N elements. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <math.h>
+
+#define MAX_ARG 128 /* maximum number of items to average */
+
+static char *version = "average v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct average
+{
+ t_object x_ob;
+ t_clock *x_clock;
+ t_inlet *x_inindex;
+ t_outlet *x_outfloat; /* output the average */
+ t_outlet *x_outtendency; /* outputs the tendency of the average */
+ t_int x_limit; /* indicates if input is 'blocked' (1) */
+ t_int x_index; /* the number of elements to average */
+ t_float x_input[MAX_ARG]; /* stores the input values we need for averaging */
+ t_int x_inpointer; /* actual position in above array */
+ t_float x_average; /* what do you guess ? */
+ t_float x_lastaverage;
+ t_int x_mode; /* how to average: linear or geometric */
+
+} t_average;
+
+ /* there must be a function for this in math.h but how is the
+ german 'Fakultät' called in english ???? */
+static int normalise(int i)
+{
+ int ret = i;
+ while(i--)
+ {
+ if(i == 0)break;
+ ret += i;
+ }
+ return (ret);
+}
+
+static void average_float(t_average *x, t_floatarg f)
+{
+ int i, j = 0;
+ t_float tendency;
+ t_float geo = 1.0;
+
+ x->x_average = 0;
+ /* put value into array */
+ x->x_input[x->x_inpointer] = f;
+ /* calulate average */
+ for(i = 0; i < x->x_index; i++)
+ {
+ if(x->x_mode == 0) /* linear */
+ {
+ x->x_average += x->x_input[i] * (1.0 / (float)x->x_index);
+ }
+ else if(x->x_mode == 1) /* geometric */
+ {
+ if(x->x_input[i] == 0)x->x_input[i] = 0.001; /* need to cheat a bit... */
+ geo *= x->x_input[i];
+ if(i == x->x_index - 1)
+ x->x_average = pow(geo, (1.0/(float)x->x_index));
+ }
+ else if(x->x_mode == 2) /* weighted */
+ {
+ x->x_average += x->x_input[(j + x->x_inpointer + x->x_index) % x->x_index] * (float)(x->x_index - (i + 1));
+ j--; /* go back in array */
+ /* normalise output */
+ if(i == x->x_index - 1)
+ x->x_average = x->x_average / (float)normalise(x->x_index - 1);
+ } else post("average: internal error!");
+ }
+ if(++x->x_inpointer > x->x_index)
+ {
+ x->x_inpointer = 0;
+ if(x->x_lastaverage < x->x_average)
+ {
+ tendency = 1; /* getting more */
+ }
+ else if(x->x_lastaverage > x->x_average)
+ {
+ tendency = -1; /* getting less */
+ }
+ else tendency = 0; /* nothing has changed */
+ outlet_float(x->x_outtendency, tendency);
+ x->x_lastaverage = x->x_average;
+ }
+ outlet_float(x->x_outfloat, x->x_average);
+}
+
+static void average_index(t_average *x, t_floatarg f)
+{
+ x->x_index = (t_int)f;
+ if(x->x_index > MAX_ARG)x->x_index = MAX_ARG;
+}
+
+static void average_reset(t_average *x)
+{
+ int i;
+ /* zeroe out the array */
+ for(i = 0; i < MAX_ARG; i++)x->x_input[i] = 0.0;
+ x->x_inpointer = 0;
+ x->x_average = 0;
+ x->x_lastaverage = 0;
+ post("average: reset");
+}
+
+static void average_linear(t_average *x)
+{
+ x->x_mode = 0;
+ post("average: linear");
+}
+
+static void average_geometric(t_average *x)
+{
+ x->x_mode = 1;
+ post("average: geometric");
+}
+
+static void average_weight(t_average *x)
+{
+ x->x_mode = 2;
+ post("average: weighted");
+}
+
+static void average_free(t_average *x)
+{
+ /* nothing to do */
+}
+
+static t_class *average_class;
+
+static void *average_new(t_floatarg f)
+{
+ int i;
+
+ t_average *x = (t_average *)pd_new(average_class);
+ x->x_inindex = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("index"));
+ x->x_outfloat = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outtendency = outlet_new(&x->x_ob, gensym("float"));
+
+ /* zeroe out the array */
+ for(i = 0; i < MAX_ARG; i++)x->x_input[i] = 0.0;
+ x->x_index = (t_int)f;
+ if(x->x_index > MAX_ARG)
+ {
+ x->x_index = MAX_ARG;
+ post("average: set number of items to %d", x->x_index);
+ }
+ x->x_inpointer = 0;
+ x->x_average = 0;
+ x->x_mode = 0;
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void average_setup(void)
+{
+ average_class = class_new(gensym("average"), (t_newmethod)average_new,
+ (t_method)average_free, sizeof(t_average), 0, A_DEFFLOAT, 0);
+#else
+void maxlib_average_setup(void)
+{
+ average_class = class_new(gensym("maxlib_average"), (t_newmethod)average_new,
+ (t_method)average_free, sizeof(t_average), 0, A_DEFFLOAT, 0);
+#endif
+ class_addmethod(average_class, (t_method)average_reset, gensym("reset"), 0);
+ class_addmethod(average_class, (t_method)average_linear, gensym("linear"), 0);
+ class_addmethod(average_class, (t_method)average_geometric, gensym("geometric"), 0);
+ class_addmethod(average_class, (t_method)average_weight, gensym("weight"), 0);
+ class_addfloat(average_class, average_float);
+ class_addmethod(average_class, (t_method)average_index, gensym("index"), A_FLOAT, 0);
+#ifndef MAXLIB
+ logpost(NULL, 4, version);
+
+#else
+ class_addcreator((t_newmethod)average_new, gensym("average"), A_DEFFLOAT, 0);
+ class_sethelpsymbol(average_class, gensym("maxlib/average-help.pd"));
+#endif
+}
+
diff --git a/beat.c b/beat.c
index a2f565e..1bf5a76 100644
--- a/beat.c
+++ b/beat.c
@@ -1,403 +1,403 @@
-/* --------------------------- beat ------------------------------------------ */
-/* */
-/* Detect the beats per minute of a MIDI stream. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code written by Robert Rowe. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define BEAT_LONG 1500 /* longest time we take into concideration (40 bpm) */
-#define BEAT_SHORT 300 /* shortest time we take into concideration (200 bpm) */
-
-static char *version = "beat v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct
-{
- t_int points; /* number of points assigned to this theory */
- double expect; /* time of next expected hit */
- t_int onbeat; /* whether (1) or not (0) it was on the beat */
-} beat_theory;
-
-typedef struct /* used for sorting theories */
-{
- t_int points;
- t_int theory;
-} beat_sort_record;
-
-
-typedef struct beat
-{
- t_object x_ob;
- t_clock *x_clock;
- t_outlet *x_outbpm; /* beat as MIDI note number */
- t_outlet *x_outms; /* beat in milliseconds */
- t_outlet *x_outbeat; /* send a bang whenever beat is 'on beat' */
- t_int x_print; /* switch printing to console window on / off */
-
- t_int x_num_beats; /* number of beats we've received */
- double x_beat_period; /* time in ms until next expected beat / beat pulse */
- beat_theory x_beats[BEAT_LONG];
- double x_beatexpect; /* expected time for next beat */
- t_int x_on_beat; /* indicate if last event was on beat */
- t_int x_band_percent;
-
- t_int x_pitch;
- t_int x_velo;
- /* helpers needed to do the time calculations */
- double x_this_input;
- double x_last_input;
- double x_lasttime;
- double x_lastlasttime;
-} t_beat;
-
-/* ---------------- mathematical functions to work with doubles -------------- */
-static double double_abs(double value)
-{
- if(value < 0)
- return (value * -1);
- else
- return (value);
-}
-
-/* --------------- beat stuff ------------------------------------------------ */
- /* evaluate results: find theory that is the most likely one and
- print out internal data to console window if print is enabled */
-static int beat_evaluate(t_beat *x)
-{
- int i, j, K;
- char string[256];
- char info[40];
- beat_sort_record theories[BEAT_LONG], *sortp, R;
- int value; /* the result of the sorting */
-
- for (i = 0; i < BEAT_LONG; i++)
- { /* prepare sort records */
- sortp = &(theories[i]);
- sortp->points = x->x_beats[i].points;
- sortp->theory = i;
- }
- for (j = 2; j < BEAT_LONG; j++)
- { /* sort */
- i = j - 1;
- K = theories[j].points;
- R = theories[j];
- while (i > 0)
- {
- if (K >= theories[i].points)
- {
- theories[i+1] = R;
- break;
- }
- else
- {
- theories[i+1] = theories[i];
- i -= 1;
- }
- }
- if (i==0) theories[i+1] = R;
- }
- /* get leading result */
- sortp = &(theories[BEAT_LONG - 1]);
- value = sortp->theory; /* get our resulting theory */
-
- if(x->x_print)
- {
- post(" 0 1 2 3 4 R E");
- *string = '\0'; /* print out five leading theories */
- sprintf(info, "%4g", x->x_this_input);
- strcat(string, info);
- for(i = 1; i < 6; i++)
- {
- sortp = &(theories[BEAT_LONG - i]);
- sprintf(info, " %4d[%3d]", (int) sortp->theory, (int) sortp->points);
- strcat(string, info);
- }
- sprintf(info, " %g %g", clock_getlogicaltime(), x->x_beatexpect);
- strcat(string, info);
- post(string);
- }
-
- return value;
-}
-
- /* reduce duration to fit into our processing window */
- /* some sort of 'double modulo'... */
-static double beat_reduce_offset(double duration)
-{
- double temp = duration;
- int divisor = 2; /* first try dividing by two */
- while (temp > BEAT_LONG) /* while duration is too long */
- temp = duration / divisor++; /* divide by progressively higher divisors */
- return temp; /* return a value in bounds */
-}
-
-/*
- * beat_eligible: determine whether an event is eligible for consideration
- * as a beat theory
- */
-static int beat_eligible(double candidate, int* offsets, int num_offsets)
-{
- double diff;
- int i;
-
- if (candidate >= BEAT_LONG) /* if too long try subharmonics */
- candidate = beat_reduce_offset(candidate);
-
- /* if candidate is close to one already found */
- for(i = 0; i < num_offsets; i++)
- {
- diff = double_abs((candidate - offsets[i]));
- if (diff < offsets[i]/20) {
- if (candidate > offsets[i])
- ++offsets[i]; else /* pull existing one */
- if (candidate < offsets[i]) /* toward new candidate */
- --offsets[i];
- return 0; /* declare candidate ineligible */
- }
- }
- return candidate; /* otherwise return legal candidate */
-}
-
-static void beat_float(t_beat *x, t_floatarg f)
-{
- t_int velo = x->x_velo;
- int i, j, indx;
- int num_offsets, candidate;
- int low_limit, high_limit, width, deviation;
- int points, band, center_offset, period;
- beat_theory* t;
- int offsets[7];
- static int factors[10] =
- { 200, 50, 300, 150, 66, 400, 600, 133, 33, 75 };
- double now = clock_getlogicaltime();
- t_float outvalue;
-
- x->x_pitch = (t_int)f;
- x->x_this_input = clock_gettimesince(x->x_last_input);
-
- if(velo != 0) /* note-on received */
- {
- if(++x->x_num_beats == 1)
- {
- goto time; /* only one event, no beats yet */
- }
-
- num_offsets = 0;
- candidate = beat_eligible(x->x_this_input, offsets, num_offsets);
- if(candidate)
- offsets[num_offsets++] = candidate; /* offset[0] set to incoming offset */
-
- if(x->x_num_beats > 2)
- { /* if three events */
- /* check previous for eligibility */
- candidate = beat_eligible(x->x_lasttime, offsets, num_offsets);
- if (candidate)
- offsets[num_offsets++] = candidate;
- candidate = x->x_this_input + x->x_lasttime; /* add current and previous offsets */
- candidate = beat_eligible(candidate, offsets, num_offsets);
- if (candidate) /* add to list if eligible */
- offsets[num_offsets++] = candidate;
- }
-
- if(x->x_num_beats > 3)
- {
- candidate = beat_eligible(x->x_lastlasttime, offsets, num_offsets);
- if (candidate)
- offsets[num_offsets++] = candidate;
- candidate += x->x_lasttime;
- candidate = beat_eligible(candidate, offsets, num_offsets);
- if (candidate)
- offsets[num_offsets++] = candidate;
- }
-
- indx = 0;
- for(i = num_offsets; i < 7; i++)
- {
- offsets[i] = 0;
- if (indx >= 10) break;
- candidate = 0;
- while ((indx < 10) && (!candidate))
- candidate = beat_eligible((x->x_this_input * factors[indx++])/100, offsets, num_offsets);
- if (candidate)
- offsets[num_offsets++] = candidate;
- }
-
- for(i = 0; i < num_offsets; i++)
- {
- band = offsets[i] * x->x_band_percent / 100;
- if ((low_limit = offsets[i] - band) < 0) /* add points in a critical band */
- low_limit = 0; /* around calculated offset */
- if ((high_limit = offsets[i] + band) > BEAT_LONG)
- high_limit = BEAT_LONG;
- center_offset = offsets[i]; /* midpoint of increment */
- points = 0;
- for (j = low_limit; j < high_limit; j++)
- {
- if ((points = x->x_beats[j].points) > 0)
- { /* if there is already activation */
- deviation = j - center_offset; /* record deviation from midpoint */
- x->x_beats[j].points = 0;
- if (deviation < 0) { /* if there is activation below midpoint */
- t = &(x->x_beats[j+1]); /* take theory one above prior */
- } else
- if (deviation > 0) { /* if there is activation above midpoint */
- t = &(x->x_beats[j-1]); /* take theory one below prior */
- } else
- t = &(x->x_beats[j]); /* landed right on it */
- t->points = points + (num_offsets-i);
- break;
- }
- }
- if (!points)
- x->x_beats[center_offset].points = num_offsets - i;
- }
-
- /* boost hits, and suppress theories with missed beats */
- period = 0;
- points = 0;
- for (i = BEAT_SHORT; i < BEAT_LONG; i++)
- {
- t = &(x->x_beats[i]);
- width = 5 > (t->expect / 7) ? 5 : (t->expect / 7);
- t->expect -= x->x_this_input;
- t->onbeat = 0;
- if(double_abs(t->expect) <= width) /* lies within range */
- {
- t->expect = i;
- t->onbeat = 1;
- if (t->points > 0)
- t->points += 4; /* add 4 points */
- }
- else if(t->expect < 0)
- {
- t->points -= 8;
- t->expect = i;
- }
- if (t->points < 0) t->points = 0; else
- if (t->points > 200) t->points = 200;
- if (t->points > points)
- {
- points = t->points;
- period = i;
- }
- }
-
-
-
- x->x_beat_period = (double)period;
- t = &(x->x_beats[period]);
- x->x_beatexpect = now + (double)t->expect;
- x->x_on_beat = t->onbeat;
-
-time:
- x->x_lastlasttime = x->x_lasttime;
- x->x_lasttime = x->x_this_input; //now;
- x->x_last_input = now;
-
- if(x->x_on_beat)outlet_bang(x->x_outbeat);
- outvalue = (t_float)beat_evaluate(x);
- outlet_float(x->x_outms, outvalue);
- if(x->x_beat_period)outlet_float(x->x_outbpm, (t_float)(60000.0 / outvalue));
- }
- return;
-}
-
-static void beat_ft1(t_beat *x, t_floatarg f)
-{
- x->x_velo = (t_int)f;
-}
-
- /* toggle printing on/off */
-static void beat_print(t_beat *x)
-{
- if(x->x_print)x->x_print = 0;
- else x->x_print = 1;
-}
-
-static void beat_reset(t_beat *x)
-{
- int i;
-
- for(i = 0; i < BEAT_LONG; i++)
- {
- x->x_beats[i].points = 0;
- x->x_beats[i].expect = i;
- x->x_beats[i].onbeat = 0;
- }
- x->x_lastlasttime = 0;
- x->x_lasttime = 0;
- x->x_num_beats = 0;
- x->x_beat_period = 0;
- x->x_on_beat = 0;
-}
-
-static t_class *beat_class;
-
-static void beat_free(t_beat *x)
-{
- /* nothing to do */
-}
-
-static void *beat_new(t_floatarg f)
-{
- t_beat *x = (t_beat *)pd_new(beat_class);
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- x->x_outbpm = outlet_new(&x->x_ob, gensym("float"));
- x->x_outms = outlet_new(&x->x_ob, gensym("float"));
- x->x_outbeat = outlet_new(&x->x_ob, gensym("bang"));
-
- beat_reset(x);
- x->x_band_percent = 4; /* allow 4% 'jitter' by default */
- if(f)x->x_band_percent = (t_int)f;
-
- post("beat: band percentage set to %d", x->x_band_percent);
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void beat_setup(void)
-{
- beat_class = class_new(gensym("beat"), (t_newmethod)beat_new,
- (t_method)beat_free, sizeof(t_beat), 0, A_DEFFLOAT, 0);
-#else
-void maxlib_beat_setup(void)
-{
- beat_class = class_new(gensym("maxlib_beat"), (t_newmethod)beat_new,
- (t_method)beat_free, sizeof(t_beat), 0, A_DEFFLOAT, 0);
-#endif
- class_addfloat(beat_class, beat_float);
- class_addmethod(beat_class, (t_method)beat_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addmethod(beat_class, (t_method)beat_reset, gensym("reset"), 0);
- class_addmethod(beat_class, (t_method)beat_print, gensym("print"), 0);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_addcreator((t_newmethod)beat_new, gensym("beat"), A_DEFFLOAT, 0);
- class_sethelpsymbol(beat_class, gensym("maxlib/beat-help.pd"));
-#endif
-}
-
+/* --------------------------- beat ------------------------------------------ */
+/* */
+/* Detect the beats per minute of a MIDI stream. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code written by Robert Rowe. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define BEAT_LONG 1500 /* longest time we take into concideration (40 bpm) */
+#define BEAT_SHORT 300 /* shortest time we take into concideration (200 bpm) */
+
+static char *version = "beat v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct
+{
+ t_int points; /* number of points assigned to this theory */
+ double expect; /* time of next expected hit */
+ t_int onbeat; /* whether (1) or not (0) it was on the beat */
+} beat_theory;
+
+typedef struct /* used for sorting theories */
+{
+ t_int points;
+ t_int theory;
+} beat_sort_record;
+
+
+typedef struct beat
+{
+ t_object x_ob;
+ t_clock *x_clock;
+ t_outlet *x_outbpm; /* beat as MIDI note number */
+ t_outlet *x_outms; /* beat in milliseconds */
+ t_outlet *x_outbeat; /* send a bang whenever beat is 'on beat' */
+ t_int x_print; /* switch printing to console window on / off */
+
+ t_int x_num_beats; /* number of beats we've received */
+ double x_beat_period; /* time in ms until next expected beat / beat pulse */
+ beat_theory x_beats[BEAT_LONG];
+ double x_beatexpect; /* expected time for next beat */
+ t_int x_on_beat; /* indicate if last event was on beat */
+ t_int x_band_percent;
+
+ t_int x_pitch;
+ t_int x_velo;
+ /* helpers needed to do the time calculations */
+ double x_this_input;
+ double x_last_input;
+ double x_lasttime;
+ double x_lastlasttime;
+} t_beat;
+
+/* ---------------- mathematical functions to work with doubles -------------- */
+static double double_abs(double value)
+{
+ if(value < 0)
+ return (value * -1);
+ else
+ return (value);
+}
+
+/* --------------- beat stuff ------------------------------------------------ */
+ /* evaluate results: find theory that is the most likely one and
+ print out internal data to console window if print is enabled */
+static int beat_evaluate(t_beat *x)
+{
+ int i, j, K;
+ char string[256];
+ char info[40];
+ beat_sort_record theories[BEAT_LONG], *sortp, R;
+ int value; /* the result of the sorting */
+
+ for (i = 0; i < BEAT_LONG; i++)
+ { /* prepare sort records */
+ sortp = &(theories[i]);
+ sortp->points = x->x_beats[i].points;
+ sortp->theory = i;
+ }
+ for (j = 2; j < BEAT_LONG; j++)
+ { /* sort */
+ i = j - 1;
+ K = theories[j].points;
+ R = theories[j];
+ while (i > 0)
+ {
+ if (K >= theories[i].points)
+ {
+ theories[i+1] = R;
+ break;
+ }
+ else
+ {
+ theories[i+1] = theories[i];
+ i -= 1;
+ }
+ }
+ if (i==0) theories[i+1] = R;
+ }
+ /* get leading result */
+ sortp = &(theories[BEAT_LONG - 1]);
+ value = sortp->theory; /* get our resulting theory */
+
+ if(x->x_print)
+ {
+ post(" 0 1 2 3 4 R E");
+ *string = '\0'; /* print out five leading theories */
+ sprintf(info, "%4g", x->x_this_input);
+ strcat(string, info);
+ for(i = 1; i < 6; i++)
+ {
+ sortp = &(theories[BEAT_LONG - i]);
+ sprintf(info, " %4d[%3d]", (int) sortp->theory, (int) sortp->points);
+ strcat(string, info);
+ }
+ sprintf(info, " %g %g", clock_getlogicaltime(), x->x_beatexpect);
+ strcat(string, info);
+ post(string);
+ }
+
+ return value;
+}
+
+ /* reduce duration to fit into our processing window */
+ /* some sort of 'double modulo'... */
+static double beat_reduce_offset(double duration)
+{
+ double temp = duration;
+ int divisor = 2; /* first try dividing by two */
+ while (temp > BEAT_LONG) /* while duration is too long */
+ temp = duration / divisor++; /* divide by progressively higher divisors */
+ return temp; /* return a value in bounds */
+}
+
+/*
+ * beat_eligible: determine whether an event is eligible for consideration
+ * as a beat theory
+ */
+static int beat_eligible(double candidate, int* offsets, int num_offsets)
+{
+ double diff;
+ int i;
+
+ if (candidate >= BEAT_LONG) /* if too long try subharmonics */
+ candidate = beat_reduce_offset(candidate);
+
+ /* if candidate is close to one already found */
+ for(i = 0; i < num_offsets; i++)
+ {
+ diff = double_abs((candidate - offsets[i]));
+ if (diff < offsets[i]/20) {
+ if (candidate > offsets[i])
+ ++offsets[i]; else /* pull existing one */
+ if (candidate < offsets[i]) /* toward new candidate */
+ --offsets[i];
+ return 0; /* declare candidate ineligible */
+ }
+ }
+ return candidate; /* otherwise return legal candidate */
+}
+
+static void beat_float(t_beat *x, t_floatarg f)
+{
+ t_int velo = x->x_velo;
+ int i, j, indx;
+ int num_offsets, candidate;
+ int low_limit, high_limit, width, deviation;
+ int points, band, center_offset, period;
+ beat_theory* t;
+ int offsets[7];
+ static int factors[10] =
+ { 200, 50, 300, 150, 66, 400, 600, 133, 33, 75 };
+ double now = clock_getlogicaltime();
+ t_float outvalue;
+
+ x->x_pitch = (t_int)f;
+ x->x_this_input = clock_gettimesince(x->x_last_input);
+
+ if(velo != 0) /* note-on received */
+ {
+ if(++x->x_num_beats == 1)
+ {
+ goto time; /* only one event, no beats yet */
+ }
+
+ num_offsets = 0;
+ candidate = beat_eligible(x->x_this_input, offsets, num_offsets);
+ if(candidate)
+ offsets[num_offsets++] = candidate; /* offset[0] set to incoming offset */
+
+ if(x->x_num_beats > 2)
+ { /* if three events */
+ /* check previous for eligibility */
+ candidate = beat_eligible(x->x_lasttime, offsets, num_offsets);
+ if (candidate)
+ offsets[num_offsets++] = candidate;
+ candidate = x->x_this_input + x->x_lasttime; /* add current and previous offsets */
+ candidate = beat_eligible(candidate, offsets, num_offsets);
+ if (candidate) /* add to list if eligible */
+ offsets[num_offsets++] = candidate;
+ }
+
+ if(x->x_num_beats > 3)
+ {
+ candidate = beat_eligible(x->x_lastlasttime, offsets, num_offsets);
+ if (candidate)
+ offsets[num_offsets++] = candidate;
+ candidate += x->x_lasttime;
+ candidate = beat_eligible(candidate, offsets, num_offsets);
+ if (candidate)
+ offsets[num_offsets++] = candidate;
+ }
+
+ indx = 0;
+ for(i = num_offsets; i < 7; i++)
+ {
+ offsets[i] = 0;
+ if (indx >= 10) break;
+ candidate = 0;
+ while ((indx < 10) && (!candidate))
+ candidate = beat_eligible((x->x_this_input * factors[indx++])/100, offsets, num_offsets);
+ if (candidate)
+ offsets[num_offsets++] = candidate;
+ }
+
+ for(i = 0; i < num_offsets; i++)
+ {
+ band = offsets[i] * x->x_band_percent / 100;
+ if ((low_limit = offsets[i] - band) < 0) /* add points in a critical band */
+ low_limit = 0; /* around calculated offset */
+ if ((high_limit = offsets[i] + band) > BEAT_LONG)
+ high_limit = BEAT_LONG;
+ center_offset = offsets[i]; /* midpoint of increment */
+ points = 0;
+ for (j = low_limit; j < high_limit; j++)
+ {
+ if ((points = x->x_beats[j].points) > 0)
+ { /* if there is already activation */
+ deviation = j - center_offset; /* record deviation from midpoint */
+ x->x_beats[j].points = 0;
+ if (deviation < 0) { /* if there is activation below midpoint */
+ t = &(x->x_beats[j+1]); /* take theory one above prior */
+ } else
+ if (deviation > 0) { /* if there is activation above midpoint */
+ t = &(x->x_beats[j-1]); /* take theory one below prior */
+ } else
+ t = &(x->x_beats[j]); /* landed right on it */
+ t->points = points + (num_offsets-i);
+ break;
+ }
+ }
+ if (!points)
+ x->x_beats[center_offset].points = num_offsets - i;
+ }
+
+ /* boost hits, and suppress theories with missed beats */
+ period = 0;
+ points = 0;
+ for (i = BEAT_SHORT; i < BEAT_LONG; i++)
+ {
+ t = &(x->x_beats[i]);
+ width = 5 > (t->expect / 7) ? 5 : (t->expect / 7);
+ t->expect -= x->x_this_input;
+ t->onbeat = 0;
+ if(double_abs(t->expect) <= width) /* lies within range */
+ {
+ t->expect = i;
+ t->onbeat = 1;
+ if (t->points > 0)
+ t->points += 4; /* add 4 points */
+ }
+ else if(t->expect < 0)
+ {
+ t->points -= 8;
+ t->expect = i;
+ }
+ if (t->points < 0) t->points = 0; else
+ if (t->points > 200) t->points = 200;
+ if (t->points > points)
+ {
+ points = t->points;
+ period = i;
+ }
+ }
+
+
+
+ x->x_beat_period = (double)period;
+ t = &(x->x_beats[period]);
+ x->x_beatexpect = now + (double)t->expect;
+ x->x_on_beat = t->onbeat;
+
+time:
+ x->x_lastlasttime = x->x_lasttime;
+ x->x_lasttime = x->x_this_input; //now;
+ x->x_last_input = now;
+
+ if(x->x_on_beat)outlet_bang(x->x_outbeat);
+ outvalue = (t_float)beat_evaluate(x);
+ outlet_float(x->x_outms, outvalue);
+ if(x->x_beat_period)outlet_float(x->x_outbpm, (t_float)(60000.0 / outvalue));
+ }
+ return;
+}
+
+static void beat_ft1(t_beat *x, t_floatarg f)
+{
+ x->x_velo = (t_int)f;
+}
+
+ /* toggle printing on/off */
+static void beat_print(t_beat *x)
+{
+ if(x->x_print)x->x_print = 0;
+ else x->x_print = 1;
+}
+
+static void beat_reset(t_beat *x)
+{
+ int i;
+
+ for(i = 0; i < BEAT_LONG; i++)
+ {
+ x->x_beats[i].points = 0;
+ x->x_beats[i].expect = i;
+ x->x_beats[i].onbeat = 0;
+ }
+ x->x_lastlasttime = 0;
+ x->x_lasttime = 0;
+ x->x_num_beats = 0;
+ x->x_beat_period = 0;
+ x->x_on_beat = 0;
+}
+
+static t_class *beat_class;
+
+static void beat_free(t_beat *x)
+{
+ /* nothing to do */
+}
+
+static void *beat_new(t_floatarg f)
+{
+ t_beat *x = (t_beat *)pd_new(beat_class);
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ x->x_outbpm = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outms = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outbeat = outlet_new(&x->x_ob, gensym("bang"));
+
+ beat_reset(x);
+ x->x_band_percent = 4; /* allow 4% 'jitter' by default */
+ if(f)x->x_band_percent = (t_int)f;
+
+ post("beat: band percentage set to %d", x->x_band_percent);
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void beat_setup(void)
+{
+ beat_class = class_new(gensym("beat"), (t_newmethod)beat_new,
+ (t_method)beat_free, sizeof(t_beat), 0, A_DEFFLOAT, 0);
+#else
+void maxlib_beat_setup(void)
+{
+ beat_class = class_new(gensym("maxlib_beat"), (t_newmethod)beat_new,
+ (t_method)beat_free, sizeof(t_beat), 0, A_DEFFLOAT, 0);
+#endif
+ class_addfloat(beat_class, beat_float);
+ class_addmethod(beat_class, (t_method)beat_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(beat_class, (t_method)beat_reset, gensym("reset"), 0);
+ class_addmethod(beat_class, (t_method)beat_print, gensym("print"), 0);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_addcreator((t_newmethod)beat_new, gensym("beat"), A_DEFFLOAT, 0);
+ class_sethelpsymbol(beat_class, gensym("maxlib/beat-help.pd"));
+#endif
+}
+
diff --git a/beta.c b/beta.c
index c99b538..2d7f3b3 100644
--- a/beta.c
+++ b/beta.c
@@ -1,107 +1,107 @@
-/* ---------------------------- rand_beta ------------------------------------- */
-/* */
-/* rand_beta generates a beta distributed random variable. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-#define fran() (t_float)rand()/(t_float)RAND_MAX
-#ifndef M_PI
-#define M_PI 3.1415927
-#endif
-
-static char *version = "beta v0.1, generates a beta distributed random variable\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-/* -------------------------- rand_beta ------------------------------ */
-
-static t_class *rand_beta_class;
-
-typedef struct _rand_beta
-{
- t_object x_obj;
- t_float x_a;
- t_float x_b;
-} t_rand_beta;
-
-static void *rand_beta_new(t_floatarg a, t_floatarg b)
-{
- t_rand_beta *x = (t_rand_beta *)pd_new(rand_beta_class);
- srand( (unsigned)time( NULL ) );
- floatinlet_new(&x->x_obj, &x->x_a);
- floatinlet_new(&x->x_obj, &x->x_b);
- outlet_new(&x->x_obj, &s_float);
- x->x_a = a;
- x->x_b = b;
- return (x);
-}
-
-static void rand_beta_bang(t_rand_beta *x)
-{
- t_float u1, u2, y01, y2, sum, a, b, ainv, binv;
- a = (x->x_a <= 0 ? 0.0001 : x->x_a);
- b = (x->x_b <= 0 ? 0.0001 : x->x_b);
- ainv = 1/a;
- binv = 1/b;
- do
- {
- do
- {
- u1 = fran();
- }
- while(u1 == 0);
- do
- {
- u2 = fran();
- }
- while(u2 == 0);
- y01 = pow(u1, ainv);
- y2 = pow(u2, binv);
- sum = y01 + y2;
- }
- while(sum > 1);
- outlet_float(x->x_obj.ob_outlet, y01/sum);
-}
-
-#ifndef MAXLIB
-void beta_setup(void)
-{
- rand_beta_class = class_new(gensym("beta"), (t_newmethod)rand_beta_new, 0,
- sizeof(t_rand_beta), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addbang(rand_beta_class, rand_beta_bang);
- class_sethelpsymbol(rand_beta_class, gensym("beta-help.pd"));
- post(version);
-}
-#else
-void maxlib_beta_setup(void)
-{
- rand_beta_class = class_new(gensym("maxlib_beta"), (t_newmethod)rand_beta_new, 0,
- sizeof(t_rand_beta), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addbang(rand_beta_class, rand_beta_bang);
- class_addcreator((t_newmethod)rand_beta_new, gensym("beta"), A_DEFFLOAT, A_DEFFLOAT, 0);
- class_sethelpsymbol(rand_beta_class, gensym("maxlib/beta-help.pd"));
-}
-#endif
+/* ---------------------------- rand_beta ------------------------------------- */
+/* */
+/* rand_beta generates a beta distributed random variable. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+
+#define fran() (t_float)rand()/(t_float)RAND_MAX
+#ifndef M_PI
+#define M_PI 3.1415927
+#endif
+
+static char *version = "beta v0.1, generates a beta distributed random variable\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- rand_beta ------------------------------ */
+
+static t_class *rand_beta_class;
+
+typedef struct _rand_beta
+{
+ t_object x_obj;
+ t_float x_a;
+ t_float x_b;
+} t_rand_beta;
+
+static void *rand_beta_new(t_floatarg a, t_floatarg b)
+{
+ t_rand_beta *x = (t_rand_beta *)pd_new(rand_beta_class);
+ srand( (unsigned)time( NULL ) );
+ floatinlet_new(&x->x_obj, &x->x_a);
+ floatinlet_new(&x->x_obj, &x->x_b);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_a = a;
+ x->x_b = b;
+ return (x);
+}
+
+static void rand_beta_bang(t_rand_beta *x)
+{
+ t_float u1, u2, y01, y2, sum, a, b, ainv, binv;
+ a = (x->x_a <= 0 ? 0.0001 : x->x_a);
+ b = (x->x_b <= 0 ? 0.0001 : x->x_b);
+ ainv = 1/a;
+ binv = 1/b;
+ do
+ {
+ do
+ {
+ u1 = fran();
+ }
+ while(u1 == 0);
+ do
+ {
+ u2 = fran();
+ }
+ while(u2 == 0);
+ y01 = pow(u1, ainv);
+ y2 = pow(u2, binv);
+ sum = y01 + y2;
+ }
+ while(sum > 1);
+ outlet_float(x->x_obj.ob_outlet, y01/sum);
+}
+
+#ifndef MAXLIB
+void beta_setup(void)
+{
+ rand_beta_class = class_new(gensym("beta"), (t_newmethod)rand_beta_new, 0,
+ sizeof(t_rand_beta), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addbang(rand_beta_class, rand_beta_bang);
+ class_sethelpsymbol(rand_beta_class, gensym("beta-help.pd"));
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_beta_setup(void)
+{
+ rand_beta_class = class_new(gensym("maxlib_beta"), (t_newmethod)rand_beta_new, 0,
+ sizeof(t_rand_beta), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addbang(rand_beta_class, rand_beta_bang);
+ class_addcreator((t_newmethod)rand_beta_new, gensym("beta"), A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_sethelpsymbol(rand_beta_class, gensym("maxlib/beta-help.pd"));
+}
+#endif
diff --git a/bilex.c b/bilex.c
index eb54aa4..6bd432e 100644
--- a/bilex.c
+++ b/bilex.c
@@ -1,91 +1,91 @@
-/* ---------------------------- rand_bilex ------------------------------------ */
-/* */
-/* rand_bilex generates a bilinear exponentially distributed random variable. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
+/* ---------------------------- rand_bilex ------------------------------------ */
+/* */
+/* rand_bilex generates a bilinear exponentially distributed random variable. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-#define fran() (t_float)rand()/(t_float)RAND_MAX
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
-static char *version = "bilex v0.1, generates bilinear exponentially distributed random\n"
- " variable, written by Olaf Matthes <olaf.matthes@gmx.de>";
+#define fran() (t_float)rand()/(t_float)RAND_MAX
-/* -------------------------- rand_bilex ------------------------------ */
-
-static t_class *rand_bilex_class;
-
-typedef struct _rand_bilex
-{
- t_object x_obj;
- t_float x_lambda;
-} t_rand_bilex;
-
-static void *rand_bilex_new(t_floatarg f)
-{
- t_rand_bilex *x = (t_rand_bilex *)pd_new(rand_bilex_class);
- srand( (unsigned)time( NULL ) );
- floatinlet_new(&x->x_obj, &x->x_lambda);
- outlet_new(&x->x_obj, &s_float);
- x->x_lambda = f;
- return (x);
-}
-
-static void rand_bilex_bang(t_rand_bilex *x)
-{
- t_float u, s = 1, l;
- l = (x->x_lambda <= 0 ? 0.0001 : x->x_lambda);
- do
- {
- u = 2*fran();
- }
- while(u == 0 || u == 2);
- if(u > 1)
- {
- u = 2-u;
- s=-1;
- }
- outlet_float(x->x_obj.ob_outlet, s*log(u)/l);
-}
-
-#ifndef MAXLIB
-void bilex_setup(void)
-{
- rand_bilex_class = class_new(gensym("bilex"), (t_newmethod)rand_bilex_new, 0,
- sizeof(t_rand_bilex), 0, A_DEFFLOAT, 0);
- class_addbang(rand_bilex_class, rand_bilex_bang);
- class_sethelpsymbol(rand_bilex_class, gensym("bilex-help.pd"));
- post(version);
-}
-#else
-void maxlib_bilex_setup(void)
-{
- rand_bilex_class = class_new(gensym("maxlib_bilex"), (t_newmethod)rand_bilex_new, 0,
- sizeof(t_rand_bilex), 0, A_DEFFLOAT, 0);
- class_addbang(rand_bilex_class, rand_bilex_bang);
- class_addcreator((t_newmethod)rand_bilex_new, gensym("bilex"), A_DEFFLOAT, 0);
- class_sethelpsymbol(rand_bilex_class, gensym("maxlib/bilex-help.pd"));
-}
-#endif
+static char *version = "bilex v0.1, generates bilinear exponentially distributed random\n"
+ " variable, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- rand_bilex ------------------------------ */
+
+static t_class *rand_bilex_class;
+
+typedef struct _rand_bilex
+{
+ t_object x_obj;
+ t_float x_lambda;
+} t_rand_bilex;
+
+static void *rand_bilex_new(t_floatarg f)
+{
+ t_rand_bilex *x = (t_rand_bilex *)pd_new(rand_bilex_class);
+ srand( (unsigned)time( NULL ) );
+ floatinlet_new(&x->x_obj, &x->x_lambda);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_lambda = f;
+ return (x);
+}
+
+static void rand_bilex_bang(t_rand_bilex *x)
+{
+ t_float u, s = 1, l;
+ l = (x->x_lambda <= 0 ? 0.0001 : x->x_lambda);
+ do
+ {
+ u = 2*fran();
+ }
+ while(u == 0 || u == 2);
+ if(u > 1)
+ {
+ u = 2-u;
+ s=-1;
+ }
+ outlet_float(x->x_obj.ob_outlet, s*log(u)/l);
+}
+
+#ifndef MAXLIB
+void bilex_setup(void)
+{
+ rand_bilex_class = class_new(gensym("bilex"), (t_newmethod)rand_bilex_new, 0,
+ sizeof(t_rand_bilex), 0, A_DEFFLOAT, 0);
+ class_addbang(rand_bilex_class, rand_bilex_bang);
+ class_sethelpsymbol(rand_bilex_class, gensym("bilex-help.pd"));
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_bilex_setup(void)
+{
+ rand_bilex_class = class_new(gensym("maxlib_bilex"), (t_newmethod)rand_bilex_new, 0,
+ sizeof(t_rand_bilex), 0, A_DEFFLOAT, 0);
+ class_addbang(rand_bilex_class, rand_bilex_bang);
+ class_addcreator((t_newmethod)rand_bilex_new, gensym("bilex"), A_DEFFLOAT, 0);
+ class_sethelpsymbol(rand_bilex_class, gensym("maxlib/bilex-help.pd"));
+}
+#endif
diff --git a/borax.c b/borax.c
index 32979b7..fc271bf 100644
--- a/borax.c
+++ b/borax.c
@@ -1,238 +1,238 @@
-/* ------------------------- borax ------------------------------------------ */
-/* */
-/* "swiss army knife" for music analysis. Inspired by 'borax' for Max. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-
-#define MAX_POLY 128 /* maximum number of notes played at a time */
-
-static char *version = "borax v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct borax
-{
- t_object x_ob;
- t_inlet *x_invelo; /* inlet for velocity */
- t_inlet *x_inreset; /* inlet to reset the object */
- t_outlet *x_outnotecount; /* counts notes */
- t_outlet *x_outvoicealloc; /* assigns every note a unique number */
- t_outlet *x_outpoly; /* number of notes playing (polyphony) */
- t_outlet *x_outpitch; /* pitch of current note */
- t_outlet *x_outvelo; /* velocity of current note */
- t_outlet *x_outdurcount; /* number assigned to duration value */
- t_outlet *x_outdurval; /* duration value */
- t_outlet *x_outtimecount; /* number assigned to delta time value */
- t_outlet *x_outtimeval; /* delta time value */
-
-
- t_float x_notecount;
- t_int x_pitch;
- t_int x_velo;
- t_float x_voicecount;
- t_int x_voicealloc;
- t_int x_poly;
- t_float x_durcount;
- t_float x_durval;
- t_float x_timecount;
- t_float x_timeval;
- /* helpers needed to do the calculations */
- double x_starttime[MAX_POLY];
- double x_laststarttime;
- t_int x_alloctable[MAX_POLY];
-
-} t_borax;
-
-static void borax_float(t_borax *x, t_floatarg f)
-{
- t_int velo = x->x_velo;
- t_int allloc = 0;
- int i;
-
- x->x_pitch = (t_int)f;
-
- if(velo == 0)
- {
- /* note off received... */
- if(x->x_poly > 0)x->x_poly--; /* polyphony has decreased by one */
- x->x_durcount++; /* we can calculate the duration */
- for(i = 0; i < MAX_POLY; i++) /* search for voice allocation number */
- {
- /* search for corresponding alloc number */
- if(x->x_alloctable[i] == x->x_pitch)
- {
- x->x_voicealloc = i;
- x->x_alloctable[i] = 0; /* free the alloc number */
- break;
- }
- /* couldn't find it ? */
- if(i == MAX_POLY - 1)
- {
- post("borax: no corresponding note-on found (ignored)");
- return;
- }
- }
- x->x_durval = clock_gettimesince(x->x_starttime[x->x_voicealloc]);
- }
- else if(velo != 0)
- {
- /* note on received... */
- x->x_poly++; /* number of currently playing notes has increased */
- x->x_notecount++; /* total number of notes has increased */
- /* assign a voice allocation number */
- for(i = 0; i < MAX_POLY; i++)
- {
- /* search for free alloc number */
- if(x->x_alloctable[i] == 0)
- {
- x->x_voicealloc = i; /* take the number */
- x->x_alloctable[i] = x->x_pitch; /* ... and store pitch */
- break;
- }
- /* couldn't find any ? */
- if(i == MAX_POLY - 1)
- {
- post("borax: too many note-on messages (ignored)");
- return;
- }
- }
- /* calculate time in case it's not the first note */
- if(x->x_notecount > 1)
- {
- x->x_timecount++;
- x->x_timeval = clock_gettimesince(x->x_laststarttime);
- }
- /* save the new start time */
- x->x_laststarttime = x->x_starttime[x->x_voicealloc] = clock_getlogicaltime();
- }
- /* output values from right to left */
- outlet_float(x->x_outtimeval, x->x_timeval);
- outlet_float(x->x_outtimecount, x->x_timecount);
- outlet_float(x->x_outdurval, x->x_durval);
- outlet_float(x->x_outdurcount, x->x_durcount);
- outlet_float(x->x_outvelo, velo);
- outlet_float(x->x_outpitch, x->x_pitch);
- outlet_float(x->x_outpoly, x->x_poly);
- outlet_float(x->x_outvoicealloc, x->x_voicealloc);
- outlet_float(x->x_outnotecount, x->x_notecount);
-}
-
-static void borax_ft1(t_borax *x, t_floatarg f)
-{
- x->x_velo = (t_int)f;
-}
-
-static void borax_reset(t_borax *x)
-{
- int i;
- post("borax: reset");
- x->x_notecount = 0;
- x->x_pitch = 0;
- x->x_velo = 0;
- x->x_voicecount = 0;
- x->x_voicealloc = 0;
- x->x_poly = 0;
- x->x_durcount = 0;
- x->x_durval = 0;
- x->x_timecount = 0;
- x->x_timeval = 0;
- outlet_float(x->x_outtimeval, x->x_timeval);
- outlet_float(x->x_outtimecount, x->x_timecount);
- outlet_float(x->x_outdurval, x->x_durval);
- outlet_float(x->x_outdurcount, x->x_durcount);
- for(i = 0; i < MAX_POLY; i++)
- {
- if(x->x_alloctable[i] != 0)
- {
- x->x_poly--;
- /* send note-off */
- outlet_float(x->x_outvelo, 0);
- outlet_float(x->x_outpitch, x->x_alloctable[i]);
- outlet_float(x->x_outpoly, x->x_poly);
- outlet_float(x->x_outvoicealloc, i);
- }
- x->x_alloctable[i] = 0;
- }
- outlet_float(x->x_outvelo, x->x_velo);
- outlet_float(x->x_outpitch, x->x_pitch);
- outlet_float(x->x_outpoly, x->x_poly);
- outlet_float(x->x_outvoicealloc, x->x_voicealloc);
- outlet_float(x->x_outnotecount, x->x_notecount);
-}
-
-static t_class *borax_class;
-
-static void *borax_new(void)
-{
- int i;
-
- t_borax *x = (t_borax *)pd_new(borax_class);
- x->x_invelo = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- x->x_inreset = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("bang"), gensym("ft2"));
- x->x_outnotecount = outlet_new(&x->x_ob, gensym("float"));
- x->x_outvoicealloc = outlet_new(&x->x_ob, gensym("float"));
- x->x_outpoly = outlet_new(&x->x_ob, gensym("float"));
- x->x_outpitch = outlet_new(&x->x_ob, gensym("float"));
- x->x_outvelo = outlet_new(&x->x_ob, gensym("float"));
- x->x_outdurcount = outlet_new(&x->x_ob, gensym("float"));
- x->x_outdurval = outlet_new(&x->x_ob, gensym("float"));
- x->x_outtimecount = outlet_new(&x->x_ob, gensym("float"));
- x->x_outtimeval = outlet_new(&x->x_ob, gensym("float"));
-
- for(i = 0; i < MAX_POLY; i++)x->x_alloctable[i] = 0;
- x->x_notecount = 0;
- x->x_pitch = 0;
- x->x_velo = 0;
- x->x_voicecount = 0;
- x->x_voicealloc = 0;
- x->x_poly = 0;
- x->x_durcount = 0;
- x->x_durval = 0;
- x->x_timecount = 0;
- x->x_timeval = 0;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void borax_setup(void)
-{
- borax_class = class_new(gensym("borax"), (t_newmethod)borax_new,
- 0, sizeof(t_borax), 0, 0);
-#else
-void maxlib_borax_setup(void)
-{
- borax_class = class_new(gensym("maxlib_borax"), (t_newmethod)borax_new,
- 0, sizeof(t_borax), 0, 0);
-#endif
- class_addmethod(borax_class, (t_method)borax_reset, gensym("reset"), 0);
- class_addmethod(borax_class, (t_method)borax_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addmethod(borax_class, (t_method)borax_reset, gensym("ft2"), A_GIMME, 0);
- class_addfloat(borax_class, borax_float);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_addcreator((t_newmethod)borax_new, gensym("borax"), 0);
- class_sethelpsymbol(borax_class, gensym("maxlib/borax-help.pd"));
-#endif
-}
-
+/* ------------------------- borax ------------------------------------------ */
+/* */
+/* "swiss army knife" for music analysis. Inspired by 'borax' for Max. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+#define MAX_POLY 128 /* maximum number of notes played at a time */
+
+static char *version = "borax v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct borax
+{
+ t_object x_ob;
+ t_inlet *x_invelo; /* inlet for velocity */
+ t_inlet *x_inreset; /* inlet to reset the object */
+ t_outlet *x_outnotecount; /* counts notes */
+ t_outlet *x_outvoicealloc; /* assigns every note a unique number */
+ t_outlet *x_outpoly; /* number of notes playing (polyphony) */
+ t_outlet *x_outpitch; /* pitch of current note */
+ t_outlet *x_outvelo; /* velocity of current note */
+ t_outlet *x_outdurcount; /* number assigned to duration value */
+ t_outlet *x_outdurval; /* duration value */
+ t_outlet *x_outtimecount; /* number assigned to delta time value */
+ t_outlet *x_outtimeval; /* delta time value */
+
+
+ t_float x_notecount;
+ t_int x_pitch;
+ t_int x_velo;
+ t_float x_voicecount;
+ t_int x_voicealloc;
+ t_int x_poly;
+ t_float x_durcount;
+ t_float x_durval;
+ t_float x_timecount;
+ t_float x_timeval;
+ /* helpers needed to do the calculations */
+ double x_starttime[MAX_POLY];
+ double x_laststarttime;
+ t_int x_alloctable[MAX_POLY];
+
+} t_borax;
+
+static void borax_float(t_borax *x, t_floatarg f)
+{
+ t_int velo = x->x_velo;
+ t_int allloc = 0;
+ int i;
+
+ x->x_pitch = (t_int)f;
+
+ if(velo == 0)
+ {
+ /* note off received... */
+ if(x->x_poly > 0)x->x_poly--; /* polyphony has decreased by one */
+ x->x_durcount++; /* we can calculate the duration */
+ for(i = 0; i < MAX_POLY; i++) /* search for voice allocation number */
+ {
+ /* search for corresponding alloc number */
+ if(x->x_alloctable[i] == x->x_pitch)
+ {
+ x->x_voicealloc = i;
+ x->x_alloctable[i] = 0; /* free the alloc number */
+ break;
+ }
+ /* couldn't find it ? */
+ if(i == MAX_POLY - 1)
+ {
+ post("borax: no corresponding note-on found (ignored)");
+ return;
+ }
+ }
+ x->x_durval = clock_gettimesince(x->x_starttime[x->x_voicealloc]);
+ }
+ else if(velo != 0)
+ {
+ /* note on received... */
+ x->x_poly++; /* number of currently playing notes has increased */
+ x->x_notecount++; /* total number of notes has increased */
+ /* assign a voice allocation number */
+ for(i = 0; i < MAX_POLY; i++)
+ {
+ /* search for free alloc number */
+ if(x->x_alloctable[i] == 0)
+ {
+ x->x_voicealloc = i; /* take the number */
+ x->x_alloctable[i] = x->x_pitch; /* ... and store pitch */
+ break;
+ }
+ /* couldn't find any ? */
+ if(i == MAX_POLY - 1)
+ {
+ post("borax: too many note-on messages (ignored)");
+ return;
+ }
+ }
+ /* calculate time in case it's not the first note */
+ if(x->x_notecount > 1)
+ {
+ x->x_timecount++;
+ x->x_timeval = clock_gettimesince(x->x_laststarttime);
+ }
+ /* save the new start time */
+ x->x_laststarttime = x->x_starttime[x->x_voicealloc] = clock_getlogicaltime();
+ }
+ /* output values from right to left */
+ outlet_float(x->x_outtimeval, x->x_timeval);
+ outlet_float(x->x_outtimecount, x->x_timecount);
+ outlet_float(x->x_outdurval, x->x_durval);
+ outlet_float(x->x_outdurcount, x->x_durcount);
+ outlet_float(x->x_outvelo, velo);
+ outlet_float(x->x_outpitch, x->x_pitch);
+ outlet_float(x->x_outpoly, x->x_poly);
+ outlet_float(x->x_outvoicealloc, x->x_voicealloc);
+ outlet_float(x->x_outnotecount, x->x_notecount);
+}
+
+static void borax_ft1(t_borax *x, t_floatarg f)
+{
+ x->x_velo = (t_int)f;
+}
+
+static void borax_reset(t_borax *x)
+{
+ int i;
+ post("borax: reset");
+ x->x_notecount = 0;
+ x->x_pitch = 0;
+ x->x_velo = 0;
+ x->x_voicecount = 0;
+ x->x_voicealloc = 0;
+ x->x_poly = 0;
+ x->x_durcount = 0;
+ x->x_durval = 0;
+ x->x_timecount = 0;
+ x->x_timeval = 0;
+ outlet_float(x->x_outtimeval, x->x_timeval);
+ outlet_float(x->x_outtimecount, x->x_timecount);
+ outlet_float(x->x_outdurval, x->x_durval);
+ outlet_float(x->x_outdurcount, x->x_durcount);
+ for(i = 0; i < MAX_POLY; i++)
+ {
+ if(x->x_alloctable[i] != 0)
+ {
+ x->x_poly--;
+ /* send note-off */
+ outlet_float(x->x_outvelo, 0);
+ outlet_float(x->x_outpitch, x->x_alloctable[i]);
+ outlet_float(x->x_outpoly, x->x_poly);
+ outlet_float(x->x_outvoicealloc, i);
+ }
+ x->x_alloctable[i] = 0;
+ }
+ outlet_float(x->x_outvelo, x->x_velo);
+ outlet_float(x->x_outpitch, x->x_pitch);
+ outlet_float(x->x_outpoly, x->x_poly);
+ outlet_float(x->x_outvoicealloc, x->x_voicealloc);
+ outlet_float(x->x_outnotecount, x->x_notecount);
+}
+
+static t_class *borax_class;
+
+static void *borax_new(void)
+{
+ int i;
+
+ t_borax *x = (t_borax *)pd_new(borax_class);
+ x->x_invelo = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ x->x_inreset = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("bang"), gensym("ft2"));
+ x->x_outnotecount = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outvoicealloc = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outpoly = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outpitch = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outvelo = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outdurcount = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outdurval = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outtimecount = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outtimeval = outlet_new(&x->x_ob, gensym("float"));
+
+ for(i = 0; i < MAX_POLY; i++)x->x_alloctable[i] = 0;
+ x->x_notecount = 0;
+ x->x_pitch = 0;
+ x->x_velo = 0;
+ x->x_voicecount = 0;
+ x->x_voicealloc = 0;
+ x->x_poly = 0;
+ x->x_durcount = 0;
+ x->x_durval = 0;
+ x->x_timecount = 0;
+ x->x_timeval = 0;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void borax_setup(void)
+{
+ borax_class = class_new(gensym("borax"), (t_newmethod)borax_new,
+ 0, sizeof(t_borax), 0, 0);
+#else
+void maxlib_borax_setup(void)
+{
+ borax_class = class_new(gensym("maxlib_borax"), (t_newmethod)borax_new,
+ 0, sizeof(t_borax), 0, 0);
+#endif
+ class_addmethod(borax_class, (t_method)borax_reset, gensym("reset"), 0);
+ class_addmethod(borax_class, (t_method)borax_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(borax_class, (t_method)borax_reset, gensym("ft2"), A_GIMME, 0);
+ class_addfloat(borax_class, borax_float);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_addcreator((t_newmethod)borax_new, gensym("borax"), 0);
+ class_sethelpsymbol(borax_class, gensym("maxlib/borax-help.pd"));
+#endif
+}
+
diff --git a/cauchy.c b/cauchy.c
index ee64296..73fcfef 100644
--- a/cauchy.c
+++ b/cauchy.c
@@ -1,89 +1,89 @@
-/* ---------------------------- rand_cauchy ----------------------------------- */
-/* */
-/* rand_cauchy generates a Cauchy distributed random variable. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
+/* ---------------------------- rand_cauchy ----------------------------------- */
+/* */
+/* rand_cauchy generates a Cauchy distributed random variable. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-#define fran() (t_float)rand()/(t_float)RAND_MAX
-#ifndef M_PI
-#define M_PI 3.1415927
-#endif
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
-static char *version = "cauchy v0.1, generates a Cauchy distributed random variable\n"
- " with a spread governed by to parameter 'aplha',\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
+#define fran() (t_float)rand()/(t_float)RAND_MAX
+#ifndef M_PI
+#define M_PI 3.1415927
+#endif
-/* -------------------------- rand_cauchy ------------------------------ */
-
-static t_class *rand_cauchy_class;
-
-typedef struct _rand_cauchy
-{
- t_object x_obj;
- t_float x_alpha;
-} t_rand_cauchy;
-
-static void *rand_cauchy_new(t_floatarg f)
-{
- t_rand_cauchy *x = (t_rand_cauchy *)pd_new(rand_cauchy_class);
- srand( (unsigned)time( NULL ) );
- floatinlet_new(&x->x_obj, &x->x_alpha);
- outlet_new(&x->x_obj, &s_float);
- x->x_alpha = f;
- return (x);
-}
-
-static void rand_cauchy_bang(t_rand_cauchy *x)
-{
- t_float u;
- do
- {
- u = fran();
- }
- while(u == 0.5);
- u *= M_PI;
- outlet_float(x->x_obj.ob_outlet, x->x_alpha*tan(u));
-}
-
-#ifndef MAXLIB
-void cauchy_setup(void)
-{
- rand_cauchy_class = class_new(gensym("cauchy"), (t_newmethod)rand_cauchy_new, 0,
- sizeof(t_rand_cauchy), 0, A_DEFFLOAT, 0);
- class_addbang(rand_cauchy_class, rand_cauchy_bang);
- class_sethelpsymbol(rand_cauchy_class, gensym("cauchy-help.pd"));
- post(version);
-#else
-void maxlib_cauchy_setup(void)
-{
- rand_cauchy_class = class_new(gensym("maxlib_cauchy"), (t_newmethod)rand_cauchy_new, 0,
- sizeof(t_rand_cauchy), 0, A_DEFFLOAT, 0);
- class_addbang(rand_cauchy_class, rand_cauchy_bang);
- class_addcreator((t_newmethod)rand_cauchy_new, gensym("cauchy"), A_DEFFLOAT, 0);
- class_sethelpsymbol(rand_cauchy_class, gensym("maxlib/cauchy-help.pd"));
-#endif
-}
+static char *version = "cauchy v0.1, generates a Cauchy distributed random variable\n"
+ " with a spread governed by to parameter 'aplha',\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- rand_cauchy ------------------------------ */
+
+static t_class *rand_cauchy_class;
+
+typedef struct _rand_cauchy
+{
+ t_object x_obj;
+ t_float x_alpha;
+} t_rand_cauchy;
+
+static void *rand_cauchy_new(t_floatarg f)
+{
+ t_rand_cauchy *x = (t_rand_cauchy *)pd_new(rand_cauchy_class);
+ srand( (unsigned)time( NULL ) );
+ floatinlet_new(&x->x_obj, &x->x_alpha);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_alpha = f;
+ return (x);
+}
+
+static void rand_cauchy_bang(t_rand_cauchy *x)
+{
+ t_float u;
+ do
+ {
+ u = fran();
+ }
+ while(u == 0.5);
+ u *= M_PI;
+ outlet_float(x->x_obj.ob_outlet, x->x_alpha*tan(u));
+}
+
+#ifndef MAXLIB
+void cauchy_setup(void)
+{
+ rand_cauchy_class = class_new(gensym("cauchy"), (t_newmethod)rand_cauchy_new, 0,
+ sizeof(t_rand_cauchy), 0, A_DEFFLOAT, 0);
+ class_addbang(rand_cauchy_class, rand_cauchy_bang);
+ class_sethelpsymbol(rand_cauchy_class, gensym("cauchy-help.pd"));
+ logpost(NULL, 4, version);
+#else
+void maxlib_cauchy_setup(void)
+{
+ rand_cauchy_class = class_new(gensym("maxlib_cauchy"), (t_newmethod)rand_cauchy_new, 0,
+ sizeof(t_rand_cauchy), 0, A_DEFFLOAT, 0);
+ class_addbang(rand_cauchy_class, rand_cauchy_bang);
+ class_addcreator((t_newmethod)rand_cauchy_new, gensym("cauchy"), A_DEFFLOAT, 0);
+ class_sethelpsymbol(rand_cauchy_class, gensym("maxlib/cauchy-help.pd"));
+#endif
+}
diff --git a/chord.c b/chord.c
index a1839d3..ad3f6eb 100644
--- a/chord.c
+++ b/chord.c
@@ -1,1822 +1,1822 @@
-/* ------------------------- chord ------------------------------------------ */
-/* */
-/* Tries to detect a chord (or any harmonic relations) of incoming notes. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <string.h>
-#ifndef _WIN32
-#include <stdlib.h>
-#endif
-
-
-#define MAX_POLY 32 /* maximum number of notes played at a time */
-
-#define kUnison 0
-#define kMaj 1
-#define kMin 2
-#define kDim 3
-#define kAug 4
-#define kMaj7 5
-#define kDom7 6
-#define kMin7 7
-#define kHalfDim7 8
-#define kDim7 9
-#define kMinMaj7 10
-#define kMaj7s5 11
-#define kMaj7b5 12
-#define kDom7s5 13
-#define kDom7b5 14
-#define kDomb9 15
-#define kMaj9 16
-#define kDom9 17
-#define kMin9 18
-#define kHalfDim9 19
-#define kMinMaj9 20
-#define kDimMaj9 21
-#define kMaj9b5 22
-#define kDom9b5 23
-#define kDom9b13 24
-#define kMin9s11 25
-#define kmM9b11 26
-#define kMaj7b9 27
-#define kMaj7s5b9 28
-#define kDom7b9 29
-#define kMin7b9 30
-#define kMinb9s11 31
-#define kHalfDimb9 32
-#define kDim7b9 33
-#define kMinMajb9 34
-#define kDimMajb9 35
-#define kMaj7s9 36
-#define kDom7s9 37
-#define kMaj7s11 38
-#define kMs9s11 39
-#define kHDimb11 40
-#define kMaj11 41
-#define kDom11 42
-#define kMin11 43
-#define kHalfDim11 44
-#define kDim11 45
-#define kMinMaj11 46
-#define kDimMaj11 47
-#define kMaj11b5 48
-#define kMaj11s5 49
-#define kMaj11b9 50
-#define kMaj11s9 51
-#define kMaj11b13 52
-#define kMaj11s13 53
-#define kM11b5b9 54
-#define kDom11b5 55
-#define kDom11b9 56
-#define kDom11s9 57
-#define kHalfDim11b9 58
-#define kDom7s11 59
-#define kMin7s11 60
-#define kDom13s11 61
-#define kM7b913 62
-#define kMaj7s13 63
-#define kMaj9s13 64
-#define kM7b9s13 65
-#define kDom7b13 66
-#define kChrom 67
-#define kNone 68
-
-#define kXX -1
-
-
-static char *version = "chord v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-static char* pitch_class[13] = {"C ", "Db ", "D ", "Eb ", "E ", "F ", "Gb ", "G ", "Ab ", "A ", "Bb ", "B ", "no root "};
-static char name_class[7] = {'C', 'D', 'E', 'F', 'G', 'A', 'B'};
-
-typedef struct {
- int type;
- int rootMember;
-} t_type_root;
-
-typedef struct chord
-{
- t_object x_ob;
- t_outlet *x_outchordval; /* chord as MIDI note number of base note */
- t_outlet *x_outchordclass; /* class of chord's bass note */
- t_outlet *x_outchordname; /* chord name, e.g. "Cmajor7" */
- t_outlet *x_outchordinversion; /* inversion of the chord (root = 0, 1st = 1, 2nd = 2) */
- t_outlet *x_outchordnotes; /* list with note numbers belonging to the chord */
-
- t_int x_pitch;
- t_int x_pc[12]; /* pitch class array */
- t_int x_abs_pc[12]; /* pitch class array: absolute MIDI note numbers */
- t_int x_velo;
- t_int x_alloctable[MAX_POLY]; /* a table used to store all playing notes */
- t_int x_poly; /* number of notes currently playing */
- t_atom x_chordlist[12]; /* list that stores the note numbers for output */
- t_int x_split; /* highes note number to process */
-
- t_int x_chord_type; /* chord's type (number between 0 and 68) */
- t_int x_chord_root; /* chord's root (pitch class) */
- t_int x_chord_bass; /* chord's bass note (MIDI note number) */
- t_int x_chord_inversion; /* chord's state of inversion (root, 1st, 2nd) */
-
-} t_chord;
-
-/* functions */
-static void chord_kick_out_member(t_chord *x, t_int number, t_int *members);
-static void chord_chord_finder(t_chord *x, t_int num_pcs);
-static void chord_draw_chord_type(t_chord *x, t_int num_pcs);
-
-
-static void chord_unison(t_chord *x)
-{
- int i;
- int member = 0;
- for(i = 0; i < 12; i++)
- if(x->x_pc[i])
- {
- member = i; // find pitch class
- break;
- }
- x->x_chord_type = 0;
- x->x_chord_root = member;
- chord_draw_chord_type(x, 1); // output onto the screen
-}
-
-static void chord_dyad(t_chord *x)
-{
- static t_type_root dyads[11] =
- {{ kMaj7, 1 }, { kDom7, 1 }, { kMin, 0 }, { kMaj, 0 }, { kMaj, 1 },
- { kDom7 , 0 }, { kMaj, 0 }, { kMaj, 1 }, { kMin, 1 }, { kDom7, 0 }, { kMaj7, 0 }};
- register t_type_root* t;
-
- int members[2];
- int i, j = 0;
- int interval1;
-
- for(i = 0; i < 12; i++)
- if(x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */
- interval1 = members[1] - members[0]; /* calculate interval between first two members */
- interval1 = interval1 - 1; /* reduce interval1 to start at zero */
- t = &(dyads[interval1]); /* find TypeRoot struct for this interval */
- x->x_chord_type = t->type;
- if (interval1 == 5)
- x->x_chord_root = (members[0]+8)%12;
- else
- x->x_chord_root = members[t->rootMember];
- x->x_chord_inversion = t->rootMember; /* get state of inversion */
- chord_draw_chord_type(x, 2); /* output results */
-}
-
-static void chord_triad(t_chord *x)
-{
- static t_type_root triads[10][10] =
- {/* interval1 is a half step */
- {{ kMaj7b9, 1 }, { kMaj9, 1 }, { kMinMaj7, 1 }, { kMaj7, 1 }, { kDom7s11,2 },
- { kDomb9 , 0 }, { kMaj7, 1 }, { kMaj7s5, 1 }, { kMin9, 2 }, { kMaj7b9, 0 }},
- /* interval1 is a whole step */
- {{ kMin9, 0 }, { kDom9, 0 }, { kMin7, 1 }, { kDom7, 1 }, { kDom9, 0 },
- { kHalfDim7, 1 }, { kDom7, 1 }, { kDom9, 0 }, { kMaj9, 0 }},
- /* interval1 is a minor third */
- {{ kMaj7s5, 2 }, { kDom7, 2 }, { kDim, 0 }, { kMin, 0 }, { kMaj, 2 },
- { kDim, 2 }, { kMin7, 0 }, { kMinMaj7, 0 }},
- /* interval1 is a major third */
- {{ kMaj7, 2 }, { kHalfDim7, 2 }, { kMaj, 0 }, { kAug, 0 }, { kMin, 2 },
- { kDom7, 0 }, { kMaj7, 0 }},
- /* interval1 is a perfect fourth */
- {{ kDomb9, 1 }, { kDom9, 1 }, { kMin, 1 }, { kMaj, 1 }, { kDom9, 2 },
- { kDom7s11, 1 }},
- /* interval1 is an augmented fourth */
- {{ kDom7s11, 0 }, { kDom7, 2 }, { kDim, 1 }, { kHalfDim7, 0 }, { kDomb9, 2 }},
- /* interval1 is a perfect fifth */
- {{ kMaj7, 2 }, { kMin7, 2 }, { kDom7, 0 }, { kMaj7, 0 }},
- /* interval1 is a minor sixth */
- {{ kMinMaj7, 2 }, { kDom9, 1 }, { kMaj7s5, 0 }},
- /* interval1 is a major sixth */
- {{ kMaj9, 2 }, { kMin9, 1 }},
- /* interval1 is a minor seventh */
- {{ kMaj7b9, 2 }}
- };
- register t_type_root* t;
-
- int members[3];
- int i, j = 0;
- int interval1, interval2;
-
- for(i = 0; i < 12; i++)
- if(x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */
- interval1 = members[1] - members[0]; /* calculate interval between first two members */
- interval2 = members[2] - members[0]; /* calculate interval between first and third */
- interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */
- interval1 = interval1 - 1; /* reduce interval1 to start at zero */
- t = &(triads[interval1][interval2]); /* find TypeRoot struct for this interval vector */
- x->x_chord_type = t->type;
- x->x_chord_root = members[t->rootMember];
- switch(t->rootMember) { /* get state of inversion */
- case 0:
- x->x_chord_inversion = 0;
- break;
- case 1:
- x->x_chord_inversion = 2;
- break;
- case 2:
- x->x_chord_inversion = 1;
- }
- chord_draw_chord_type(x, 3); /* output onto the screen */
-}
-
-static void chord_quartad(t_chord *x)
-{
- static t_type_root quartads[9][9][9] =
- {
- {/* interval1 is a half step */
- {/* interval2 is a whole step */
- { kM7b9s13, 2 }, { kMinMajb9,1 }, { kMaj7b9, 1 }, { kMaj7s13, 2 }, { kDimMajb9, 1 },
- { kMaj7b9, 1 }, { kMaj7s13, 2 }, { kM7b913, 1 }, { kM7b9s13, 1 }},
- {/* interval2 is a minor third */
- { kMinMaj9, 1 }, { kMaj9, 1 }, { kHalfDimb9,0 }, { kMin7b9, 0 }, { kMaj9, 1 },
- { kDim7b9, 0 }, { kMin7b9, 0 }, { kMinMajb9, 0 }},
- {/* interval2 is a major third */
- { kMaj7s9, 1 }, { kDom7s11, 3 }, { kDomb9, 0 }, { kMinMaj7, 1 }, { kDom7s9, 3 },
- { kDomb9, 0 }, { kMaj7b9, 0 }},
- {/* interval2 is a perfect fourth */
- { kMaj11, 1 }, { kMaj7b5, 1 }, { kMaj7, 1 }, { kMaj7s5, 1 }, { kMin9, 3 },
- { kMaj7s13, 1 }},
- {/* interval2 is a tritone */
- { kDimMaj9, 3 }, { kDom11, 3 }, { kDim7b9, 0 }, { kHalfDimb9,0 }, { kDimMajb9, 0 }},
- {/* interval2 is a perfect fifth */
- { kMaj11, 3 }, { kDom7s9, 3 }, { kDomb9, 0 }, { kMaj7b9, 0 }},
- {/* interval2 is a minor sixth */
- { kMaj7s9, 3 }, { kMin9, 3 }, { kMaj7s13, 1 }},
- {/* interval2 is a major sixth */
- { kMinMaj9, 3 }, { kM7b913, 0 }},
- {/* interval2 is a minor seventh */
- { kM7b9s13, 0 }}
- },
- {/* interval1 is a whole step */
- {/* interval2 is a minor third */
- { kM7b913, 2 }, { kMin7b9, 1 }, { kDomb9, 1 }, { kMin9, 0 }, { kHalfDimb9,1 },
- { kDomb9, 1 }, { kMin9, 0 }, { kMinMaj9, 0 }},
- {/* interval2 is a major third */
- { kMin9, 1 }, { kDom9, 1 }, { kDom9, 0 }, { kDom7s5, 2 }, { kDom9, 1 },
- { kDom9, 0 }, { kMaj9, 0 }},
- {/* interval2 is a perfect fourth */
- { kDom7s9, 1 }, { kDom11, 3 }, { kHalfDim7, 1 }, { kMin7, 1 }, { kDom9, 3 },
- { kHalfDimb9,3 }},
- {/* interval2 is a tritone */
- { kDom11, 1 }, { kDom7b5, 3 }, { kDom7, 1 }, { kDom7s5, 1 }, { kMin7b9, 3 }},
- {/* interval2 is a perfect fifth */
- { kMaj7b5, 3 }, { kDom11, 1 }, { kDom9, 0 }, { kMaj9, 0 }},
- {/* interval2 is a minor sixth */
- { kDom7s11, 1 }, { kDom9, 3 }, { kDim7b9, 3 }},
- {/* interval2 is a major sixth */
- { kMaj9, 3 }, { kMin7b9, 3 }},
- {/* interval2 is a minor seventh */
- { kMinMajb9, 3 }}
- },
- {/* interval1 is a minor third */
- {/* interval2 is a major third */
- { kMaj7s13, 3 }, { kDim7b9, 1 }, { kDom7s9, 0 }, { kMaj7s5, 2 }, { kDim7b9, 1 },
- { kDom7s9, 0 }, { kMaj7s9, 0 }},
- {/* interval2 is a perfect fourth */
- { kDomb9, 2 }, { kDom9, 2 }, { kMin7, 2 }, { kDom7, 2 }, { kDom11, 2 },
- { kDom7s11, 2 }},
- {/* interval2 is a tritone */
- { kDim7b9, 2 }, { kDom7, 3 }, { kDim7, 0 }, { kHalfDim7, 0 }, { kDomb9, 3 }},
- {/* interval2 is a perfect fifth */
- { kMaj7, 3 }, { kHalfDim7,3 }, { kMin7, 0 }, { kMinMaj7, 0 }},
- {/* interval2 is a minor sixth */
- { kDomb9, 2 }, { kDom9, 2 }, { kDom7s9, 2 }},
- {/* interval2 is a major sixth */
- { kHalfDimb9,2 }, { kDomb9, 3 }},
- {/* interval2 is a minor seventh */
- { kMaj7b9, 3 }}
- },
- {/* interval1 is a major third */
- {/* interval2 is a perfect fourth */
- { kMaj7b9, 2 }, { kMaj9, 2 }, { kMinMaj7, 2 }, { kMaj7, 2 }, { kDom11, 0 },
- { kMaj11, 0 }},
- {/* interval2 is a tritone */
- { kHalfDimb9,2 }, { kDom7s5, 3 }, { kHalfDim7, 2 }, { kDom7b5, 0 }, { kMaj7b5, 0 }},
- {/* interval2 is a perfect fifth */
- { kMaj7s5, 3 }, { kMin7, 3 }, { kDom7, 0 }, { kMaj7, 0 }},
- {/* interval2 is a minor sixth */
- { kMinMaj7, 3 }, { kDom7s5, 0 }, { kMaj7s5, 0 }},
- {/* interval2 is a major sixth */
- { kMin7b9, 2 }, { kMin9, 2 }},
- {/* interval2 is a minor seventh */
- { kMaj7s13, 0 }}
- },
- {/* interval1 is a perfect fourth */
- {/* interval2 is a tritone */
- { kDimMajb9, 2 }, { kMin7b9, 1 }, { kDomb9, 1 }, { kMaj7b5, 2 }, { kDimMaj9, 0 }},
- {/* interval2 is a perfect fifth */
- { kMin9, 1 }, { kDom9, 1 }, { kDom11, 0 }, { kDom11, 2 }},
- {/* interval2 is a minor sixth */
- { kDom7s9, 1 }, { kDom9, 3 }, { kDim7b9, 3 }},
- {/* interval2 is a major sixth */
- { kMaj9, 3 }, { kHalfDimb9,3 }},
- {/* interval2 is a minor seventh */
- { kDimMajb9, 3 }}
- },
- {/* interval1 is a tritone */
- {/* interval2 is a perfect fifth */
- { kMaj7s13, 3 }, { kHalfDimb9,1 }, { kDom7s11, 0 }, { kMaj11, 2 }},
- {/* interval2 is a minor sixth */
- { kDomb9, 2 }, { kDom9, 2 }, { kDom7s9, 2 }},
- {/* interval2 is a major sixth */
- { kDim7b9, 2 }, { kDomb9, 3 }},
- {/* interval2 is a minor seventh */
- { kMaj7b9, 3 }}
- },
- {/* interval1 is a perfect fifth */
- {/* interval2 is a minor sixth */
- { kMaj7b9, 2 }, { kMaj9, 2 }, { kMaj7s9, 2 }},
- {/* interval2 is a major sixth */
- { kMin7b9, 2 }, { kMin9, 2 }},
- {/* interval2 is a minor seventh */
- { kMaj7s13, 0 }}
- },
- {/* interval1 is a minor sixth */
- {/* interval2 is a major sixth */
- { kMinMajb9, 2 }, { kMinMaj9, 2 }},
- {/* interval2 is a minor seventh */
- { kM7b913, 3 }}
- },
- {/* interval1 is a major sixth */
- {/* interval2 is a minor seventh */
- { kM7b9s13, 2 }}
- }
- };
-
- register t_type_root* t;
-
- int members[4];
- int interval1, interval2, interval3;
- int i, j = 0;
- for (i=0; i<12; i++)
- if (x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */
- interval1 = members[1] - members[0]; /* calculate interval between first two members */
- interval2 = members[2] - members[0]; /* calculate interval between first and third */
- interval3 = members[3] - members[0]; /* calculate interval between first and third */
- interval3 = interval3 - interval2 - 1; /* reduce interval3 to start at zero */
- interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */
- interval1 = interval1 - 1; /* reduce interval1 to start at zero */
-
- /* find TypeRoot struct for this interval set */
- t = &(quartads[interval1][interval2][interval3]);
- x->x_chord_type = t->type;
- x->x_chord_root = members[t->rootMember];
- switch(t->rootMember) { /* get state of inversion */
- case 0:
- x->x_chord_inversion = 0;
- break;
- case 1:
- x->x_chord_inversion = 2;
- break;
- case 2:
- x->x_chord_inversion = 2;
- break;
- case 3:
- x->x_chord_inversion = 1;
- }
- chord_draw_chord_type(x, 4); /* output results */
-}
-
-static void chord_fatal_error(char* s1, char* s2)
-{
- post("chord: error: %s : %s", s1, s2);
-}
-
-static void chord_quintad(t_chord *x)
-{
- static int initialized = 0;
- static t_type_root quintads[8][8][8][8];
- register int i, j, k, l;
- register t_type_root *t;
- t_int members[5];
- int interval1, interval2, interval3, interval4;
- int *st;
- int maj9[5][4] = {{1,1,2,3}, {0,1,1,2}, {3,0,1,1}, {2,3,0,1}, {1,2,3,0}};
- int dom9[5][4] = {{1,1,2,2}, {1,1,1,2}, {2,1,1,1}, {2,2,1,1}, {1,2,2,1}};
- int min9[5][4] = {{1,0,3,2}, {1,1,0,3}, {2,1,1,0}, {3,2,1,1}, {0,3,2,1}};
- int had9[5][4] = {{1,0,2,3}, {1,1,0,2}, {3,1,1,0}, {2,3,1,1}, {0,2,3,1}};
- int miM9[5][4] = {{1,0,3,3}, {0,1,0,3}, {3,0,1,0}, {3,3,0,1}, {0,3,3,0}};
- int diM9[5][4] = {{1,0,2,4}, {0,1,0,2}, {4,0,1,0}, {2,4,0,1}, {0,2,4,0}};
- int M9b5[5][4] = {{1,1,1,4}, {0,1,1,1}, {4,0,1,1}, {1,4,0,1}, {1,1,4,0}};
- int D9b5[5][4] = {{1,1,1,3}, {1,1,1,1}, {3,1,1,1}, {1,3,1,1}, {1,1,3,1}};
- int mM91[5][4] = {{1,0,0,6}, {0,1,0,0}, {6,0,1,0}, {0,6,0,1}, {0,0,6,0}};
- int M7b9[5][4] = {{0,2,2,3}, {0,0,2,2}, {3,0,0,2}, {2,3,0,0}, {2,2,3,0}};
- int M5b9[5][4] = {{0,2,3,2}, {0,0,2,3}, {2,0,0,2}, {3,2,0,0}, {2,3,2,0}};
- int D7b9[5][4] = {{0,2,2,2}, {1,0,2,2}, {2,1,0,2}, {2,2,1,0}, {2,2,2,1}};
- int m7b9[5][4] = {{0,1,3,2}, {1,0,1,3}, {2,1,0,1}, {3,2,1,0}, {1,3,2,1}};
- int mb51[5][4] = {{0,1,2,0}, {4,0,1,2}, {0,4,0,1}, {2,0,4,0}, {1,2,0,4}};
- int d7b9[5][4] = {{0,1,2,3}, {1,0,1,2}, {3,1,0,1}, {2,3,1,0}, {1,2,3,1}};
- int mMb9[5][4] = {{0,1,3,3}, {0,0,1,3}, {3,0,0,1}, {3,3,0,0}, {1,3,3,0}};
- int dMb9[5][4] = {{0,1,2,4}, {0,0,1,2}, {4,0,0,1}, {2,4,0,0}, {1,2,4,0}};
- int dib9[5][4] = {{0,1,2,2}, {2,0,1,2}, {2,2,0,1}, {2,2,2,0}, {1,2,2,2}};
- int M7s9[5][4] = {{2,0,2,3}, {0,2,0,2}, {3,0,2,0}, {2,3,0,2}, {0,2,3,0}};
- int D7s9[5][4] = {{2,0,2,2}, {1,2,0,2}, {2,1,2,0}, {2,2,1,2}, {0,2,2,1}};
- int M7s1[5][4] = {{3,1,0,3}, {0,3,1,0}, {3,0,3,1}, {0,3,0,3}, {1,0,3,0}};
- int d9b3[5][4] = {{1,1,2,0}, {3,1,1,2}, {0,3,1,1}, {2,0,3,1}, {1,2,0,3}};
- int M9s3[5][4] = {{1,4,2,0}, {0,1,4,2}, {0,0,1,4}, {2,0,0,1}, {4,2,0,0}};
- int M9st[5][4] = {{1,1,5,0}, {0,1,1,5}, {0,0,1,1}, {5,0,0,1}, {1,5,0,0}};
- int s9s1[5][4] = {{2,0,1,0}, {4,2,0,1}, {0,4,2,0}, {1,0,4,2}, {0,1,0,4}};
- int h7b1[5][4] = {{2,0,1,3}, {1,2,0,1}, {3,1,2,0}, {1,3,1,2}, {0,1,3,1}};
- int M711[5][4] = {{3,0,1,3}, {0,3,0,1}, {3,0,3,0}, {1,3,0,3}, {0,1,3,0}};
- int M115[5][4] = {{1,1,0,5}, {0,1,1,0}, {5,0,1,1}, {0,5,0,1}, {1,0,5,0}};
- int d711[5][4] = {{3,0,1,2}, {1,3,0,1}, {2,1,3,0}, {1,2,1,3}, {0,1,2,1}};
- int d712[5][4] = {{1,1,0,1}, {4,1,1,0}, {1,4,1,1}, {0,1,4,1}, {1,0,1,4}};
- int d713[5][4] = {{1,1,0,4}, {1,1,1,0}, {4,1,1,1}, {0,4,1,1}, {1,0,4,1}};
- int m711[5][4] = {{2,1,1,2}, {1,2,1,1}, {2,1,2,1}, {1,2,1,2}, {1,1,2,1}};
- int m712[5][4] = {{1,0,1,1}, {4,1,0,1}, {1,4,1,0}, {1,1,4,1}, {0,1,1,4}};
- int di11[5][4] = {{1,0,1,0}, {5,1,0,1}, {0,5,1,0}, {1,0,5,1}, {0,1,0,5}};
- int mM11[5][4] = {{2,1,1,3}, {0,2,1,1}, {3,0,2,1}, {1,3,0,2}, {1,1,3,0}};
- int dM11[5][4] = {{2,1,0,4}, {0,2,1,0}, {4,0,2,1}, {0,4,0,2}, {1,0,4,0}};
- int Meb5[5][4] = {{3,0,0,4}, {0,3,0,0}, {4,0,3,0}, {0,4,0,3}, {0,0,4,0}};
- int Mes5[5][4] = {{3,0,2,2}, {0,3,0,2}, {2,0,3,0}, {2,2,0,3}, {0,2,2,0}};
- int Meb9[5][4] = {{0,2,0,5}, {0,0,2,0}, {5,0,0,2}, {0,5,0,0}, {2,0,5,0}};
- int Mes9[5][4] = {{2,0,0,5}, {0,2,0,0}, {5,0,2,0}, {0,5,0,2}, {0,0,5,0}};
- int Deb5[5][4] = {{3,0,0,3}, {1,3,0,0}, {3,1,3,0}, {0,3,1,3}, {0,0,3,1}};
- int Mes3[5][4] = {{3,0,4,0}, {0,3,0,4}, {0,0,3,0}, {4,0,0,3}, {0,4,0,0}};
- int Deb9[5][4] = {{0,2,0,4}, {1,0,2,0}, {4,1,0,2}, {0,4,1,0}, {2,0,4,1}};
- int De91[5][4] = {{0,2,0,1}, {4,0,2,0}, {1,4,0,2}, {0,1,4,0}, {2,0,1,4}};
- int Des9[5][4] = {{2,0,0,4}, {1,2,0,0}, {4,1,2,0}, {0,4,1,2}, {0,0,4,1}};
- int Ds11[5][4] = {{3,1,0,2}, {1,3,1,0}, {2,1,3,1}, {0,2,1,3}, {1,0,2,1}};
- int m7s1[5][4] = {{2,2,0,2}, {1,2,2,0}, {2,1,2,2}, {0,2,1,2}, {2,0,2,1}};
- int D3s1[5][4] = {{5,0,1,0}, {1,5,0,1}, {0,1,5,0}, {1,0,1,5}, {0,1,0,1}};
- int Mb9s[5][4] = {{0,2,5,0}, {0,0,2,5}, {0,0,0,2}, {5,0,0,0}, {2,5,0,0}};
- int D7b3[5][4] = {{3,2,0,1}, {1,3,2,0}, {1,1,3,2}, {0,1,1,3}, {2,0,1,1}};
-
- if (!initialized) {
- for (i=0; i<8; i++)
- for (j=0; j<8; j++)
- for (k=0; k<8; k++)
- for (l=0; l<8; l++) {
- quintads[i][j][k][l].type = kNone;
- quintads[i][j][k][l].rootMember = kXX;
- }
-
-
- // major ninths
- for (i=0; i<5; i++) {
- st = maj9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- t->type = kMaj9;
- t->rootMember = i;
- }
-
- // dominant ninths
- for (i=0; i<5; i++) {
- st = dom9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "dom9");
- t->type = kDom9;
- t->rootMember = i;
- }
-
- // minor ninths
- for (i=0; i<5; i++) {
- st = min9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "min9");
- t->type = kMin9;
- t->rootMember = i;
- }
-
- // half diminished ninths
- for (i=0; i<5; i++) {
- st = had9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "had9");
- t->type = kHalfDim9;
- t->rootMember = i;
- }
-
- // minor/major ninths
- for (i=0; i<5; i++) {
- st = miM9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "miM9");
- t->type = kMinMaj9;
- t->rootMember = i;
- }
-
- // diminished/major ninths
- for (i=0; i<5; i++) {
- st = diM9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "diM9");
- t->type = kDimMaj9;
- t->rootMember = i;
- }
-
- // major ninth flat 5
- for (i=0; i<5; i++) {
- st = M9b5[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M9b5");
- t->type = kMaj9b5;
- t->rootMember = i;
- }
-
- // dominant ninth flat 5
- for (i=0; i<5; i++) {
- st = D9b5[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "D9b5");
- t->type = kDom9b5;
- t->rootMember = i;
- }
-
- // minor/major ninth flat 11
- for (i=0; i<5; i++) {
- st = mM91[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "mM91");
- t->type = kmM9b11;
- t->rootMember = i;
- }
-
- // major seventh flat nine
- for (i=0; i<5; i++) {
- st = M7b9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M7b9");
- t->type = kMaj7b9;
- t->rootMember = i;
- }
-
- // major seventh sharp five flat nine
- for (i=0; i<5; i++) {
- st = M5b9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M5b9");
- t->type = kMaj7s5b9;
- t->rootMember = i;
- }
-
- // dominant seventh flat nine
- for (i=0; i<5; i++) {
- st = D7b9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "D7b9");
- t->type = kDom7b9;
- t->rootMember = i;
- }
-
- // minor seventh flat nine
- for (i=0; i<5; i++) {
- t = &(quintads[m7b9[i][0]][m7b9[i][1]][m7b9[i][2]][m7b9[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "m7b9");
- t->type = kMin7b9;
- t->rootMember = i;
- }
-
- // minor flat nine sharp eleventh
- for (i=0; i<5; i++) {
- st = mb51[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "mb51");
- t->type = kMinb9s11;
- t->rootMember = i;
- }
-
- // half diminished seventh flat nine
- for (i=0; i<5; i++) {
- st = d7b9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "d7b9");
- t->type = kHalfDimb9;
- t->rootMember = i;
- }
-
- // minor/major seventh flat nine
- for (i=0; i<5; i++) {
- st = mMb9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "mMb9");
- t->type = kMinMajb9;
- t->rootMember = i;
- }
-
- // diminished major seventh flat nine
- for (i=0; i<5; i++) {
- st = dMb9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "dMb9");
- t->type = kDimMajb9;
- t->rootMember = i;
- }
-
- // diminished seventh flat nine
- for (i=0; i<5; i++) {
- t = &(quintads[dib9[i][0]][dib9[i][1]][dib9[i][2]][dib9[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "dib9");
- t->type = kDim7b9;
- t->rootMember = i;
- }
-
- // major seventh sharp nine
- for (i=0; i<5; i++) {
- t = &(quintads[M7s9[i][0]][M7s9[i][1]][M7s9[i][2]][M7s9[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M7s9");
- t->type = kMaj7s9;
- t->rootMember = i;
- }
-
- // dominant seventh sharp nine
- for (i=0; i<5; i++) {
- t = &(quintads[D7s9[i][0]][D7s9[i][1]][D7s9[i][2]][D7s9[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "D7s9");
- t->type = kDom7s9;
- t->rootMember = i;
- }
-
- // major seventh sharp eleventh
- for (i=0; i<5; i++) {
- t = &(quintads[M7s1[i][0]][M7s1[i][1]][M7s1[i][2]][M7s1[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M7s1");
- t->type = kMaj7s11;
- t->rootMember = i;
- }
-
- // dominant ninth flat thirteenth
- for (i=0; i<5; i++) {
- st = d9b3[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "d9b3");
- t->type = kDom9b13;
- t->rootMember = i;
- }
-
- // major ninth sharp thirteenth
- for (i=0; i<5; i++) {
- st = M9s3[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M9s3");
- t->type = kMaj9s13;
- t->rootMember = i;
- }
-
- // major ninth sharp thirteenth
- for (i=0; i<5; i++) {
- t = &(quintads[M9st[i][0]][M9st[i][1]][M9st[i][2]][M9st[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M9st");
- t->type = kMaj9s13;
- t->rootMember = i;
- }
-
- // major chord sharp ninth sharp eleventh
- for (i=0; i<5; i++) {
- st = s9s1[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "s9s1");
- t->type = kMs9s11;
- t->rootMember = i;
- }
-
- // half diminished seven flat 11
- for (i=0; i<5; i++) {
- st = h7b1[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "h7b1");
- t->type = kHDimb11;
- t->rootMember = i;
- }
-
- // major eleventh
- for (i=0; i<5; i++) {
- t = &(quintads[M711[i][0]][M711[i][1]][M711[i][2]][M711[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M711");
- t->type = kMaj11;
- t->rootMember = i;
- }
-
- // major eleventh
- for (i=0; i<5; i++) {
- t = &(quintads[M115[i][0]][M115[i][1]][M115[i][2]][M115[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M711");
- t->type = kMaj11;
- t->rootMember = i;
- }
-
- // dominant eleventh
- for (i=0; i<5; i++) {
- t = &(quintads[d711[i][0]][d711[i][1]][d711[i][2]][d711[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "d711");
- t->type = kDom11;
- t->rootMember = i;
- }
-
- // dominant eleventh
- for (i=0; i<5; i++) {
- t = &(quintads[d712[i][0]][d712[i][1]][d712[i][2]][d712[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "d712");
- t->type = kDom11;
- t->rootMember = i;
- }
-
- // dominant eleventh
- for (i=0; i<5; i++) {
- st = d713[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "d713");
- t->type = kDom11;
- t->rootMember = i;
- }
-
- // minor eleventh
- for (i=0; i<5; i++) {
- t = &(quintads[m711[i][0]][m711[i][1]][m711[i][2]][m711[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "m711");
- t->type = kMin11;
- t->rootMember = i;
- }
-
- // minor eleventh
- for (i=0; i<5; i++) {
- t = &(quintads[m712[i][0]][m712[i][1]][m712[i][2]][m712[i][3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "m712");
- t->type = kMin11;
- t->rootMember = i;
- }
-
- // diminished eleventh
- for (i=0; i<5; i++) {
- st = di11[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "di11");
- t->type = kDim11;
- t->rootMember = i;
- }
-
- // minor/major eleventh
- for (i=0; i<5; i++) {
- st = mM11[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "mM11");
- t->type = kMinMaj11;
- t->rootMember = i;
- }
-
- // diminished major eleventh
- for (i=0; i<5; i++) {
- st = dM11[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "dM11");
- t->type = kDimMaj11;
- t->rootMember = i;
- }
-
- // major eleventh flat fifth
- for (i=0; i<5; i++) {
- st = Meb5[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "Meb5");
- t->type = kMaj11b5;
- t->rootMember = i;
- }
-
- // major eleventh sharp fifth
- for (i=0; i<5; i++) {
- st = Mes5[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "Mes5");
- t->type = kMaj11s5;
- t->rootMember = i;
- }
-
- // major eleventh flat ninth
- for (i=0; i<5; i++) {
- st = Meb9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "Meb9");
- t->type = kMaj11b9;
- t->rootMember = i;
- }
-
- // major eleventh sharp ninth
- for (i=0; i<5; i++) {
- st = Mes9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "Mes9");
- t->type = kMaj11s9;
- t->rootMember = i;
- }
-
- // major eleventh sharp thirteenth
- for (i=0; i<5; i++) {
- st = Mes3[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "Mes3");
- t->type = kMaj11s13;
- t->rootMember = i;
- }
-
- // dominant eleventh flat fifth
- for (i=0; i<5; i++) {
- st = Deb5[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "Deb5");
- t->type = kDom11b5;
- t->rootMember = i;
- }
-
- // dominant eleventh flat ninth
- for (i=0; i<5; i++) {
- st = Deb9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "Deb9");
- t->type = kDom11b9;
- t->rootMember = i;
- }
-
- // dominant eleventh flat ninth
- for (i=0; i<5; i++) {
- st = De91[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "De91");
- t->type = kDom11b9;
- t->rootMember = i;
- }
-
- // dominant eleventh sharp ninth
- for (i=0; i<5; i++) {
- st = Des9[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "Des9");
- t->type = kDom11s9;
- t->rootMember = i;
- }
-
- // dominant seventh sharp eleventh
- for (i=0; i<5; i++) {
- st = Ds11[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "Ds11");
- t->type = kDom7s11;
- t->rootMember = i;
- }
-
- // minor seventh sharp eleventh
- for (i=0; i<5; i++) {
- st = m7s1[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "m7s1");
- t->type = kMin7s11;
- t->rootMember = i;
- }
-
- // dominant thirteenth sharp eleventh
- for (i=0; i<5; i++) {
- st = D3s1[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "D3s1");
- t->type = kDom13s11;
- t->rootMember = i;
- }
-
- // major seventh flat ninth sharp thirteenth
- for (i=0; i<5; i++) {
- st = Mb9s[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "Mb9s");
- t->type = kM7b9s13;
- t->rootMember = i;
- }
-
- // dominant seventh flat thirteenth
- for (i=0; i<5; i++) {
- st = D7b3[i];
- t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "D7b3");
- t->type = kDom7b13;
- t->rootMember = i;
- }
-
- initialized = 1;
- return;
- }
-
- j = 0;
- for (i=0; i<12; i++)
- if (x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */
- interval1 = members[1] - members[0]; /* calculate interval between first two members */
- interval2 = members[2] - members[0]; /* calculate interval between first and third */
- interval3 = members[3] - members[0]; /* calculate interval between first and third */
- interval4 = members[4] - members[0]; /* calculate interval between first and fourth */
- interval4 = interval4 - interval3 - 1; /* reduce interval4 to start at zero */
- interval3 = interval3 - interval2 - 1; /* reduce interval3 to start at zero */
- interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */
- interval1 = interval1 - 1; /* reduce interval1 to start at zero */
-
- // find TypeRoot struct for this interval set
- t = &(quintads[interval1][interval2][interval3][interval4]);
- if (t->rootMember != kXX)
- {
- x->x_chord_type = t->type;
- x->x_chord_root = members[t->rootMember];
- switch(t->rootMember) { /* get state of inversion */
- case 0:
- x->x_chord_inversion = 0;
- break;
- case 1:
- x->x_chord_inversion = 2;
- break;
- case 2:
- x->x_chord_inversion = 2;
- break;
- case 3:
- x->x_chord_inversion = 2;
- break;
- case 4:
- x->x_chord_inversion = 1;
- }
- chord_draw_chord_type(x, 5); /* output result */
- } else
- chord_kick_out_member(x, 5, members);
-}
-
-static void chord_sextad(t_chord *x)
-{
- static int initialized = 0;
- static t_type_root sextads[7][7][7][7][7];
- register int i, j, k, l, m;
- register t_type_root *t;
- register int* st;
- t_int members[6];
- int interval1, interval2, interval3, interval4, interval5;
-
- int D9b3[6][5] =
- {{1,1,2,0,1}, {1,1,1,2,0}, {1,1,1,1,2}, {0,1,1,1,1}, {2,0,1,1,1}, {1,2,0,1,1}};
- int m9s1[6][5] =
- {{1,0,2,0,2}, {1,1,0,2,0}, {2,1,1,0,2}, {0,2,1,1,0}, {2,0,2,1,1}, {0,2,0,2,1}};
- int M711[6][5] =
- {{1,1,0,1,3}, {0,1,1,0,1}, {3,0,1,1,0}, {1,3,0,1,1}, {0,1,3,0,1}, {1,0,1,3,0}};
- int D711[6][5] =
- {{1,1,0,1,2}, {1,1,1,0,1}, {2,1,1,1,0}, {1,2,1,1,1}, {0,1,2,1,1}, {1,0,1,2,1}};
- int hd11[6][5] =
- {{1,0,1,0,3}, {1,1,0,1,0}, {3,1,1,0,1}, {0,3,1,1,0}, {1,0,3,1,1}, {0,1,0,3,1}};
- int M1b5[6][5] =
- {{1,1,0,0,4}, {0,1,1,0,0}, {4,0,1,1,0}, {0,4,0,1,1}, {0,0,4,0,1}, {1,0,0,4,0}};
- int M159[6][5] =
- {{0,2,0,0,4}, {0,0,2,0,0}, {4,0,0,2,0}, {0,4,0,0,2}, {0,0,4,0,0}, {2,0,0,4,0}};
- int M1s3[6][5] =
- {{1,1,0,4,0}, {0,1,1,0,4}, {0,0,1,1,0}, {4,0,0,1,1}, {0,4,0,0,1}, {1,0,4,0,0}};
- int hd19[6][5] =
- {{0,1,1,0,3}, {1,0,1,1,0}, {3,1,0,1,1}, {0,3,1,0,1}, {1,0,3,1,0}, {1,1,0,3,1}};
- int M1b3[6][5] =
- {{3,0,1,0,2}, {0,3,0,1,0}, {2,0,3,0,1}, {0,2,0,3,0}, {1,0,2,0,3}, {0,1,0,2,0}};
- int D1b5[6][5] =
- {{1,1,0,0,3}, {1,1,1,0,0}, {3,1,1,1,0}, {0,3,1,1,1}, {0,0,3,1,1}, {1,0,0,3,1}};
- int D1s9[6][5] =
- {{2,0,0,1,2}, {1,2,0,0,1}, {2,1,2,0,0}, {1,2,1,2,0}, {0,1,2,1,2}, {0,0,1,2,1}};
- int m791[6][5] =
- {{0,1,2,0,2}, {1,0,1,2,0}, {2,1,0,1,2}, {0,2,1,0,1}, {2,0,2,1,0}, {1,2,0,2,1}};
- int d7s1[6][5] =
- {{1,1,1,0,2}, {1,1,1,1,0}, {2,1,1,1,1}, {0,2,1,1,1}, {1,0,2,1,1}, {1,1,0,2,1}};
- int d3s1[6][5] =
- {{3,1,0,1,0}, {1,3,1,0,1}, {0,1,3,1,0}, {1,0,1,3,1}, {0,1,0,1,3}, {1,0,1,0,1}};
-
-
- if (!initialized) {
- for (i=0; i<7; i++)
- for (j=0; j<7; j++)
- for (k=0; k<7; k++)
- for (l=0; l<7; l++)
- for (m=0; m<7; m++) {
- sextads[i][j][k][l][m].type = kNone;
- sextads[i][j][k][l][m].rootMember = kXX;
- }
-
- // dominant ninth flat thirteen
- for (i=0; i<6; i++) {
- st = D9b3[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "D9b3");
- t->type = kDom9b13;
- t->rootMember = i;
- }
-
- // minor ninth sharp eleventh
- for (i=0; i<6; i++) {
- st = m9s1[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "m9s1");
- t->type = kMin9s11;
- t->rootMember = i;
- }
-
- // major eleventh
- for (i=0; i<6; i++) {
- st = M711[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M711");
- t->type = kMaj11;
- t->rootMember = i;
- }
-
- // dominant eleventh
- for (i=0; i<6; i++) {
- st = D711[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "D711");
- t->type = kDom11;
- t->rootMember = i;
- }
-
- // half diminished eleventh
- for (i=0; i<6; i++) {
- st = hd11[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "hd11");
- t->type = kHalfDim11;
- t->rootMember = i;
- }
-
- // major eleventh flat 5
- for (i=0; i<6; i++) {
- st = M1b5[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M1b5");
- t->type = kMaj11b5;
- t->rootMember = i;
- }
-
- // major eleventh flat 5 flat 9
- for (i=0; i<6; i++) {
- st = M159[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M159");
- t->type = kM11b5b9;
- t->rootMember = i;
- }
-
- // major eleventh sharp 13
- for (i=0; i<6; i++) {
- st = M1s3[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M1s3");
- t->type = kMaj11s13;
- t->rootMember = i;
- }
-
- // half diminished eleventh flat 9
- for (i=0; i<6; i++) {
- st = hd19[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "hd19");
- t->type = kHalfDim11b9;
- t->rootMember = i;
- }
-
- // major eleventh flat 13
- for (i=0; i<6; i++) {
- st = M1b3[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "M1b3");
- t->type = kMaj11b13;
- t->rootMember = i;
- }
-
- // dominant eleventh flat five
- for (i=0; i<6; i++) {
- st = D1b5[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "D1b5");
- t->type = kDom11b5;
- t->rootMember = i;
- }
-
- // dominant eleventh sharp nine
- for (i=0; i<6; i++) {
- st = D1s9[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "D1s9");
- t->type = kDom11s9;
- t->rootMember = i;
- }
-
- // minor seventh flat 9 sharp 11
- for (i=0; i<6; i++) {
- st = m791[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "m791");
- t->type = kMinb9s11;
- t->rootMember = i;
- }
-
- // dominant seventh sharp 11
- for (i=0; i<6; i++) {
- st = d7s1[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "d7s1");
- t->type = kDom7s11;
- t->rootMember = i;
- }
-
- // dominant thirteenth sharp 11
- for (i=0; i<6; i++) {
- st = d3s1[i];
- t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
- if (t->type != kNone) chord_fatal_error("redefining chord", "d3s1");
- t->type = kDom13s11;
- t->rootMember = i;
- }
-
- initialized = 1;
- return;
- }
-
- j = 0;
- for (i=0; i<12; i++)
- if (x->x_pc[i]) members[j++] = i; // load members array with chord pitch classes
- interval1 = members[1] - members[0]; // calculate interval between first two members
- interval2 = members[2] - members[0]; // calculate interval between first and third
- interval3 = members[3] - members[0]; // calculate interval between first and third
- interval4 = members[4] - members[0]; // calculate interval between first and fourth
- interval5 = members[5] - members[0]; // calculate interval between first and fifth
- interval5 = interval5 - interval4 - 1; // reduce interval5 to start at zero
- interval4 = interval4 - interval3 - 1; // reduce interval4 to start at zero
- interval3 = interval3 - interval2 - 1; // reduce interval3 to start at zero
- interval2 = interval2 - interval1 - 1; // reduce interval2 to start at zero
- interval1 = interval1 - 1; // reduce interval1 to start at zero
-
- // find TypeRoot struct for this interval set
- t = &(sextads[interval1][interval2][interval3][interval4][interval5]);
- if (t->rootMember != kXX) {
- x->x_chord_type = t->type;
- x->x_chord_root = members[t->rootMember];
- switch(t->rootMember) { /* get state of inversion */
- case 0:
- x->x_chord_inversion = 0;
- break;
- case 1:
- x->x_chord_inversion = 2;
- break;
- case 2:
- x->x_chord_inversion = 2;
- break;
- case 3:
- x->x_chord_inversion = 2;
- break;
- case 4:
- x->x_chord_inversion = 2;
- break;
- case 5: x->x_chord_inversion = 1;
- }
- chord_draw_chord_type(x, 6); // output onto the screen
- } else
- chord_kick_out_member(x, 6, members);
-}
-
-static int chord_accidental(t_int pc)
-{
- switch (pc) {
- case 0:
- case 2:
- case 4:
- case 5:
- case 7:
- case 9:
- case 11: return 0;
- case 1:
- case 3:
- case 6:
- case 8:
- case 10:
- default: return 1;
- }
-}
-
-static int chord_name_third(t_chord *x, char* chord, int c, int rootName)
-{
- int third = (x->x_chord_root+4)%12; // look for major third
- if (x->x_pc[third]) { // if one is there
- x->x_pc[third] = 0; // erase from pcs array
- chord[c++] = name_class[(rootName+2)%7];
- if (chord_accidental(third)) { // if it has an chord_accidental
- // make it a flat if the root also has an chord_accidental
- if (chord_accidental(x->x_chord_root))
- chord[c++] = 'b';
- // otherwise make it a sharp
- else
- chord[c++] = '#';
- }
- chord[c++] = ' ';
- return c; // return if major third found
- }
-
- third = (x->x_chord_root+3)%12; // no major, look for minor third
- if (x->x_pc[third]) { // if one is there
- x->x_pc[third] = 0; // erase from pcs array
- chord[c++] = name_class[(rootName+2)%7];
- if (chord_accidental(third)) // if it has an chord_accidental
- chord[c++] = 'b'; else // make it a flat
- if (chord_accidental(x->x_chord_root)) { // if the root has an chord_accidental
- chord[c++] = 'b'; // make the third a flat
- if (chord[0] == 'G') // if the root is Gb
- chord[c++] = 'b'; // this must be Bbb
- }
- chord[c++] = ' ';
- return c;
- }
-
- return c; // if we get here there was no third
-}
-
-static int chord_name_fifth(t_chord *x, char* chord, int c, int rootName)
-{
- int fifth = (x->x_chord_root+7)%12;
- if (x->x_pc[fifth]) {
- x->x_pc[fifth] = 0;
- chord[c++] = name_class[(rootName+4)%7];
- if (chord_accidental(fifth)) {
- if (chord_accidental(x->x_chord_root)) chord[c++] = 'b';
- else chord[c++] = '#';
- }
- chord[c++] = ' ';
- return c;
- }
-
- fifth = (x->x_chord_root+6)%12;
- if (x->x_pc[fifth]) {
- x->x_pc[fifth] = 0;
- chord[c++] = name_class[(rootName+4)%7];
- if (chord[0] != 'B') chord[c++] = 'b';
- if (chord_accidental(x->x_chord_root)) chord[c++] = 'b';
- chord[c++] = ' ';
- return c;
- }
-
- fifth = (x->x_chord_root+8)%12;
- if (x->x_pc[fifth]) {
- x->x_pc[fifth] = 0;
- chord[c++] = name_class[(rootName+4)%7];
- if (chord_accidental(fifth)) chord[c++] = '#'; else
- if (!chord_accidental(x->x_chord_root)) {
- chord[c++] = '#';
- if (chord[0] == 'B')
- chord[c++] = '#';
- }
- chord[c++] = ' ';
- return c;
- }
-
- return c;
-}
-
-static int chord_name_seventh(t_chord *x, char* chord, int c, int rootName)
-{
- int seventh = (x->x_chord_root+11)%12;
- if (x->x_pc[seventh]) {
- x->x_pc[seventh] = 0;
- chord[c++] = name_class[(rootName+6)%7];
- if (chord_accidental(seventh)) chord[c++] = '#';
- chord[c++] = ' ';
- return c;
- }
- seventh = (x->x_chord_root+10)%12;
- if (x->x_pc[seventh]) {
- x->x_pc[seventh] = 0;
- chord[c++] = name_class[(rootName+6)%7];
- if (chord_accidental(seventh) || chord_accidental(x->x_chord_root))
- chord[c++] = 'b';
- chord[c++] = ' ';
- return c;
- }
- seventh = (x->x_chord_root+9)%12;
- if (x->x_pc[seventh]) {
- x->x_pc[seventh] = 0;
- chord[c++] = name_class[(rootName+6)%7];
- chord[c++] = 'b';
- if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; else
- if (chord_accidental((seventh+1)%12)) chord[c++] = 'b';
- chord[c++] = ' ';
- return c;
- }
- return c;
-}
-
-static int chord_name_ninth(t_chord *x, char* chord, int c, int rootName)
-{
- int ninth = (x->x_chord_root+2)%12;
- if (x->x_pc[ninth]) {
- x->x_pc[ninth] = 0;
- chord[c++] = name_class[(rootName+1)%7];
- if (chord_accidental(ninth)) {
- if (chord_accidental(x->x_chord_root)) chord[c++] = 'b';
- else chord[c++] = '#';
- }
- chord[c++] = ' ';
- return c;
- }
-
- ninth = (x->x_chord_root+1)%12;
- if (x->x_pc[ninth]) {
- x->x_pc[ninth] = 0;
- chord[c++] = name_class[(rootName+1)%7];
- if (chord_accidental(ninth)) chord[c++] = 'b';
- else {
- if (chord_accidental(x->x_chord_root)) {
- chord[c++] = 'b';
- if ((x->x_chord_root == 1) || (x->x_chord_root == 6) || (x->x_chord_root == 8))
- chord[c++] = 'b';
- }
- }
- chord[c++] = ' ';
- return c;
- }
-
- ninth = (x->x_chord_root+3)%12;
- if (x->x_pc[ninth]) {
- x->x_pc[ninth] = 0;
- chord[c++] = name_class[(rootName+1)%7];
- if (chord_accidental(ninth)) chord[c++] = '#'; else
- if (!chord_accidental(x->x_chord_root)) {
- chord[c++] = '#';
- if (chord_accidental((x->x_chord_root+2)%12))
- chord[c++] = '#';
- }
- chord[c++] = ' ';
- return c;
- }
-
- return c;
-}
-
-static int chord_name_eleventh(t_chord *x, char* chord, int c, int rootName)
-{
- int eleventh = (x->x_chord_root+5)%12;
- if (x->x_pc[eleventh]) {
- x->x_pc[eleventh] = 0;
- chord[c++] = name_class[(rootName+3)%7];
- if (chord_accidental(eleventh)) chord[c++] = 'b'; else
- if (chord_accidental(x->x_chord_root)) chord[c++] = 'b';
- chord[c++] = ' ';
- return c;
- }
-
- eleventh = (x->x_chord_root+6)%12;
- if (x->x_pc[eleventh]) {
- x->x_pc[eleventh] = 0;
- chord[c++] = name_class[(rootName+3)%7];
- if (chord_accidental(eleventh)) chord[c++] = '#'; else
- if ((!chord_accidental(x->x_chord_root)) && (x->x_chord_root == 11))
- chord[c++] = '#';
- chord[c++] = ' ';
- return c;
- }
-
- return c;
-}
-
-static int chord_name_thirteenth(t_chord *x, char* chord, int c, int rootName)
-{
- int thirteenth = (x->x_chord_root+9)%12;
- if (x->x_pc[thirteenth]) {
- x->x_pc[thirteenth] = 0;
- chord[c++] = name_class[(rootName+5)%7];
- if (chord_accidental(thirteenth)) {
- if (chord_accidental(x->x_chord_root))
- chord[c++] = 'b';
- else
- chord[c++] = '#';
- }
-
- chord[c++] = ' ';
- return c;
- }
-
- thirteenth = (x->x_chord_root+10)%12;
- if (x->x_pc[thirteenth]) {
- x->x_pc[thirteenth] = 0;
- chord[c++] = name_class[(rootName+5)%7];
- if (chord_accidental(thirteenth)) chord[c++] = '#'; else
- if (!chord_accidental(x->x_chord_root)) {
- chord[c++] = '#';
- if (chord_accidental((x->x_chord_root+9)%12))
- chord[c++] = '#';
- }
- chord[c++] = ' ';
- return c;
- }
-
- thirteenth = (x->x_chord_root+8)%12;
- if (x->x_pc[thirteenth]) {
- x->x_pc[thirteenth] = 0;
- chord[c++] = name_class[(rootName+5)%7];
- if (chord_accidental(thirteenth)) chord[c++] = 'b'; else
- if (chord_accidental(x->x_chord_root)) {
- chord[c++] = 'b';
- if (chord_accidental(x->x_chord_root+9)%12)
- chord[c++] = 'b';
- }
- chord[c++] = ' ';
- return c;
- }
-
- return c;
-}
-
-
-
-static void chord_spell_chord(t_chord *x, char *chord, t_int num_pcs)
-{
- int rootName = 0; // keep index of root name class
- int c = 0; // pointer to current character
- int named = 0; // how many members have been named
- int mark;
- int i;
-
- // use chordRoot to set rootName index and store characters for name
- switch (x->x_chord_root)
- {
- case 0: chord[c++] = name_class[rootName=0]; break;
- case 1: chord[c++] = name_class[rootName=1];
- chord[c++] = 'b'; break;
- case 2: chord[c++] = name_class[rootName=1]; break;
- case 3: chord[c++] = name_class[rootName=2];
- chord[c++] = 'b'; break;
- case 4: chord[c++] = name_class[rootName=2]; break;
- case 5: chord[c++] = name_class[rootName=3]; break;
- case 6: chord[c++] = name_class[rootName=4];
- chord[c++] = 'b'; break;
- case 7: chord[c++] = name_class[rootName=4]; break;
- case 8: chord[c++] = name_class[rootName=5];
- chord[c++] = 'b'; break;
- case 9: chord[c++] = name_class[rootName=5]; break;
- case 10: chord[c++] = name_class[rootName=6];
- chord[c++] = 'b'; break;
- case 11: chord[c++] = name_class[rootName=6]; break;
- default: break;
- }
- x->x_pc[x->x_chord_root] = 0; /* set this member to zero */
-
- chord[c++] = ' '; // insert space
- if (++named == num_pcs) { // if everything is named
- chord[c] = '\0'; // terminate the string
- return; // and return
- }
-
- mark = c; // use mark to see if new names are added
- for (i=0; i<6; i++) {
- // advance search by thirds
- switch (i) {
- case 0: mark = chord_name_third (x, chord, c, rootName); break;
- case 1: mark = chord_name_fifth (x, chord, c, rootName); break;
- case 2: mark = chord_name_seventh (x, chord, c, rootName); break;
- case 3: mark = chord_name_ninth (x, chord, c, rootName); break;
- case 4: mark = chord_name_eleventh (x, chord, c, rootName); break;
- case 5: mark = chord_name_thirteenth(x, chord, c, rootName); break;
- }
- if (mark != c) { // if new name is added
- ++named; // increment count of named members
- c = mark; // update character pointer
- }
- if (named == num_pcs) { // if everything is named
- chord[c] = '\0'; // terminate the string
- return; // and return
- }
- }
-
- chord[c] = '\0';
-}
-
-
-static void chord_draw_chord_type(t_chord *x, t_int num_pcs)
-{
- char chord[255]; /* output string */
- int i, j;
-
- /* get members of chord */
- j = 0;
- for(i = 0; i < 12; i++)
- {
- if(x->x_pc[i])
- {
- SETFLOAT(x->x_chordlist+j, x->x_abs_pc[i]);
- j++;
- }
- }
-
- if (x->x_chord_type != kNone)
- {
- chord_spell_chord(x, chord, num_pcs); /* spell chord members */
- }
- else
- {
- post("going...");
- chord[0] = '\0';
- for(i = 0; i < 12; i++)
- if (x->x_pc[i])
- strcat(chord, pitch_class[i]); /* output single notes */
- post("did it");
- }
-
- strcat(chord, ": ");
- strcat(chord, pitch_class[x->x_chord_root]);
-
- /* append name of chord type */
- switch (x->x_chord_type) {
- case kUnison: strcat(chord, "unison"); break;
- case kMaj: strcat(chord, "major"); break;
- case kMin: strcat(chord, "minor"); break;
- case kDim: strcat(chord, "diminished"); break;
- case kAug: strcat(chord, "augmented"); break;
-
- case kMaj7: strcat(chord, "major 7th"); break;
- case kDom7: strcat(chord, "dominant 7th"); break;
- case kMin7: strcat(chord, "minor 7th"); break;
- case kHalfDim7: strcat(chord, "half diminished 7th"); break;
- case kDim7: strcat(chord, "diminished 7th"); break;
- case kMinMaj7: strcat(chord, "minor/major 7th"); break;
-
- case kMaj7s5: strcat(chord, "major 7th #5"); break;
- case kMaj7b5: strcat(chord, "major 7th b5"); break;
- case kDom7s5: strcat(chord, "dominant 7th #5"); break;
- case kDom7b5: strcat(chord, "dominant 7th b5"); break;
- case kDomb9: strcat(chord, "dominant b9"); break;
-
- case kMaj9: strcat(chord, "major 9th"); break;
- case kDom9: strcat(chord, "dominant 9th"); break;
- case kMin9: strcat(chord, "minor 9th"); break;
- case kHalfDim9: strcat(chord, "half diminished 9th"); break;
- case kMinMaj9: strcat(chord, "minor major 9th"); break;
- case kDimMaj9: strcat(chord, "diminished major 9th");break;
- case kMaj9b5: strcat(chord, "major 9th b5"); break;
- case kDom9b5: strcat(chord, "dominant 9th b5"); break;
- case kDom9b13: strcat(chord, "dominant 9th b13"); break;
- case kMin9s11: strcat(chord, "minor 9th #11"); break;
- case kmM9b11: strcat(chord, "minor/maj 9th b11"); break;
-
- case kMaj7b9: strcat(chord, "major 7th b9"); break;
- case kMaj7s5b9: strcat(chord, "major 7th #5 b9"); break;
- case kDom7b9: strcat(chord, "dominant 7th b9"); break;
- case kMin7b9: strcat(chord, "minor 7th b9"); break;
- case kMinb9s11: strcat(chord, "minor b9 #11"); break;
- case kHalfDimb9:strcat(chord, "half diminished b9"); break;
- case kDim7b9: strcat(chord, "diminished b9"); break;
- case kMinMajb9: strcat(chord, "minor/major b9"); break;
- case kDimMajb9: strcat(chord, "diminished M7 b9"); break;
-
- case kMaj7s9: strcat(chord, "major 7th #9"); break;
- case kDom7s9: strcat(chord, "dominant #9"); break;
- case kMaj7s11: strcat(chord, "major 7th #11"); break;
- case kMaj9s13: strcat(chord, "major 9th #13"); break;
- case kMs9s11: strcat(chord, "major #9 #11"); break;
- case kHDimb11: strcat(chord, "half diminished b11"); break;
-
- case kMaj11: strcat(chord, "major 11th"); break;
- case kDom11: strcat(chord, "dominant 11th"); break;
- case kMin11: strcat(chord, "minor 11th"); break;
- case kHalfDim11:strcat(chord, "half diminished 11th");break;
- case kDim11: strcat(chord, "diminished 11th"); break;
- case kMinMaj11: strcat(chord, "minor/major 11th"); break;
- case kDimMaj11: strcat(chord, "diminished maj 11th"); break;
-
- case kMaj11b5: strcat(chord, "major 11th b5"); break;
- case kMaj11s5: strcat(chord, "major 11th #5"); break;
- case kMaj11b9: strcat(chord, "major 11th b9"); break;
- case kMaj11s9: strcat(chord, "major 11th #9"); break;
- case kMaj11b13: strcat(chord, "major 11th b13"); break;
- case kMaj11s13: strcat(chord, "major 11th #13"); break;
- case kM11b5b9: strcat(chord, "major 11th b5 b9"); break;
- case kDom11b5: strcat(chord, "dominant 11th b5"); break;
- case kDom11b9: strcat(chord, "dominant 11th b9"); break;
- case kDom11s9: strcat(chord, "dominant 11th #9"); break;
- case kHalfDim11b9:strcat(chord, "half dim 11th b9"); break;
- case kDom7s11: strcat(chord, "dominant #11"); break;
- case kMin7s11: strcat(chord, "minor 7th #11"); break;
-
- case kDom13s11: strcat(chord, "dominant 13th #11"); break;
- case kM7b913: strcat(chord, "major 7 b9 13"); break;
- case kMaj7s13: strcat(chord, "major 7th #13"); break;
- case kM7b9s13: strcat(chord, "major 7 b9 #13"); break;
- case kDom7b13: strcat(chord, "dominant 7th b13"); break;
- case kChrom: strcat(chord, "chromatic"); break;
- case kNone:
- default: strcat(chord, "unknown"); break;
- }
-
- x->x_chord_bass = x->x_abs_pc[x->x_chord_root]; /* get MIDI note number of bass */
-
- /* output results */
- outlet_list(x->x_outchordnotes, NULL, j, x->x_chordlist);
- outlet_float(x->x_outchordinversion, x->x_chord_inversion);
- outlet_symbol(x->x_outchordname, gensym(chord));
- outlet_float(x->x_outchordclass, x->x_chord_root);
- outlet_float(x->x_outchordval, x->x_chord_bass);
-}
-
-static void chord_kick_out_member(t_chord *x, t_int number, t_int *members)
-{
- int *distances;
- int minDistance = 1000;
- int badMember = 0;
- int i, j, interval;
-
- distances = getbytes(number*sizeof(int));
-
- for (i=0; i<number; i++) {
- // initialize total distance to zero
- distances[i] = 0;
- for (j=0; j<number; j++)
- if (j != i) {
- // get absolute value of interval size
- interval = abs(members[i] - members[j]);
- // make inversions of intervals equivalent
- if (interval > 6) interval = 12 - interval;
- // add absolute interval size to total
- distances[i] += interval;
- }
-
- // if this is the smallest total distance
- if (distances[i] < minDistance) {
- // remember it
- minDistance = distances[i];
- badMember = i;
- }
- }
- freebytes(distances, number * sizeof(int));
- x->x_pc[members[badMember]] = 0; // cancel out most dissonant member
- chord_chord_finder(x, number-1); // call chord finder again without it
- x->x_pc[members[badMember]] = 1; // replace most dissonant member
-}
-
-static void chord_chord_finder(t_chord *x, t_int num_pcs)
-{
- int i;
- x->x_chord_type = kNone;
- x->x_chord_root = kXX; /* none */
- switch (num_pcs) {
- case 1: chord_unison(x); break;
- case 2: chord_dyad(x); break;
- case 3: chord_triad(x); break;
- case 4: chord_quartad(x); break;
- case 5: chord_quintad(x); break;
- case 6: chord_sextad(x); break;
- default: x->x_chord_type = kChrom;
- for(i = 0; i < 12; i++) // 12 was num_pcs !?
- {
- if(x->x_pc[i])
- {
- x->x_chord_root = i;
- break;
- }
- }
- }
-}
-
-static void chord_float(t_chord *x, t_floatarg f)
-{
- t_int velo = x->x_velo;
- t_int allloc = 0;
- t_int num_pc = 0; /* number of pitch classes present */
- int i, j, k, l;
-
- x->x_pitch = (t_int)f;
-
- if(x->x_pitch <= x->x_split)
- {
- /* first we need to put the note into the allocation table */
- if(velo == 0) /* got note-off: remove from allocation table */
- {
- if(x->x_poly > 0)x->x_poly--; /* polyphony has decreased by one */
- for(i = 0; i < MAX_POLY; i++) /* search for voice allocation number */
- {
- /* search for corresponding alloc number */
- if(x->x_alloctable[i] == x->x_pitch)
- {
- x->x_alloctable[i] = -1; /* free the alloc number */
- break;
- }
- /* couldn't find it ? */
- if(i == MAX_POLY - 1)
- {
- post("chord: no corresponding note-on found (ignored)");
- return;
- }
- }
- return; /* no need to look for chord */
- }
- else /* we got a note-on message */
- {
- if(x->x_poly == MAX_POLY)
- {
- post("chord: too many note-on messages (ignored)");
- return;
- }
-
- x->x_poly++; /* number of currently playing notes has increased */
- /* assign a voice allocation number */
- for(i = 0; i < MAX_POLY; i++)
- {
- /* search for free alloc number */
- if(x->x_alloctable[i] == -1)
- {
- x->x_alloctable[i] = x->x_pitch; /* ... and store pitch */
- break;
- }
- }
- /* copy all notes into the pitch class array */
- for(i = 0; i < 12; i++)
- {
- x->x_pc[i] = 0; /* empty pitch class */
- x->x_abs_pc[i] = -1; /* empty absolute values */
- }
- for(i = 0; i < MAX_POLY; i++)
- {
- /* check for presence of pitch class */
- if(x->x_alloctable[i] != -1)
- {
- if(!x->x_pc[x->x_alloctable[i]%12]) /* a new pitch class */
- {
- x->x_abs_pc[x->x_alloctable[i]%12] = x->x_alloctable[i];
- }
- else if(x->x_abs_pc[x->x_alloctable[i]%12] > x->x_alloctable[i]) /* remember lowest pitch */
- {
- x->x_abs_pc[x->x_alloctable[i]%12] = x->x_alloctable[i];
- }
-
- x->x_pc[x->x_alloctable[i]%12] = 1; /* indicate presence of pc */
- }
- }
- /* count number of pitch classes */
- for(i = 0; i < 12; i++)
- {
- num_pc += x->x_pc[i];
- }
- // post("%d pitch classes", num_pc);
- }
- }
-
- chord_chord_finder(x, num_pc);
-}
-
-static void chord_ft1(t_chord *x, t_floatarg f)
-{
- x->x_velo = (t_int)f;
-}
-
-static t_class *chord_class;
-
-static void *chord_new(t_floatarg f)
-{
- int i;
- t_chord *x = (t_chord *)pd_new(chord_class);
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- x->x_outchordval = outlet_new(&x->x_ob, gensym("float"));
- x->x_outchordclass = outlet_new(&x->x_ob, gensym("float"));
- x->x_outchordname = outlet_new(&x->x_ob, gensym("symbol"));
- x->x_outchordinversion = outlet_new(&x->x_ob, gensym("float"));
- x->x_outchordnotes = outlet_new(&x->x_ob, gensym("float"));
-
- x->x_split = (t_int)f;
- if(x->x_split == 0)x->x_split = 128;
- for(i = 0; i < MAX_POLY; i++)x->x_alloctable[i] = -1;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void chord_setup(void)
-{
- chord_class = class_new(gensym("chord"), (t_newmethod)chord_new,
- 0, sizeof(t_chord), 0, A_DEFFLOAT, 0);
-#else
-void maxlib_chord_setup(void)
-{
- chord_class = class_new(gensym("maxlib_chord"), (t_newmethod)chord_new,
- 0, sizeof(t_chord), 0, A_DEFFLOAT, 0);
-#endif
- class_addfloat(chord_class, chord_float);
- class_addmethod(chord_class, (t_method)chord_ft1, gensym("ft1"), A_FLOAT, 0);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_addcreator((t_newmethod)chord_new, gensym("chord"), A_DEFFLOAT, 0);
- class_sethelpsymbol(chord_class, gensym("maxlib/chord-help.pd"));
-#endif
-}
-
+/* ------------------------- chord ------------------------------------------ */
+/* */
+/* Tries to detect a chord (or any harmonic relations) of incoming notes. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <string.h>
+#ifndef _WIN32
+#include <stdlib.h>
+#endif
+
+
+#define MAX_POLY 32 /* maximum number of notes played at a time */
+
+#define kUnison 0
+#define kMaj 1
+#define kMin 2
+#define kDim 3
+#define kAug 4
+#define kMaj7 5
+#define kDom7 6
+#define kMin7 7
+#define kHalfDim7 8
+#define kDim7 9
+#define kMinMaj7 10
+#define kMaj7s5 11
+#define kMaj7b5 12
+#define kDom7s5 13
+#define kDom7b5 14
+#define kDomb9 15
+#define kMaj9 16
+#define kDom9 17
+#define kMin9 18
+#define kHalfDim9 19
+#define kMinMaj9 20
+#define kDimMaj9 21
+#define kMaj9b5 22
+#define kDom9b5 23
+#define kDom9b13 24
+#define kMin9s11 25
+#define kmM9b11 26
+#define kMaj7b9 27
+#define kMaj7s5b9 28
+#define kDom7b9 29
+#define kMin7b9 30
+#define kMinb9s11 31
+#define kHalfDimb9 32
+#define kDim7b9 33
+#define kMinMajb9 34
+#define kDimMajb9 35
+#define kMaj7s9 36
+#define kDom7s9 37
+#define kMaj7s11 38
+#define kMs9s11 39
+#define kHDimb11 40
+#define kMaj11 41
+#define kDom11 42
+#define kMin11 43
+#define kHalfDim11 44
+#define kDim11 45
+#define kMinMaj11 46
+#define kDimMaj11 47
+#define kMaj11b5 48
+#define kMaj11s5 49
+#define kMaj11b9 50
+#define kMaj11s9 51
+#define kMaj11b13 52
+#define kMaj11s13 53
+#define kM11b5b9 54
+#define kDom11b5 55
+#define kDom11b9 56
+#define kDom11s9 57
+#define kHalfDim11b9 58
+#define kDom7s11 59
+#define kMin7s11 60
+#define kDom13s11 61
+#define kM7b913 62
+#define kMaj7s13 63
+#define kMaj9s13 64
+#define kM7b9s13 65
+#define kDom7b13 66
+#define kChrom 67
+#define kNone 68
+
+#define kXX -1
+
+
+static char *version = "chord v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+static char* pitch_class[13] = {"C ", "Db ", "D ", "Eb ", "E ", "F ", "Gb ", "G ", "Ab ", "A ", "Bb ", "B ", "no root "};
+static char name_class[7] = {'C', 'D', 'E', 'F', 'G', 'A', 'B'};
+
+typedef struct {
+ int type;
+ int rootMember;
+} t_type_root;
+
+typedef struct chord
+{
+ t_object x_ob;
+ t_outlet *x_outchordval; /* chord as MIDI note number of base note */
+ t_outlet *x_outchordclass; /* class of chord's bass note */
+ t_outlet *x_outchordname; /* chord name, e.g. "Cmajor7" */
+ t_outlet *x_outchordinversion; /* inversion of the chord (root = 0, 1st = 1, 2nd = 2) */
+ t_outlet *x_outchordnotes; /* list with note numbers belonging to the chord */
+
+ t_int x_pitch;
+ t_int x_pc[12]; /* pitch class array */
+ t_int x_abs_pc[12]; /* pitch class array: absolute MIDI note numbers */
+ t_int x_velo;
+ t_int x_alloctable[MAX_POLY]; /* a table used to store all playing notes */
+ t_int x_poly; /* number of notes currently playing */
+ t_atom x_chordlist[12]; /* list that stores the note numbers for output */
+ t_int x_split; /* highes note number to process */
+
+ t_int x_chord_type; /* chord's type (number between 0 and 68) */
+ t_int x_chord_root; /* chord's root (pitch class) */
+ t_int x_chord_bass; /* chord's bass note (MIDI note number) */
+ t_int x_chord_inversion; /* chord's state of inversion (root, 1st, 2nd) */
+
+} t_chord;
+
+/* functions */
+static void chord_kick_out_member(t_chord *x, t_int number, t_int *members);
+static void chord_chord_finder(t_chord *x, t_int num_pcs);
+static void chord_draw_chord_type(t_chord *x, t_int num_pcs);
+
+
+static void chord_unison(t_chord *x)
+{
+ int i;
+ int member = 0;
+ for(i = 0; i < 12; i++)
+ if(x->x_pc[i])
+ {
+ member = i; // find pitch class
+ break;
+ }
+ x->x_chord_type = 0;
+ x->x_chord_root = member;
+ chord_draw_chord_type(x, 1); // output onto the screen
+}
+
+static void chord_dyad(t_chord *x)
+{
+ static t_type_root dyads[11] =
+ {{ kMaj7, 1 }, { kDom7, 1 }, { kMin, 0 }, { kMaj, 0 }, { kMaj, 1 },
+ { kDom7 , 0 }, { kMaj, 0 }, { kMaj, 1 }, { kMin, 1 }, { kDom7, 0 }, { kMaj7, 0 }};
+ register t_type_root* t;
+
+ int members[2];
+ int i, j = 0;
+ int interval1;
+
+ for(i = 0; i < 12; i++)
+ if(x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */
+ interval1 = members[1] - members[0]; /* calculate interval between first two members */
+ interval1 = interval1 - 1; /* reduce interval1 to start at zero */
+ t = &(dyads[interval1]); /* find TypeRoot struct for this interval */
+ x->x_chord_type = t->type;
+ if (interval1 == 5)
+ x->x_chord_root = (members[0]+8)%12;
+ else
+ x->x_chord_root = members[t->rootMember];
+ x->x_chord_inversion = t->rootMember; /* get state of inversion */
+ chord_draw_chord_type(x, 2); /* output results */
+}
+
+static void chord_triad(t_chord *x)
+{
+ static t_type_root triads[10][10] =
+ {/* interval1 is a half step */
+ {{ kMaj7b9, 1 }, { kMaj9, 1 }, { kMinMaj7, 1 }, { kMaj7, 1 }, { kDom7s11,2 },
+ { kDomb9 , 0 }, { kMaj7, 1 }, { kMaj7s5, 1 }, { kMin9, 2 }, { kMaj7b9, 0 }},
+ /* interval1 is a whole step */
+ {{ kMin9, 0 }, { kDom9, 0 }, { kMin7, 1 }, { kDom7, 1 }, { kDom9, 0 },
+ { kHalfDim7, 1 }, { kDom7, 1 }, { kDom9, 0 }, { kMaj9, 0 }},
+ /* interval1 is a minor third */
+ {{ kMaj7s5, 2 }, { kDom7, 2 }, { kDim, 0 }, { kMin, 0 }, { kMaj, 2 },
+ { kDim, 2 }, { kMin7, 0 }, { kMinMaj7, 0 }},
+ /* interval1 is a major third */
+ {{ kMaj7, 2 }, { kHalfDim7, 2 }, { kMaj, 0 }, { kAug, 0 }, { kMin, 2 },
+ { kDom7, 0 }, { kMaj7, 0 }},
+ /* interval1 is a perfect fourth */
+ {{ kDomb9, 1 }, { kDom9, 1 }, { kMin, 1 }, { kMaj, 1 }, { kDom9, 2 },
+ { kDom7s11, 1 }},
+ /* interval1 is an augmented fourth */
+ {{ kDom7s11, 0 }, { kDom7, 2 }, { kDim, 1 }, { kHalfDim7, 0 }, { kDomb9, 2 }},
+ /* interval1 is a perfect fifth */
+ {{ kMaj7, 2 }, { kMin7, 2 }, { kDom7, 0 }, { kMaj7, 0 }},
+ /* interval1 is a minor sixth */
+ {{ kMinMaj7, 2 }, { kDom9, 1 }, { kMaj7s5, 0 }},
+ /* interval1 is a major sixth */
+ {{ kMaj9, 2 }, { kMin9, 1 }},
+ /* interval1 is a minor seventh */
+ {{ kMaj7b9, 2 }}
+ };
+ register t_type_root* t;
+
+ int members[3];
+ int i, j = 0;
+ int interval1, interval2;
+
+ for(i = 0; i < 12; i++)
+ if(x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */
+ interval1 = members[1] - members[0]; /* calculate interval between first two members */
+ interval2 = members[2] - members[0]; /* calculate interval between first and third */
+ interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */
+ interval1 = interval1 - 1; /* reduce interval1 to start at zero */
+ t = &(triads[interval1][interval2]); /* find TypeRoot struct for this interval vector */
+ x->x_chord_type = t->type;
+ x->x_chord_root = members[t->rootMember];
+ switch(t->rootMember) { /* get state of inversion */
+ case 0:
+ x->x_chord_inversion = 0;
+ break;
+ case 1:
+ x->x_chord_inversion = 2;
+ break;
+ case 2:
+ x->x_chord_inversion = 1;
+ }
+ chord_draw_chord_type(x, 3); /* output onto the screen */
+}
+
+static void chord_quartad(t_chord *x)
+{
+ static t_type_root quartads[9][9][9] =
+ {
+ {/* interval1 is a half step */
+ {/* interval2 is a whole step */
+ { kM7b9s13, 2 }, { kMinMajb9,1 }, { kMaj7b9, 1 }, { kMaj7s13, 2 }, { kDimMajb9, 1 },
+ { kMaj7b9, 1 }, { kMaj7s13, 2 }, { kM7b913, 1 }, { kM7b9s13, 1 }},
+ {/* interval2 is a minor third */
+ { kMinMaj9, 1 }, { kMaj9, 1 }, { kHalfDimb9,0 }, { kMin7b9, 0 }, { kMaj9, 1 },
+ { kDim7b9, 0 }, { kMin7b9, 0 }, { kMinMajb9, 0 }},
+ {/* interval2 is a major third */
+ { kMaj7s9, 1 }, { kDom7s11, 3 }, { kDomb9, 0 }, { kMinMaj7, 1 }, { kDom7s9, 3 },
+ { kDomb9, 0 }, { kMaj7b9, 0 }},
+ {/* interval2 is a perfect fourth */
+ { kMaj11, 1 }, { kMaj7b5, 1 }, { kMaj7, 1 }, { kMaj7s5, 1 }, { kMin9, 3 },
+ { kMaj7s13, 1 }},
+ {/* interval2 is a tritone */
+ { kDimMaj9, 3 }, { kDom11, 3 }, { kDim7b9, 0 }, { kHalfDimb9,0 }, { kDimMajb9, 0 }},
+ {/* interval2 is a perfect fifth */
+ { kMaj11, 3 }, { kDom7s9, 3 }, { kDomb9, 0 }, { kMaj7b9, 0 }},
+ {/* interval2 is a minor sixth */
+ { kMaj7s9, 3 }, { kMin9, 3 }, { kMaj7s13, 1 }},
+ {/* interval2 is a major sixth */
+ { kMinMaj9, 3 }, { kM7b913, 0 }},
+ {/* interval2 is a minor seventh */
+ { kM7b9s13, 0 }}
+ },
+ {/* interval1 is a whole step */
+ {/* interval2 is a minor third */
+ { kM7b913, 2 }, { kMin7b9, 1 }, { kDomb9, 1 }, { kMin9, 0 }, { kHalfDimb9,1 },
+ { kDomb9, 1 }, { kMin9, 0 }, { kMinMaj9, 0 }},
+ {/* interval2 is a major third */
+ { kMin9, 1 }, { kDom9, 1 }, { kDom9, 0 }, { kDom7s5, 2 }, { kDom9, 1 },
+ { kDom9, 0 }, { kMaj9, 0 }},
+ {/* interval2 is a perfect fourth */
+ { kDom7s9, 1 }, { kDom11, 3 }, { kHalfDim7, 1 }, { kMin7, 1 }, { kDom9, 3 },
+ { kHalfDimb9,3 }},
+ {/* interval2 is a tritone */
+ { kDom11, 1 }, { kDom7b5, 3 }, { kDom7, 1 }, { kDom7s5, 1 }, { kMin7b9, 3 }},
+ {/* interval2 is a perfect fifth */
+ { kMaj7b5, 3 }, { kDom11, 1 }, { kDom9, 0 }, { kMaj9, 0 }},
+ {/* interval2 is a minor sixth */
+ { kDom7s11, 1 }, { kDom9, 3 }, { kDim7b9, 3 }},
+ {/* interval2 is a major sixth */
+ { kMaj9, 3 }, { kMin7b9, 3 }},
+ {/* interval2 is a minor seventh */
+ { kMinMajb9, 3 }}
+ },
+ {/* interval1 is a minor third */
+ {/* interval2 is a major third */
+ { kMaj7s13, 3 }, { kDim7b9, 1 }, { kDom7s9, 0 }, { kMaj7s5, 2 }, { kDim7b9, 1 },
+ { kDom7s9, 0 }, { kMaj7s9, 0 }},
+ {/* interval2 is a perfect fourth */
+ { kDomb9, 2 }, { kDom9, 2 }, { kMin7, 2 }, { kDom7, 2 }, { kDom11, 2 },
+ { kDom7s11, 2 }},
+ {/* interval2 is a tritone */
+ { kDim7b9, 2 }, { kDom7, 3 }, { kDim7, 0 }, { kHalfDim7, 0 }, { kDomb9, 3 }},
+ {/* interval2 is a perfect fifth */
+ { kMaj7, 3 }, { kHalfDim7,3 }, { kMin7, 0 }, { kMinMaj7, 0 }},
+ {/* interval2 is a minor sixth */
+ { kDomb9, 2 }, { kDom9, 2 }, { kDom7s9, 2 }},
+ {/* interval2 is a major sixth */
+ { kHalfDimb9,2 }, { kDomb9, 3 }},
+ {/* interval2 is a minor seventh */
+ { kMaj7b9, 3 }}
+ },
+ {/* interval1 is a major third */
+ {/* interval2 is a perfect fourth */
+ { kMaj7b9, 2 }, { kMaj9, 2 }, { kMinMaj7, 2 }, { kMaj7, 2 }, { kDom11, 0 },
+ { kMaj11, 0 }},
+ {/* interval2 is a tritone */
+ { kHalfDimb9,2 }, { kDom7s5, 3 }, { kHalfDim7, 2 }, { kDom7b5, 0 }, { kMaj7b5, 0 }},
+ {/* interval2 is a perfect fifth */
+ { kMaj7s5, 3 }, { kMin7, 3 }, { kDom7, 0 }, { kMaj7, 0 }},
+ {/* interval2 is a minor sixth */
+ { kMinMaj7, 3 }, { kDom7s5, 0 }, { kMaj7s5, 0 }},
+ {/* interval2 is a major sixth */
+ { kMin7b9, 2 }, { kMin9, 2 }},
+ {/* interval2 is a minor seventh */
+ { kMaj7s13, 0 }}
+ },
+ {/* interval1 is a perfect fourth */
+ {/* interval2 is a tritone */
+ { kDimMajb9, 2 }, { kMin7b9, 1 }, { kDomb9, 1 }, { kMaj7b5, 2 }, { kDimMaj9, 0 }},
+ {/* interval2 is a perfect fifth */
+ { kMin9, 1 }, { kDom9, 1 }, { kDom11, 0 }, { kDom11, 2 }},
+ {/* interval2 is a minor sixth */
+ { kDom7s9, 1 }, { kDom9, 3 }, { kDim7b9, 3 }},
+ {/* interval2 is a major sixth */
+ { kMaj9, 3 }, { kHalfDimb9,3 }},
+ {/* interval2 is a minor seventh */
+ { kDimMajb9, 3 }}
+ },
+ {/* interval1 is a tritone */
+ {/* interval2 is a perfect fifth */
+ { kMaj7s13, 3 }, { kHalfDimb9,1 }, { kDom7s11, 0 }, { kMaj11, 2 }},
+ {/* interval2 is a minor sixth */
+ { kDomb9, 2 }, { kDom9, 2 }, { kDom7s9, 2 }},
+ {/* interval2 is a major sixth */
+ { kDim7b9, 2 }, { kDomb9, 3 }},
+ {/* interval2 is a minor seventh */
+ { kMaj7b9, 3 }}
+ },
+ {/* interval1 is a perfect fifth */
+ {/* interval2 is a minor sixth */
+ { kMaj7b9, 2 }, { kMaj9, 2 }, { kMaj7s9, 2 }},
+ {/* interval2 is a major sixth */
+ { kMin7b9, 2 }, { kMin9, 2 }},
+ {/* interval2 is a minor seventh */
+ { kMaj7s13, 0 }}
+ },
+ {/* interval1 is a minor sixth */
+ {/* interval2 is a major sixth */
+ { kMinMajb9, 2 }, { kMinMaj9, 2 }},
+ {/* interval2 is a minor seventh */
+ { kM7b913, 3 }}
+ },
+ {/* interval1 is a major sixth */
+ {/* interval2 is a minor seventh */
+ { kM7b9s13, 2 }}
+ }
+ };
+
+ register t_type_root* t;
+
+ int members[4];
+ int interval1, interval2, interval3;
+ int i, j = 0;
+ for (i=0; i<12; i++)
+ if (x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */
+ interval1 = members[1] - members[0]; /* calculate interval between first two members */
+ interval2 = members[2] - members[0]; /* calculate interval between first and third */
+ interval3 = members[3] - members[0]; /* calculate interval between first and third */
+ interval3 = interval3 - interval2 - 1; /* reduce interval3 to start at zero */
+ interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */
+ interval1 = interval1 - 1; /* reduce interval1 to start at zero */
+
+ /* find TypeRoot struct for this interval set */
+ t = &(quartads[interval1][interval2][interval3]);
+ x->x_chord_type = t->type;
+ x->x_chord_root = members[t->rootMember];
+ switch(t->rootMember) { /* get state of inversion */
+ case 0:
+ x->x_chord_inversion = 0;
+ break;
+ case 1:
+ x->x_chord_inversion = 2;
+ break;
+ case 2:
+ x->x_chord_inversion = 2;
+ break;
+ case 3:
+ x->x_chord_inversion = 1;
+ }
+ chord_draw_chord_type(x, 4); /* output results */
+}
+
+static void chord_fatal_error(char* s1, char* s2)
+{
+ post("chord: error: %s : %s", s1, s2);
+}
+
+static void chord_quintad(t_chord *x)
+{
+ static int initialized = 0;
+ static t_type_root quintads[8][8][8][8];
+ register int i, j, k, l;
+ register t_type_root *t;
+ t_int members[5];
+ int interval1, interval2, interval3, interval4;
+ int *st;
+ int maj9[5][4] = {{1,1,2,3}, {0,1,1,2}, {3,0,1,1}, {2,3,0,1}, {1,2,3,0}};
+ int dom9[5][4] = {{1,1,2,2}, {1,1,1,2}, {2,1,1,1}, {2,2,1,1}, {1,2,2,1}};
+ int min9[5][4] = {{1,0,3,2}, {1,1,0,3}, {2,1,1,0}, {3,2,1,1}, {0,3,2,1}};
+ int had9[5][4] = {{1,0,2,3}, {1,1,0,2}, {3,1,1,0}, {2,3,1,1}, {0,2,3,1}};
+ int miM9[5][4] = {{1,0,3,3}, {0,1,0,3}, {3,0,1,0}, {3,3,0,1}, {0,3,3,0}};
+ int diM9[5][4] = {{1,0,2,4}, {0,1,0,2}, {4,0,1,0}, {2,4,0,1}, {0,2,4,0}};
+ int M9b5[5][4] = {{1,1,1,4}, {0,1,1,1}, {4,0,1,1}, {1,4,0,1}, {1,1,4,0}};
+ int D9b5[5][4] = {{1,1,1,3}, {1,1,1,1}, {3,1,1,1}, {1,3,1,1}, {1,1,3,1}};
+ int mM91[5][4] = {{1,0,0,6}, {0,1,0,0}, {6,0,1,0}, {0,6,0,1}, {0,0,6,0}};
+ int M7b9[5][4] = {{0,2,2,3}, {0,0,2,2}, {3,0,0,2}, {2,3,0,0}, {2,2,3,0}};
+ int M5b9[5][4] = {{0,2,3,2}, {0,0,2,3}, {2,0,0,2}, {3,2,0,0}, {2,3,2,0}};
+ int D7b9[5][4] = {{0,2,2,2}, {1,0,2,2}, {2,1,0,2}, {2,2,1,0}, {2,2,2,1}};
+ int m7b9[5][4] = {{0,1,3,2}, {1,0,1,3}, {2,1,0,1}, {3,2,1,0}, {1,3,2,1}};
+ int mb51[5][4] = {{0,1,2,0}, {4,0,1,2}, {0,4,0,1}, {2,0,4,0}, {1,2,0,4}};
+ int d7b9[5][4] = {{0,1,2,3}, {1,0,1,2}, {3,1,0,1}, {2,3,1,0}, {1,2,3,1}};
+ int mMb9[5][4] = {{0,1,3,3}, {0,0,1,3}, {3,0,0,1}, {3,3,0,0}, {1,3,3,0}};
+ int dMb9[5][4] = {{0,1,2,4}, {0,0,1,2}, {4,0,0,1}, {2,4,0,0}, {1,2,4,0}};
+ int dib9[5][4] = {{0,1,2,2}, {2,0,1,2}, {2,2,0,1}, {2,2,2,0}, {1,2,2,2}};
+ int M7s9[5][4] = {{2,0,2,3}, {0,2,0,2}, {3,0,2,0}, {2,3,0,2}, {0,2,3,0}};
+ int D7s9[5][4] = {{2,0,2,2}, {1,2,0,2}, {2,1,2,0}, {2,2,1,2}, {0,2,2,1}};
+ int M7s1[5][4] = {{3,1,0,3}, {0,3,1,0}, {3,0,3,1}, {0,3,0,3}, {1,0,3,0}};
+ int d9b3[5][4] = {{1,1,2,0}, {3,1,1,2}, {0,3,1,1}, {2,0,3,1}, {1,2,0,3}};
+ int M9s3[5][4] = {{1,4,2,0}, {0,1,4,2}, {0,0,1,4}, {2,0,0,1}, {4,2,0,0}};
+ int M9st[5][4] = {{1,1,5,0}, {0,1,1,5}, {0,0,1,1}, {5,0,0,1}, {1,5,0,0}};
+ int s9s1[5][4] = {{2,0,1,0}, {4,2,0,1}, {0,4,2,0}, {1,0,4,2}, {0,1,0,4}};
+ int h7b1[5][4] = {{2,0,1,3}, {1,2,0,1}, {3,1,2,0}, {1,3,1,2}, {0,1,3,1}};
+ int M711[5][4] = {{3,0,1,3}, {0,3,0,1}, {3,0,3,0}, {1,3,0,3}, {0,1,3,0}};
+ int M115[5][4] = {{1,1,0,5}, {0,1,1,0}, {5,0,1,1}, {0,5,0,1}, {1,0,5,0}};
+ int d711[5][4] = {{3,0,1,2}, {1,3,0,1}, {2,1,3,0}, {1,2,1,3}, {0,1,2,1}};
+ int d712[5][4] = {{1,1,0,1}, {4,1,1,0}, {1,4,1,1}, {0,1,4,1}, {1,0,1,4}};
+ int d713[5][4] = {{1,1,0,4}, {1,1,1,0}, {4,1,1,1}, {0,4,1,1}, {1,0,4,1}};
+ int m711[5][4] = {{2,1,1,2}, {1,2,1,1}, {2,1,2,1}, {1,2,1,2}, {1,1,2,1}};
+ int m712[5][4] = {{1,0,1,1}, {4,1,0,1}, {1,4,1,0}, {1,1,4,1}, {0,1,1,4}};
+ int di11[5][4] = {{1,0,1,0}, {5,1,0,1}, {0,5,1,0}, {1,0,5,1}, {0,1,0,5}};
+ int mM11[5][4] = {{2,1,1,3}, {0,2,1,1}, {3,0,2,1}, {1,3,0,2}, {1,1,3,0}};
+ int dM11[5][4] = {{2,1,0,4}, {0,2,1,0}, {4,0,2,1}, {0,4,0,2}, {1,0,4,0}};
+ int Meb5[5][4] = {{3,0,0,4}, {0,3,0,0}, {4,0,3,0}, {0,4,0,3}, {0,0,4,0}};
+ int Mes5[5][4] = {{3,0,2,2}, {0,3,0,2}, {2,0,3,0}, {2,2,0,3}, {0,2,2,0}};
+ int Meb9[5][4] = {{0,2,0,5}, {0,0,2,0}, {5,0,0,2}, {0,5,0,0}, {2,0,5,0}};
+ int Mes9[5][4] = {{2,0,0,5}, {0,2,0,0}, {5,0,2,0}, {0,5,0,2}, {0,0,5,0}};
+ int Deb5[5][4] = {{3,0,0,3}, {1,3,0,0}, {3,1,3,0}, {0,3,1,3}, {0,0,3,1}};
+ int Mes3[5][4] = {{3,0,4,0}, {0,3,0,4}, {0,0,3,0}, {4,0,0,3}, {0,4,0,0}};
+ int Deb9[5][4] = {{0,2,0,4}, {1,0,2,0}, {4,1,0,2}, {0,4,1,0}, {2,0,4,1}};
+ int De91[5][4] = {{0,2,0,1}, {4,0,2,0}, {1,4,0,2}, {0,1,4,0}, {2,0,1,4}};
+ int Des9[5][4] = {{2,0,0,4}, {1,2,0,0}, {4,1,2,0}, {0,4,1,2}, {0,0,4,1}};
+ int Ds11[5][4] = {{3,1,0,2}, {1,3,1,0}, {2,1,3,1}, {0,2,1,3}, {1,0,2,1}};
+ int m7s1[5][4] = {{2,2,0,2}, {1,2,2,0}, {2,1,2,2}, {0,2,1,2}, {2,0,2,1}};
+ int D3s1[5][4] = {{5,0,1,0}, {1,5,0,1}, {0,1,5,0}, {1,0,1,5}, {0,1,0,1}};
+ int Mb9s[5][4] = {{0,2,5,0}, {0,0,2,5}, {0,0,0,2}, {5,0,0,0}, {2,5,0,0}};
+ int D7b3[5][4] = {{3,2,0,1}, {1,3,2,0}, {1,1,3,2}, {0,1,1,3}, {2,0,1,1}};
+
+ if (!initialized) {
+ for (i=0; i<8; i++)
+ for (j=0; j<8; j++)
+ for (k=0; k<8; k++)
+ for (l=0; l<8; l++) {
+ quintads[i][j][k][l].type = kNone;
+ quintads[i][j][k][l].rootMember = kXX;
+ }
+
+
+ // major ninths
+ for (i=0; i<5; i++) {
+ st = maj9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ t->type = kMaj9;
+ t->rootMember = i;
+ }
+
+ // dominant ninths
+ for (i=0; i<5; i++) {
+ st = dom9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "dom9");
+ t->type = kDom9;
+ t->rootMember = i;
+ }
+
+ // minor ninths
+ for (i=0; i<5; i++) {
+ st = min9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "min9");
+ t->type = kMin9;
+ t->rootMember = i;
+ }
+
+ // half diminished ninths
+ for (i=0; i<5; i++) {
+ st = had9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "had9");
+ t->type = kHalfDim9;
+ t->rootMember = i;
+ }
+
+ // minor/major ninths
+ for (i=0; i<5; i++) {
+ st = miM9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "miM9");
+ t->type = kMinMaj9;
+ t->rootMember = i;
+ }
+
+ // diminished/major ninths
+ for (i=0; i<5; i++) {
+ st = diM9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "diM9");
+ t->type = kDimMaj9;
+ t->rootMember = i;
+ }
+
+ // major ninth flat 5
+ for (i=0; i<5; i++) {
+ st = M9b5[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M9b5");
+ t->type = kMaj9b5;
+ t->rootMember = i;
+ }
+
+ // dominant ninth flat 5
+ for (i=0; i<5; i++) {
+ st = D9b5[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "D9b5");
+ t->type = kDom9b5;
+ t->rootMember = i;
+ }
+
+ // minor/major ninth flat 11
+ for (i=0; i<5; i++) {
+ st = mM91[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "mM91");
+ t->type = kmM9b11;
+ t->rootMember = i;
+ }
+
+ // major seventh flat nine
+ for (i=0; i<5; i++) {
+ st = M7b9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M7b9");
+ t->type = kMaj7b9;
+ t->rootMember = i;
+ }
+
+ // major seventh sharp five flat nine
+ for (i=0; i<5; i++) {
+ st = M5b9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M5b9");
+ t->type = kMaj7s5b9;
+ t->rootMember = i;
+ }
+
+ // dominant seventh flat nine
+ for (i=0; i<5; i++) {
+ st = D7b9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "D7b9");
+ t->type = kDom7b9;
+ t->rootMember = i;
+ }
+
+ // minor seventh flat nine
+ for (i=0; i<5; i++) {
+ t = &(quintads[m7b9[i][0]][m7b9[i][1]][m7b9[i][2]][m7b9[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "m7b9");
+ t->type = kMin7b9;
+ t->rootMember = i;
+ }
+
+ // minor flat nine sharp eleventh
+ for (i=0; i<5; i++) {
+ st = mb51[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "mb51");
+ t->type = kMinb9s11;
+ t->rootMember = i;
+ }
+
+ // half diminished seventh flat nine
+ for (i=0; i<5; i++) {
+ st = d7b9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "d7b9");
+ t->type = kHalfDimb9;
+ t->rootMember = i;
+ }
+
+ // minor/major seventh flat nine
+ for (i=0; i<5; i++) {
+ st = mMb9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "mMb9");
+ t->type = kMinMajb9;
+ t->rootMember = i;
+ }
+
+ // diminished major seventh flat nine
+ for (i=0; i<5; i++) {
+ st = dMb9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "dMb9");
+ t->type = kDimMajb9;
+ t->rootMember = i;
+ }
+
+ // diminished seventh flat nine
+ for (i=0; i<5; i++) {
+ t = &(quintads[dib9[i][0]][dib9[i][1]][dib9[i][2]][dib9[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "dib9");
+ t->type = kDim7b9;
+ t->rootMember = i;
+ }
+
+ // major seventh sharp nine
+ for (i=0; i<5; i++) {
+ t = &(quintads[M7s9[i][0]][M7s9[i][1]][M7s9[i][2]][M7s9[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M7s9");
+ t->type = kMaj7s9;
+ t->rootMember = i;
+ }
+
+ // dominant seventh sharp nine
+ for (i=0; i<5; i++) {
+ t = &(quintads[D7s9[i][0]][D7s9[i][1]][D7s9[i][2]][D7s9[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "D7s9");
+ t->type = kDom7s9;
+ t->rootMember = i;
+ }
+
+ // major seventh sharp eleventh
+ for (i=0; i<5; i++) {
+ t = &(quintads[M7s1[i][0]][M7s1[i][1]][M7s1[i][2]][M7s1[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M7s1");
+ t->type = kMaj7s11;
+ t->rootMember = i;
+ }
+
+ // dominant ninth flat thirteenth
+ for (i=0; i<5; i++) {
+ st = d9b3[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "d9b3");
+ t->type = kDom9b13;
+ t->rootMember = i;
+ }
+
+ // major ninth sharp thirteenth
+ for (i=0; i<5; i++) {
+ st = M9s3[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M9s3");
+ t->type = kMaj9s13;
+ t->rootMember = i;
+ }
+
+ // major ninth sharp thirteenth
+ for (i=0; i<5; i++) {
+ t = &(quintads[M9st[i][0]][M9st[i][1]][M9st[i][2]][M9st[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M9st");
+ t->type = kMaj9s13;
+ t->rootMember = i;
+ }
+
+ // major chord sharp ninth sharp eleventh
+ for (i=0; i<5; i++) {
+ st = s9s1[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "s9s1");
+ t->type = kMs9s11;
+ t->rootMember = i;
+ }
+
+ // half diminished seven flat 11
+ for (i=0; i<5; i++) {
+ st = h7b1[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "h7b1");
+ t->type = kHDimb11;
+ t->rootMember = i;
+ }
+
+ // major eleventh
+ for (i=0; i<5; i++) {
+ t = &(quintads[M711[i][0]][M711[i][1]][M711[i][2]][M711[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M711");
+ t->type = kMaj11;
+ t->rootMember = i;
+ }
+
+ // major eleventh
+ for (i=0; i<5; i++) {
+ t = &(quintads[M115[i][0]][M115[i][1]][M115[i][2]][M115[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M711");
+ t->type = kMaj11;
+ t->rootMember = i;
+ }
+
+ // dominant eleventh
+ for (i=0; i<5; i++) {
+ t = &(quintads[d711[i][0]][d711[i][1]][d711[i][2]][d711[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "d711");
+ t->type = kDom11;
+ t->rootMember = i;
+ }
+
+ // dominant eleventh
+ for (i=0; i<5; i++) {
+ t = &(quintads[d712[i][0]][d712[i][1]][d712[i][2]][d712[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "d712");
+ t->type = kDom11;
+ t->rootMember = i;
+ }
+
+ // dominant eleventh
+ for (i=0; i<5; i++) {
+ st = d713[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "d713");
+ t->type = kDom11;
+ t->rootMember = i;
+ }
+
+ // minor eleventh
+ for (i=0; i<5; i++) {
+ t = &(quintads[m711[i][0]][m711[i][1]][m711[i][2]][m711[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "m711");
+ t->type = kMin11;
+ t->rootMember = i;
+ }
+
+ // minor eleventh
+ for (i=0; i<5; i++) {
+ t = &(quintads[m712[i][0]][m712[i][1]][m712[i][2]][m712[i][3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "m712");
+ t->type = kMin11;
+ t->rootMember = i;
+ }
+
+ // diminished eleventh
+ for (i=0; i<5; i++) {
+ st = di11[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "di11");
+ t->type = kDim11;
+ t->rootMember = i;
+ }
+
+ // minor/major eleventh
+ for (i=0; i<5; i++) {
+ st = mM11[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "mM11");
+ t->type = kMinMaj11;
+ t->rootMember = i;
+ }
+
+ // diminished major eleventh
+ for (i=0; i<5; i++) {
+ st = dM11[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "dM11");
+ t->type = kDimMaj11;
+ t->rootMember = i;
+ }
+
+ // major eleventh flat fifth
+ for (i=0; i<5; i++) {
+ st = Meb5[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "Meb5");
+ t->type = kMaj11b5;
+ t->rootMember = i;
+ }
+
+ // major eleventh sharp fifth
+ for (i=0; i<5; i++) {
+ st = Mes5[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "Mes5");
+ t->type = kMaj11s5;
+ t->rootMember = i;
+ }
+
+ // major eleventh flat ninth
+ for (i=0; i<5; i++) {
+ st = Meb9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "Meb9");
+ t->type = kMaj11b9;
+ t->rootMember = i;
+ }
+
+ // major eleventh sharp ninth
+ for (i=0; i<5; i++) {
+ st = Mes9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "Mes9");
+ t->type = kMaj11s9;
+ t->rootMember = i;
+ }
+
+ // major eleventh sharp thirteenth
+ for (i=0; i<5; i++) {
+ st = Mes3[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "Mes3");
+ t->type = kMaj11s13;
+ t->rootMember = i;
+ }
+
+ // dominant eleventh flat fifth
+ for (i=0; i<5; i++) {
+ st = Deb5[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "Deb5");
+ t->type = kDom11b5;
+ t->rootMember = i;
+ }
+
+ // dominant eleventh flat ninth
+ for (i=0; i<5; i++) {
+ st = Deb9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "Deb9");
+ t->type = kDom11b9;
+ t->rootMember = i;
+ }
+
+ // dominant eleventh flat ninth
+ for (i=0; i<5; i++) {
+ st = De91[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "De91");
+ t->type = kDom11b9;
+ t->rootMember = i;
+ }
+
+ // dominant eleventh sharp ninth
+ for (i=0; i<5; i++) {
+ st = Des9[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "Des9");
+ t->type = kDom11s9;
+ t->rootMember = i;
+ }
+
+ // dominant seventh sharp eleventh
+ for (i=0; i<5; i++) {
+ st = Ds11[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "Ds11");
+ t->type = kDom7s11;
+ t->rootMember = i;
+ }
+
+ // minor seventh sharp eleventh
+ for (i=0; i<5; i++) {
+ st = m7s1[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "m7s1");
+ t->type = kMin7s11;
+ t->rootMember = i;
+ }
+
+ // dominant thirteenth sharp eleventh
+ for (i=0; i<5; i++) {
+ st = D3s1[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "D3s1");
+ t->type = kDom13s11;
+ t->rootMember = i;
+ }
+
+ // major seventh flat ninth sharp thirteenth
+ for (i=0; i<5; i++) {
+ st = Mb9s[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "Mb9s");
+ t->type = kM7b9s13;
+ t->rootMember = i;
+ }
+
+ // dominant seventh flat thirteenth
+ for (i=0; i<5; i++) {
+ st = D7b3[i];
+ t = &(quintads[st[0]][st[1]][st[2]][st[3]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "D7b3");
+ t->type = kDom7b13;
+ t->rootMember = i;
+ }
+
+ initialized = 1;
+ return;
+ }
+
+ j = 0;
+ for (i=0; i<12; i++)
+ if (x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */
+ interval1 = members[1] - members[0]; /* calculate interval between first two members */
+ interval2 = members[2] - members[0]; /* calculate interval between first and third */
+ interval3 = members[3] - members[0]; /* calculate interval between first and third */
+ interval4 = members[4] - members[0]; /* calculate interval between first and fourth */
+ interval4 = interval4 - interval3 - 1; /* reduce interval4 to start at zero */
+ interval3 = interval3 - interval2 - 1; /* reduce interval3 to start at zero */
+ interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */
+ interval1 = interval1 - 1; /* reduce interval1 to start at zero */
+
+ // find TypeRoot struct for this interval set
+ t = &(quintads[interval1][interval2][interval3][interval4]);
+ if (t->rootMember != kXX)
+ {
+ x->x_chord_type = t->type;
+ x->x_chord_root = members[t->rootMember];
+ switch(t->rootMember) { /* get state of inversion */
+ case 0:
+ x->x_chord_inversion = 0;
+ break;
+ case 1:
+ x->x_chord_inversion = 2;
+ break;
+ case 2:
+ x->x_chord_inversion = 2;
+ break;
+ case 3:
+ x->x_chord_inversion = 2;
+ break;
+ case 4:
+ x->x_chord_inversion = 1;
+ }
+ chord_draw_chord_type(x, 5); /* output result */
+ } else
+ chord_kick_out_member(x, 5, members);
+}
+
+static void chord_sextad(t_chord *x)
+{
+ static int initialized = 0;
+ static t_type_root sextads[7][7][7][7][7];
+ register int i, j, k, l, m;
+ register t_type_root *t;
+ register int* st;
+ t_int members[6];
+ int interval1, interval2, interval3, interval4, interval5;
+
+ int D9b3[6][5] =
+ {{1,1,2,0,1}, {1,1,1,2,0}, {1,1,1,1,2}, {0,1,1,1,1}, {2,0,1,1,1}, {1,2,0,1,1}};
+ int m9s1[6][5] =
+ {{1,0,2,0,2}, {1,1,0,2,0}, {2,1,1,0,2}, {0,2,1,1,0}, {2,0,2,1,1}, {0,2,0,2,1}};
+ int M711[6][5] =
+ {{1,1,0,1,3}, {0,1,1,0,1}, {3,0,1,1,0}, {1,3,0,1,1}, {0,1,3,0,1}, {1,0,1,3,0}};
+ int D711[6][5] =
+ {{1,1,0,1,2}, {1,1,1,0,1}, {2,1,1,1,0}, {1,2,1,1,1}, {0,1,2,1,1}, {1,0,1,2,1}};
+ int hd11[6][5] =
+ {{1,0,1,0,3}, {1,1,0,1,0}, {3,1,1,0,1}, {0,3,1,1,0}, {1,0,3,1,1}, {0,1,0,3,1}};
+ int M1b5[6][5] =
+ {{1,1,0,0,4}, {0,1,1,0,0}, {4,0,1,1,0}, {0,4,0,1,1}, {0,0,4,0,1}, {1,0,0,4,0}};
+ int M159[6][5] =
+ {{0,2,0,0,4}, {0,0,2,0,0}, {4,0,0,2,0}, {0,4,0,0,2}, {0,0,4,0,0}, {2,0,0,4,0}};
+ int M1s3[6][5] =
+ {{1,1,0,4,0}, {0,1,1,0,4}, {0,0,1,1,0}, {4,0,0,1,1}, {0,4,0,0,1}, {1,0,4,0,0}};
+ int hd19[6][5] =
+ {{0,1,1,0,3}, {1,0,1,1,0}, {3,1,0,1,1}, {0,3,1,0,1}, {1,0,3,1,0}, {1,1,0,3,1}};
+ int M1b3[6][5] =
+ {{3,0,1,0,2}, {0,3,0,1,0}, {2,0,3,0,1}, {0,2,0,3,0}, {1,0,2,0,3}, {0,1,0,2,0}};
+ int D1b5[6][5] =
+ {{1,1,0,0,3}, {1,1,1,0,0}, {3,1,1,1,0}, {0,3,1,1,1}, {0,0,3,1,1}, {1,0,0,3,1}};
+ int D1s9[6][5] =
+ {{2,0,0,1,2}, {1,2,0,0,1}, {2,1,2,0,0}, {1,2,1,2,0}, {0,1,2,1,2}, {0,0,1,2,1}};
+ int m791[6][5] =
+ {{0,1,2,0,2}, {1,0,1,2,0}, {2,1,0,1,2}, {0,2,1,0,1}, {2,0,2,1,0}, {1,2,0,2,1}};
+ int d7s1[6][5] =
+ {{1,1,1,0,2}, {1,1,1,1,0}, {2,1,1,1,1}, {0,2,1,1,1}, {1,0,2,1,1}, {1,1,0,2,1}};
+ int d3s1[6][5] =
+ {{3,1,0,1,0}, {1,3,1,0,1}, {0,1,3,1,0}, {1,0,1,3,1}, {0,1,0,1,3}, {1,0,1,0,1}};
+
+
+ if (!initialized) {
+ for (i=0; i<7; i++)
+ for (j=0; j<7; j++)
+ for (k=0; k<7; k++)
+ for (l=0; l<7; l++)
+ for (m=0; m<7; m++) {
+ sextads[i][j][k][l][m].type = kNone;
+ sextads[i][j][k][l][m].rootMember = kXX;
+ }
+
+ // dominant ninth flat thirteen
+ for (i=0; i<6; i++) {
+ st = D9b3[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "D9b3");
+ t->type = kDom9b13;
+ t->rootMember = i;
+ }
+
+ // minor ninth sharp eleventh
+ for (i=0; i<6; i++) {
+ st = m9s1[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "m9s1");
+ t->type = kMin9s11;
+ t->rootMember = i;
+ }
+
+ // major eleventh
+ for (i=0; i<6; i++) {
+ st = M711[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M711");
+ t->type = kMaj11;
+ t->rootMember = i;
+ }
+
+ // dominant eleventh
+ for (i=0; i<6; i++) {
+ st = D711[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "D711");
+ t->type = kDom11;
+ t->rootMember = i;
+ }
+
+ // half diminished eleventh
+ for (i=0; i<6; i++) {
+ st = hd11[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "hd11");
+ t->type = kHalfDim11;
+ t->rootMember = i;
+ }
+
+ // major eleventh flat 5
+ for (i=0; i<6; i++) {
+ st = M1b5[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M1b5");
+ t->type = kMaj11b5;
+ t->rootMember = i;
+ }
+
+ // major eleventh flat 5 flat 9
+ for (i=0; i<6; i++) {
+ st = M159[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M159");
+ t->type = kM11b5b9;
+ t->rootMember = i;
+ }
+
+ // major eleventh sharp 13
+ for (i=0; i<6; i++) {
+ st = M1s3[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M1s3");
+ t->type = kMaj11s13;
+ t->rootMember = i;
+ }
+
+ // half diminished eleventh flat 9
+ for (i=0; i<6; i++) {
+ st = hd19[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "hd19");
+ t->type = kHalfDim11b9;
+ t->rootMember = i;
+ }
+
+ // major eleventh flat 13
+ for (i=0; i<6; i++) {
+ st = M1b3[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "M1b3");
+ t->type = kMaj11b13;
+ t->rootMember = i;
+ }
+
+ // dominant eleventh flat five
+ for (i=0; i<6; i++) {
+ st = D1b5[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "D1b5");
+ t->type = kDom11b5;
+ t->rootMember = i;
+ }
+
+ // dominant eleventh sharp nine
+ for (i=0; i<6; i++) {
+ st = D1s9[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "D1s9");
+ t->type = kDom11s9;
+ t->rootMember = i;
+ }
+
+ // minor seventh flat 9 sharp 11
+ for (i=0; i<6; i++) {
+ st = m791[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "m791");
+ t->type = kMinb9s11;
+ t->rootMember = i;
+ }
+
+ // dominant seventh sharp 11
+ for (i=0; i<6; i++) {
+ st = d7s1[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "d7s1");
+ t->type = kDom7s11;
+ t->rootMember = i;
+ }
+
+ // dominant thirteenth sharp 11
+ for (i=0; i<6; i++) {
+ st = d3s1[i];
+ t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]);
+ if (t->type != kNone) chord_fatal_error("redefining chord", "d3s1");
+ t->type = kDom13s11;
+ t->rootMember = i;
+ }
+
+ initialized = 1;
+ return;
+ }
+
+ j = 0;
+ for (i=0; i<12; i++)
+ if (x->x_pc[i]) members[j++] = i; // load members array with chord pitch classes
+ interval1 = members[1] - members[0]; // calculate interval between first two members
+ interval2 = members[2] - members[0]; // calculate interval between first and third
+ interval3 = members[3] - members[0]; // calculate interval between first and third
+ interval4 = members[4] - members[0]; // calculate interval between first and fourth
+ interval5 = members[5] - members[0]; // calculate interval between first and fifth
+ interval5 = interval5 - interval4 - 1; // reduce interval5 to start at zero
+ interval4 = interval4 - interval3 - 1; // reduce interval4 to start at zero
+ interval3 = interval3 - interval2 - 1; // reduce interval3 to start at zero
+ interval2 = interval2 - interval1 - 1; // reduce interval2 to start at zero
+ interval1 = interval1 - 1; // reduce interval1 to start at zero
+
+ // find TypeRoot struct for this interval set
+ t = &(sextads[interval1][interval2][interval3][interval4][interval5]);
+ if (t->rootMember != kXX) {
+ x->x_chord_type = t->type;
+ x->x_chord_root = members[t->rootMember];
+ switch(t->rootMember) { /* get state of inversion */
+ case 0:
+ x->x_chord_inversion = 0;
+ break;
+ case 1:
+ x->x_chord_inversion = 2;
+ break;
+ case 2:
+ x->x_chord_inversion = 2;
+ break;
+ case 3:
+ x->x_chord_inversion = 2;
+ break;
+ case 4:
+ x->x_chord_inversion = 2;
+ break;
+ case 5: x->x_chord_inversion = 1;
+ }
+ chord_draw_chord_type(x, 6); // output onto the screen
+ } else
+ chord_kick_out_member(x, 6, members);
+}
+
+static int chord_accidental(t_int pc)
+{
+ switch (pc) {
+ case 0:
+ case 2:
+ case 4:
+ case 5:
+ case 7:
+ case 9:
+ case 11: return 0;
+ case 1:
+ case 3:
+ case 6:
+ case 8:
+ case 10:
+ default: return 1;
+ }
+}
+
+static int chord_name_third(t_chord *x, char* chord, int c, int rootName)
+{
+ int third = (x->x_chord_root+4)%12; // look for major third
+ if (x->x_pc[third]) { // if one is there
+ x->x_pc[third] = 0; // erase from pcs array
+ chord[c++] = name_class[(rootName+2)%7];
+ if (chord_accidental(third)) { // if it has an chord_accidental
+ // make it a flat if the root also has an chord_accidental
+ if (chord_accidental(x->x_chord_root))
+ chord[c++] = 'b';
+ // otherwise make it a sharp
+ else
+ chord[c++] = '#';
+ }
+ chord[c++] = ' ';
+ return c; // return if major third found
+ }
+
+ third = (x->x_chord_root+3)%12; // no major, look for minor third
+ if (x->x_pc[third]) { // if one is there
+ x->x_pc[third] = 0; // erase from pcs array
+ chord[c++] = name_class[(rootName+2)%7];
+ if (chord_accidental(third)) // if it has an chord_accidental
+ chord[c++] = 'b'; else // make it a flat
+ if (chord_accidental(x->x_chord_root)) { // if the root has an chord_accidental
+ chord[c++] = 'b'; // make the third a flat
+ if (chord[0] == 'G') // if the root is Gb
+ chord[c++] = 'b'; // this must be Bbb
+ }
+ chord[c++] = ' ';
+ return c;
+ }
+
+ return c; // if we get here there was no third
+}
+
+static int chord_name_fifth(t_chord *x, char* chord, int c, int rootName)
+{
+ int fifth = (x->x_chord_root+7)%12;
+ if (x->x_pc[fifth]) {
+ x->x_pc[fifth] = 0;
+ chord[c++] = name_class[(rootName+4)%7];
+ if (chord_accidental(fifth)) {
+ if (chord_accidental(x->x_chord_root)) chord[c++] = 'b';
+ else chord[c++] = '#';
+ }
+ chord[c++] = ' ';
+ return c;
+ }
+
+ fifth = (x->x_chord_root+6)%12;
+ if (x->x_pc[fifth]) {
+ x->x_pc[fifth] = 0;
+ chord[c++] = name_class[(rootName+4)%7];
+ if (chord[0] != 'B') chord[c++] = 'b';
+ if (chord_accidental(x->x_chord_root)) chord[c++] = 'b';
+ chord[c++] = ' ';
+ return c;
+ }
+
+ fifth = (x->x_chord_root+8)%12;
+ if (x->x_pc[fifth]) {
+ x->x_pc[fifth] = 0;
+ chord[c++] = name_class[(rootName+4)%7];
+ if (chord_accidental(fifth)) chord[c++] = '#'; else
+ if (!chord_accidental(x->x_chord_root)) {
+ chord[c++] = '#';
+ if (chord[0] == 'B')
+ chord[c++] = '#';
+ }
+ chord[c++] = ' ';
+ return c;
+ }
+
+ return c;
+}
+
+static int chord_name_seventh(t_chord *x, char* chord, int c, int rootName)
+{
+ int seventh = (x->x_chord_root+11)%12;
+ if (x->x_pc[seventh]) {
+ x->x_pc[seventh] = 0;
+ chord[c++] = name_class[(rootName+6)%7];
+ if (chord_accidental(seventh)) chord[c++] = '#';
+ chord[c++] = ' ';
+ return c;
+ }
+ seventh = (x->x_chord_root+10)%12;
+ if (x->x_pc[seventh]) {
+ x->x_pc[seventh] = 0;
+ chord[c++] = name_class[(rootName+6)%7];
+ if (chord_accidental(seventh) || chord_accidental(x->x_chord_root))
+ chord[c++] = 'b';
+ chord[c++] = ' ';
+ return c;
+ }
+ seventh = (x->x_chord_root+9)%12;
+ if (x->x_pc[seventh]) {
+ x->x_pc[seventh] = 0;
+ chord[c++] = name_class[(rootName+6)%7];
+ chord[c++] = 'b';
+ if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; else
+ if (chord_accidental((seventh+1)%12)) chord[c++] = 'b';
+ chord[c++] = ' ';
+ return c;
+ }
+ return c;
+}
+
+static int chord_name_ninth(t_chord *x, char* chord, int c, int rootName)
+{
+ int ninth = (x->x_chord_root+2)%12;
+ if (x->x_pc[ninth]) {
+ x->x_pc[ninth] = 0;
+ chord[c++] = name_class[(rootName+1)%7];
+ if (chord_accidental(ninth)) {
+ if (chord_accidental(x->x_chord_root)) chord[c++] = 'b';
+ else chord[c++] = '#';
+ }
+ chord[c++] = ' ';
+ return c;
+ }
+
+ ninth = (x->x_chord_root+1)%12;
+ if (x->x_pc[ninth]) {
+ x->x_pc[ninth] = 0;
+ chord[c++] = name_class[(rootName+1)%7];
+ if (chord_accidental(ninth)) chord[c++] = 'b';
+ else {
+ if (chord_accidental(x->x_chord_root)) {
+ chord[c++] = 'b';
+ if ((x->x_chord_root == 1) || (x->x_chord_root == 6) || (x->x_chord_root == 8))
+ chord[c++] = 'b';
+ }
+ }
+ chord[c++] = ' ';
+ return c;
+ }
+
+ ninth = (x->x_chord_root+3)%12;
+ if (x->x_pc[ninth]) {
+ x->x_pc[ninth] = 0;
+ chord[c++] = name_class[(rootName+1)%7];
+ if (chord_accidental(ninth)) chord[c++] = '#'; else
+ if (!chord_accidental(x->x_chord_root)) {
+ chord[c++] = '#';
+ if (chord_accidental((x->x_chord_root+2)%12))
+ chord[c++] = '#';
+ }
+ chord[c++] = ' ';
+ return c;
+ }
+
+ return c;
+}
+
+static int chord_name_eleventh(t_chord *x, char* chord, int c, int rootName)
+{
+ int eleventh = (x->x_chord_root+5)%12;
+ if (x->x_pc[eleventh]) {
+ x->x_pc[eleventh] = 0;
+ chord[c++] = name_class[(rootName+3)%7];
+ if (chord_accidental(eleventh)) chord[c++] = 'b'; else
+ if (chord_accidental(x->x_chord_root)) chord[c++] = 'b';
+ chord[c++] = ' ';
+ return c;
+ }
+
+ eleventh = (x->x_chord_root+6)%12;
+ if (x->x_pc[eleventh]) {
+ x->x_pc[eleventh] = 0;
+ chord[c++] = name_class[(rootName+3)%7];
+ if (chord_accidental(eleventh)) chord[c++] = '#'; else
+ if ((!chord_accidental(x->x_chord_root)) && (x->x_chord_root == 11))
+ chord[c++] = '#';
+ chord[c++] = ' ';
+ return c;
+ }
+
+ return c;
+}
+
+static int chord_name_thirteenth(t_chord *x, char* chord, int c, int rootName)
+{
+ int thirteenth = (x->x_chord_root+9)%12;
+ if (x->x_pc[thirteenth]) {
+ x->x_pc[thirteenth] = 0;
+ chord[c++] = name_class[(rootName+5)%7];
+ if (chord_accidental(thirteenth)) {
+ if (chord_accidental(x->x_chord_root))
+ chord[c++] = 'b';
+ else
+ chord[c++] = '#';
+ }
+
+ chord[c++] = ' ';
+ return c;
+ }
+
+ thirteenth = (x->x_chord_root+10)%12;
+ if (x->x_pc[thirteenth]) {
+ x->x_pc[thirteenth] = 0;
+ chord[c++] = name_class[(rootName+5)%7];
+ if (chord_accidental(thirteenth)) chord[c++] = '#'; else
+ if (!chord_accidental(x->x_chord_root)) {
+ chord[c++] = '#';
+ if (chord_accidental((x->x_chord_root+9)%12))
+ chord[c++] = '#';
+ }
+ chord[c++] = ' ';
+ return c;
+ }
+
+ thirteenth = (x->x_chord_root+8)%12;
+ if (x->x_pc[thirteenth]) {
+ x->x_pc[thirteenth] = 0;
+ chord[c++] = name_class[(rootName+5)%7];
+ if (chord_accidental(thirteenth)) chord[c++] = 'b'; else
+ if (chord_accidental(x->x_chord_root)) {
+ chord[c++] = 'b';
+ if (chord_accidental(x->x_chord_root+9)%12)
+ chord[c++] = 'b';
+ }
+ chord[c++] = ' ';
+ return c;
+ }
+
+ return c;
+}
+
+
+
+static void chord_spell_chord(t_chord *x, char *chord, t_int num_pcs)
+{
+ int rootName = 0; // keep index of root name class
+ int c = 0; // pointer to current character
+ int named = 0; // how many members have been named
+ int mark;
+ int i;
+
+ // use chordRoot to set rootName index and store characters for name
+ switch (x->x_chord_root)
+ {
+ case 0: chord[c++] = name_class[rootName=0]; break;
+ case 1: chord[c++] = name_class[rootName=1];
+ chord[c++] = 'b'; break;
+ case 2: chord[c++] = name_class[rootName=1]; break;
+ case 3: chord[c++] = name_class[rootName=2];
+ chord[c++] = 'b'; break;
+ case 4: chord[c++] = name_class[rootName=2]; break;
+ case 5: chord[c++] = name_class[rootName=3]; break;
+ case 6: chord[c++] = name_class[rootName=4];
+ chord[c++] = 'b'; break;
+ case 7: chord[c++] = name_class[rootName=4]; break;
+ case 8: chord[c++] = name_class[rootName=5];
+ chord[c++] = 'b'; break;
+ case 9: chord[c++] = name_class[rootName=5]; break;
+ case 10: chord[c++] = name_class[rootName=6];
+ chord[c++] = 'b'; break;
+ case 11: chord[c++] = name_class[rootName=6]; break;
+ default: break;
+ }
+ x->x_pc[x->x_chord_root] = 0; /* set this member to zero */
+
+ chord[c++] = ' '; // insert space
+ if (++named == num_pcs) { // if everything is named
+ chord[c] = '\0'; // terminate the string
+ return; // and return
+ }
+
+ mark = c; // use mark to see if new names are added
+ for (i=0; i<6; i++) {
+ // advance search by thirds
+ switch (i) {
+ case 0: mark = chord_name_third (x, chord, c, rootName); break;
+ case 1: mark = chord_name_fifth (x, chord, c, rootName); break;
+ case 2: mark = chord_name_seventh (x, chord, c, rootName); break;
+ case 3: mark = chord_name_ninth (x, chord, c, rootName); break;
+ case 4: mark = chord_name_eleventh (x, chord, c, rootName); break;
+ case 5: mark = chord_name_thirteenth(x, chord, c, rootName); break;
+ }
+ if (mark != c) { // if new name is added
+ ++named; // increment count of named members
+ c = mark; // update character pointer
+ }
+ if (named == num_pcs) { // if everything is named
+ chord[c] = '\0'; // terminate the string
+ return; // and return
+ }
+ }
+
+ chord[c] = '\0';
+}
+
+
+static void chord_draw_chord_type(t_chord *x, t_int num_pcs)
+{
+ char chord[255]; /* output string */
+ int i, j;
+
+ /* get members of chord */
+ j = 0;
+ for(i = 0; i < 12; i++)
+ {
+ if(x->x_pc[i])
+ {
+ SETFLOAT(x->x_chordlist+j, x->x_abs_pc[i]);
+ j++;
+ }
+ }
+
+ if (x->x_chord_type != kNone)
+ {
+ chord_spell_chord(x, chord, num_pcs); /* spell chord members */
+ }
+ else
+ {
+ post("going...");
+ chord[0] = '\0';
+ for(i = 0; i < 12; i++)
+ if (x->x_pc[i])
+ strcat(chord, pitch_class[i]); /* output single notes */
+ post("did it");
+ }
+
+ strcat(chord, ": ");
+ strcat(chord, pitch_class[x->x_chord_root]);
+
+ /* append name of chord type */
+ switch (x->x_chord_type) {
+ case kUnison: strcat(chord, "unison"); break;
+ case kMaj: strcat(chord, "major"); break;
+ case kMin: strcat(chord, "minor"); break;
+ case kDim: strcat(chord, "diminished"); break;
+ case kAug: strcat(chord, "augmented"); break;
+
+ case kMaj7: strcat(chord, "major 7th"); break;
+ case kDom7: strcat(chord, "dominant 7th"); break;
+ case kMin7: strcat(chord, "minor 7th"); break;
+ case kHalfDim7: strcat(chord, "half diminished 7th"); break;
+ case kDim7: strcat(chord, "diminished 7th"); break;
+ case kMinMaj7: strcat(chord, "minor/major 7th"); break;
+
+ case kMaj7s5: strcat(chord, "major 7th #5"); break;
+ case kMaj7b5: strcat(chord, "major 7th b5"); break;
+ case kDom7s5: strcat(chord, "dominant 7th #5"); break;
+ case kDom7b5: strcat(chord, "dominant 7th b5"); break;
+ case kDomb9: strcat(chord, "dominant b9"); break;
+
+ case kMaj9: strcat(chord, "major 9th"); break;
+ case kDom9: strcat(chord, "dominant 9th"); break;
+ case kMin9: strcat(chord, "minor 9th"); break;
+ case kHalfDim9: strcat(chord, "half diminished 9th"); break;
+ case kMinMaj9: strcat(chord, "minor major 9th"); break;
+ case kDimMaj9: strcat(chord, "diminished major 9th");break;
+ case kMaj9b5: strcat(chord, "major 9th b5"); break;
+ case kDom9b5: strcat(chord, "dominant 9th b5"); break;
+ case kDom9b13: strcat(chord, "dominant 9th b13"); break;
+ case kMin9s11: strcat(chord, "minor 9th #11"); break;
+ case kmM9b11: strcat(chord, "minor/maj 9th b11"); break;
+
+ case kMaj7b9: strcat(chord, "major 7th b9"); break;
+ case kMaj7s5b9: strcat(chord, "major 7th #5 b9"); break;
+ case kDom7b9: strcat(chord, "dominant 7th b9"); break;
+ case kMin7b9: strcat(chord, "minor 7th b9"); break;
+ case kMinb9s11: strcat(chord, "minor b9 #11"); break;
+ case kHalfDimb9:strcat(chord, "half diminished b9"); break;
+ case kDim7b9: strcat(chord, "diminished b9"); break;
+ case kMinMajb9: strcat(chord, "minor/major b9"); break;
+ case kDimMajb9: strcat(chord, "diminished M7 b9"); break;
+
+ case kMaj7s9: strcat(chord, "major 7th #9"); break;
+ case kDom7s9: strcat(chord, "dominant #9"); break;
+ case kMaj7s11: strcat(chord, "major 7th #11"); break;
+ case kMaj9s13: strcat(chord, "major 9th #13"); break;
+ case kMs9s11: strcat(chord, "major #9 #11"); break;
+ case kHDimb11: strcat(chord, "half diminished b11"); break;
+
+ case kMaj11: strcat(chord, "major 11th"); break;
+ case kDom11: strcat(chord, "dominant 11th"); break;
+ case kMin11: strcat(chord, "minor 11th"); break;
+ case kHalfDim11:strcat(chord, "half diminished 11th");break;
+ case kDim11: strcat(chord, "diminished 11th"); break;
+ case kMinMaj11: strcat(chord, "minor/major 11th"); break;
+ case kDimMaj11: strcat(chord, "diminished maj 11th"); break;
+
+ case kMaj11b5: strcat(chord, "major 11th b5"); break;
+ case kMaj11s5: strcat(chord, "major 11th #5"); break;
+ case kMaj11b9: strcat(chord, "major 11th b9"); break;
+ case kMaj11s9: strcat(chord, "major 11th #9"); break;
+ case kMaj11b13: strcat(chord, "major 11th b13"); break;
+ case kMaj11s13: strcat(chord, "major 11th #13"); break;
+ case kM11b5b9: strcat(chord, "major 11th b5 b9"); break;
+ case kDom11b5: strcat(chord, "dominant 11th b5"); break;
+ case kDom11b9: strcat(chord, "dominant 11th b9"); break;
+ case kDom11s9: strcat(chord, "dominant 11th #9"); break;
+ case kHalfDim11b9:strcat(chord, "half dim 11th b9"); break;
+ case kDom7s11: strcat(chord, "dominant #11"); break;
+ case kMin7s11: strcat(chord, "minor 7th #11"); break;
+
+ case kDom13s11: strcat(chord, "dominant 13th #11"); break;
+ case kM7b913: strcat(chord, "major 7 b9 13"); break;
+ case kMaj7s13: strcat(chord, "major 7th #13"); break;
+ case kM7b9s13: strcat(chord, "major 7 b9 #13"); break;
+ case kDom7b13: strcat(chord, "dominant 7th b13"); break;
+ case kChrom: strcat(chord, "chromatic"); break;
+ case kNone:
+ default: strcat(chord, "unknown"); break;
+ }
+
+ x->x_chord_bass = x->x_abs_pc[x->x_chord_root]; /* get MIDI note number of bass */
+
+ /* output results */
+ outlet_list(x->x_outchordnotes, NULL, j, x->x_chordlist);
+ outlet_float(x->x_outchordinversion, x->x_chord_inversion);
+ outlet_symbol(x->x_outchordname, gensym(chord));
+ outlet_float(x->x_outchordclass, x->x_chord_root);
+ outlet_float(x->x_outchordval, x->x_chord_bass);
+}
+
+static void chord_kick_out_member(t_chord *x, t_int number, t_int *members)
+{
+ int *distances;
+ int minDistance = 1000;
+ int badMember = 0;
+ int i, j, interval;
+
+ distances = getbytes(number*sizeof(int));
+
+ for (i=0; i<number; i++) {
+ // initialize total distance to zero
+ distances[i] = 0;
+ for (j=0; j<number; j++)
+ if (j != i) {
+ // get absolute value of interval size
+ interval = abs(members[i] - members[j]);
+ // make inversions of intervals equivalent
+ if (interval > 6) interval = 12 - interval;
+ // add absolute interval size to total
+ distances[i] += interval;
+ }
+
+ // if this is the smallest total distance
+ if (distances[i] < minDistance) {
+ // remember it
+ minDistance = distances[i];
+ badMember = i;
+ }
+ }
+ freebytes(distances, number * sizeof(int));
+ x->x_pc[members[badMember]] = 0; // cancel out most dissonant member
+ chord_chord_finder(x, number-1); // call chord finder again without it
+ x->x_pc[members[badMember]] = 1; // replace most dissonant member
+}
+
+static void chord_chord_finder(t_chord *x, t_int num_pcs)
+{
+ int i;
+ x->x_chord_type = kNone;
+ x->x_chord_root = kXX; /* none */
+ switch (num_pcs) {
+ case 1: chord_unison(x); break;
+ case 2: chord_dyad(x); break;
+ case 3: chord_triad(x); break;
+ case 4: chord_quartad(x); break;
+ case 5: chord_quintad(x); break;
+ case 6: chord_sextad(x); break;
+ default: x->x_chord_type = kChrom;
+ for(i = 0; i < 12; i++) // 12 was num_pcs !?
+ {
+ if(x->x_pc[i])
+ {
+ x->x_chord_root = i;
+ break;
+ }
+ }
+ }
+}
+
+static void chord_float(t_chord *x, t_floatarg f)
+{
+ t_int velo = x->x_velo;
+ t_int allloc = 0;
+ t_int num_pc = 0; /* number of pitch classes present */
+ int i, j, k, l;
+
+ x->x_pitch = (t_int)f;
+
+ if(x->x_pitch <= x->x_split)
+ {
+ /* first we need to put the note into the allocation table */
+ if(velo == 0) /* got note-off: remove from allocation table */
+ {
+ if(x->x_poly > 0)x->x_poly--; /* polyphony has decreased by one */
+ for(i = 0; i < MAX_POLY; i++) /* search for voice allocation number */
+ {
+ /* search for corresponding alloc number */
+ if(x->x_alloctable[i] == x->x_pitch)
+ {
+ x->x_alloctable[i] = -1; /* free the alloc number */
+ break;
+ }
+ /* couldn't find it ? */
+ if(i == MAX_POLY - 1)
+ {
+ post("chord: no corresponding note-on found (ignored)");
+ return;
+ }
+ }
+ return; /* no need to look for chord */
+ }
+ else /* we got a note-on message */
+ {
+ if(x->x_poly == MAX_POLY)
+ {
+ post("chord: too many note-on messages (ignored)");
+ return;
+ }
+
+ x->x_poly++; /* number of currently playing notes has increased */
+ /* assign a voice allocation number */
+ for(i = 0; i < MAX_POLY; i++)
+ {
+ /* search for free alloc number */
+ if(x->x_alloctable[i] == -1)
+ {
+ x->x_alloctable[i] = x->x_pitch; /* ... and store pitch */
+ break;
+ }
+ }
+ /* copy all notes into the pitch class array */
+ for(i = 0; i < 12; i++)
+ {
+ x->x_pc[i] = 0; /* empty pitch class */
+ x->x_abs_pc[i] = -1; /* empty absolute values */
+ }
+ for(i = 0; i < MAX_POLY; i++)
+ {
+ /* check for presence of pitch class */
+ if(x->x_alloctable[i] != -1)
+ {
+ if(!x->x_pc[x->x_alloctable[i]%12]) /* a new pitch class */
+ {
+ x->x_abs_pc[x->x_alloctable[i]%12] = x->x_alloctable[i];
+ }
+ else if(x->x_abs_pc[x->x_alloctable[i]%12] > x->x_alloctable[i]) /* remember lowest pitch */
+ {
+ x->x_abs_pc[x->x_alloctable[i]%12] = x->x_alloctable[i];
+ }
+
+ x->x_pc[x->x_alloctable[i]%12] = 1; /* indicate presence of pc */
+ }
+ }
+ /* count number of pitch classes */
+ for(i = 0; i < 12; i++)
+ {
+ num_pc += x->x_pc[i];
+ }
+ // post("%d pitch classes", num_pc);
+ }
+ }
+
+ chord_chord_finder(x, num_pc);
+}
+
+static void chord_ft1(t_chord *x, t_floatarg f)
+{
+ x->x_velo = (t_int)f;
+}
+
+static t_class *chord_class;
+
+static void *chord_new(t_floatarg f)
+{
+ int i;
+ t_chord *x = (t_chord *)pd_new(chord_class);
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ x->x_outchordval = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outchordclass = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outchordname = outlet_new(&x->x_ob, gensym("symbol"));
+ x->x_outchordinversion = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outchordnotes = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_split = (t_int)f;
+ if(x->x_split == 0)x->x_split = 128;
+ for(i = 0; i < MAX_POLY; i++)x->x_alloctable[i] = -1;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void chord_setup(void)
+{
+ chord_class = class_new(gensym("chord"), (t_newmethod)chord_new,
+ 0, sizeof(t_chord), 0, A_DEFFLOAT, 0);
+#else
+void maxlib_chord_setup(void)
+{
+ chord_class = class_new(gensym("maxlib_chord"), (t_newmethod)chord_new,
+ 0, sizeof(t_chord), 0, A_DEFFLOAT, 0);
+#endif
+ class_addfloat(chord_class, chord_float);
+ class_addmethod(chord_class, (t_method)chord_ft1, gensym("ft1"), A_FLOAT, 0);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_addcreator((t_newmethod)chord_new, gensym("chord"), A_DEFFLOAT, 0);
+ class_sethelpsymbol(chord_class, gensym("maxlib/chord-help.pd"));
+#endif
+}
+
diff --git a/delta.c b/delta.c
index 41e9b6e..f47e6a9 100644
--- a/delta.c
+++ b/delta.c
@@ -1,139 +1,139 @@
-/* ------------------------- delta ------------------------------------------ */
-/* */
-/* Claculate 1st or 2nd order difference. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Inspired by code written by Trond Lossius. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-
-#define MAXSIZE 32
-
-static char *version = "delta v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct delta
-{
- t_object x_ob;
- t_outlet *x_out; /* result */
- t_int x_order; /* 1st or second order */
- t_int x_clearflag;
- t_float x_delta; /* the result */
-
- t_float x_prev; /* previous value */
- t_float x_prev2; /* value previous to previous value */
-} t_delta;
-
-static void delta_clear(t_delta *x)
-{
- if(x->x_order == 2)
- x->x_clearflag = 2;
- else
- x->x_clearflag = 1;
- x->x_delta = 0;
-}
-
-static void delta_bang(t_delta *x)
-{
- outlet_float(x->x_out, x->x_delta);
-}
-
-static void delta_float(t_delta *x, t_floatarg f)
-{
- if(x->x_order != 2) /* first order */
- {
- if(x->x_clearflag)
- {
- x->x_prev = f;
- x->x_delta = 0;
- x->x_clearflag = 0;
- }
- else
- {
- x->x_delta = f - x->x_prev;
- x->x_prev = f;
- }
- }
- else
- {
- switch(x->x_clearflag)
- {
- case 0:
- x->x_delta = f - 2*x->x_prev + x->x_prev2;
- x->x_prev2 = x->x_prev;
- x->x_prev = f;
- break;
- case 1:
- x->x_prev = f;
- x->x_clearflag--;
- break;
- case 2:
- x->x_prev2 = f;
- x->x_clearflag--;
- break;
- }
- }
- delta_bang(x);
-}
-
-static t_class *delta_class;
-
-static void *delta_new(t_floatarg f)
-{
- int i;
-
- t_delta *x = (t_delta *)pd_new(delta_class);
- x->x_out = outlet_new(&x->x_ob, gensym("float"));
-
- x->x_order = (int)f;
- if(x->x_order == 2)
- x->x_clearflag = 2;
- else
- x->x_clearflag = 1;
- x->x_delta = 0;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void delta_setup(void)
-{
- delta_class = class_new(gensym("delta"), (t_newmethod)delta_new,
- 0, sizeof(t_delta), 0, A_DEFFLOAT, 0);
-#else
-void maxlib_delta_setup(void)
-{
- delta_class = class_new(gensym("maxlib_delta"), (t_newmethod)delta_new,
- 0, sizeof(t_delta), 0, A_DEFFLOAT, 0);
-#endif
- class_addfloat(delta_class, delta_float);
- class_addbang(delta_class, (t_method)delta_bang);
- class_addmethod(delta_class, (t_method)delta_clear, gensym("clear"), 0);
- class_sethelpsymbol(delta_class, gensym("maxlib/delta-help.pd"));
-#ifndef MAXLIB
-
- post(version);
-#else
- class_addcreator((t_newmethod)delta_new, gensym("delta"), A_DEFFLOAT, 0);
- class_sethelpsymbol(delta_class, gensym("maxlib/delta-help.pd"));
-#endif
-}
-
+/* ------------------------- delta ------------------------------------------ */
+/* */
+/* Claculate 1st or 2nd order difference. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Inspired by code written by Trond Lossius. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+
+#define MAXSIZE 32
+
+static char *version = "delta v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct delta
+{
+ t_object x_ob;
+ t_outlet *x_out; /* result */
+ t_int x_order; /* 1st or second order */
+ t_int x_clearflag;
+ t_float x_delta; /* the result */
+
+ t_float x_prev; /* previous value */
+ t_float x_prev2; /* value previous to previous value */
+} t_delta;
+
+static void delta_clear(t_delta *x)
+{
+ if(x->x_order == 2)
+ x->x_clearflag = 2;
+ else
+ x->x_clearflag = 1;
+ x->x_delta = 0;
+}
+
+static void delta_bang(t_delta *x)
+{
+ outlet_float(x->x_out, x->x_delta);
+}
+
+static void delta_float(t_delta *x, t_floatarg f)
+{
+ if(x->x_order != 2) /* first order */
+ {
+ if(x->x_clearflag)
+ {
+ x->x_prev = f;
+ x->x_delta = 0;
+ x->x_clearflag = 0;
+ }
+ else
+ {
+ x->x_delta = f - x->x_prev;
+ x->x_prev = f;
+ }
+ }
+ else
+ {
+ switch(x->x_clearflag)
+ {
+ case 0:
+ x->x_delta = f - 2*x->x_prev + x->x_prev2;
+ x->x_prev2 = x->x_prev;
+ x->x_prev = f;
+ break;
+ case 1:
+ x->x_prev = f;
+ x->x_clearflag--;
+ break;
+ case 2:
+ x->x_prev2 = f;
+ x->x_clearflag--;
+ break;
+ }
+ }
+ delta_bang(x);
+}
+
+static t_class *delta_class;
+
+static void *delta_new(t_floatarg f)
+{
+ int i;
+
+ t_delta *x = (t_delta *)pd_new(delta_class);
+ x->x_out = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_order = (int)f;
+ if(x->x_order == 2)
+ x->x_clearflag = 2;
+ else
+ x->x_clearflag = 1;
+ x->x_delta = 0;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void delta_setup(void)
+{
+ delta_class = class_new(gensym("delta"), (t_newmethod)delta_new,
+ 0, sizeof(t_delta), 0, A_DEFFLOAT, 0);
+#else
+void maxlib_delta_setup(void)
+{
+ delta_class = class_new(gensym("maxlib_delta"), (t_newmethod)delta_new,
+ 0, sizeof(t_delta), 0, A_DEFFLOAT, 0);
+#endif
+ class_addfloat(delta_class, delta_float);
+ class_addbang(delta_class, (t_method)delta_bang);
+ class_addmethod(delta_class, (t_method)delta_clear, gensym("clear"), 0);
+ class_sethelpsymbol(delta_class, gensym("maxlib/delta-help.pd"));
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_addcreator((t_newmethod)delta_new, gensym("delta"), A_DEFFLOAT, 0);
+ class_sethelpsymbol(delta_class, gensym("maxlib/delta-help.pd"));
+#endif
+}
+
diff --git a/deny.c b/deny.c
index 1ab4de8..5525cc2 100644
--- a/deny.c
+++ b/deny.c
@@ -1,114 +1,114 @@
-/* ---------------------------- deny --------------------------------------- */
-/* */
-/* Lets only floats/symbols through that are denyed to do so. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <string.h>
-
-static char *version = "deny v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct deny
-{
- t_object x_obj;
- t_outlet *x_out;
- t_atom *x_elem; // list of elemets that are denyed to pass
- t_int x_numelem; // the number of elemetns in our deny-list
-} t_deny;
-
- /* we got a symbol... */
-static void deny_symbol(t_deny *x, t_symbol *s)
-{
- int i, deny = 0;
- for(i = 0; i < x->x_numelem; i++)
- {
- if(x->x_elem[i].a_type == A_SYMBOL) // compare with all symbols in our list
- if(atom_getsymbolarg(i, x->x_numelem, x->x_elem) == s)
- {
- deny = 1;
- return;
- }
- }
- if(!deny)outlet_symbol(x->x_out, s);
-}
-
- /* we got a float... */
-static void deny_float(t_deny *x, t_floatarg f)
-{
- int i, deny = 0;
- for(i = 0; i < x->x_numelem; i++)
- {
- if(x->x_elem[i].a_type == A_FLOAT) // compare with all floats in our list
- if(atom_getfloatarg(i, x->x_numelem, x->x_elem) == f)
- {
- deny = 1; // input is in deny-list
- return;
- }
- }
- if(!deny)outlet_float(x->x_out, f);
-}
-
-static t_class *deny_class;
-
-static void deny_free(t_deny *x)
-{
- freebytes(x->x_elem, x->x_numelem*sizeof(t_atom));
-}
-
-static void *deny_new(t_symbol *s, int argc, t_atom *argv)
-{
- t_deny *x = (t_deny *)pd_new(deny_class);
-
- x->x_numelem = argc; // get the number of elements
- x->x_elem = getbytes(argc*sizeof(t_atom));
- memcpy(x->x_elem, argv, argc*sizeof(t_atom));
-
- x->x_out = outlet_new(&x->x_obj, gensym("anything"));
-
- // post("deny: got %d elements", x->x_numelem);
-
- return (x);
-}
-
-#ifndef MAXLIB
-void deny_setup(void)
-{
- /* the object's class: */
- deny_class = class_new(gensym("deny"), (t_newmethod)deny_new,
- (t_method)deny_free, sizeof(t_deny), 0, A_GIMME, 0);
-#else
-void maxlib_deny_setup(void)
-{
- /* the object's class: */
- deny_class = class_new(gensym("maxlib_deny"), (t_newmethod)deny_new,
- (t_method)deny_free, sizeof(t_deny), 0, A_GIMME, 0);
- class_addcreator((t_newmethod)deny_new, gensym("deny"), A_GIMME, 0);
-#endif
- class_addsymbol(deny_class, deny_symbol);
- class_addfloat(deny_class, deny_float);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_sethelpsymbol(deny_class, gensym("maxlib/deny-help.pd"));
-#endif
-}
+/* ---------------------------- deny --------------------------------------- */
+/* */
+/* Lets only floats/symbols through that are denyed to do so. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <string.h>
+
+static char *version = "deny v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct deny
+{
+ t_object x_obj;
+ t_outlet *x_out;
+ t_atom *x_elem; // list of elemets that are denyed to pass
+ t_int x_numelem; // the number of elemetns in our deny-list
+} t_deny;
+
+ /* we got a symbol... */
+static void deny_symbol(t_deny *x, t_symbol *s)
+{
+ int i, deny = 0;
+ for(i = 0; i < x->x_numelem; i++)
+ {
+ if(x->x_elem[i].a_type == A_SYMBOL) // compare with all symbols in our list
+ if(atom_getsymbolarg(i, x->x_numelem, x->x_elem) == s)
+ {
+ deny = 1;
+ return;
+ }
+ }
+ if(!deny)outlet_symbol(x->x_out, s);
+}
+
+ /* we got a float... */
+static void deny_float(t_deny *x, t_floatarg f)
+{
+ int i, deny = 0;
+ for(i = 0; i < x->x_numelem; i++)
+ {
+ if(x->x_elem[i].a_type == A_FLOAT) // compare with all floats in our list
+ if(atom_getfloatarg(i, x->x_numelem, x->x_elem) == f)
+ {
+ deny = 1; // input is in deny-list
+ return;
+ }
+ }
+ if(!deny)outlet_float(x->x_out, f);
+}
+
+static t_class *deny_class;
+
+static void deny_free(t_deny *x)
+{
+ freebytes(x->x_elem, x->x_numelem*sizeof(t_atom));
+}
+
+static void *deny_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_deny *x = (t_deny *)pd_new(deny_class);
+
+ x->x_numelem = argc; // get the number of elements
+ x->x_elem = getbytes(argc*sizeof(t_atom));
+ memcpy(x->x_elem, argv, argc*sizeof(t_atom));
+
+ x->x_out = outlet_new(&x->x_obj, gensym("anything"));
+
+ // post("deny: got %d elements", x->x_numelem);
+
+ return (x);
+}
+
+#ifndef MAXLIB
+void deny_setup(void)
+{
+ /* the object's class: */
+ deny_class = class_new(gensym("deny"), (t_newmethod)deny_new,
+ (t_method)deny_free, sizeof(t_deny), 0, A_GIMME, 0);
+#else
+void maxlib_deny_setup(void)
+{
+ /* the object's class: */
+ deny_class = class_new(gensym("maxlib_deny"), (t_newmethod)deny_new,
+ (t_method)deny_free, sizeof(t_deny), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)deny_new, gensym("deny"), A_GIMME, 0);
+#endif
+ class_addsymbol(deny_class, deny_symbol);
+ class_addfloat(deny_class, deny_float);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(deny_class, gensym("maxlib/deny-help.pd"));
+#endif
+}
diff --git a/dist.c b/dist.c
index 38544d5..e98eebb 100644
--- a/dist.c
+++ b/dist.c
@@ -1,279 +1,279 @@
-/* -------------------------- dist ------------------------------------------ */
-/* */
-/* Distributes incoming data to a changeable list of receive objects. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-/*
- connect <symbol list>: store receive objects in list of receivers
- disconnect <symbol list>: remove objects from list of receivers
- clear: clear list of receivers
- send <anything>: send anything to all receives named in the list of receivers */
-
-#include "m_pd.h"
-
-#include <string.h>
-#include <stdio.h>
-
-#define MAX_REC 64 /* maximum number of receive objects */
-#define MAX_ARG 32 /* maximum number of arguments to pass on */
-
-static char *version = "dist v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-static t_class *dist_class;
-
-typedef struct _dist
-{
- t_object x_obj;
- t_symbol *x_sym[MAX_REC]; /* names of receiving objects */
- t_int x_rec; /* current number of receiving objects */
- t_int x_verbose; /* set to 0 to turn off detailed output in Pd window */
-} t_dist;
-
-static void dist_bang(t_dist *x)
-{
- int i;
-
- for(i = 0; i <= x->x_rec; i++)
- {
- if (x->x_sym[i]->s_thing) pd_bang(x->x_sym[i]->s_thing);
- }
-}
-
-static void dist_float(t_dist *x, t_float f)
-{
- int i;
-
- for(i = 0; i <= x->x_rec; i++)
- {
- if (x->x_sym[i]->s_thing) pd_float(x->x_sym[i]->s_thing, f);
- }
-}
-
-static void dist_symbol(t_dist *x, t_symbol *s)
-{
- int i;
-
- for(i = 0; i <= x->x_rec; i++)
- {
- if (x->x_sym[i]->s_thing) pd_symbol(x->x_sym[i]->s_thing, s);
- }
-}
-
-static void dist_pointer(t_dist *x, t_gpointer *gp)
-{
- int i;
-
- for(i = 0; i <= x->x_rec; i++)
- {
- if (x->x_sym[i]->s_thing) pd_pointer(x->x_sym[i]->s_thing, gp);
- }
-}
-
-static void dist_list(t_dist *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i;
-
- for(i = 0; i <= x->x_rec; i++)
- {
- if (x->x_sym[i]->s_thing) pd_list(x->x_sym[i]->s_thing, s, argc, argv);
- }
-}
-
-static void dist_anything(t_dist *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i;
-
- for(i = 0; i <= x->x_rec; i++)
- {
- if (x->x_sym[i]->s_thing) typedmess(x->x_sym[i]->s_thing, s, argc, argv);
- }
-}
-
- /* send 'anything' to receiver */
-static void dist_send(t_dist *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i;
- t_atom av[MAX_ARG]; /* the 'new' t_atom without first element */
- t_int ac = argc - 1; /* the 'new' number of arguments */
-
- if(ac > MAX_ARG)
- {
- post("dist: too many arguments!");
- return;
- }
-
- for(i = 1; i < argc; i++)
- {
- av[i - 1] = argv[i]; /* just copy, don't care about types */
- }
- /* send only argument-part to receivers */
- for(i = 0; i <= x->x_rec; i++)
- {
- if (x->x_sym[i]->s_thing) pd_forwardmess(x->x_sym[i]->s_thing, argc, argv);
- }
-}
-
-static void dist_connect(t_dist *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i, j;
- int exist;
- t_symbol *name;
- /* just append every new receive-name to end of list */
- for(i = 0; i < argc; i++)
- {
- exist = 0;
- if(x->x_rec == MAX_REC - 1)
- {
- post("dist: too many connections in use!");
- return;
- }
- name = atom_getsymbolarg(i, argc, argv);
- for(j = 0; j <= x->x_rec; j++)
- {
- /* check if the name already exists */
- if(x->x_sym[j] == name)
- {
- post("dist: \"%s\" already exists in list of receivers", name->s_name);
- exist = 1; /* indicate that it _does_ exist */
- }
- }
- /* add it in case it's a new one */
- if(!exist)
- {
- x->x_rec++;
- x->x_sym[x->x_rec] = name;
- if(x->x_verbose)post("dist: \"%s\" added to list of receivers", x->x_sym[x->x_rec]->s_name);
- }
- }
-}
-
-static void dist_disconnect(t_dist *x, t_symbol *s, int argc, t_atom *argv)
-{
- /* need to rearrange list in order to get rid of empty entries */
- int i, j, k;
- int done;
- t_symbol *name;
-
- for(i = 0; i < argc; i++)
- {
- name = atom_getsymbolarg(i, argc, argv); /* the one we're going to remove */
- done = 0; /* not yet removed */
- for(j = 0; j <= x->x_rec; j++) /* search for it... */
- {
- if(x->x_sym[j] == name)
- {
- x->x_rec--;
- if(x->x_verbose)post("dist: \"%s\" removed from list of receivers", x->x_sym[j]->s_name);
- x->x_sym[j] = NULL; /* delete entry */
- /* rearrange list now: move entries to close the gap */
- for(k = j; k <= x->x_rec; k++)
- {
- x->x_sym[k] = x->x_sym[k + 1];
- }
- done = 1; /* removed successfully */
- }
- }
- if(!done)post("dist: \"%s\" not in list of receivers, ignored", name->s_name);
- }
-}
-
-static void dist_clear(t_dist *x)
-{
- int i;
-
- for(i = 0; i < MAX_REC; i++)
- {
- x->x_sym[i] = NULL;
- }
- x->x_rec = -1;
-}
-
-static void dist_print(t_dist *x)
-{
- int i;
-
- if(x->x_rec == 0)
- {
- post("dist: there is one object in receiver list:");
- }
- else if(x->x_rec > 0)
- {
- post("dist: there are %d objects in receiver list:", x->x_rec + 1);
- }
- else
- {
- post("dist: there are no objects in receiver list");
- return;
- }
-
- for(i = 0; i <= x->x_rec; i++)
- {
- post(" \"%s\"", x->x_sym[i]->s_name);
- }
-}
-
-static void *dist_new(t_symbol *s, int argc, t_atom *argv)
-{
- int i;
-
- t_dist *x = (t_dist *)pd_new(dist_class);
-
- x->x_rec = -1;
- x->x_verbose = 1; /* display info on connect/disconnect */
- for(i = 0; i < argc; i++)
- {
- x->x_sym[i] = atom_getsymbolarg(i, argc, argv);
- x->x_rec++;
- }
- return (x);
-}
-
-#ifndef MAXLIB
-void dist_setup(void)
-{
- dist_class = class_new(gensym("dist"), (t_newmethod)dist_new, 0,
- sizeof(t_dist), 0, A_GIMME, 0);
-#else
-void maxlib_dist_setup(void)
-{
- dist_class = class_new(gensym("maxlib_dist"), (t_newmethod)dist_new, 0,
- sizeof(t_dist), 0, A_GIMME, 0);
-#endif
- class_addcreator((t_newmethod)dist_new, gensym("d"), A_GIMME, 0);
- class_addbang(dist_class, dist_bang);
- class_addfloat(dist_class, dist_float);
- class_addsymbol(dist_class, dist_symbol);
- class_addpointer(dist_class, dist_pointer);
- class_addlist(dist_class, dist_list);
- class_addmethod(dist_class, (t_method)dist_connect, gensym("connect"), A_GIMME, 0);
- class_addmethod(dist_class, (t_method)dist_disconnect, gensym("disconnect"), A_GIMME, 0);
- class_addmethod(dist_class, (t_method)dist_clear, gensym("clear"), 0);
- class_addmethod(dist_class, (t_method)dist_print, gensym("print"), 0);
- class_addmethod(dist_class, (t_method)dist_send, gensym("send"), A_GIMME, 0);
- class_addanything(dist_class, dist_anything);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_addcreator((t_newmethod)dist_new, gensym("dist"), A_GIMME, 0);
- class_sethelpsymbol(dist_class, gensym("maxlib/dist-help.pd"));
-#endif
-}
+/* -------------------------- dist ------------------------------------------ */
+/* */
+/* Distributes incoming data to a changeable list of receive objects. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+/*
+ connect <symbol list>: store receive objects in list of receivers
+ disconnect <symbol list>: remove objects from list of receivers
+ clear: clear list of receivers
+ send <anything>: send anything to all receives named in the list of receivers */
+
+#include "m_pd.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#define MAX_REC 64 /* maximum number of receive objects */
+#define MAX_ARG 32 /* maximum number of arguments to pass on */
+
+static char *version = "dist v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+static t_class *dist_class;
+
+typedef struct _dist
+{
+ t_object x_obj;
+ t_symbol *x_sym[MAX_REC]; /* names of receiving objects */
+ t_int x_rec; /* current number of receiving objects */
+ t_int x_verbose; /* set to 0 to turn off detailed output in Pd window */
+} t_dist;
+
+static void dist_bang(t_dist *x)
+{
+ int i;
+
+ for(i = 0; i <= x->x_rec; i++)
+ {
+ if (x->x_sym[i]->s_thing) pd_bang(x->x_sym[i]->s_thing);
+ }
+}
+
+static void dist_float(t_dist *x, t_float f)
+{
+ int i;
+
+ for(i = 0; i <= x->x_rec; i++)
+ {
+ if (x->x_sym[i]->s_thing) pd_float(x->x_sym[i]->s_thing, f);
+ }
+}
+
+static void dist_symbol(t_dist *x, t_symbol *s)
+{
+ int i;
+
+ for(i = 0; i <= x->x_rec; i++)
+ {
+ if (x->x_sym[i]->s_thing) pd_symbol(x->x_sym[i]->s_thing, s);
+ }
+}
+
+static void dist_pointer(t_dist *x, t_gpointer *gp)
+{
+ int i;
+
+ for(i = 0; i <= x->x_rec; i++)
+ {
+ if (x->x_sym[i]->s_thing) pd_pointer(x->x_sym[i]->s_thing, gp);
+ }
+}
+
+static void dist_list(t_dist *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+
+ for(i = 0; i <= x->x_rec; i++)
+ {
+ if (x->x_sym[i]->s_thing) pd_list(x->x_sym[i]->s_thing, s, argc, argv);
+ }
+}
+
+static void dist_anything(t_dist *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+
+ for(i = 0; i <= x->x_rec; i++)
+ {
+ if (x->x_sym[i]->s_thing) typedmess(x->x_sym[i]->s_thing, s, argc, argv);
+ }
+}
+
+ /* send 'anything' to receiver */
+static void dist_send(t_dist *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ t_atom av[MAX_ARG]; /* the 'new' t_atom without first element */
+ t_int ac = argc - 1; /* the 'new' number of arguments */
+
+ if(ac > MAX_ARG)
+ {
+ post("dist: too many arguments!");
+ return;
+ }
+
+ for(i = 1; i < argc; i++)
+ {
+ av[i - 1] = argv[i]; /* just copy, don't care about types */
+ }
+ /* send only argument-part to receivers */
+ for(i = 0; i <= x->x_rec; i++)
+ {
+ if (x->x_sym[i]->s_thing) pd_forwardmess(x->x_sym[i]->s_thing, argc, argv);
+ }
+}
+
+static void dist_connect(t_dist *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i, j;
+ int exist;
+ t_symbol *name;
+ /* just append every new receive-name to end of list */
+ for(i = 0; i < argc; i++)
+ {
+ exist = 0;
+ if(x->x_rec == MAX_REC - 1)
+ {
+ post("dist: too many connections in use!");
+ return;
+ }
+ name = atom_getsymbolarg(i, argc, argv);
+ for(j = 0; j <= x->x_rec; j++)
+ {
+ /* check if the name already exists */
+ if(x->x_sym[j] == name)
+ {
+ post("dist: \"%s\" already exists in list of receivers", name->s_name);
+ exist = 1; /* indicate that it _does_ exist */
+ }
+ }
+ /* add it in case it's a new one */
+ if(!exist)
+ {
+ x->x_rec++;
+ x->x_sym[x->x_rec] = name;
+ if(x->x_verbose)post("dist: \"%s\" added to list of receivers", x->x_sym[x->x_rec]->s_name);
+ }
+ }
+}
+
+static void dist_disconnect(t_dist *x, t_symbol *s, int argc, t_atom *argv)
+{
+ /* need to rearrange list in order to get rid of empty entries */
+ int i, j, k;
+ int done;
+ t_symbol *name;
+
+ for(i = 0; i < argc; i++)
+ {
+ name = atom_getsymbolarg(i, argc, argv); /* the one we're going to remove */
+ done = 0; /* not yet removed */
+ for(j = 0; j <= x->x_rec; j++) /* search for it... */
+ {
+ if(x->x_sym[j] == name)
+ {
+ x->x_rec--;
+ if(x->x_verbose)post("dist: \"%s\" removed from list of receivers", x->x_sym[j]->s_name);
+ x->x_sym[j] = NULL; /* delete entry */
+ /* rearrange list now: move entries to close the gap */
+ for(k = j; k <= x->x_rec; k++)
+ {
+ x->x_sym[k] = x->x_sym[k + 1];
+ }
+ done = 1; /* removed successfully */
+ }
+ }
+ if(!done)post("dist: \"%s\" not in list of receivers, ignored", name->s_name);
+ }
+}
+
+static void dist_clear(t_dist *x)
+{
+ int i;
+
+ for(i = 0; i < MAX_REC; i++)
+ {
+ x->x_sym[i] = NULL;
+ }
+ x->x_rec = -1;
+}
+
+static void dist_print(t_dist *x)
+{
+ int i;
+
+ if(x->x_rec == 0)
+ {
+ post("dist: there is one object in receiver list:");
+ }
+ else if(x->x_rec > 0)
+ {
+ post("dist: there are %d objects in receiver list:", x->x_rec + 1);
+ }
+ else
+ {
+ post("dist: there are no objects in receiver list");
+ return;
+ }
+
+ for(i = 0; i <= x->x_rec; i++)
+ {
+ post(" \"%s\"", x->x_sym[i]->s_name);
+ }
+}
+
+static void *dist_new(t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+
+ t_dist *x = (t_dist *)pd_new(dist_class);
+
+ x->x_rec = -1;
+ x->x_verbose = 1; /* display info on connect/disconnect */
+ for(i = 0; i < argc; i++)
+ {
+ x->x_sym[i] = atom_getsymbolarg(i, argc, argv);
+ x->x_rec++;
+ }
+ return (x);
+}
+
+#ifndef MAXLIB
+void dist_setup(void)
+{
+ dist_class = class_new(gensym("dist"), (t_newmethod)dist_new, 0,
+ sizeof(t_dist), 0, A_GIMME, 0);
+#else
+void maxlib_dist_setup(void)
+{
+ dist_class = class_new(gensym("maxlib_dist"), (t_newmethod)dist_new, 0,
+ sizeof(t_dist), 0, A_GIMME, 0);
+#endif
+ class_addcreator((t_newmethod)dist_new, gensym("d"), A_GIMME, 0);
+ class_addbang(dist_class, dist_bang);
+ class_addfloat(dist_class, dist_float);
+ class_addsymbol(dist_class, dist_symbol);
+ class_addpointer(dist_class, dist_pointer);
+ class_addlist(dist_class, dist_list);
+ class_addmethod(dist_class, (t_method)dist_connect, gensym("connect"), A_GIMME, 0);
+ class_addmethod(dist_class, (t_method)dist_disconnect, gensym("disconnect"), A_GIMME, 0);
+ class_addmethod(dist_class, (t_method)dist_clear, gensym("clear"), 0);
+ class_addmethod(dist_class, (t_method)dist_print, gensym("print"), 0);
+ class_addmethod(dist_class, (t_method)dist_send, gensym("send"), A_GIMME, 0);
+ class_addanything(dist_class, dist_anything);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_addcreator((t_newmethod)dist_new, gensym("dist"), A_GIMME, 0);
+ class_sethelpsymbol(dist_class, gensym("maxlib/dist-help.pd"));
+#endif
+}
diff --git a/divide.c b/divide.c
index b13fefe..be825e8 100644
--- a/divide.c
+++ b/divide.c
@@ -1,110 +1,110 @@
-/* ------------------------- divide ------------------------------------------ */
-/* */
-/* Like '/', but calculates output whenever _any_ of the inlets changes. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-
-#define MAXSIZE 32
-
-static char *version = "divide v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct divide
-{
- t_object x_ob;
- t_inlet *x_inleft; /* leftmost inlet */
- t_inlet *x_inright; /* right inlet */
- t_outlet *x_outlet; /* result */
- t_int x_numvalues; /* number of values / inlets */
-
- t_float x_dividevalue[MAXSIZE];
-
-} t_divide;
-
-static void divide_bang(t_divide *x)
-{
- int i;
- t_float result = x->x_dividevalue[0];
- for(i = 1; i < x->x_numvalues; i++)
- result /= x->x_dividevalue[i];
- outlet_float(x->x_outlet, result);
-}
-
-static void divide_float(t_divide *x, t_floatarg f)
-{
- x->x_dividevalue[0] = f;
- divide_bang(x); /* calculate result */
-}
-
-static void divide_ft1(t_divide *x, t_floatarg f)
-{
- x->x_dividevalue[1] = f;
- divide_bang(x); /* calculate result */
-}
-
-static t_class *divide_class;
-
-static void *divide_new(t_symbol *s, t_int argc, t_atom* argv)
-{
- int i;
-
- t_divide *x = (t_divide *)pd_new(divide_class);
- x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- for(i = 2; i < argc; i++) /* create additional inlets, if any */
- {
- floatinlet_new(&x->x_ob, &x->x_dividevalue[i]);
- }
- x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
-
- for(i = 0; i < argc; i++)
- {
- x->x_dividevalue[i] = atom_getfloatarg(i, argc, argv);
- }
- x->x_numvalues = i;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void divide_setup(void)
-{
- divide_class = class_new(gensym("divide"), (t_newmethod)divide_new,
- 0, sizeof(t_divide), 0, A_GIMME, 0);
-#else
-void maxlib_divide_setup(void)
-{
- divide_class = class_new(gensym("maxlib_divide"), (t_newmethod)divide_new,
- 0, sizeof(t_divide), 0, A_GIMME, 0);
-#endif
- class_addfloat(divide_class, divide_float);
- class_addmethod(divide_class, (t_method)divide_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addbang(divide_class, (t_method)divide_bang);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_addcreator((t_newmethod)divide_new, gensym("divide"), A_GIMME, 0);
- class_sethelpsymbol(divide_class, gensym("maxlib/divide-help.pd"));
-#endif
-}
-
+/* ------------------------- divide ------------------------------------------ */
+/* */
+/* Like '/', but calculates output whenever _any_ of the inlets changes. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+
+#define MAXSIZE 32
+
+static char *version = "divide v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct divide
+{
+ t_object x_ob;
+ t_inlet *x_inleft; /* leftmost inlet */
+ t_inlet *x_inright; /* right inlet */
+ t_outlet *x_outlet; /* result */
+ t_int x_numvalues; /* number of values / inlets */
+
+ t_float x_dividevalue[MAXSIZE];
+
+} t_divide;
+
+static void divide_bang(t_divide *x)
+{
+ int i;
+ t_float result = x->x_dividevalue[0];
+ for(i = 1; i < x->x_numvalues; i++)
+ result /= x->x_dividevalue[i];
+ outlet_float(x->x_outlet, result);
+}
+
+static void divide_float(t_divide *x, t_floatarg f)
+{
+ x->x_dividevalue[0] = f;
+ divide_bang(x); /* calculate result */
+}
+
+static void divide_ft1(t_divide *x, t_floatarg f)
+{
+ x->x_dividevalue[1] = f;
+ divide_bang(x); /* calculate result */
+}
+
+static t_class *divide_class;
+
+static void *divide_new(t_symbol *s, t_int argc, t_atom* argv)
+{
+ int i;
+
+ t_divide *x = (t_divide *)pd_new(divide_class);
+ x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ for(i = 2; i < argc; i++) /* create additional inlets, if any */
+ {
+ floatinlet_new(&x->x_ob, &x->x_dividevalue[i]);
+ }
+ x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
+
+ for(i = 0; i < argc; i++)
+ {
+ x->x_dividevalue[i] = atom_getfloatarg(i, argc, argv);
+ }
+ x->x_numvalues = i;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void divide_setup(void)
+{
+ divide_class = class_new(gensym("divide"), (t_newmethod)divide_new,
+ 0, sizeof(t_divide), 0, A_GIMME, 0);
+#else
+void maxlib_divide_setup(void)
+{
+ divide_class = class_new(gensym("maxlib_divide"), (t_newmethod)divide_new,
+ 0, sizeof(t_divide), 0, A_GIMME, 0);
+#endif
+ class_addfloat(divide_class, divide_float);
+ class_addmethod(divide_class, (t_method)divide_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addbang(divide_class, (t_method)divide_bang);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_addcreator((t_newmethod)divide_new, gensym("divide"), A_GIMME, 0);
+ class_sethelpsymbol(divide_class, gensym("maxlib/divide-help.pd"));
+#endif
+}
+
diff --git a/divmod.c b/divmod.c
index 07f265e..7151baf 100644
--- a/divmod.c
+++ b/divmod.c
@@ -1,100 +1,100 @@
-/* ------------------------- divmod ----------------------------------------- */
-/* */
-/* Calculates / and % together. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-
-static char *version = "divmod v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct divmod
-{
- t_object x_ob;
- t_inlet *x_inleft; /* leftmost inlet */
- t_inlet *x_inright; /* right inlet */
- t_outlet *x_outlet1; /* result of division */
- t_outlet *x_outlet2; /* result of modulo */
-
- t_int x_leftvalue;
- t_int x_rightvalue;
-
-} t_divmod;
-
-static void divmod_float(t_divmod *x, t_floatarg f)
-{
- x->x_leftvalue = (t_int)f;
- outlet_float(x->x_outlet1, x->x_leftvalue / x->x_rightvalue);
- outlet_float(x->x_outlet2, x->x_leftvalue % x->x_rightvalue);
-}
-
-static void divmod_ft1(t_divmod *x, t_floatarg f)
-{
- x->x_rightvalue = (t_int)f;
- outlet_float(x->x_outlet1, x->x_leftvalue / x->x_rightvalue);
- outlet_float(x->x_outlet2, x->x_leftvalue % x->x_rightvalue);
-}
-
-static void divmod_bang(t_divmod *x)
-{
- outlet_float(x->x_outlet1, x->x_leftvalue / x->x_rightvalue);
- outlet_float(x->x_outlet2, x->x_leftvalue % x->x_rightvalue);
-}
-
-static t_class *divmod_class;
-
-static void *divmod_new(t_floatarg fl, t_floatarg fr)
-{
- t_divmod *x = (t_divmod *)pd_new(divmod_class);
- x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
- x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
-
- x->x_rightvalue = fr;
- x->x_leftvalue = fl;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void divmod_setup(void)
-{
- divmod_class = class_new(gensym("divmod"), (t_newmethod)divmod_new,
- 0, sizeof(t_divmod), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
-#else
-void maxlib_divmod_setup(void)
-{
- divmod_class = class_new(gensym("maxlib_divmod"), (t_newmethod)divmod_new,
- 0, sizeof(t_divmod), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
-#endif
- class_addfloat(divmod_class, divmod_float);
- class_addmethod(divmod_class, (t_method)divmod_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addbang(divmod_class, (t_method)divmod_bang);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_addcreator((t_newmethod)divmod_new, gensym("divmod"), A_DEFFLOAT, A_DEFFLOAT, 0);
- class_sethelpsymbol(divmod_class, gensym("maxlib/divmod-help.pd"));
-#endif
-}
-
+/* ------------------------- divmod ----------------------------------------- */
+/* */
+/* Calculates / and % together. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+
+static char *version = "divmod v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct divmod
+{
+ t_object x_ob;
+ t_inlet *x_inleft; /* leftmost inlet */
+ t_inlet *x_inright; /* right inlet */
+ t_outlet *x_outlet1; /* result of division */
+ t_outlet *x_outlet2; /* result of modulo */
+
+ t_int x_leftvalue;
+ t_int x_rightvalue;
+
+} t_divmod;
+
+static void divmod_float(t_divmod *x, t_floatarg f)
+{
+ x->x_leftvalue = (t_int)f;
+ outlet_float(x->x_outlet1, x->x_leftvalue / x->x_rightvalue);
+ outlet_float(x->x_outlet2, x->x_leftvalue % x->x_rightvalue);
+}
+
+static void divmod_ft1(t_divmod *x, t_floatarg f)
+{
+ x->x_rightvalue = (t_int)f;
+ outlet_float(x->x_outlet1, x->x_leftvalue / x->x_rightvalue);
+ outlet_float(x->x_outlet2, x->x_leftvalue % x->x_rightvalue);
+}
+
+static void divmod_bang(t_divmod *x)
+{
+ outlet_float(x->x_outlet1, x->x_leftvalue / x->x_rightvalue);
+ outlet_float(x->x_outlet2, x->x_leftvalue % x->x_rightvalue);
+}
+
+static t_class *divmod_class;
+
+static void *divmod_new(t_floatarg fl, t_floatarg fr)
+{
+ t_divmod *x = (t_divmod *)pd_new(divmod_class);
+ x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_rightvalue = fr;
+ x->x_leftvalue = fl;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void divmod_setup(void)
+{
+ divmod_class = class_new(gensym("divmod"), (t_newmethod)divmod_new,
+ 0, sizeof(t_divmod), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+#else
+void maxlib_divmod_setup(void)
+{
+ divmod_class = class_new(gensym("maxlib_divmod"), (t_newmethod)divmod_new,
+ 0, sizeof(t_divmod), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+#endif
+ class_addfloat(divmod_class, divmod_float);
+ class_addmethod(divmod_class, (t_method)divmod_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addbang(divmod_class, (t_method)divmod_bang);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_addcreator((t_newmethod)divmod_new, gensym("divmod"), A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_sethelpsymbol(divmod_class, gensym("maxlib/divmod-help.pd"));
+#endif
+}
+
diff --git a/edge.c b/edge.c
index 4f32e8a..8d94c71 100644
--- a/edge.c
+++ b/edge.c
@@ -1,82 +1,82 @@
-/* --------------------------- edge ----------------------------------------- */
-/* */
-/* Detect rising or falling edge of float input. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-
-static char *version = "edge v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct edge
-{
- t_object x_ob;
- t_outlet *x_out1; /* bang on rising edge */
- t_outlet *x_out2; /* bang on falling edge */
- t_float x_lastval; /* last input value */
-} t_edge;
-
-static void edge_float(t_edge *x, t_floatarg f)
-{
- if((x->x_lastval <= 0) && (f >= 1)) /* rising edge */
- outlet_bang(x->x_out1);
- else if((x->x_lastval >= 1) && (f <= 0)) /* falling edge */
- outlet_bang(x->x_out2);
-
- x->x_lastval = f; /* save last value */
-}
-
-static t_class *edge_class;
-
-static void *edge_new(t_floatarg f)
-{
- int i;
-
- t_edge *x = (t_edge *)pd_new(edge_class);
- x->x_out1 = outlet_new(&x->x_ob, gensym("bang"));
- x->x_out2 = outlet_new(&x->x_ob, gensym("bang"));
-
- x->x_lastval = f;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void edge_setup(void)
-{
- edge_class = class_new(gensym("edge"), (t_newmethod)edge_new,
- 0, sizeof(t_edge), 0, A_DEFFLOAT, 0);
- class_addfloat(edge_class, edge_float);
-
- post(version);
-}
-#else
-void maxlib_edge_setup(void)
-{
- edge_class = class_new(gensym("maxlib_edge"), (t_newmethod)edge_new,
- 0, sizeof(t_edge), 0, A_DEFFLOAT, 0);
- class_addfloat(edge_class, edge_float);
- class_addcreator((t_newmethod)edge_new, gensym("edge"), A_DEFFLOAT, 0);
- class_sethelpsymbol(edge_class, gensym("maxlib/edge-help.pd"));
-}
-#endif
-
+/* --------------------------- edge ----------------------------------------- */
+/* */
+/* Detect rising or falling edge of float input. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+
+static char *version = "edge v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct edge
+{
+ t_object x_ob;
+ t_outlet *x_out1; /* bang on rising edge */
+ t_outlet *x_out2; /* bang on falling edge */
+ t_float x_lastval; /* last input value */
+} t_edge;
+
+static void edge_float(t_edge *x, t_floatarg f)
+{
+ if((x->x_lastval <= 0) && (f >= 1)) /* rising edge */
+ outlet_bang(x->x_out1);
+ else if((x->x_lastval >= 1) && (f <= 0)) /* falling edge */
+ outlet_bang(x->x_out2);
+
+ x->x_lastval = f; /* save last value */
+}
+
+static t_class *edge_class;
+
+static void *edge_new(t_floatarg f)
+{
+ int i;
+
+ t_edge *x = (t_edge *)pd_new(edge_class);
+ x->x_out1 = outlet_new(&x->x_ob, gensym("bang"));
+ x->x_out2 = outlet_new(&x->x_ob, gensym("bang"));
+
+ x->x_lastval = f;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void edge_setup(void)
+{
+ edge_class = class_new(gensym("edge"), (t_newmethod)edge_new,
+ 0, sizeof(t_edge), 0, A_DEFFLOAT, 0);
+ class_addfloat(edge_class, edge_float);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_edge_setup(void)
+{
+ edge_class = class_new(gensym("maxlib_edge"), (t_newmethod)edge_new,
+ 0, sizeof(t_edge), 0, A_DEFFLOAT, 0);
+ class_addfloat(edge_class, edge_float);
+ class_addcreator((t_newmethod)edge_new, gensym("edge"), A_DEFFLOAT, 0);
+ class_sethelpsymbol(edge_class, gensym("maxlib/edge-help.pd"));
+}
+#endif
+
diff --git a/examplescore.txt b/examples/score.txt
index 27002f1..27002f1 100644
--- a/examplescore.txt
+++ b/examples/score.txt
diff --git a/expo.c b/expo.c
index 231a923..4b65731 100644
--- a/expo.c
+++ b/expo.c
@@ -1,86 +1,86 @@
-/* ---------------------------- rand_expo ------------------------------------- */
-/* */
-/* rand_expo generates a exponentially distributed random variable. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-#define fran() (t_float)rand()/(t_float)RAND_MAX
-
-static char *version = "expo v0.1, generates exponentially distributed random variable\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-/* -------------------------- rand_expo ------------------------------ */
-
-static t_class *rand_expo_class;
-
-typedef struct _rand_expo
-{
- t_object x_obj;
- t_float x_lambda;
-} t_rand_expo;
-
-static void *rand_expo_new(t_floatarg f)
-{
- t_rand_expo *x = (t_rand_expo *)pd_new(rand_expo_class);
- srand( (unsigned)time( NULL ) );
- floatinlet_new(&x->x_obj, &x->x_lambda);
- outlet_new(&x->x_obj, &s_float);
- x->x_lambda = f;
- return (x);
-}
-
-static void rand_expo_bang(t_rand_expo *x)
-{
- t_float u, l;
- l = (x->x_lambda <= 0 ? 0.0001 : x->x_lambda);
- do
- {
- u = fran();
- }
- while(u == 0);
- outlet_float(x->x_obj.ob_outlet, -log(u)/l);
-}
-
-#ifndef MAXLIB
-void expo_setup(void)
-{
- rand_expo_class = class_new(gensym("expo"), (t_newmethod)rand_expo_new, 0,
- sizeof(t_rand_expo), 0, A_DEFFLOAT, 0);
- class_addbang(rand_expo_class, rand_expo_bang);
- class_sethelpsymbol(rand_expo_class, gensym("expo-help.pd"));
- post(version);
-}
-#else
-void maxlib_expo_setup(void)
-{
- rand_expo_class = class_new(gensym("maxlib_expo"), (t_newmethod)rand_expo_new, 0,
- sizeof(t_rand_expo), 0, A_DEFFLOAT, 0);
- class_addbang(rand_expo_class, rand_expo_bang);
- class_addcreator((t_newmethod)rand_expo_new, gensym("expo"), A_DEFFLOAT, 0);
- class_sethelpsymbol(rand_expo_class, gensym("maxlib/expo-help.pd"));
-}
-#endif
+/* ---------------------------- rand_expo ------------------------------------- */
+/* */
+/* rand_expo generates a exponentially distributed random variable. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+
+#define fran() (t_float)rand()/(t_float)RAND_MAX
+
+static char *version = "expo v0.1, generates exponentially distributed random variable\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- rand_expo ------------------------------ */
+
+static t_class *rand_expo_class;
+
+typedef struct _rand_expo
+{
+ t_object x_obj;
+ t_float x_lambda;
+} t_rand_expo;
+
+static void *rand_expo_new(t_floatarg f)
+{
+ t_rand_expo *x = (t_rand_expo *)pd_new(rand_expo_class);
+ srand( (unsigned)time( NULL ) );
+ floatinlet_new(&x->x_obj, &x->x_lambda);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_lambda = f;
+ return (x);
+}
+
+static void rand_expo_bang(t_rand_expo *x)
+{
+ t_float u, l;
+ l = (x->x_lambda <= 0 ? 0.0001 : x->x_lambda);
+ do
+ {
+ u = fran();
+ }
+ while(u == 0);
+ outlet_float(x->x_obj.ob_outlet, -log(u)/l);
+}
+
+#ifndef MAXLIB
+void expo_setup(void)
+{
+ rand_expo_class = class_new(gensym("expo"), (t_newmethod)rand_expo_new, 0,
+ sizeof(t_rand_expo), 0, A_DEFFLOAT, 0);
+ class_addbang(rand_expo_class, rand_expo_bang);
+ class_sethelpsymbol(rand_expo_class, gensym("expo-help.pd"));
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_expo_setup(void)
+{
+ rand_expo_class = class_new(gensym("maxlib_expo"), (t_newmethod)rand_expo_new, 0,
+ sizeof(t_rand_expo), 0, A_DEFFLOAT, 0);
+ class_addbang(rand_expo_class, rand_expo_bang);
+ class_addcreator((t_newmethod)rand_expo_new, gensym("expo"), A_DEFFLOAT, 0);
+ class_sethelpsymbol(rand_expo_class, gensym("maxlib/expo-help.pd"));
+}
+#endif
diff --git a/fifo.c b/fifo.c
index c932c07..b747b70 100644
--- a/fifo.c
+++ b/fifo.c
@@ -1,96 +1,96 @@
-/* ---------------------------- fifo ------------------------------------------ */
-/* */
-/* Fifo buffer of floats, empties itselfe on every bang (in order of coming in) */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* Fifi-code based St. Rainstick fifi.c for Max, */
-/* copyright St. Rainstick, Amsterdam 1995 */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-
-static char *version = "fifo v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct fifo
-{
- t_object d_ob;
- t_float *getal;
- t_int count, end, size;
- t_outlet *out;
-
-}t_fifo;
-
-static t_class *fifo_class;
-
-static void fifo_int(t_fifo *x, t_floatarg n)
-{
- x->getal[x->count] = n;
- x->count = (x->count + 1) % x->size;
-}
-
-static void fifo_bang(t_fifo *x)
-{
- if (x->end != x->count){
- outlet_float(x->out,x->getal[x->end]);
- x->end = (x->end + 1) % x->size;
- }
-}
-
-static void fifo_free(t_fifo *x)
-{
- freebytes(x->getal, x->size * sizeof(t_float));
-}
-
-static void *fifo_new(t_floatarg n)
-{
-
- t_fifo *x = (t_fifo *)pd_new(fifo_class);
- if (n<10) n = 10;
- x->size = (t_int)n;
- x->end = 0;
- x->count = 0;
- x->getal = (t_float *)getbytes(x->size * sizeof(t_float));
- x->out = outlet_new(&x->d_ob, gensym("float"));
-
- return (x);
-}
-
-#ifndef MAXLIB
-void fifo_setup(void)
-{
- fifo_class = class_new(gensym("fifo"), (t_newmethod)fifo_new,
- (t_method)fifo_free, sizeof(t_fifo), 0, A_DEFFLOAT, 0);
- class_addfloat(fifo_class, fifo_int);
- class_addbang(fifo_class, fifo_bang);
-
- post(version);
-}
-#else
-void maxlib_fifo_setup(void)
-{
- fifo_class = class_new(gensym("maxlib_fifo"), (t_newmethod)fifo_new,
- (t_method)fifo_free, sizeof(t_fifo), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)fifo_new, gensym("fifo"), A_DEFFLOAT, 0);
- class_addfloat(fifo_class, fifo_int);
- class_addbang(fifo_class, fifo_bang);
- class_sethelpsymbol(fifo_class, gensym("maxlib/fifo-help.pd"));
-}
-#endif
+/* ---------------------------- fifo ------------------------------------------ */
+/* */
+/* Fifo buffer of floats, empties itselfe on every bang (in order of coming in) */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* Fifi-code based St. Rainstick fifi.c for Max, */
+/* copyright St. Rainstick, Amsterdam 1995 */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+static char *version = "fifo v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct fifo
+{
+ t_object d_ob;
+ t_float *getal;
+ t_int count, end, size;
+ t_outlet *out;
+
+}t_fifo;
+
+static t_class *fifo_class;
+
+static void fifo_int(t_fifo *x, t_floatarg n)
+{
+ x->getal[x->count] = n;
+ x->count = (x->count + 1) % x->size;
+}
+
+static void fifo_bang(t_fifo *x)
+{
+ if (x->end != x->count){
+ outlet_float(x->out,x->getal[x->end]);
+ x->end = (x->end + 1) % x->size;
+ }
+}
+
+static void fifo_free(t_fifo *x)
+{
+ freebytes(x->getal, x->size * sizeof(t_float));
+}
+
+static void *fifo_new(t_floatarg n)
+{
+
+ t_fifo *x = (t_fifo *)pd_new(fifo_class);
+ if (n<10) n = 10;
+ x->size = (t_int)n;
+ x->end = 0;
+ x->count = 0;
+ x->getal = (t_float *)getbytes(x->size * sizeof(t_float));
+ x->out = outlet_new(&x->d_ob, gensym("float"));
+
+ return (x);
+}
+
+#ifndef MAXLIB
+void fifo_setup(void)
+{
+ fifo_class = class_new(gensym("fifo"), (t_newmethod)fifo_new,
+ (t_method)fifo_free, sizeof(t_fifo), 0, A_DEFFLOAT, 0);
+ class_addfloat(fifo_class, fifo_int);
+ class_addbang(fifo_class, fifo_bang);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_fifo_setup(void)
+{
+ fifo_class = class_new(gensym("maxlib_fifo"), (t_newmethod)fifo_new,
+ (t_method)fifo_free, sizeof(t_fifo), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)fifo_new, gensym("fifo"), A_DEFFLOAT, 0);
+ class_addfloat(fifo_class, fifo_int);
+ class_addbang(fifo_class, fifo_bang);
+ class_sethelpsymbol(fifo_class, gensym("maxlib/fifo-help.pd"));
+}
+#endif
diff --git a/gauss.c b/gauss.c
index c1f32bf..3f2270c 100644
--- a/gauss.c
+++ b/gauss.c
@@ -1,88 +1,88 @@
-/* ---------------------------- rand_gauss ----------------------------------- */
-/* */
-/* rand_gauss generates a gauss distributed random variable. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
+/* ---------------------------- rand_gauss ----------------------------------- */
+/* */
+/* rand_gauss generates a gauss distributed random variable. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-#define fran() (t_float)rand()/(t_float)RAND_MAX
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
-static char *version = "gauss v0.1, generates a Gaussian distributed random variable\n"
- " with mean 'mu' and standard deviation 'sigma',\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
+#define fran() (t_float)rand()/(t_float)RAND_MAX
+
+static char *version = "gauss v0.1, generates a Gaussian distributed random variable\n"
+ " with mean 'mu' and standard deviation 'sigma',\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- rand_gauss ------------------------------ */
+
+static t_class *rand_gauss_class;
+
+typedef struct _rand_gauss
+{
+ t_object x_obj;
+ t_float x_sigma;
+ t_float x_mu;
+} t_rand_gauss;
+
+static void *rand_gauss_new(t_floatarg fs, t_floatarg fm)
+{
+ t_rand_gauss *x = (t_rand_gauss *)pd_new(rand_gauss_class);
+ srand( (unsigned)time( NULL ) );
+ floatinlet_new(&x->x_obj, &x->x_sigma);
+ floatinlet_new(&x->x_obj, &x->x_mu);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_sigma = fs;
+ return (x);
+}
+
+static void rand_gauss_bang(t_rand_gauss *x)
+{
+ t_float u, halfN = 6.0, sum = 0, scale;
+ t_int k, N = 12;
+ scale = 1/sqrt(N/12);
+ for(k = 1; k <= N; k++)
+ sum += fran();
+ outlet_float(x->x_obj.ob_outlet, x->x_sigma*scale*(sum-halfN)+x->x_mu);
+}
+
+#ifndef MAXLIB
+void gauss_setup(void)
+{
+ rand_gauss_class = class_new(gensym("gauss"), (t_newmethod)rand_gauss_new, 0,
+ sizeof(t_rand_gauss), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addbang(rand_gauss_class, rand_gauss_bang);
+ class_sethelpsymbol(rand_gauss_class, gensym("gauss-help.pd"));
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_gauss_setup(void)
+{
+ rand_gauss_class = class_new(gensym("maxlib_gauss"), (t_newmethod)rand_gauss_new, 0,
+ sizeof(t_rand_gauss), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)rand_gauss_new, gensym("gauss"), A_DEFFLOAT, 0);
+ class_addbang(rand_gauss_class, rand_gauss_bang);
+ class_sethelpsymbol(rand_gauss_class, gensym("maxlib/gauss-help.pd"));
+}
+#endif
-/* -------------------------- rand_gauss ------------------------------ */
-
-static t_class *rand_gauss_class;
-
-typedef struct _rand_gauss
-{
- t_object x_obj;
- t_float x_sigma;
- t_float x_mu;
-} t_rand_gauss;
-
-static void *rand_gauss_new(t_floatarg fs, t_floatarg fm)
-{
- t_rand_gauss *x = (t_rand_gauss *)pd_new(rand_gauss_class);
- srand( (unsigned)time( NULL ) );
- floatinlet_new(&x->x_obj, &x->x_sigma);
- floatinlet_new(&x->x_obj, &x->x_mu);
- outlet_new(&x->x_obj, &s_float);
- x->x_sigma = fs;
- return (x);
-}
-
-static void rand_gauss_bang(t_rand_gauss *x)
-{
- t_float u, halfN = 6.0, sum = 0, scale;
- t_int k, N = 12;
- scale = 1/sqrt(N/12);
- for(k = 1; k <= N; k++)
- sum += fran();
- outlet_float(x->x_obj.ob_outlet, x->x_sigma*scale*(sum-halfN)+x->x_mu);
-}
-
-#ifndef MAXLIB
-void gauss_setup(void)
-{
- rand_gauss_class = class_new(gensym("gauss"), (t_newmethod)rand_gauss_new, 0,
- sizeof(t_rand_gauss), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addbang(rand_gauss_class, rand_gauss_bang);
- class_sethelpsymbol(rand_gauss_class, gensym("gauss-help.pd"));
- post(version);
-}
-#else
-void maxlib_gauss_setup(void)
-{
- rand_gauss_class = class_new(gensym("maxlib_gauss"), (t_newmethod)rand_gauss_new, 0,
- sizeof(t_rand_gauss), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)rand_gauss_new, gensym("gauss"), A_DEFFLOAT, 0);
- class_addbang(rand_gauss_class, rand_gauss_bang);
- class_sethelpsymbol(rand_gauss_class, gensym("maxlib/gauss-help.pd"));
-}
-#endif
-
diff --git a/gestalt.c b/gestalt.c
index 3155206..a929e0d 100644
--- a/gestalt.c
+++ b/gestalt.c
@@ -1,123 +1,123 @@
-/* ------------------------- gestalt ---------------------------------------- */
-/* */
-/* Find the 'gestalt' of the MIDI input. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <math.h>
-#include <stdio.h>
-#ifndef _WIN32
-#include <stdlib.h>
-#endif
-
-static char *version = "gestalt v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct gestalt
-{
- t_object x_ob;
- t_inlet *x_invelocity; /* inlet for velocity */
- t_outlet *x_outgestalt; /* calculated 'gestalt'-value */
-
- t_float x_lastpitch;
- t_float x_velocity;
-
- t_float x_reftime;
-
- double x_lastontime;
-
-} t_gestalt;
-
-static void gestalt_ft1(t_gestalt *x, t_floatarg f)
-{
- x->x_velocity = f;
-}
-
-static void gestalt_ft2(t_gestalt *x, t_floatarg f)
-{
- if(f > 0.0) x->x_reftime = f;
-}
-
-static void gestalt_float(t_gestalt *x, t_floatarg f)
-{
-
- int interval, pitch, gestalt;
- double ontime = clock_getlogicaltime();
-
- if(x->x_velocity) /* only process note-ons */
- {
-
- pitch = (t_int)f;
- if(pitch < 1) pitch = 0;
- if(pitch > 127) pitch = 127;
-
- interval = abs(pitch - x->x_lastpitch);
- gestalt = (clock_gettimesince(x->x_lastontime)/x->x_reftime) + interval;
-
- x->x_lastpitch = pitch;
- x->x_lastontime = ontime;
-
- /* output values from right to left */
- outlet_float(x->x_outgestalt, gestalt);
- }
-}
-
-static t_class *gestalt_class;
-
-static void *gestalt_new(t_floatarg f)
-{
- t_gestalt *x = (t_gestalt *)pd_new(gestalt_class);
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft2"));
- x->x_outgestalt = outlet_new(&x->x_ob, gensym("float"));
-
- x->x_lastontime = clock_getlogicaltime();
-
- x->x_reftime = f;
- if(x->x_reftime < 1) x->x_reftime = 1;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void gestalt_setup(void)
-{
- gestalt_class = class_new(gensym("gestalt"), (t_newmethod)gestalt_new,
- 0, sizeof(t_gestalt), 0, A_DEFFLOAT, 0);
- class_addfloat(gestalt_class, gestalt_float);
- class_addmethod(gestalt_class, (t_method)gestalt_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addmethod(gestalt_class, (t_method)gestalt_ft2, gensym("ft2"), A_FLOAT, 0);
-
- post(version);
-}
-#else
-void maxlib_gestalt_setup(void)
-{
- gestalt_class = class_new(gensym("maxlib_gestalt"), (t_newmethod)gestalt_new,
- 0, sizeof(t_gestalt), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)gestalt_new, gensym("gestalt"), A_DEFFLOAT, 0);
- class_addfloat(gestalt_class, gestalt_float);
- class_addmethod(gestalt_class, (t_method)gestalt_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addmethod(gestalt_class, (t_method)gestalt_ft2, gensym("ft2"), A_FLOAT, 0);
- class_sethelpsymbol(gestalt_class, gensym("maxlib/gestalt-help.pd"));
-}
-#endif
-
+/* ------------------------- gestalt ---------------------------------------- */
+/* */
+/* Find the 'gestalt' of the MIDI input. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <math.h>
+#include <stdio.h>
+#ifndef _WIN32
+#include <stdlib.h>
+#endif
+
+static char *version = "gestalt v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct gestalt
+{
+ t_object x_ob;
+ t_inlet *x_invelocity; /* inlet for velocity */
+ t_outlet *x_outgestalt; /* calculated 'gestalt'-value */
+
+ t_float x_lastpitch;
+ t_float x_velocity;
+
+ t_float x_reftime;
+
+ double x_lastontime;
+
+} t_gestalt;
+
+static void gestalt_ft1(t_gestalt *x, t_floatarg f)
+{
+ x->x_velocity = f;
+}
+
+static void gestalt_ft2(t_gestalt *x, t_floatarg f)
+{
+ if(f > 0.0) x->x_reftime = f;
+}
+
+static void gestalt_float(t_gestalt *x, t_floatarg f)
+{
+
+ int interval, pitch, gestalt;
+ double ontime = clock_getlogicaltime();
+
+ if(x->x_velocity) /* only process note-ons */
+ {
+
+ pitch = (t_int)f;
+ if(pitch < 1) pitch = 0;
+ if(pitch > 127) pitch = 127;
+
+ interval = abs(pitch - x->x_lastpitch);
+ gestalt = (clock_gettimesince(x->x_lastontime)/x->x_reftime) + interval;
+
+ x->x_lastpitch = pitch;
+ x->x_lastontime = ontime;
+
+ /* output values from right to left */
+ outlet_float(x->x_outgestalt, gestalt);
+ }
+}
+
+static t_class *gestalt_class;
+
+static void *gestalt_new(t_floatarg f)
+{
+ t_gestalt *x = (t_gestalt *)pd_new(gestalt_class);
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft2"));
+ x->x_outgestalt = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_lastontime = clock_getlogicaltime();
+
+ x->x_reftime = f;
+ if(x->x_reftime < 1) x->x_reftime = 1;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void gestalt_setup(void)
+{
+ gestalt_class = class_new(gensym("gestalt"), (t_newmethod)gestalt_new,
+ 0, sizeof(t_gestalt), 0, A_DEFFLOAT, 0);
+ class_addfloat(gestalt_class, gestalt_float);
+ class_addmethod(gestalt_class, (t_method)gestalt_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(gestalt_class, (t_method)gestalt_ft2, gensym("ft2"), A_FLOAT, 0);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_gestalt_setup(void)
+{
+ gestalt_class = class_new(gensym("maxlib_gestalt"), (t_newmethod)gestalt_new,
+ 0, sizeof(t_gestalt), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)gestalt_new, gensym("gestalt"), A_DEFFLOAT, 0);
+ class_addfloat(gestalt_class, gestalt_float);
+ class_addmethod(gestalt_class, (t_method)gestalt_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(gestalt_class, (t_method)gestalt_ft2, gensym("ft2"), A_FLOAT, 0);
+ class_sethelpsymbol(gestalt_class, gensym("maxlib/gestalt-help.pd"));
+}
+#endif
+
diff --git a/history.c b/history.c
index 97ff0e7..4c94927 100644
--- a/history.c
+++ b/history.c
@@ -1,271 +1,271 @@
-/* -------------------------- history ----------------------------------------- */
-/* */
-/* Calculates the average value of the elements within the last N seconds. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <math.h>
-
-#define MAX_ARG 1024 /* maximum number of items to average */
-#define MAX_TIME 60000 /* maximum time to look back */
-
-static char *version = "history v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct history
-{
- t_object x_ob;
- t_clock *x_clock;
- t_inlet *x_inindex;
- t_outlet *x_outfloat; /* output the history */
- t_outlet *x_outtendency; /* outputs the tendency of the average */
- t_int x_limit; /* indicates if input is 'blocked' (1) */
- t_int x_index; /* the number of elements to average */
- t_float x_input[MAX_ARG]; /* stores the input values we need for averaging */
- double x_intime[MAX_ARG]; /* stores the time of arrival of an element */
- t_int x_inpointer; /* actual position in above array */
- t_float x_average; /* what do you guess ? */
- t_float x_lastaverage;
- t_int x_mode; /* how to history: linear or geometric */
- t_int x_time;
-
-} t_history;
-
- /* there must be a function for this in math.h but how is the
- german 'Fakultät' called in english ???? */
-static int normalise(int i)
-{
- int ret = i;
- while(i--)
- {
- if(i == 0)break;
- ret += i;
- }
- return (ret);
-}
-
-static void history_tick(t_history *x)
-{
- t_float tendency = 0.0;
- if(x->x_lastaverage < x->x_average)
- {
- tendency = 1.0; /* getting more */
- }
- else if(x->x_lastaverage > x->x_average)
- {
- tendency = -1.0; /* getting less */
- }
- else tendency = 0.0; /* nothing has changed */
- outlet_float(x->x_outtendency, tendency);
- x->x_lastaverage = x->x_average;
- clock_delay(x->x_clock, x->x_time);
-}
-
-static void history_float(t_history *x, t_floatarg f)
-{
- int i, j = 0, k = 0, l;
- t_float geo = 1.0;
-
- x->x_average = 0;
- /* put value into array */
- x->x_input[x->x_inpointer] = f;
- x->x_intime[x->x_inpointer] = clock_getlogicaltime();
- /* look for elements that are too old */
- x->x_index = 0;
- for(i = 0; i < MAX_ARG; i++) /* check all valid elements */
- {
- if(x->x_intime[i] != 0)
- {
- if(clock_gettimesince(x->x_intime[i]) <= x->x_time) /* it's in our time window */
- {
- x->x_index++; /* count valid entries */
- }
- else /* too old, delete entry */
- {
- x->x_intime[i] = 0;
- }
- }
- }
- if(x->x_index > 1)
- {
- /* calulate history */
- for(i = 0; i < MAX_ARG; i++) /* check all valid elements */
- {
- if(x->x_intime[i] != 0) /* it's a valid entry */
- {
- k++;
- l = MAX_ARG;
-
- if(x->x_mode == 0) /* linear */
- {
- x->x_average += x->x_input[i] * (1.0 / (float)x->x_index);
- }
- else if(x->x_mode == 1) /* geometric */
- {
- if(x->x_input[i] == 0)x->x_input[i] = 0.001; /* need to cheat a bit... */
- geo *= x->x_input[i];
- if(k == x->x_index)
- x->x_average = pow(geo, (1.0/(float)x->x_index));
- }
- else if(x->x_mode == 2) /* weighted */
- {
- /* normalise output */
- if(k == x->x_index)
- {
- x->x_average += x->x_input[(j + x->x_inpointer + MAX_ARG) % MAX_ARG] * (float)(x->x_index - k);
- x->x_average = x->x_average / (float)normalise(x->x_index - 1);
- }
- else
- {
- x->x_average += x->x_input[(j + x->x_inpointer + MAX_ARG) % MAX_ARG] * (float)(x->x_index - k);
- j--; /* go back in array */
- while(l--) /* check if this will result in a valid value */
- {
- if(x->x_intime[(j + x->x_inpointer + MAX_ARG) % MAX_ARG] == 0)
- {
- j--; /* go back more if necessary */
- }
- else break; /* finished on first non-zero */
- }
- }
- } else post("history: internal error!");
- }
- }
- }
- else x->x_average = x->x_input[x->x_inpointer];
-
- if(++x->x_inpointer > MAX_ARG)
- {
- x->x_inpointer = 0;
- }
- outlet_float(x->x_outfloat, x->x_average);
-}
-
-static void history_time(t_history *x, t_floatarg f)
-{
- x->x_time = (t_int)f;
- if(x->x_time < 1) x->x_time = 1;
- if(x->x_time > MAX_TIME)x->x_time = MAX_TIME;
- clock_unset(x->x_clock);
- clock_delay(x->x_clock, 0);
-}
-
-static void history_reset(t_history *x)
-{
- int i;
- /* zeroe out the array */
- for(i = 0; i < MAX_ARG; i++)
- {
- x->x_input[i] = 0.0;
- x->x_intime[i] = 0.0;
- }
- x->x_index = 0;
- x->x_inpointer = 0;
- x->x_average = 0;
- x->x_lastaverage = 0;
- post("history: reset");
-}
-
-static void history_linear(t_history *x)
-{
- x->x_mode = 0;
- post("history: linear");
-}
-
-static void history_geometric(t_history *x)
-{
- x->x_mode = 1;
- post("history: geometric");
-}
-
-static void history_weight(t_history *x)
-{
- x->x_mode = 2;
- post("history: weighted");
-}
-
-static void history_free(t_history *x)
-{
- clock_free(x->x_clock);
-}
-
-static t_class *history_class;
-
-static void *history_new(t_floatarg f)
-{
- int i;
-
- t_history *x = (t_history *)pd_new(history_class);
- x->x_inindex = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("time"));
- x->x_outfloat = outlet_new(&x->x_ob, gensym("float"));
- x->x_outtendency = outlet_new(&x->x_ob, gensym("float"));
- x->x_clock = clock_new(x, (t_method)history_tick);
- /* zeroe out the array */
- for(i = 0; i < MAX_ARG; i++)
- {
- x->x_input[i] = 0.0;
- x->x_intime[i] = 0.0;
- }
- x->x_time = (t_int)f;
- if(x->x_time < 1) x->x_time = 1;
- if(x->x_time > MAX_TIME)
- {
- x->x_time = MAX_TIME;
- post("history: set number time to %d", x->x_time);
- }
- x->x_index = 0;
- x->x_inpointer = 0;
- x->x_average = 0;
- x->x_mode = 0;
- clock_delay(x->x_clock, 0);
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void history_setup(void)
-{
- history_class = class_new(gensym("history"), (t_newmethod)history_new,
- (t_method)history_free, sizeof(t_history), 0, A_DEFFLOAT, 0);
- class_addmethod(history_class, (t_method)history_reset, gensym("reset"), 0);
- class_addmethod(history_class, (t_method)history_linear, gensym("linear"), 0);
- class_addmethod(history_class, (t_method)history_geometric, gensym("geometric"), 0);
- class_addmethod(history_class, (t_method)history_weight, gensym("weight"), 0);
- class_addfloat(history_class, history_float);
- class_addmethod(history_class, (t_method)history_time, gensym("time"), A_FLOAT, 0);
-
- post(version);
-}
-#else
-void maxlib_history_setup(void)
-{
- history_class = class_new(gensym("maxlib_history"), (t_newmethod)history_new,
- (t_method)history_free, sizeof(t_history), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)history_new, gensym("history"), A_DEFFLOAT, 0);
- class_addmethod(history_class, (t_method)history_reset, gensym("reset"), 0);
- class_addmethod(history_class, (t_method)history_linear, gensym("linear"), 0);
- class_addmethod(history_class, (t_method)history_geometric, gensym("geometric"), 0);
- class_addmethod(history_class, (t_method)history_weight, gensym("weight"), 0);
- class_addfloat(history_class, history_float);
- class_addmethod(history_class, (t_method)history_time, gensym("time"), A_FLOAT, 0);
- class_sethelpsymbol(history_class, gensym("maxlib/history-help.pd"));
-}
-#endif
+/* -------------------------- history ----------------------------------------- */
+/* */
+/* Calculates the average value of the elements within the last N seconds. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <math.h>
+
+#define MAX_ARG 1024 /* maximum number of items to average */
+#define MAX_TIME 60000 /* maximum time to look back */
+
+static char *version = "history v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct history
+{
+ t_object x_ob;
+ t_clock *x_clock;
+ t_inlet *x_inindex;
+ t_outlet *x_outfloat; /* output the history */
+ t_outlet *x_outtendency; /* outputs the tendency of the average */
+ t_int x_limit; /* indicates if input is 'blocked' (1) */
+ t_int x_index; /* the number of elements to average */
+ t_float x_input[MAX_ARG]; /* stores the input values we need for averaging */
+ double x_intime[MAX_ARG]; /* stores the time of arrival of an element */
+ t_int x_inpointer; /* actual position in above array */
+ t_float x_average; /* what do you guess ? */
+ t_float x_lastaverage;
+ t_int x_mode; /* how to history: linear or geometric */
+ t_int x_time;
+
+} t_history;
+
+ /* there must be a function for this in math.h but how is the
+ german 'Fakultät' called in english ???? */
+static int normalise(int i)
+{
+ int ret = i;
+ while(i--)
+ {
+ if(i == 0)break;
+ ret += i;
+ }
+ return (ret);
+}
+
+static void history_tick(t_history *x)
+{
+ t_float tendency = 0.0;
+ if(x->x_lastaverage < x->x_average)
+ {
+ tendency = 1.0; /* getting more */
+ }
+ else if(x->x_lastaverage > x->x_average)
+ {
+ tendency = -1.0; /* getting less */
+ }
+ else tendency = 0.0; /* nothing has changed */
+ outlet_float(x->x_outtendency, tendency);
+ x->x_lastaverage = x->x_average;
+ clock_delay(x->x_clock, x->x_time);
+}
+
+static void history_float(t_history *x, t_floatarg f)
+{
+ int i, j = 0, k = 0, l;
+ t_float geo = 1.0;
+
+ x->x_average = 0;
+ /* put value into array */
+ x->x_input[x->x_inpointer] = f;
+ x->x_intime[x->x_inpointer] = clock_getlogicaltime();
+ /* look for elements that are too old */
+ x->x_index = 0;
+ for(i = 0; i < MAX_ARG; i++) /* check all valid elements */
+ {
+ if(x->x_intime[i] != 0)
+ {
+ if(clock_gettimesince(x->x_intime[i]) <= x->x_time) /* it's in our time window */
+ {
+ x->x_index++; /* count valid entries */
+ }
+ else /* too old, delete entry */
+ {
+ x->x_intime[i] = 0;
+ }
+ }
+ }
+ if(x->x_index > 1)
+ {
+ /* calulate history */
+ for(i = 0; i < MAX_ARG; i++) /* check all valid elements */
+ {
+ if(x->x_intime[i] != 0) /* it's a valid entry */
+ {
+ k++;
+ l = MAX_ARG;
+
+ if(x->x_mode == 0) /* linear */
+ {
+ x->x_average += x->x_input[i] * (1.0 / (float)x->x_index);
+ }
+ else if(x->x_mode == 1) /* geometric */
+ {
+ if(x->x_input[i] == 0)x->x_input[i] = 0.001; /* need to cheat a bit... */
+ geo *= x->x_input[i];
+ if(k == x->x_index)
+ x->x_average = pow(geo, (1.0/(float)x->x_index));
+ }
+ else if(x->x_mode == 2) /* weighted */
+ {
+ /* normalise output */
+ if(k == x->x_index)
+ {
+ x->x_average += x->x_input[(j + x->x_inpointer + MAX_ARG) % MAX_ARG] * (float)(x->x_index - k);
+ x->x_average = x->x_average / (float)normalise(x->x_index - 1);
+ }
+ else
+ {
+ x->x_average += x->x_input[(j + x->x_inpointer + MAX_ARG) % MAX_ARG] * (float)(x->x_index - k);
+ j--; /* go back in array */
+ while(l--) /* check if this will result in a valid value */
+ {
+ if(x->x_intime[(j + x->x_inpointer + MAX_ARG) % MAX_ARG] == 0)
+ {
+ j--; /* go back more if necessary */
+ }
+ else break; /* finished on first non-zero */
+ }
+ }
+ } else post("history: internal error!");
+ }
+ }
+ }
+ else x->x_average = x->x_input[x->x_inpointer];
+
+ if(++x->x_inpointer > MAX_ARG)
+ {
+ x->x_inpointer = 0;
+ }
+ outlet_float(x->x_outfloat, x->x_average);
+}
+
+static void history_time(t_history *x, t_floatarg f)
+{
+ x->x_time = (t_int)f;
+ if(x->x_time < 1) x->x_time = 1;
+ if(x->x_time > MAX_TIME)x->x_time = MAX_TIME;
+ clock_unset(x->x_clock);
+ clock_delay(x->x_clock, 0);
+}
+
+static void history_reset(t_history *x)
+{
+ int i;
+ /* zeroe out the array */
+ for(i = 0; i < MAX_ARG; i++)
+ {
+ x->x_input[i] = 0.0;
+ x->x_intime[i] = 0.0;
+ }
+ x->x_index = 0;
+ x->x_inpointer = 0;
+ x->x_average = 0;
+ x->x_lastaverage = 0;
+ post("history: reset");
+}
+
+static void history_linear(t_history *x)
+{
+ x->x_mode = 0;
+ post("history: linear");
+}
+
+static void history_geometric(t_history *x)
+{
+ x->x_mode = 1;
+ post("history: geometric");
+}
+
+static void history_weight(t_history *x)
+{
+ x->x_mode = 2;
+ post("history: weighted");
+}
+
+static void history_free(t_history *x)
+{
+ clock_free(x->x_clock);
+}
+
+static t_class *history_class;
+
+static void *history_new(t_floatarg f)
+{
+ int i;
+
+ t_history *x = (t_history *)pd_new(history_class);
+ x->x_inindex = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("time"));
+ x->x_outfloat = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outtendency = outlet_new(&x->x_ob, gensym("float"));
+ x->x_clock = clock_new(x, (t_method)history_tick);
+ /* zeroe out the array */
+ for(i = 0; i < MAX_ARG; i++)
+ {
+ x->x_input[i] = 0.0;
+ x->x_intime[i] = 0.0;
+ }
+ x->x_time = (t_int)f;
+ if(x->x_time < 1) x->x_time = 1;
+ if(x->x_time > MAX_TIME)
+ {
+ x->x_time = MAX_TIME;
+ post("history: set number time to %d", x->x_time);
+ }
+ x->x_index = 0;
+ x->x_inpointer = 0;
+ x->x_average = 0;
+ x->x_mode = 0;
+ clock_delay(x->x_clock, 0);
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void history_setup(void)
+{
+ history_class = class_new(gensym("history"), (t_newmethod)history_new,
+ (t_method)history_free, sizeof(t_history), 0, A_DEFFLOAT, 0);
+ class_addmethod(history_class, (t_method)history_reset, gensym("reset"), 0);
+ class_addmethod(history_class, (t_method)history_linear, gensym("linear"), 0);
+ class_addmethod(history_class, (t_method)history_geometric, gensym("geometric"), 0);
+ class_addmethod(history_class, (t_method)history_weight, gensym("weight"), 0);
+ class_addfloat(history_class, history_float);
+ class_addmethod(history_class, (t_method)history_time, gensym("time"), A_FLOAT, 0);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_history_setup(void)
+{
+ history_class = class_new(gensym("maxlib_history"), (t_newmethod)history_new,
+ (t_method)history_free, sizeof(t_history), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)history_new, gensym("history"), A_DEFFLOAT, 0);
+ class_addmethod(history_class, (t_method)history_reset, gensym("reset"), 0);
+ class_addmethod(history_class, (t_method)history_linear, gensym("linear"), 0);
+ class_addmethod(history_class, (t_method)history_geometric, gensym("geometric"), 0);
+ class_addmethod(history_class, (t_method)history_weight, gensym("weight"), 0);
+ class_addfloat(history_class, history_float);
+ class_addmethod(history_class, (t_method)history_time, gensym("time"), A_FLOAT, 0);
+ class_sethelpsymbol(history_class, gensym("maxlib/history-help.pd"));
+}
+#endif
diff --git a/ignore.c b/ignore.c
index 4dda16d..098751d 100644
--- a/ignore.c
+++ b/ignore.c
@@ -1,119 +1,119 @@
-/* ------------------------- ignore ------------------------------------------- */
-/* */
-/* Ignores input that is followed by next value faster than N ms. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-
-static char *version = "ignore v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct ignore
-{
- t_object x_ob;
- t_clock *x_clock;
- t_inlet *x_intime;
- t_outlet *x_outfloat;
- t_float x_input;
- t_float x_lastinput;
- t_int x_limit; /* indicates if input is 'blocked' (1) */
- t_int x_time; /* the time in ms */
-} t_ignore;
-
-static void ignore_tick(t_ignore *x)
-{
- x->x_limit = 0;
- /* output in case nothing has changed */
- if(x->x_lastinput == x->x_input)
- outlet_float(x->x_outfloat, x->x_lastinput);
-}
-
-static void ignore_float(t_ignore *x, t_floatarg f)
-{
- x->x_input = f;
- if(!x->x_limit)
- {
- x->x_limit = 1; /* ignore input within next N ms */
- clock_delay(x->x_clock, x->x_time); /* start clock */
- }
- else /* ignore / start clock again */
- {
- x->x_lastinput = x->x_input; /* save current as last valid value */
- clock_unset(x->x_clock); /* throw out last clock */
- clock_delay(x->x_clock, x->x_time); /* start new clock */
- }
-}
-
-static void ignore_time(t_ignore *x, t_floatarg f)
-{
- x->x_time = (t_int)f;
-}
-
-static void ignore_reset(t_ignore *x)
-{
- x->x_limit = 0;
- post("ignore: reset");
-}
-
-static void ignore_free(t_ignore *x)
-{
- clock_free(x->x_clock);
-}
-
-static t_class *ignore_class;
-
-static void *ignore_new(t_floatarg f)
-{
- t_ignore *x = (t_ignore *)pd_new(ignore_class);
- x->x_intime = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("time"));
- x->x_outfloat = outlet_new(&x->x_ob, gensym("float"));
- x->x_clock = clock_new(x, (t_method)ignore_tick);
-
- x->x_time = (t_int)f;
- x->x_lastinput = 0;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void ignore_setup(void)
-{
- ignore_class = class_new(gensym("ignore"), (t_newmethod)ignore_new,
- (t_method)ignore_free, sizeof(t_ignore), 0, A_DEFFLOAT, 0);
- class_addmethod(ignore_class, (t_method)ignore_reset, gensym("reset"), 0);
- class_addmethod(ignore_class, (t_method)ignore_time, gensym("time"), A_FLOAT, 0);
- class_addfloat(ignore_class, ignore_float);
-
- post(version);
-}
-#else
-void maxlib_ignore_setup(void)
-{
- ignore_class = class_new(gensym("maxlib_ignore"), (t_newmethod)ignore_new,
- (t_method)ignore_free, sizeof(t_ignore), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)ignore_new, gensym("ignore"), A_DEFFLOAT, 0);
- class_addmethod(ignore_class, (t_method)ignore_reset, gensym("reset"), 0);
- class_addmethod(ignore_class, (t_method)ignore_time, gensym("time"), A_FLOAT, 0);
- class_addfloat(ignore_class, ignore_float);
- class_sethelpsymbol(ignore_class, gensym("maxlib/ignore-help.pd"));
-}
-#endif
-
+/* ------------------------- ignore ------------------------------------------- */
+/* */
+/* Ignores input that is followed by next value faster than N ms. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+static char *version = "ignore v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct ignore
+{
+ t_object x_ob;
+ t_clock *x_clock;
+ t_inlet *x_intime;
+ t_outlet *x_outfloat;
+ t_float x_input;
+ t_float x_lastinput;
+ t_int x_limit; /* indicates if input is 'blocked' (1) */
+ t_int x_time; /* the time in ms */
+} t_ignore;
+
+static void ignore_tick(t_ignore *x)
+{
+ x->x_limit = 0;
+ /* output in case nothing has changed */
+ if(x->x_lastinput == x->x_input)
+ outlet_float(x->x_outfloat, x->x_lastinput);
+}
+
+static void ignore_float(t_ignore *x, t_floatarg f)
+{
+ x->x_input = f;
+ if(!x->x_limit)
+ {
+ x->x_limit = 1; /* ignore input within next N ms */
+ clock_delay(x->x_clock, x->x_time); /* start clock */
+ }
+ else /* ignore / start clock again */
+ {
+ x->x_lastinput = x->x_input; /* save current as last valid value */
+ clock_unset(x->x_clock); /* throw out last clock */
+ clock_delay(x->x_clock, x->x_time); /* start new clock */
+ }
+}
+
+static void ignore_time(t_ignore *x, t_floatarg f)
+{
+ x->x_time = (t_int)f;
+}
+
+static void ignore_reset(t_ignore *x)
+{
+ x->x_limit = 0;
+ post("ignore: reset");
+}
+
+static void ignore_free(t_ignore *x)
+{
+ clock_free(x->x_clock);
+}
+
+static t_class *ignore_class;
+
+static void *ignore_new(t_floatarg f)
+{
+ t_ignore *x = (t_ignore *)pd_new(ignore_class);
+ x->x_intime = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("time"));
+ x->x_outfloat = outlet_new(&x->x_ob, gensym("float"));
+ x->x_clock = clock_new(x, (t_method)ignore_tick);
+
+ x->x_time = (t_int)f;
+ x->x_lastinput = 0;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void ignore_setup(void)
+{
+ ignore_class = class_new(gensym("ignore"), (t_newmethod)ignore_new,
+ (t_method)ignore_free, sizeof(t_ignore), 0, A_DEFFLOAT, 0);
+ class_addmethod(ignore_class, (t_method)ignore_reset, gensym("reset"), 0);
+ class_addmethod(ignore_class, (t_method)ignore_time, gensym("time"), A_FLOAT, 0);
+ class_addfloat(ignore_class, ignore_float);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_ignore_setup(void)
+{
+ ignore_class = class_new(gensym("maxlib_ignore"), (t_newmethod)ignore_new,
+ (t_method)ignore_free, sizeof(t_ignore), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)ignore_new, gensym("ignore"), A_DEFFLOAT, 0);
+ class_addmethod(ignore_class, (t_method)ignore_reset, gensym("reset"), 0);
+ class_addmethod(ignore_class, (t_method)ignore_time, gensym("time"), A_FLOAT, 0);
+ class_addfloat(ignore_class, ignore_float);
+ class_sethelpsymbol(ignore_class, gensym("maxlib/ignore-help.pd"));
+}
+#endif
+
diff --git a/iso.c b/iso.c
index 43af2b1..69a13ec 100644
--- a/iso.c
+++ b/iso.c
@@ -1,219 +1,219 @@
-/* ---------------------------- iso ------------------------------------------- */
-/* */
-/* Queue up pitch and attack point series. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on iso for Max by Charlie Baker (baker@foxtrot.ccmrc.ucsb.edu). */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-
-#define MAXPOLY 32
-
-static char *version = "iso v0.1, written for Max by Charlie Baker <baker@foxtrot.ccmrc.ucsb.edu>\n"
- " ported to Pd by Olaf Matthes <olaf.matthes@gmx.de>";
-
-/* Iso object data structure */
-
-typedef struct iso
-{
- t_object iso_ob;
- t_outlet *iso_out1; /* outlet 1*/
- t_outlet *iso_out2; /* outlet 2*/
- t_inlet *iso_in2; /* inlet 2 (attack list) */
- t_clock *iso_clock;
- t_int ptchlength,atklength,curptch,curatk;
- t_float pitches[MAXPOLY];
- t_float atks[MAXPOLY];
- t_int loop,stop;
- t_float hook,duty;
-} t_iso;
-
-static t_class *iso_class;
-
-/* take list and create matrix */
-
-static void iso_bang(t_iso *x)
-{
- x->stop = 0;
- x->curptch = 0;
- x->curatk = 0;
- clock_delay(x->iso_clock, 0);
-}
-
-
-static void iso_clock_fun(t_iso *x)
-{
- if (!x->stop) {
- clock_delay(x->iso_clock, (double)(x->atks[x->curatk] * x->hook));
- outlet_float(x->iso_out2,(t_float)(x->atks[x->curatk] * x->hook * x->duty));
- outlet_float(x->iso_out1,x->pitches[x->curptch] );
- if (x->loop) {
- x->curatk = ((x->curatk + 1) % x->atklength);
- x->curptch = ((x->curptch + 1) % x->ptchlength);
- }
- else {
- if (((x->curatk + 1) >= x->atklength) || ((x->curptch + 1) >= x->ptchlength))
- x->stop = 1;
- else {
- x->curptch += 1;
- x->curatk += 1;
- }
- }
- }
-}
-
-static void iso_hook(t_iso *x, t_floatarg hook)
-{
- if (hook < 1.0) hook = 1.0;
- x->hook = (t_float)hook;
-}
-
-static void iso_duty(t_iso *x, t_floatarg duty)
-{
- if (duty < 1.0) duty = 1.0;
- x->duty = (t_float)duty;
-}
-
-static void iso_list(t_iso *x, t_symbol *s, t_int argc, t_atom* argv)
-{
- int i;
- if (argc > MAXPOLY) post("iso: only %d values max. allowed in list!", MAXPOLY);
- for (i = 0; i < argc; i++) x->atks[i] = argv[i].a_w.w_float;
- x->atklength = argc;
-}
-
-static void iso_pitch(t_iso *x, t_symbol *s, t_int argc, t_atom* argv)
-{
- int i;
- if (argc > MAXPOLY) post("iso: only %d values max. allowed in list!", MAXPOLY);
- for (i = 0; i < argc; i++) x->pitches[i] = argv[i].a_w.w_float;
- x->ptchlength = argc;
-}
-
-static void iso_start(t_iso *x, t_symbol *s, t_int argc, t_atom* argv)
-{
- t_int start = atom_getfloatarg(0, argc, argv);
- x->stop = 0;
- if (start) {
- x->curptch = (t_int)((start - 1) % x->ptchlength);
- x->curatk = (t_int)((start - 1) % x->atklength);
- }
- else {
- x->curptch = 0;
- x->curatk = 0;
- }
- clock_delay(x->iso_clock, 0);
-}
-
-static void iso_stop(t_iso *x)
-{
- x->stop = 1;
- x->curatk = 0;
- x->curptch = 0;
-}
-
-static void iso_pause(t_iso *x)
-{
- x->stop = 1;
-}
-
-static void iso_loop(t_iso *x)
-{
- x->loop = 1;
-}
-
-static void iso_resume(t_iso *x)
-{
- x->stop = 0;
- clock_delay(x->iso_clock, 0);
-}
-
-static void iso_unloop(t_iso *x)
-{
- x->loop = 0;
-}
-
-
-static void *iso_new(void) {
- t_iso *x = (t_iso *)pd_new(iso_class); /* allocates memory and sticks in an inlet */
- x->iso_clock = clock_new(x, (t_method)iso_clock_fun);
- x->iso_out1 = outlet_new(&x->iso_ob, gensym("float"));
- x->iso_out2 = outlet_new(&x->iso_ob, gensym("float"));
- x->iso_in2 = inlet_new(&x->iso_ob, &x->iso_ob.ob_pd, gensym("list"), gensym("attack"));
- x->stop = 0;
- x->loop = 1;
- x->hook = 1.0;
- x->curptch = 0;
- x->curatk = 0;
- x->ptchlength = 1;
- x->atklength = 1;
- x->pitches[0] = 60;
- x->atks[0] = 500;
- x->duty = 1.0;
-
- return (x); /* always return a copy of the created object */
-}
-
-static void iso_free(t_iso *x) {
-
- clock_free(x->iso_clock);
-}
-
-#ifndef MAXLIB
-void iso_setup(void) {
-
- iso_class = class_new(gensym("iso"), (t_newmethod)iso_new,
- (t_method)iso_free, sizeof(t_iso), 0, 0);
- class_addmethod(iso_class, (t_method)iso_duty, gensym("duty"), A_FLOAT, 0);
- class_addmethod(iso_class, (t_method)iso_list, gensym("attack"), A_GIMME, 0);
- class_addmethod(iso_class, (t_method)iso_start, gensym("start"), A_GIMME, 0);
- class_addmethod(iso_class, (t_method)iso_stop, gensym("stop"), 0);
- class_addmethod(iso_class, (t_method)iso_pause, gensym("pause"), 0);
- class_addmethod(iso_class, (t_method)iso_loop, gensym("loop"), 0);
- class_addmethod(iso_class, (t_method)iso_unloop, gensym("unloop"), 0);
- class_addmethod(iso_class, (t_method)iso_resume, gensym("resume"), 0);
- class_addmethod(iso_class, (t_method)iso_hook, gensym("hook"), A_FLOAT, 0);
- class_addbang(iso_class, iso_bang);
- class_addlist(iso_class, iso_pitch);
-
- post(version);
-}
-#else
-void maxlib_iso_setup(void) {
-
- iso_class = class_new(gensym("maxlib_iso"), (t_newmethod)iso_new,
- (t_method)iso_free, sizeof(t_iso), 0, 0);
- class_addcreator((t_newmethod)iso_new, gensym("iso"), 0);
- class_addmethod(iso_class, (t_method)iso_duty, gensym("duty"), A_FLOAT, 0);
- class_addmethod(iso_class, (t_method)iso_list, gensym("attack"), A_GIMME, 0);
- class_addmethod(iso_class, (t_method)iso_start, gensym("start"), A_GIMME, 0);
- class_addmethod(iso_class, (t_method)iso_stop, gensym("stop"), 0);
- class_addmethod(iso_class, (t_method)iso_pause, gensym("pause"), 0);
- class_addmethod(iso_class, (t_method)iso_loop, gensym("loop"), 0);
- class_addmethod(iso_class, (t_method)iso_unloop, gensym("unloop"), 0);
- class_addmethod(iso_class, (t_method)iso_resume, gensym("resume"), 0);
- class_addmethod(iso_class, (t_method)iso_hook, gensym("hook"), A_FLOAT, 0);
- class_addbang(iso_class, iso_bang);
- class_addlist(iso_class, iso_pitch);
- class_sethelpsymbol(iso_class, gensym("maxlib/iso-help.pd"));
-}
-#endif
+/* ---------------------------- iso ------------------------------------------- */
+/* */
+/* Queue up pitch and attack point series. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on iso for Max by Charlie Baker (baker@foxtrot.ccmrc.ucsb.edu). */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+
+#define MAXPOLY 32
+
+static char *version = "iso v0.1, written for Max by Charlie Baker <baker@foxtrot.ccmrc.ucsb.edu>\n"
+ " ported to Pd by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* Iso object data structure */
+
+typedef struct iso
+{
+ t_object iso_ob;
+ t_outlet *iso_out1; /* outlet 1*/
+ t_outlet *iso_out2; /* outlet 2*/
+ t_inlet *iso_in2; /* inlet 2 (attack list) */
+ t_clock *iso_clock;
+ t_int ptchlength,atklength,curptch,curatk;
+ t_float pitches[MAXPOLY];
+ t_float atks[MAXPOLY];
+ t_int loop,stop;
+ t_float hook,duty;
+} t_iso;
+
+static t_class *iso_class;
+
+/* take list and create matrix */
+
+static void iso_bang(t_iso *x)
+{
+ x->stop = 0;
+ x->curptch = 0;
+ x->curatk = 0;
+ clock_delay(x->iso_clock, 0);
+}
+
+
+static void iso_clock_fun(t_iso *x)
+{
+ if (!x->stop) {
+ clock_delay(x->iso_clock, (double)(x->atks[x->curatk] * x->hook));
+ outlet_float(x->iso_out2,(t_float)(x->atks[x->curatk] * x->hook * x->duty));
+ outlet_float(x->iso_out1,x->pitches[x->curptch] );
+ if (x->loop) {
+ x->curatk = ((x->curatk + 1) % x->atklength);
+ x->curptch = ((x->curptch + 1) % x->ptchlength);
+ }
+ else {
+ if (((x->curatk + 1) >= x->atklength) || ((x->curptch + 1) >= x->ptchlength))
+ x->stop = 1;
+ else {
+ x->curptch += 1;
+ x->curatk += 1;
+ }
+ }
+ }
+}
+
+static void iso_hook(t_iso *x, t_floatarg hook)
+{
+ if (hook < 1.0) hook = 1.0;
+ x->hook = (t_float)hook;
+}
+
+static void iso_duty(t_iso *x, t_floatarg duty)
+{
+ if (duty < 1.0) duty = 1.0;
+ x->duty = (t_float)duty;
+}
+
+static void iso_list(t_iso *x, t_symbol *s, t_int argc, t_atom* argv)
+{
+ int i;
+ if (argc > MAXPOLY) post("iso: only %d values max. allowed in list!", MAXPOLY);
+ for (i = 0; i < argc; i++) x->atks[i] = argv[i].a_w.w_float;
+ x->atklength = argc;
+}
+
+static void iso_pitch(t_iso *x, t_symbol *s, t_int argc, t_atom* argv)
+{
+ int i;
+ if (argc > MAXPOLY) post("iso: only %d values max. allowed in list!", MAXPOLY);
+ for (i = 0; i < argc; i++) x->pitches[i] = argv[i].a_w.w_float;
+ x->ptchlength = argc;
+}
+
+static void iso_start(t_iso *x, t_symbol *s, t_int argc, t_atom* argv)
+{
+ t_int start = atom_getfloatarg(0, argc, argv);
+ x->stop = 0;
+ if (start) {
+ x->curptch = (t_int)((start - 1) % x->ptchlength);
+ x->curatk = (t_int)((start - 1) % x->atklength);
+ }
+ else {
+ x->curptch = 0;
+ x->curatk = 0;
+ }
+ clock_delay(x->iso_clock, 0);
+}
+
+static void iso_stop(t_iso *x)
+{
+ x->stop = 1;
+ x->curatk = 0;
+ x->curptch = 0;
+}
+
+static void iso_pause(t_iso *x)
+{
+ x->stop = 1;
+}
+
+static void iso_loop(t_iso *x)
+{
+ x->loop = 1;
+}
+
+static void iso_resume(t_iso *x)
+{
+ x->stop = 0;
+ clock_delay(x->iso_clock, 0);
+}
+
+static void iso_unloop(t_iso *x)
+{
+ x->loop = 0;
+}
+
+
+static void *iso_new(void) {
+ t_iso *x = (t_iso *)pd_new(iso_class); /* allocates memory and sticks in an inlet */
+ x->iso_clock = clock_new(x, (t_method)iso_clock_fun);
+ x->iso_out1 = outlet_new(&x->iso_ob, gensym("float"));
+ x->iso_out2 = outlet_new(&x->iso_ob, gensym("float"));
+ x->iso_in2 = inlet_new(&x->iso_ob, &x->iso_ob.ob_pd, gensym("list"), gensym("attack"));
+ x->stop = 0;
+ x->loop = 1;
+ x->hook = 1.0;
+ x->curptch = 0;
+ x->curatk = 0;
+ x->ptchlength = 1;
+ x->atklength = 1;
+ x->pitches[0] = 60;
+ x->atks[0] = 500;
+ x->duty = 1.0;
+
+ return (x); /* always return a copy of the created object */
+}
+
+static void iso_free(t_iso *x) {
+
+ clock_free(x->iso_clock);
+}
+
+#ifndef MAXLIB
+void iso_setup(void) {
+
+ iso_class = class_new(gensym("iso"), (t_newmethod)iso_new,
+ (t_method)iso_free, sizeof(t_iso), 0, 0);
+ class_addmethod(iso_class, (t_method)iso_duty, gensym("duty"), A_FLOAT, 0);
+ class_addmethod(iso_class, (t_method)iso_list, gensym("attack"), A_GIMME, 0);
+ class_addmethod(iso_class, (t_method)iso_start, gensym("start"), A_GIMME, 0);
+ class_addmethod(iso_class, (t_method)iso_stop, gensym("stop"), 0);
+ class_addmethod(iso_class, (t_method)iso_pause, gensym("pause"), 0);
+ class_addmethod(iso_class, (t_method)iso_loop, gensym("loop"), 0);
+ class_addmethod(iso_class, (t_method)iso_unloop, gensym("unloop"), 0);
+ class_addmethod(iso_class, (t_method)iso_resume, gensym("resume"), 0);
+ class_addmethod(iso_class, (t_method)iso_hook, gensym("hook"), A_FLOAT, 0);
+ class_addbang(iso_class, iso_bang);
+ class_addlist(iso_class, iso_pitch);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_iso_setup(void) {
+
+ iso_class = class_new(gensym("maxlib_iso"), (t_newmethod)iso_new,
+ (t_method)iso_free, sizeof(t_iso), 0, 0);
+ class_addcreator((t_newmethod)iso_new, gensym("iso"), 0);
+ class_addmethod(iso_class, (t_method)iso_duty, gensym("duty"), A_FLOAT, 0);
+ class_addmethod(iso_class, (t_method)iso_list, gensym("attack"), A_GIMME, 0);
+ class_addmethod(iso_class, (t_method)iso_start, gensym("start"), A_GIMME, 0);
+ class_addmethod(iso_class, (t_method)iso_stop, gensym("stop"), 0);
+ class_addmethod(iso_class, (t_method)iso_pause, gensym("pause"), 0);
+ class_addmethod(iso_class, (t_method)iso_loop, gensym("loop"), 0);
+ class_addmethod(iso_class, (t_method)iso_unloop, gensym("unloop"), 0);
+ class_addmethod(iso_class, (t_method)iso_resume, gensym("resume"), 0);
+ class_addmethod(iso_class, (t_method)iso_hook, gensym("hook"), A_FLOAT, 0);
+ class_addbang(iso_class, iso_bang);
+ class_addlist(iso_class, iso_pitch);
+ class_sethelpsymbol(iso_class, gensym("maxlib/iso-help.pd"));
+}
+#endif
diff --git a/lifo.c b/lifo.c
index 81e2dc0..3f062ae 100644
--- a/lifo.c
+++ b/lifo.c
@@ -1,109 +1,109 @@
-/* ---------------------------- lifo ------------------------------------------ */
-/* */
-/* lifo buffer of floats, empties itselfe on every bang (in order of coming in) */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* Fifi-code based St. Rainstick fifo.c for Max, */
-/* copyright St. Rainstick, Amsterdam 1995 */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-
-static char *version = "lifo v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct lifo
-{
- t_object d_ob;
- t_float *getal;
- t_int size, teller;
- t_outlet *out;
-
-}t_lifo;
-
-static t_class *lifo_class;
-
-static void lifo_int(t_lifo *x, t_floatarg n)
+/* ---------------------------- lifo ------------------------------------------ */
+/* */
+/* lifo buffer of floats, empties itselfe on every bang (in order of coming in) */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* Fifi-code based St. Rainstick fifo.c for Max, */
+/* copyright St. Rainstick, Amsterdam 1995 */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+static char *version = "lifo v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct lifo
+{
+ t_object d_ob;
+ t_float *getal;
+ t_int size, teller;
+ t_outlet *out;
+
+}t_lifo;
+
+static t_class *lifo_class;
+
+static void lifo_int(t_lifo *x, t_floatarg n)
{
if(x->teller < x->size )
{
- x->getal[x->teller] = n;
+ x->getal[x->teller] = n;
x->teller++;
}
else
post("no more lifo memory");
-
-}
-
-static void lifo_bang(t_lifo *x)
-{
+
+}
+
+static void lifo_bang(t_lifo *x)
+{
if (x->teller > 0)
- {
- outlet_float(x->out,x->getal[x->teller-1]);
- x->teller--;
- }
-}
-
-static void lifo_clear(t_lifo *x)
-{
- x->teller = 0;
-}
-
-static void lifo_free(t_lifo *x)
-{
- freebytes(x->getal, x->size * sizeof(t_float));
-}
-
-static void *lifo_new(t_floatarg n)
-{
-
- t_lifo *x = (t_lifo *)pd_new(lifo_class);
- if (n<10) n = 10;
- x->size = (t_int)n;
- x->teller = 0;
- x->getal = (t_float *)getbytes(x->size * sizeof(t_float));
- x->out = outlet_new(&x->d_ob, gensym("float"));
-
- return (x);
-}
-
-#ifndef MAXLIB
-void lifo_setup(void)
-{
- lifo_class = class_new(gensym("lifo"), (t_newmethod)lifo_new,
- (t_method)lifo_free, sizeof(t_lifo), 0, A_DEFFLOAT, 0);
- class_addfloat(lifo_class, lifo_int);
- class_addbang(lifo_class, lifo_bang);
- class_addmethod(lifo_class, (t_method)lifo_clear, gensym("clear"), 0);
-
- post(version);
-}
-#else
-void maxlib_lifo_setup(void)
-{
- lifo_class = class_new(gensym("maxlib_lifo"), (t_newmethod)lifo_new,
- (t_method)lifo_free, sizeof(t_lifo), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)lifo_new, gensym("lifo"), A_DEFFLOAT, 0);
- class_addfloat(lifo_class, lifo_int);
- class_addbang(lifo_class, lifo_bang);
- class_addmethod(lifo_class, (t_method)lifo_clear, gensym("clear"), 0);
- class_sethelpsymbol(lifo_class, gensym("maxlib/lifo-help.pd"));
-}
-#endif
+ {
+ outlet_float(x->out,x->getal[x->teller-1]);
+ x->teller--;
+ }
+}
+
+static void lifo_clear(t_lifo *x)
+{
+ x->teller = 0;
+}
+
+static void lifo_free(t_lifo *x)
+{
+ freebytes(x->getal, x->size * sizeof(t_float));
+}
+
+static void *lifo_new(t_floatarg n)
+{
+
+ t_lifo *x = (t_lifo *)pd_new(lifo_class);
+ if (n<10) n = 10;
+ x->size = (t_int)n;
+ x->teller = 0;
+ x->getal = (t_float *)getbytes(x->size * sizeof(t_float));
+ x->out = outlet_new(&x->d_ob, gensym("float"));
+
+ return (x);
+}
+
+#ifndef MAXLIB
+void lifo_setup(void)
+{
+ lifo_class = class_new(gensym("lifo"), (t_newmethod)lifo_new,
+ (t_method)lifo_free, sizeof(t_lifo), 0, A_DEFFLOAT, 0);
+ class_addfloat(lifo_class, lifo_int);
+ class_addbang(lifo_class, lifo_bang);
+ class_addmethod(lifo_class, (t_method)lifo_clear, gensym("clear"), 0);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_lifo_setup(void)
+{
+ lifo_class = class_new(gensym("maxlib_lifo"), (t_newmethod)lifo_new,
+ (t_method)lifo_free, sizeof(t_lifo), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)lifo_new, gensym("lifo"), A_DEFFLOAT, 0);
+ class_addfloat(lifo_class, lifo_int);
+ class_addbang(lifo_class, lifo_bang);
+ class_addmethod(lifo_class, (t_method)lifo_clear, gensym("clear"), 0);
+ class_sethelpsymbol(lifo_class, gensym("maxlib/lifo-help.pd"));
+}
+#endif
diff --git a/limit.c b/limit.c
index cf3d97a..cfd79ea 100644
--- a/limit.c
+++ b/limit.c
@@ -1,125 +1,125 @@
-/* ------------------------- limit ------------------------------------------ */
-/* */
-/* limits input to lie within an output range. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <math.h>
-
-static char *version = "limit v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct limit
-{
- t_object x_ob;
- t_float x_ol; /* low border of output range */
- t_float x_oh; /* high border of output range */
- t_float x_ratio; /* 'compression ratio' */
- t_outlet *x_outlet1; /* result */
- t_float x_f;
-} t_limit;
-
-static void limit_float(t_limit *x, t_floatarg f)
-{
- if(x->x_oh < x->x_ol) /* swap values */
- {
- int i = x->x_oh;
- x->x_oh = x->x_ol;
- x->x_ol = i;
- }
- if(x->x_ratio == 0) /* 'clip' mode */
- {
- if(f > x->x_oh)f = x->x_oh;
- else if(f < x->x_ol)f = x->x_ol;
- }
- else /* 'compress' mode */
- {
- int diff;
- if(f > x->x_oh)
- {
- diff = f - x->x_oh;
- f = x->x_oh + (diff / x->x_ratio);
- }
- else if(f < x->x_ol)
- {
- diff = x->x_ol - f;
- f = x->x_ol - (diff / x->x_ratio);
- }
- }
- outlet_float(x->x_outlet1, f);
- x->x_f = f;
-}
-
-static void limit_bang(t_limit *x)
-{
- limit_float(x, x->x_f); /* recalculate result */
-}
-
-static t_class *limit_class;
-
-static void *limit_new(t_floatarg fol, t_floatarg foh, t_floatarg fr)
-{
- t_limit *x = (t_limit *)pd_new(limit_class);
-
- floatinlet_new(&x->x_ob, &x->x_ol);
- floatinlet_new(&x->x_ob, &x->x_oh);
- floatinlet_new(&x->x_ob, &x->x_ratio);
-
- x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
-
- /* default values taken from Max's limit */
- x->x_ol = fol;
- x->x_oh = foh;
- if(x->x_oh < x->x_ol) /* swap values */
- {
- int i = x->x_oh;
- x->x_oh = x->x_ol;
- x->x_ol = i;
- }
- x->x_ratio = fr;
- x->x_f = 0;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void limit_setup(void)
-{
- limit_class = class_new(gensym("limit"), (t_newmethod)limit_new,
- 0, sizeof(t_limit), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
-#else
-void maxlib_limit_setup(void)
-{
- limit_class = class_new(gensym("maxlib_limit"), (t_newmethod)limit_new,
- 0, sizeof(t_limit), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)limit_new, gensym("limit"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
-#endif
- class_addfloat(limit_class, limit_float);
- class_addbang(limit_class, limit_bang);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_sethelpsymbol(limit_class, gensym("maxlib/limit-help.pd"));
-#endif
-}
-
+/* ------------------------- limit ------------------------------------------ */
+/* */
+/* limits input to lie within an output range. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+
+static char *version = "limit v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct limit
+{
+ t_object x_ob;
+ t_float x_ol; /* low border of output range */
+ t_float x_oh; /* high border of output range */
+ t_float x_ratio; /* 'compression ratio' */
+ t_outlet *x_outlet1; /* result */
+ t_float x_f;
+} t_limit;
+
+static void limit_float(t_limit *x, t_floatarg f)
+{
+ if(x->x_oh < x->x_ol) /* swap values */
+ {
+ int i = x->x_oh;
+ x->x_oh = x->x_ol;
+ x->x_ol = i;
+ }
+ if(x->x_ratio == 0) /* 'clip' mode */
+ {
+ if(f > x->x_oh)f = x->x_oh;
+ else if(f < x->x_ol)f = x->x_ol;
+ }
+ else /* 'compress' mode */
+ {
+ int diff;
+ if(f > x->x_oh)
+ {
+ diff = f - x->x_oh;
+ f = x->x_oh + (diff / x->x_ratio);
+ }
+ else if(f < x->x_ol)
+ {
+ diff = x->x_ol - f;
+ f = x->x_ol - (diff / x->x_ratio);
+ }
+ }
+ outlet_float(x->x_outlet1, f);
+ x->x_f = f;
+}
+
+static void limit_bang(t_limit *x)
+{
+ limit_float(x, x->x_f); /* recalculate result */
+}
+
+static t_class *limit_class;
+
+static void *limit_new(t_floatarg fol, t_floatarg foh, t_floatarg fr)
+{
+ t_limit *x = (t_limit *)pd_new(limit_class);
+
+ floatinlet_new(&x->x_ob, &x->x_ol);
+ floatinlet_new(&x->x_ob, &x->x_oh);
+ floatinlet_new(&x->x_ob, &x->x_ratio);
+
+ x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
+
+ /* default values taken from Max's limit */
+ x->x_ol = fol;
+ x->x_oh = foh;
+ if(x->x_oh < x->x_ol) /* swap values */
+ {
+ int i = x->x_oh;
+ x->x_oh = x->x_ol;
+ x->x_ol = i;
+ }
+ x->x_ratio = fr;
+ x->x_f = 0;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void limit_setup(void)
+{
+ limit_class = class_new(gensym("limit"), (t_newmethod)limit_new,
+ 0, sizeof(t_limit), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+#else
+void maxlib_limit_setup(void)
+{
+ limit_class = class_new(gensym("maxlib_limit"), (t_newmethod)limit_new,
+ 0, sizeof(t_limit), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)limit_new, gensym("limit"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+#endif
+ class_addfloat(limit_class, limit_float);
+ class_addbang(limit_class, limit_bang);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(limit_class, gensym("maxlib/limit-help.pd"));
+#endif
+}
+
diff --git a/linear.c b/linear.c
index 492b961..a12881d 100644
--- a/linear.c
+++ b/linear.c
@@ -1,81 +1,81 @@
-/* ---------------------------- rand_linear ----------------------------------- */
-/* */
-/* rand_linear generates a linearly distributed random variable. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-#define fran() (t_float)rand()/(t_float)RAND_MAX
-
-static char *version = "linear v0.1, generates linearly distributed random variable\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-/* -------------------------- rand_linear ------------------------------ */
-
-static t_class *rand_linear_class;
-
-typedef struct _rand_linear
-{
- t_object x_obj;
-} t_rand_linear;
-
-static void *rand_linear_new(t_floatarg f)
-{
- t_rand_linear *x = (t_rand_linear *)pd_new(rand_linear_class);
- srand( (unsigned)time( NULL ) );
- outlet_new(&x->x_obj, &s_float);
- return (x);
-}
-
-static void rand_linear_bang(t_rand_linear *x)
-{
- t_float u1, u2;
- u1 = fran();
- u2 = fran();
- if(u2 < u1)
- u1 = u2;
- outlet_float(x->x_obj.ob_outlet, u1);
-}
-
-#ifndef MAXLIB
-void linear_setup(void)
-{
- rand_linear_class = class_new(gensym("linear"), (t_newmethod)rand_linear_new, 0,
- sizeof(t_rand_linear), 0, A_DEFFLOAT, 0);
- class_addbang(rand_linear_class, rand_linear_bang);
- class_sethelpsymbol(rand_linear_class, gensym("linear-help.pd"));
- post(version);
-}
-#else
-void maxlib_linear_setup(void)
-{
- rand_linear_class = class_new(gensym("maxlib_linear"), (t_newmethod)rand_linear_new, 0,
- sizeof(t_rand_linear), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)rand_linear_new, gensym("linear"), A_DEFFLOAT, 0);
- class_addbang(rand_linear_class, rand_linear_bang);
- class_sethelpsymbol(rand_linear_class, gensym("maxlib/linear-help.pd"));
-}
-#endif
+/* ---------------------------- rand_linear ----------------------------------- */
+/* */
+/* rand_linear generates a linearly distributed random variable. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+
+#define fran() (t_float)rand()/(t_float)RAND_MAX
+
+static char *version = "linear v0.1, generates linearly distributed random variable\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- rand_linear ------------------------------ */
+
+static t_class *rand_linear_class;
+
+typedef struct _rand_linear
+{
+ t_object x_obj;
+} t_rand_linear;
+
+static void *rand_linear_new(t_floatarg f)
+{
+ t_rand_linear *x = (t_rand_linear *)pd_new(rand_linear_class);
+ srand( (unsigned)time( NULL ) );
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void rand_linear_bang(t_rand_linear *x)
+{
+ t_float u1, u2;
+ u1 = fran();
+ u2 = fran();
+ if(u2 < u1)
+ u1 = u2;
+ outlet_float(x->x_obj.ob_outlet, u1);
+}
+
+#ifndef MAXLIB
+void linear_setup(void)
+{
+ rand_linear_class = class_new(gensym("linear"), (t_newmethod)rand_linear_new, 0,
+ sizeof(t_rand_linear), 0, A_DEFFLOAT, 0);
+ class_addbang(rand_linear_class, rand_linear_bang);
+ class_sethelpsymbol(rand_linear_class, gensym("linear-help.pd"));
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_linear_setup(void)
+{
+ rand_linear_class = class_new(gensym("maxlib_linear"), (t_newmethod)rand_linear_new, 0,
+ sizeof(t_rand_linear), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)rand_linear_new, gensym("linear"), A_DEFFLOAT, 0);
+ class_addbang(rand_linear_class, rand_linear_bang);
+ class_sethelpsymbol(rand_linear_class, gensym("maxlib/linear-help.pd"));
+}
+#endif
diff --git a/listfifo.c b/listfifo.c
index 4c6e93d..9433a79 100644
--- a/listfifo.c
+++ b/listfifo.c
@@ -1,109 +1,109 @@
-/* ---------------------------- listfifo -------------------------------------- */
-/* */
-/* Fifo buffer of lists, empties itselfe on every bang (in order of coming in) */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-
-#define MAX_ELEM 256 /* maximum number of list elements to pass on */
-
-static char *version = "listfifo v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct listfifo
-{
- t_object d_ob;
- t_atom *getal; /* stores the list values */
- t_int *getsize; /* stores the number of elements in list */
- t_int count, end, size;
- t_outlet *out;
-
-}t_listfifo;
-
-static t_class *listfifo_class;
-
-static void listfifo_list(t_listfifo *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i;
- if(argc > MAX_ELEM)
- {
- post("listfifo: to many arguments in list, ignored");
- return;
- }
- for(i = 0; i < argc; i++)
- x->getal[(x->count * MAX_ELEM) + i] = argv[i];
- x->getsize[x->count] = argc;
- x->count = (x->count + 1) % x->size;
- // post("got %d elements", argc);
-}
-
-static void listfifo_bang(t_listfifo *x)
-{
- // post("count = %d, end = %d", x->count, x->end);
- if (x->end != x->count){
- outlet_list(x->out, NULL, x->getsize[x->end], x->getal+(x->end * MAX_ELEM));
- x->end = (x->end + 1) % x->size;
- }
-}
-
-static void listfifo_free(t_listfifo *x)
-{
- freebytes(x->getsize, x->size * sizeof(t_int));
- freebytes(x->getal, x->size * sizeof(t_float) * MAX_ELEM);
-}
-
-static void *listfifo_new(t_floatarg n)
-{
- int i;
-
- t_listfifo *x = (t_listfifo *)pd_new(listfifo_class);
- if (n<10) n = 10;
- x->size = (t_int)n;
- x->end = 0;
- x->count = 0;
- x->getsize = (t_int *)getbytes(x->size * sizeof(t_int));
- x->getal = (t_atom *)getbytes(x->size * sizeof(t_atom) * MAX_ELEM);
- x->out = outlet_new(&x->d_ob, gensym("list"));
-
- return (x);
-}
-
-#ifndef MAXLIB
-void listfifo_setup(void)
-{
- listfifo_class = class_new(gensym("listfifo"), (t_newmethod)listfifo_new,
- (t_method)listfifo_free, sizeof(t_listfifo), 0, A_DEFFLOAT, 0);
- class_addbang(listfifo_class, listfifo_bang);
- class_addlist(listfifo_class, listfifo_list);
-
- post(version);
-}
-#else
-void maxlib_listfifo_setup(void)
-{
- listfifo_class = class_new(gensym("maxlib_listfifo"), (t_newmethod)listfifo_new,
- (t_method)listfifo_free, sizeof(t_listfifo), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)listfifo_new, gensym("listfifo"), A_DEFFLOAT, 0);
- class_addbang(listfifo_class, listfifo_bang);
- class_addlist(listfifo_class, listfifo_list);
- class_sethelpsymbol(listfifo_class, gensym("maxlib/listfifo-help.pd"));
-}
-#endif
+/* ---------------------------- listfifo -------------------------------------- */
+/* */
+/* Fifo buffer of lists, empties itselfe on every bang (in order of coming in) */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+#define MAX_ELEM 256 /* maximum number of list elements to pass on */
+
+static char *version = "listfifo v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct listfifo
+{
+ t_object d_ob;
+ t_atom *getal; /* stores the list values */
+ t_int *getsize; /* stores the number of elements in list */
+ t_int count, end, size;
+ t_outlet *out;
+
+}t_listfifo;
+
+static t_class *listfifo_class;
+
+static void listfifo_list(t_listfifo *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ if(argc > MAX_ELEM)
+ {
+ post("listfifo: to many arguments in list, ignored");
+ return;
+ }
+ for(i = 0; i < argc; i++)
+ x->getal[(x->count * MAX_ELEM) + i] = argv[i];
+ x->getsize[x->count] = argc;
+ x->count = (x->count + 1) % x->size;
+ // post("got %d elements", argc);
+}
+
+static void listfifo_bang(t_listfifo *x)
+{
+ // post("count = %d, end = %d", x->count, x->end);
+ if (x->end != x->count){
+ outlet_list(x->out, NULL, x->getsize[x->end], x->getal+(x->end * MAX_ELEM));
+ x->end = (x->end + 1) % x->size;
+ }
+}
+
+static void listfifo_free(t_listfifo *x)
+{
+ freebytes(x->getsize, x->size * sizeof(t_int));
+ freebytes(x->getal, x->size * sizeof(t_float) * MAX_ELEM);
+}
+
+static void *listfifo_new(t_floatarg n)
+{
+ int i;
+
+ t_listfifo *x = (t_listfifo *)pd_new(listfifo_class);
+ if (n<10) n = 10;
+ x->size = (t_int)n;
+ x->end = 0;
+ x->count = 0;
+ x->getsize = (t_int *)getbytes(x->size * sizeof(t_int));
+ x->getal = (t_atom *)getbytes(x->size * sizeof(t_atom) * MAX_ELEM);
+ x->out = outlet_new(&x->d_ob, gensym("list"));
+
+ return (x);
+}
+
+#ifndef MAXLIB
+void listfifo_setup(void)
+{
+ listfifo_class = class_new(gensym("listfifo"), (t_newmethod)listfifo_new,
+ (t_method)listfifo_free, sizeof(t_listfifo), 0, A_DEFFLOAT, 0);
+ class_addbang(listfifo_class, listfifo_bang);
+ class_addlist(listfifo_class, listfifo_list);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_listfifo_setup(void)
+{
+ listfifo_class = class_new(gensym("maxlib_listfifo"), (t_newmethod)listfifo_new,
+ (t_method)listfifo_free, sizeof(t_listfifo), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)listfifo_new, gensym("listfifo"), A_DEFFLOAT, 0);
+ class_addbang(listfifo_class, listfifo_bang);
+ class_addlist(listfifo_class, listfifo_list);
+ class_sethelpsymbol(listfifo_class, gensym("maxlib/listfifo-help.pd"));
+}
+#endif
diff --git a/listfunnel.c b/listfunnel.c
index 0626057..83f3927 100644
--- a/listfunnel.c
+++ b/listfunnel.c
@@ -1,92 +1,92 @@
-/* ------------------------- listfunnel ------------------------------------- */
-/* */
-/* Convert list into two-element lists with source index. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-static char *version = "listfunnel v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct listfunnel
-{
- t_object x_ob;
- t_outlet *x_outlet; /* result */
-} t_listfunnel;
-
-static void listfunnel_list(t_listfunnel *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i;
- t_atom list[2];
-
- for(i = 0; i < argc; i++)
- {
- SETFLOAT(list, i);
- list[1] = argv[i]; // SETFLOAT(list+1, atom_getfloatarg(i, argc, argv));
- outlet_list(x->x_outlet, NULL, 2, list);
- }
-}
-
-static void listfunnel_float(t_listfunnel *x, t_floatarg f)
-{
- t_atom list[2];
-
- SETFLOAT(list, 0);
- SETFLOAT(list+1, f);
- outlet_list(x->x_outlet, NULL, 2, list);
-}
-
-static t_class *listfunnel_class;
-
-static void *listfunnel_new(void)
-{
- int i;
-
- t_listfunnel *x = (t_listfunnel *)pd_new(listfunnel_class);
- x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void listfunnel_setup(void)
-{
- listfunnel_class = class_new(gensym("listfunnel"), (t_newmethod)listfunnel_new,
- 0, sizeof(t_listfunnel), 0, 0, 0);
- class_addfloat(listfunnel_class, listfunnel_float);
- class_addlist(listfunnel_class, listfunnel_list);
-
- post(version);
-}
-#else
-void maxlib_listfunnel_setup(void)
-{
- listfunnel_class = class_new(gensym("maxlib_listfunnel"), (t_newmethod)listfunnel_new,
- 0, sizeof(t_listfunnel), 0, 0, 0);
- class_addcreator((t_newmethod)listfunnel_new, gensym("listfunnel"), 0);
- class_addfloat(listfunnel_class, listfunnel_float);
- class_addlist(listfunnel_class, listfunnel_list);
- class_sethelpsymbol(listfunnel_class, gensym("maxlib/listfunnel-help.pd"));
-}
-#endif
-
+/* ------------------------- listfunnel ------------------------------------- */
+/* */
+/* Convert list into two-element lists with source index. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static char *version = "listfunnel v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct listfunnel
+{
+ t_object x_ob;
+ t_outlet *x_outlet; /* result */
+} t_listfunnel;
+
+static void listfunnel_list(t_listfunnel *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ t_atom list[2];
+
+ for(i = 0; i < argc; i++)
+ {
+ SETFLOAT(list, i);
+ list[1] = argv[i]; // SETFLOAT(list+1, atom_getfloatarg(i, argc, argv));
+ outlet_list(x->x_outlet, NULL, 2, list);
+ }
+}
+
+static void listfunnel_float(t_listfunnel *x, t_floatarg f)
+{
+ t_atom list[2];
+
+ SETFLOAT(list, 0);
+ SETFLOAT(list+1, f);
+ outlet_list(x->x_outlet, NULL, 2, list);
+}
+
+static t_class *listfunnel_class;
+
+static void *listfunnel_new(void)
+{
+ int i;
+
+ t_listfunnel *x = (t_listfunnel *)pd_new(listfunnel_class);
+ x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void listfunnel_setup(void)
+{
+ listfunnel_class = class_new(gensym("listfunnel"), (t_newmethod)listfunnel_new,
+ 0, sizeof(t_listfunnel), 0, 0, 0);
+ class_addfloat(listfunnel_class, listfunnel_float);
+ class_addlist(listfunnel_class, listfunnel_list);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_listfunnel_setup(void)
+{
+ listfunnel_class = class_new(gensym("maxlib_listfunnel"), (t_newmethod)listfunnel_new,
+ 0, sizeof(t_listfunnel), 0, 0, 0);
+ class_addcreator((t_newmethod)listfunnel_new, gensym("listfunnel"), 0);
+ class_addfloat(listfunnel_class, listfunnel_float);
+ class_addlist(listfunnel_class, listfunnel_list);
+ class_sethelpsymbol(listfunnel_class, gensym("maxlib/listfunnel-help.pd"));
+}
+#endif
+
diff --git a/HISTORY b/manual/HISTORY.txt
index c90963f..c90963f 100644
--- a/HISTORY
+++ b/manual/HISTORY.txt
diff --git a/automata.txt b/manual/automata.txt
index 3f5ff21..3f5ff21 100644
--- a/automata.txt
+++ b/manual/automata.txt
diff --git a/match.c b/match.c
index 48eca45..53ad633 100644
--- a/match.c
+++ b/match.c
@@ -1,274 +1,274 @@
-/* ------------------------- match ------------------------------------------ */
-/* */
-/* Outputs a list when a list of input values matches the creation args. */
-/* Written by Krzysztof Czaja for his cyclone library. */
-/* Modified to fit into maxlib by Olaf Matthes <olaf.matthes@gmx.de>. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-/* this is the original copyright notice: */
-
-/* Copyright (c) 1997-2002 Miller Puckette and others.
- * For information on usage and redistribution, and for a DISCLAIMER OF ALL
- * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
-
-
-#include <string.h>
-#include "m_pd.h"
-
-#define MATCH_INISIZE 16 /* LATER rethink */
-
-typedef struct _match
-{
- t_object x_ob;
- int x_size; /* as allocated */
- int x_patlen; /* as used */
- t_atom *x_pattern;
- t_atom x_patini[MATCH_INISIZE];
- int x_quelen;
- t_atom *x_queue;
- t_atom x_queini[MATCH_INISIZE];
- t_atom *x_queend;
- t_atom *x_queptr; /* writing head, post-incremented (oldest-pointing) */
- int x_;
-} t_match;
-
-static t_class *match_class;
-
-/* a caller must check for nrequested > *sizep */
-/* returns actual number of atoms: requested (success)
- or a default value of initial size (failure) */
-/* the result is guaranteed to be >= min(nrequested, inisize) */
-static int match_grow(int nrequested, int *sizep, t_atom **bufp,
- int inisize, t_atom *bufini)
-{
- int newsize = *sizep * 2;
- while (newsize < nrequested) newsize *= 2;
- if (*bufp == bufini)
- *bufp = (t_atom *)getbytes(newsize * sizeof(**bufp));
- else
- *bufp = (t_atom *)resizebytes(*bufp, *sizep * sizeof(**bufp),
- newsize * sizeof(**bufp));
- if (*bufp)
- *sizep = newsize;
- else
- {
- *bufp = bufini;
- nrequested = *sizep = inisize;
- }
- return (nrequested);
-}
-
-static void match_clear(t_match *x)
-{
- x->x_quelen = 0;
- x->x_queptr = x->x_queue;
-}
-
-/* x->x_patlen > 0 is assumed */
-/* LATER use a lock to disable reentrant calls. I do not see any
- purpose of reentering match, but lets CHECKME first... */
-static void match_checkin(t_match *x)
-{
- int i, patlen = x->x_patlen;
- t_atom *queptr, *pp, *qp;
- if (x->x_queptr >= x->x_queend)
- x->x_queptr = x->x_queue;
- else x->x_queptr++;
- if (x->x_quelen < patlen && ++(x->x_quelen) < patlen)
- return;
-
- qp = queptr = x->x_queptr;
- for (i = 0, pp = x->x_pattern; i < patlen; i++, pp++)
- {
- if (pp->a_type == A_FLOAT)
- {
- if (qp->a_type != A_FLOAT || qp->a_w.w_float != pp->a_w.w_float)
- break;
- }
- else if (pp->a_type == A_SYMBOL)
- {
- if (qp->a_type != A_SYMBOL || qp->a_w.w_symbol != pp->a_w.w_symbol)
- break;
- }
- else if (pp->a_type == A_NULL)
- {
- if (qp->a_type == A_FLOAT || qp->a_type == A_SYMBOL)
- {
- /* instantiating a pattern */
- *pp = *qp;
- qp->a_type = A_NULL;
- }
- else break; /* LATER rethink */
- }
- else break; /* LATER rethink */
- if (qp >= x->x_queend)
- qp = x->x_queue;
- else qp++;
- }
- if (i == patlen)
- {
- pp = x->x_pattern;
- if (pp->a_type == A_FLOAT)
- {
- if (patlen == 1)
- outlet_float(((t_object *)x)->ob_outlet, pp->a_w.w_float);
- else
- outlet_list(((t_object *)x)->ob_outlet, &s_list, patlen, pp);
- }
- else /* assuming A_SYMBOL (see above) */
- {
- if (pp->a_w.w_symbol == &s_symbol /* bypassing typedmess() */
- && patlen == 2 && pp[1].a_type == A_SYMBOL)
- outlet_symbol(((t_object *)x)->ob_outlet, pp[1].a_w.w_symbol);
- else
- outlet_anything(((t_object *)x)->ob_outlet, pp->a_w.w_symbol,
- patlen - 1, pp + 1);
- }
- /* CHECKED: no implicit clear (resolving overlapping patterns) */
- }
- /* restoring a pattern */
- for (i = 0, pp = x->x_pattern; i < patlen; i++, pp++)
- {
- if (queptr->a_type == A_NULL)
- {
- queptr->a_type = pp->a_type;
- pp->a_type = A_NULL;
- }
- if (queptr >= x->x_queend)
- queptr = x->x_queue;
- else queptr++;
- }
-}
-
-static void match_float(t_match *x, t_float f)
-{
- if (x->x_patlen)
- {
- SETFLOAT(x->x_queptr, f);
- match_checkin(x);
- }
-}
-
-static void match_symbol(t_match *x, t_symbol *s)
-{
- if (s && s != &s_ && x->x_patlen)
- {
- SETSYMBOL(x->x_queptr, s);
- match_checkin(x);
- }
-}
-
-/* LATER gpointer */
-
-static void match_list(t_match *x, t_symbol *s, int ac, t_atom *av)
-{
- while (ac--)
- {
- if (av->a_type == A_FLOAT) match_float(x, av->a_w.w_float);
- else if (av->a_type == A_SYMBOL) match_symbol(x, av->a_w.w_symbol);
- av++;
- }
-}
-
-static void match_anything(t_match *x, t_symbol *s, int ac, t_atom *av)
-{
- match_symbol(x, s);
- match_list(x, 0, ac, av);
-}
-
-static void match_set(t_match *x, t_symbol *s, int ac, t_atom *av)
-{
- if (ac) /* CHECKED */
- {
- t_atom *pp;
- t_symbol *ps_nn;
- int newlen = ac * 2;
- if (newlen > x->x_size)
- {
- newlen = match_grow(newlen, &x->x_size, &x->x_pattern,
- MATCH_INISIZE * 2, x->x_patini);
- if (newlen == MATCH_INISIZE * 2)
- {
- x->x_queue = x->x_queini;
- ac = MATCH_INISIZE;
- }
- else x->x_queue = x->x_pattern + x->x_size / 2;
- }
- x->x_patlen = ac;
- x->x_queend = x->x_queue + ac - 1;
- match_clear(x); /* CHECKED */
- memcpy(x->x_pattern, av, ac * sizeof(*x->x_pattern));
- pp = x->x_pattern;
- ps_nn = gensym("nn");
- while (ac--)
- {
- if (pp->a_type == A_SYMBOL && pp->a_w.w_symbol == ps_nn)
- pp->a_type = A_NULL;
- pp++;
- }
- }
-}
-
-static void match_free(t_match *x)
-{
- if (x->x_pattern != x->x_patini)
- freebytes(x->x_pattern, 2 * x->x_size * sizeof(*x->x_pattern));
-}
-
-static void *match_new(t_symbol *s, int ac, t_atom *av)
-{
- t_match *x = (t_match *)pd_new(match_class);
- x->x_size = MATCH_INISIZE * 2;
- x->x_patlen = 0;
- x->x_pattern = x->x_patini;
- x->x_queue = x->x_queini;
- /* x->x_queend is not used unless x->x_patlen > 0,
- LATER consider chosing a more defensive way... */
- outlet_new((t_object *)x, &s_anything);
- match_clear(x);
- match_set(x, 0, ac, av);
- return (x);
-}
-
-#ifndef MAXLIB
-void match_setup(void)
-{
- match_class = class_new(gensym("match"), (t_newmethod)match_new,
- (t_method)match_free, sizeof(t_match), 0, A_GIMME, 0);
-#else
-void maxlib_match_setup(void)
-{
- match_class = class_new(gensym("maxlib_match"), (t_newmethod)match_new,
- (t_method)match_free, sizeof(t_match), 0, A_GIMME, 0);
- class_addcreator((t_newmethod)match_new, gensym("match"), A_GIMME, 0);
-#endif
- class_addfloat(match_class, match_float);
- class_addsymbol(match_class, match_symbol);
- class_addlist(match_class, match_list);
- class_addanything(match_class, match_anything);
- class_addmethod(match_class, (t_method)match_set, gensym("set"), A_GIMME, 0);
- class_addmethod(match_class, (t_method)match_clear, gensym("clear"), 0);
-#ifndef MAXLIB
-
-#else
- class_sethelpsymbol(match_class, gensym("maxlib/match-help.pd"));
-#endif
-}
+/* ------------------------- match ------------------------------------------ */
+/* */
+/* Outputs a list when a list of input values matches the creation args. */
+/* Written by Krzysztof Czaja for his cyclone library. */
+/* Modified to fit into maxlib by Olaf Matthes <olaf.matthes@gmx.de>. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+/* this is the original copyright notice: */
+
+/* Copyright (c) 1997-2002 Miller Puckette and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+
+#include <string.h>
+#include "m_pd.h"
+
+#define MATCH_INISIZE 16 /* LATER rethink */
+
+typedef struct _match
+{
+ t_object x_ob;
+ int x_size; /* as allocated */
+ int x_patlen; /* as used */
+ t_atom *x_pattern;
+ t_atom x_patini[MATCH_INISIZE];
+ int x_quelen;
+ t_atom *x_queue;
+ t_atom x_queini[MATCH_INISIZE];
+ t_atom *x_queend;
+ t_atom *x_queptr; /* writing head, post-incremented (oldest-pointing) */
+ int x_;
+} t_match;
+
+static t_class *match_class;
+
+/* a caller must check for nrequested > *sizep */
+/* returns actual number of atoms: requested (success)
+ or a default value of initial size (failure) */
+/* the result is guaranteed to be >= min(nrequested, inisize) */
+static int match_grow(int nrequested, int *sizep, t_atom **bufp,
+ int inisize, t_atom *bufini)
+{
+ int newsize = *sizep * 2;
+ while (newsize < nrequested) newsize *= 2;
+ if (*bufp == bufini)
+ *bufp = (t_atom *)getbytes(newsize * sizeof(**bufp));
+ else
+ *bufp = (t_atom *)resizebytes(*bufp, *sizep * sizeof(**bufp),
+ newsize * sizeof(**bufp));
+ if (*bufp)
+ *sizep = newsize;
+ else
+ {
+ *bufp = bufini;
+ nrequested = *sizep = inisize;
+ }
+ return (nrequested);
+}
+
+static void match_clear(t_match *x)
+{
+ x->x_quelen = 0;
+ x->x_queptr = x->x_queue;
+}
+
+/* x->x_patlen > 0 is assumed */
+/* LATER use a lock to disable reentrant calls. I do not see any
+ purpose of reentering match, but lets CHECKME first... */
+static void match_checkin(t_match *x)
+{
+ int i, patlen = x->x_patlen;
+ t_atom *queptr, *pp, *qp;
+ if (x->x_queptr >= x->x_queend)
+ x->x_queptr = x->x_queue;
+ else x->x_queptr++;
+ if (x->x_quelen < patlen && ++(x->x_quelen) < patlen)
+ return;
+
+ qp = queptr = x->x_queptr;
+ for (i = 0, pp = x->x_pattern; i < patlen; i++, pp++)
+ {
+ if (pp->a_type == A_FLOAT)
+ {
+ if (qp->a_type != A_FLOAT || qp->a_w.w_float != pp->a_w.w_float)
+ break;
+ }
+ else if (pp->a_type == A_SYMBOL)
+ {
+ if (qp->a_type != A_SYMBOL || qp->a_w.w_symbol != pp->a_w.w_symbol)
+ break;
+ }
+ else if (pp->a_type == A_NULL)
+ {
+ if (qp->a_type == A_FLOAT || qp->a_type == A_SYMBOL)
+ {
+ /* instantiating a pattern */
+ *pp = *qp;
+ qp->a_type = A_NULL;
+ }
+ else break; /* LATER rethink */
+ }
+ else break; /* LATER rethink */
+ if (qp >= x->x_queend)
+ qp = x->x_queue;
+ else qp++;
+ }
+ if (i == patlen)
+ {
+ pp = x->x_pattern;
+ if (pp->a_type == A_FLOAT)
+ {
+ if (patlen == 1)
+ outlet_float(((t_object *)x)->ob_outlet, pp->a_w.w_float);
+ else
+ outlet_list(((t_object *)x)->ob_outlet, &s_list, patlen, pp);
+ }
+ else /* assuming A_SYMBOL (see above) */
+ {
+ if (pp->a_w.w_symbol == &s_symbol /* bypassing typedmess() */
+ && patlen == 2 && pp[1].a_type == A_SYMBOL)
+ outlet_symbol(((t_object *)x)->ob_outlet, pp[1].a_w.w_symbol);
+ else
+ outlet_anything(((t_object *)x)->ob_outlet, pp->a_w.w_symbol,
+ patlen - 1, pp + 1);
+ }
+ /* CHECKED: no implicit clear (resolving overlapping patterns) */
+ }
+ /* restoring a pattern */
+ for (i = 0, pp = x->x_pattern; i < patlen; i++, pp++)
+ {
+ if (queptr->a_type == A_NULL)
+ {
+ queptr->a_type = pp->a_type;
+ pp->a_type = A_NULL;
+ }
+ if (queptr >= x->x_queend)
+ queptr = x->x_queue;
+ else queptr++;
+ }
+}
+
+static void match_float(t_match *x, t_float f)
+{
+ if (x->x_patlen)
+ {
+ SETFLOAT(x->x_queptr, f);
+ match_checkin(x);
+ }
+}
+
+static void match_symbol(t_match *x, t_symbol *s)
+{
+ if (s && s != &s_ && x->x_patlen)
+ {
+ SETSYMBOL(x->x_queptr, s);
+ match_checkin(x);
+ }
+}
+
+/* LATER gpointer */
+
+static void match_list(t_match *x, t_symbol *s, int ac, t_atom *av)
+{
+ while (ac--)
+ {
+ if (av->a_type == A_FLOAT) match_float(x, av->a_w.w_float);
+ else if (av->a_type == A_SYMBOL) match_symbol(x, av->a_w.w_symbol);
+ av++;
+ }
+}
+
+static void match_anything(t_match *x, t_symbol *s, int ac, t_atom *av)
+{
+ match_symbol(x, s);
+ match_list(x, 0, ac, av);
+}
+
+static void match_set(t_match *x, t_symbol *s, int ac, t_atom *av)
+{
+ if (ac) /* CHECKED */
+ {
+ t_atom *pp;
+ t_symbol *ps_nn;
+ int newlen = ac * 2;
+ if (newlen > x->x_size)
+ {
+ newlen = match_grow(newlen, &x->x_size, &x->x_pattern,
+ MATCH_INISIZE * 2, x->x_patini);
+ if (newlen == MATCH_INISIZE * 2)
+ {
+ x->x_queue = x->x_queini;
+ ac = MATCH_INISIZE;
+ }
+ else x->x_queue = x->x_pattern + x->x_size / 2;
+ }
+ x->x_patlen = ac;
+ x->x_queend = x->x_queue + ac - 1;
+ match_clear(x); /* CHECKED */
+ memcpy(x->x_pattern, av, ac * sizeof(*x->x_pattern));
+ pp = x->x_pattern;
+ ps_nn = gensym("nn");
+ while (ac--)
+ {
+ if (pp->a_type == A_SYMBOL && pp->a_w.w_symbol == ps_nn)
+ pp->a_type = A_NULL;
+ pp++;
+ }
+ }
+}
+
+static void match_free(t_match *x)
+{
+ if (x->x_pattern != x->x_patini)
+ freebytes(x->x_pattern, 2 * x->x_size * sizeof(*x->x_pattern));
+}
+
+static void *match_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_match *x = (t_match *)pd_new(match_class);
+ x->x_size = MATCH_INISIZE * 2;
+ x->x_patlen = 0;
+ x->x_pattern = x->x_patini;
+ x->x_queue = x->x_queini;
+ /* x->x_queend is not used unless x->x_patlen > 0,
+ LATER consider chosing a more defensive way... */
+ outlet_new((t_object *)x, &s_anything);
+ match_clear(x);
+ match_set(x, 0, ac, av);
+ return (x);
+}
+
+#ifndef MAXLIB
+void match_setup(void)
+{
+ match_class = class_new(gensym("match"), (t_newmethod)match_new,
+ (t_method)match_free, sizeof(t_match), 0, A_GIMME, 0);
+#else
+void maxlib_match_setup(void)
+{
+ match_class = class_new(gensym("maxlib_match"), (t_newmethod)match_new,
+ (t_method)match_free, sizeof(t_match), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)match_new, gensym("match"), A_GIMME, 0);
+#endif
+ class_addfloat(match_class, match_float);
+ class_addsymbol(match_class, match_symbol);
+ class_addlist(match_class, match_list);
+ class_addanything(match_class, match_anything);
+ class_addmethod(match_class, (t_method)match_set, gensym("set"), A_GIMME, 0);
+ class_addmethod(match_class, (t_method)match_clear, gensym("clear"), 0);
+#ifndef MAXLIB
+
+#else
+ class_sethelpsymbol(match_class, gensym("maxlib/match-help.pd"));
+#endif
+}
diff --git a/maxlib-meta.pd b/maxlib-meta.pd
index 2602b0f..9d6d387 100644
--- a/maxlib-meta.pd
+++ b/maxlib-meta.pd
@@ -4,5 +4,5 @@
#X text 10 30 NAME maxlib;
#X text 10 50 AUTHOR Olaf Matthes <olaf.matthes@gmx.de>;
#X text 10 70 LICENSE GNU GPL;
-#X text 10 90 VERSION 1.5.4;
+#X text 10 90 VERSION 1.5.5;
#X restore 10 10 pd META;
diff --git a/maxlib.c b/maxlib.c
index f470693..160503e 100644
--- a/maxlib.c
+++ b/maxlib.c
@@ -1,192 +1,192 @@
-/* -------------------------- maxlib ---------------------------------------- */
-/* */
-/* maxlib :: music analysis extensions library. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-#ifndef VERSION
-#define VERSION "1.5.4"
-#endif
-
-#include "m_pd.h"
-
-
-#ifndef __DATE__
-#define __DATE__ "without using a gnu compiler"
-#endif
-
-typedef struct _maxlib
-{
- t_object x_obj;
-} t_maxlib;
-
-static t_class* maxlib_class;
-
- /* objects */
-void maxlib_allow_setup();
-void maxlib_arbran_setup();
-void maxlib_arraycopy_setup();
-void maxlib_average_setup();
-void maxlib_beat_setup();
-void maxlib_beta_setup();
-void maxlib_bilex_setup();
-void maxlib_borax_setup();
-void maxlib_cauchy_setup();
-void maxlib_chord_setup();
-void maxlib_delta_setup();
-void maxlib_deny_setup();
-void maxlib_dist_setup();
-void maxlib_divide_setup();
-void maxlib_divmod_setup();
-void maxlib_edge_setup();
-void maxlib_expo_setup();
-void maxlib_fifo_setup();
-void maxlib_gauss_setup();
-void maxlib_gestalt_setup();
-void maxlib_history_setup();
-void maxlib_ignore_setup();
-void maxlib_iso_setup();
-void maxlib_lifo_setup();
-void maxlib_limit_setup();
-void maxlib_linear_setup();
-void maxlib_listfifo_setup();
-void maxlib_listfunnel_setup();
-void maxlib_match_setup();
-void maxlib_minus_setup();
-void maxlib_mlife_setup();
-void maxlib_multi_setup();
-void maxlib_nchange_setup();
-void maxlib_netclient_setup();
-void maxlib_netdist_setup();
-void maxlib_netrec_setup();
-void maxlib_netserver_setup();
-void maxlib_nroute_setup();
-void maxlib_pitch_setup();
-void maxlib_plus_setup();
-void maxlib_poisson_setup();
-void maxlib_pong_setup();
-void maxlib_pulse_setup();
-void maxlib_remote_setup();
-void maxlib_rewrap_setup();
-void maxlib_rhythm_setup();
-void maxlib_scale_setup();
-void maxlib_score_setup();
-void maxlib_speedlim_setup();
-void maxlib_split_setup();
-void maxlib_step_setup();
-void maxlib_subst_setup();
-void maxlib_sync_setup();
-void maxlib_temperature_setup();
-void maxlib_tilt_setup();
-void maxlib_timebang_setup();
-void maxlib_triang_setup();
-void maxlib_unroute_setup();
-void maxlib_urn_setup();
-void maxlib_velocity_setup();
-void maxlib_weibull_setup();
-void maxlib_wrap_setup();
-
-static void* maxlib_new(t_symbol* s)
-{
- t_maxlib *x = (t_maxlib *)pd_new(maxlib_class);
- return (x);
-}
-
-void maxlib_setup(void)
-{
- maxlib_class = class_new(gensym("maxlib"), (t_newmethod)maxlib_new, 0,
- sizeof(t_maxlib), 0,0);
-
- maxlib_allow_setup();
- maxlib_arbran_setup();
- maxlib_arraycopy_setup();
- maxlib_average_setup();
- maxlib_beat_setup();
- maxlib_beta_setup();
- maxlib_bilex_setup();
- maxlib_borax_setup();
- maxlib_cauchy_setup();
- maxlib_chord_setup();
- maxlib_delta_setup();
- maxlib_deny_setup();
- maxlib_dist_setup();
- maxlib_divide_setup();
- maxlib_divmod_setup();
- maxlib_edge_setup();
- maxlib_expo_setup();
- maxlib_fifo_setup();
- maxlib_gauss_setup();
- maxlib_gestalt_setup();
- maxlib_history_setup();
- maxlib_ignore_setup();
- maxlib_iso_setup();
- maxlib_lifo_setup();
- maxlib_limit_setup();
- maxlib_linear_setup();
- maxlib_listfifo_setup();
- maxlib_listfunnel_setup();
- maxlib_match_setup();
- maxlib_minus_setup();
- maxlib_mlife_setup();
- maxlib_multi_setup();
- maxlib_nchange_setup();
- maxlib_netclient_setup();
- maxlib_netdist_setup();
- maxlib_netrec_setup();
- maxlib_netserver_setup();
- maxlib_nroute_setup();
- maxlib_pitch_setup();
- maxlib_plus_setup();
- maxlib_poisson_setup();
- maxlib_pong_setup();
- maxlib_pulse_setup();
- maxlib_remote_setup();
- maxlib_rewrap_setup();
- maxlib_rhythm_setup();
- maxlib_scale_setup();
- maxlib_score_setup();
- maxlib_speedlim_setup();
- maxlib_split_setup();
- maxlib_step_setup();
- maxlib_subst_setup();
- maxlib_sync_setup();
- maxlib_temperature_setup();
- maxlib_tilt_setup();
- maxlib_timebang_setup();
- maxlib_triang_setup();
- maxlib_unroute_setup();
- maxlib_urn_setup();
- maxlib_velocity_setup();
- maxlib_weibull_setup();
- maxlib_wrap_setup();
-
- post("\n maxlib :: Music Analysis eXtensions LIBrary");
- post(" written by Olaf Matthes <olaf.matthes@gmx.de>");
- post(" version "VERSION);
- post(" compiled "__DATE__);
- post(" latest version at http://www.akustische-kunst.org/puredata/maxlib/");
- post(" objects: allow arbran arraycopy average beat beta bilex borax cauchy ");
- post(" chord delta deny dist divide divmod edge expo fifo gauss ");
- post(" gestalt history ignore iso lifo linear listfifo listfunnel ");
- post(" match minus mlife multi nchange netclient netdist netrec ");
- post(" netserver nroute pitch plus poisson pong pulse remote rewrap ");
- post(" rhythm scale score speedlim split step subst sync temperature ");
- post(" tilt timebang triang unroute urn velocity weibull wrap\n");
-}
+/* -------------------------- maxlib ---------------------------------------- */
+/* */
+/* maxlib :: music analysis extensions library. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+#ifndef VERSION
+#define VERSION "1.5.4"
+#endif
+
+#include "m_pd.h"
+
+
+#ifndef __DATE__
+#define __DATE__ "without using a gnu compiler"
+#endif
+
+typedef struct _maxlib
+{
+ t_object x_obj;
+} t_maxlib;
+
+static t_class* maxlib_class;
+
+ /* objects */
+void maxlib_allow_setup();
+void maxlib_arbran_setup();
+void maxlib_arraycopy_setup();
+void maxlib_average_setup();
+void maxlib_beat_setup();
+void maxlib_beta_setup();
+void maxlib_bilex_setup();
+void maxlib_borax_setup();
+void maxlib_cauchy_setup();
+void maxlib_chord_setup();
+void maxlib_delta_setup();
+void maxlib_deny_setup();
+void maxlib_dist_setup();
+void maxlib_divide_setup();
+void maxlib_divmod_setup();
+void maxlib_edge_setup();
+void maxlib_expo_setup();
+void maxlib_fifo_setup();
+void maxlib_gauss_setup();
+void maxlib_gestalt_setup();
+void maxlib_history_setup();
+void maxlib_ignore_setup();
+void maxlib_iso_setup();
+void maxlib_lifo_setup();
+void maxlib_limit_setup();
+void maxlib_linear_setup();
+void maxlib_listfifo_setup();
+void maxlib_listfunnel_setup();
+void maxlib_match_setup();
+void maxlib_minus_setup();
+void maxlib_mlife_setup();
+void maxlib_multi_setup();
+void maxlib_nchange_setup();
+void maxlib_netclient_setup();
+void maxlib_netdist_setup();
+void maxlib_netrec_setup();
+void maxlib_netserver_setup();
+void maxlib_nroute_setup();
+void maxlib_pitch_setup();
+void maxlib_plus_setup();
+void maxlib_poisson_setup();
+void maxlib_pong_setup();
+void maxlib_pulse_setup();
+void maxlib_remote_setup();
+void maxlib_rewrap_setup();
+void maxlib_rhythm_setup();
+void maxlib_scale_setup();
+void maxlib_score_setup();
+void maxlib_speedlim_setup();
+void maxlib_split_setup();
+void maxlib_step_setup();
+void maxlib_subst_setup();
+void maxlib_sync_setup();
+void maxlib_temperature_setup();
+void maxlib_tilt_setup();
+void maxlib_timebang_setup();
+void maxlib_triang_setup();
+void maxlib_unroute_setup();
+void maxlib_urn_setup();
+void maxlib_velocity_setup();
+void maxlib_weibull_setup();
+void maxlib_wrap_setup();
+
+static void* maxlib_new(t_symbol* s)
+{
+ t_maxlib *x = (t_maxlib *)pd_new(maxlib_class);
+ return (x);
+}
+
+void maxlib_setup(void)
+{
+ maxlib_class = class_new(gensym("maxlib"), (t_newmethod)maxlib_new, 0,
+ sizeof(t_maxlib), 0,0);
+
+ maxlib_allow_setup();
+ maxlib_arbran_setup();
+ maxlib_arraycopy_setup();
+ maxlib_average_setup();
+ maxlib_beat_setup();
+ maxlib_beta_setup();
+ maxlib_bilex_setup();
+ maxlib_borax_setup();
+ maxlib_cauchy_setup();
+ maxlib_chord_setup();
+ maxlib_delta_setup();
+ maxlib_deny_setup();
+ maxlib_dist_setup();
+ maxlib_divide_setup();
+ maxlib_divmod_setup();
+ maxlib_edge_setup();
+ maxlib_expo_setup();
+ maxlib_fifo_setup();
+ maxlib_gauss_setup();
+ maxlib_gestalt_setup();
+ maxlib_history_setup();
+ maxlib_ignore_setup();
+ maxlib_iso_setup();
+ maxlib_lifo_setup();
+ maxlib_limit_setup();
+ maxlib_linear_setup();
+ maxlib_listfifo_setup();
+ maxlib_listfunnel_setup();
+ maxlib_match_setup();
+ maxlib_minus_setup();
+ maxlib_mlife_setup();
+ maxlib_multi_setup();
+ maxlib_nchange_setup();
+ maxlib_netclient_setup();
+ maxlib_netdist_setup();
+ maxlib_netrec_setup();
+ maxlib_netserver_setup();
+ maxlib_nroute_setup();
+ maxlib_pitch_setup();
+ maxlib_plus_setup();
+ maxlib_poisson_setup();
+ maxlib_pong_setup();
+ maxlib_pulse_setup();
+ maxlib_remote_setup();
+ maxlib_rewrap_setup();
+ maxlib_rhythm_setup();
+ maxlib_scale_setup();
+ maxlib_score_setup();
+ maxlib_speedlim_setup();
+ maxlib_split_setup();
+ maxlib_step_setup();
+ maxlib_subst_setup();
+ maxlib_sync_setup();
+ maxlib_temperature_setup();
+ maxlib_tilt_setup();
+ maxlib_timebang_setup();
+ maxlib_triang_setup();
+ maxlib_unroute_setup();
+ maxlib_urn_setup();
+ maxlib_velocity_setup();
+ maxlib_weibull_setup();
+ maxlib_wrap_setup();
+
+ post("\n maxlib :: Music Analysis eXtensions LIBrary");
+ post(" written by Olaf Matthes <olaf.matthes@gmx.de>");
+ logpost(NULL, 4, " version "VERSION);
+ post(" compiled "__DATE__);
+ logpost(NULL, 4, " latest version at http://www.akustische-kunst.org/puredata/maxlib/");
+ post(" objects: allow arbran arraycopy average beat beta bilex borax cauchy ");
+ post(" chord delta deny dist divide divmod edge expo fifo gauss ");
+ post(" gestalt history ignore iso lifo linear listfifo listfunnel ");
+ post(" match minus mlife multi nchange netclient netdist netrec ");
+ post(" netserver nroute pitch plus poisson pong pulse remote rewrap ");
+ post(" rhythm scale score speedlim split step subst sync temperature ");
+ post(" tilt timebang triang unroute urn velocity weibull wrap\n");
+}
diff --git a/minus.c b/minus.c
index c1de401..6c88583 100644
--- a/minus.c
+++ b/minus.c
@@ -1,111 +1,111 @@
-/* ------------------------- minus ------------------------------------------ */
-/* */
-/* Like '-', but calculates output whenever _any_ of the inlets changes. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-
-#define MAXSIZE 32
-
-static char *version = "minus v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct minus
-{
- t_object x_ob;
- t_inlet *x_inleft; /* leftmost inlet */
- t_inlet *x_inright; /* right inlet */
- t_outlet *x_outlet; /* result */
- t_int x_numvalues; /* number of values / inlets */
-
- t_float x_minusvalue[MAXSIZE];
-
-} t_minus;
-
-static void minus_bang(t_minus *x)
-{
- int i;
- t_float result = x->x_minusvalue[0];
- for(i = 1; i < x->x_numvalues; i++)
- result -= x->x_minusvalue[i];
- outlet_float(x->x_outlet, result);
-}
-
-static void minus_float(t_minus *x, t_floatarg f)
-{
- x->x_minusvalue[0] = f;
- minus_bang(x); /* calculate result */
-}
-
-static void minus_ft1(t_minus *x, t_floatarg f)
-{
- x->x_minusvalue[1] = f;
- minus_bang(x); /* calculate result */
-}
-
-static t_class *minus_class;
-
-static void *minus_new(t_symbol *s, t_int argc, t_atom* argv)
-{
- int i;
-
- t_minus *x = (t_minus *)pd_new(minus_class);
- x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- for(i = 2; i < argc; i++) /* create additional inlets, if any */
- {
- // inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- floatinlet_new(&x->x_ob, &x->x_minusvalue[i]);
- }
- x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
-
- for(i = 0; i < argc; i++)
- {
- x->x_minusvalue[i] = atom_getfloatarg(i, argc, argv);
- }
- x->x_numvalues = i;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void minus_setup(void)
-{
- minus_class = class_new(gensym("minus"), (t_newmethod)minus_new,
- 0, sizeof(t_minus), 0, A_GIMME, 0);
- class_addfloat(minus_class, minus_float);
- class_addmethod(minus_class, (t_method)minus_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addbang(minus_class, (t_method)minus_bang);
-
- post(version);
-}
-#else
-void maxlib_minus_setup(void)
-{
- minus_class = class_new(gensym("maxlib_minus"), (t_newmethod)minus_new,
- 0, sizeof(t_minus), 0, A_GIMME, 0);
- class_addcreator((t_newmethod)minus_new, gensym("minus"), A_GIMME, 0);
- class_addfloat(minus_class, minus_float);
- class_addmethod(minus_class, (t_method)minus_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addbang(minus_class, (t_method)minus_bang);
- class_sethelpsymbol(minus_class, gensym("maxlib/minus-help.pd"));
-}
-#endif
+/* ------------------------- minus ------------------------------------------ */
+/* */
+/* Like '-', but calculates output whenever _any_ of the inlets changes. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+
+#define MAXSIZE 32
+
+static char *version = "minus v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct minus
+{
+ t_object x_ob;
+ t_inlet *x_inleft; /* leftmost inlet */
+ t_inlet *x_inright; /* right inlet */
+ t_outlet *x_outlet; /* result */
+ t_int x_numvalues; /* number of values / inlets */
+
+ t_float x_minusvalue[MAXSIZE];
+
+} t_minus;
+
+static void minus_bang(t_minus *x)
+{
+ int i;
+ t_float result = x->x_minusvalue[0];
+ for(i = 1; i < x->x_numvalues; i++)
+ result -= x->x_minusvalue[i];
+ outlet_float(x->x_outlet, result);
+}
+
+static void minus_float(t_minus *x, t_floatarg f)
+{
+ x->x_minusvalue[0] = f;
+ minus_bang(x); /* calculate result */
+}
+
+static void minus_ft1(t_minus *x, t_floatarg f)
+{
+ x->x_minusvalue[1] = f;
+ minus_bang(x); /* calculate result */
+}
+
+static t_class *minus_class;
+
+static void *minus_new(t_symbol *s, t_int argc, t_atom* argv)
+{
+ int i;
+
+ t_minus *x = (t_minus *)pd_new(minus_class);
+ x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ for(i = 2; i < argc; i++) /* create additional inlets, if any */
+ {
+ // inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ floatinlet_new(&x->x_ob, &x->x_minusvalue[i]);
+ }
+ x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
+
+ for(i = 0; i < argc; i++)
+ {
+ x->x_minusvalue[i] = atom_getfloatarg(i, argc, argv);
+ }
+ x->x_numvalues = i;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void minus_setup(void)
+{
+ minus_class = class_new(gensym("minus"), (t_newmethod)minus_new,
+ 0, sizeof(t_minus), 0, A_GIMME, 0);
+ class_addfloat(minus_class, minus_float);
+ class_addmethod(minus_class, (t_method)minus_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addbang(minus_class, (t_method)minus_bang);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_minus_setup(void)
+{
+ minus_class = class_new(gensym("maxlib_minus"), (t_newmethod)minus_new,
+ 0, sizeof(t_minus), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)minus_new, gensym("minus"), A_GIMME, 0);
+ class_addfloat(minus_class, minus_float);
+ class_addmethod(minus_class, (t_method)minus_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addbang(minus_class, (t_method)minus_bang);
+ class_sethelpsymbol(minus_class, gensym("maxlib/minus-help.pd"));
+}
+#endif
diff --git a/mlife.c b/mlife.c
index 4b77e09..0768f16 100644
--- a/mlife.c
+++ b/mlife.c
@@ -1,515 +1,515 @@
-/* ------------------------- mlife ------------------------------------------ */
-/* */
-/* A linear cellular automata object for PureData. */
-/* Based on 'mlife' by pauld@koncon.nl */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-#include "m_pd.h"
-
-
-static char *version = "mlife v0.1, a linear cellular automata object for Pd\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-#undef DEBUG
-//#define DEBUG
-
-
-#define INTSIZE sizeof(unsigned int) * 8
-#define LONGSIZE sizeof(unsigned long) * 8
-#define DEFAULT_DIE_LO 2
-#define DEFAULT_DIE_HI 3
-#define DEFAULT_N_SIZE 3
-
-#define MAXSIZE 1024
-
-#include <stdio.h>
-#include <stdlib.h>
-
-/* -------------------- random stuff -------------------- */
-static union {
- unsigned long next;
- struct {
- unsigned short : 1;
- unsigned short n : 15;
- } bits;
-} seed = { 1 };
-
-
-/*
- * rand - pseudo-random number generator
- *
- */
-
-static int my_rand(void)
-{
- seed.next = seed.next * 1103515245 + 12345;
- return(seed.bits.n);
-}
-
-
-/*
- * srand - seed pseudo-random number generator
- *
- */
-
-static void my_srand(unsigned n)
-{
- seed.next = n;
-}
-/* --------------------------------------------------------- */
-
-//
-// Maxlife object data structure
-//
-typedef struct maxlife
-{
- t_object ml_ob; // must begin every object
- t_int universe[MAXSIZE]; // array of cells - alive and dead
- t_outlet *out[MAXSIZE]; // outlets
- t_int size; // size of the CA field/world
- t_int view_start; // Start of viewport
- t_int view_size; // length of viewport and number of outlets
- t_int rule_die_lo; // death if less than this
- t_int rule_die_hi; // death if greater then this
- t_int neighbourhood_size; // # of cells either side to check
- t_int closed; // closed universe if true
-} t_maxlife;
-
-//
-// Function prototypes for our methods and functions
-//
-static t_class *mlife_class; // global variable that points to the Maxlife class
-
-//
-// ml_nextgeneration
-// Step through the array, applying the rules and reset each cell
-// accordingly. For each cell:
-// - Check the number of neighbours (watch for "closed")
-// using neighbourhood_size
-//
-// - If neighbours < rule_die_lo the cell is cleared (0)
-//
-// - If neighbours > rule_die_hi the cell is cleared (0)
-//
-// - Else the cell is filled (1)
-//
-// not called by Pd itself
-//
-static void ml_nextgeneration(t_maxlife *mlp)
-{
- register long i, j, k;
- register long size, neighbourhood_size, max_neighbours, min_neighbours, neighbours;
- register int closed, out_of_bounds;
-
- // get the important info a little closer to hand
- size = mlp->size;
- closed = mlp->closed;
- neighbourhood_size = mlp->neighbourhood_size;
- max_neighbours = mlp->rule_die_hi;
- min_neighbours = mlp->rule_die_lo;
-
-#ifdef DEBUG
- post("mlife:next_generation called, vars n_size=%ld, n_max=%ld, n_min=%ld",
- neighbourhood_size, max_neighbours, min_neighbours);
-#endif
- // for each cell...
- for(i=0; i<size; i++)
- {
- neighbours = 0L; // reset count of neighbours
-
- // for each neighbourhood, count the neighbours
- for(j = i-neighbourhood_size; j <= i+neighbourhood_size; j++)
- {
- k = j; // k is the index into the array, decoupled from j
- // don't go outside our array, or wrap if closed
- if(closed)
- {
- if(j < 0)
- k = size + j; // j is a negative number. size-1?
- if(j > size-1L)
- k = j - size - 1L; // not size-1 ???
-
- if(j != i) // skip our own location in this roundup
- if(mlp->universe[k]) // if there's a neighbour inc count
- neighbours++;
- }
- else // not closed
- {
- out_of_bounds = 0;
- if(k < 0L) // start of array
- {
- out_of_bounds = 1;
- k = 0L;
- }
- if(k > size-1L)
- {
- out_of_bounds = 1;
- k = size-1L; // end of array
- }
-
- if((j != i) && !out_of_bounds) // skip our own location in this roundup
- if(mlp->universe[k]) // if there's a neighbour inc count
- neighbours++;
- }
-
- } // end of neighbour search
-
- // based on number of neighbours, fill or clear this cell (i)
- if((neighbours < min_neighbours) || (neighbours > max_neighbours))
- mlp->universe[i] = 0;
- else
- mlp->universe[i] = 1;
- }
-}
-
-//
-// method to set the die_lo number
-//
-static void ml_set_die_lo(t_maxlife *mlp, t_floatarg die_lo)
-{
- mlp->rule_die_lo = (t_int)die_lo;
-}
-
-//
-// method to set the die_hi number
-//
-static void ml_set_die_hi(t_maxlife *mlp, t_floatarg die_hi)
-{
- mlp->rule_die_hi = (t_int)die_hi;
-}
-
-//
-// method to set the die_lo number
-//
-static void ml_set_neighbourhood(t_maxlife *mlp, t_floatarg n_size)
-{
- mlp->neighbourhood_size = (t_int)n_size;
-}
-
-//
-// bang method outputs bangs for filled cells within the view port
-//
-static void ml_bang(t_maxlife *mlp) // argument is a pointer to an instance
-{
- register long i, view_start;
-
-#ifdef DEBUG
- post("mlife:ml_bang called, sending bangs");
-#endif
-
- view_start = mlp->view_start;
-
- // loop through the outlets right->left sending bangs if alive
- for(i=view_start+mlp->view_size-2; i>=view_start-1; i--)
- {
- // send a bang out the appropriate outlet
- if(mlp->universe[i])
- outlet_bang(mlp->out[i-view_start+1]);
- }
-
- ml_nextgeneration(mlp);
-}
-
-//
-// int method outputs ints for ALL cells in the view port (1=filled, 0=not)
-//
-static void ml_int(t_maxlife *mlp, t_floatarg dummy)
-{
- t_int i, view_start;
-
-#ifdef DEBUG
- post("mlife:ml_int method called");
-#endif
-
- view_start = mlp->view_start;
-
- // loop through the outlets right -> left sending ints
- for(i = view_start + mlp->view_size - 2; i >= view_start - 1; i--)
- {
- //outlet_int(mlp->out[i-view_start+1], mlp->universe[i]);
- if(mlp->universe[i] == 1)
- outlet_float(mlp->out[i-view_start+1], 1);
- else if(mlp->universe[i] == 0)
- outlet_float(mlp->out[i-view_start+1], 0);
- else
- error("mlife: corrupted data in universe[] array!");
- }
-
- ml_nextgeneration(mlp);
-}
-
-
-//
-// method to print out the array
-//
-static void ml_display(t_maxlife *mlp)
-{
- register long i;
- char s[MAXSIZE];
-
-#ifdef DEBUG
- post("mlife: display method called");
-#endif
-
- for(i = 0; i < mlp->size; i++) // print the universe array
- {
- //s[i] = itoa(mlp->universe[i]); // my very primitive itoa()
- if(mlp->universe[i])
- s[i] = '1';
- else
- s[i] = '0';
- }
- s[mlp->size] = '\0'; // null terminate the string
- post("%s", s);
-}
-
-//
-// method to fill the array with a number
-//
-static void ml_fill(t_maxlife *mlp, t_floatarg fill_no)
-{
- t_int n;
- register long i, j;
-
- for(i=mlp->size-1; i >= 0; i--) // fill the universe array from the back
- {
- n = (t_int)fill_no;
-
- for(j=(long)INTSIZE; j>0; j--, i--, n>>=1)
- {
- if(i < 0L)
- {
- return;
- }
- if(n & 01)
- mlp->universe[i] = 1;
- else
- mlp->universe[i] = 0;
- }
- }
-}
-
-//
-// method to fill the array with a random number
-//
-static void ml_randfill(t_maxlife *mlp)
-{
- unsigned int s, rnum;
- register unsigned int n;
- register long i, j;
-
-#ifdef DEBUG
- post("mlife: randfill method called");
-#endif
-
- s = (unsigned int)clock_getlogicaltime(); // set seed to a new number
- my_srand(s); // reseed the 'random' generator
- rnum = (unsigned int)my_rand();
-
- for(i=mlp->size - 1; i>=0; i--) // fill the universe array from the back
- {
- n = rnum;
-
- for(j=(long)INTSIZE; j>0; j--, i--, n>>=1)
- {
- if(i < 0L)
- {
- return;
- }
- if(n & 01)
- mlp->universe[i] = 1;
- else
- mlp->universe[i] = 0;
- }
- }
-}
-
-//
-// method to seed the array with a number
-//
-static void ml_seed(t_maxlife *mlp, t_floatarg start, t_floatarg fill_no)
-{
- t_int n;
- register long i, st, end;
-
-#ifdef DEBUG
- post("mlife: seed method called");
-#endif
-
- st = (t_int)start;
- n = (t_int)fill_no;
-
- if(st+(t_int)INTSIZE > mlp->size)
- i = mlp->size - 1;
- else
- i = st+(long)INTSIZE - 1;
-
- // init the universe array from the back i>=start?
- for(; i >= start - 1; i--, n>>=1)
- {
- if(n & 01)
- mlp->universe[i] = 1;
- else
- mlp->universe[i] = 0;
- }
-}
-
-//
-// method to seed the array with a random number
-//
-static void ml_randseed(t_maxlife *mlp, t_floatarg start)
-{
- unsigned long s, rnum;
- register unsigned long n;
- register long i, st;
-
-#ifdef DEBUG
- post("mlife: randseed method called, INTSIZE=%ld", (long)INTSIZE);
-#endif
- //if((start < 1) || (start > mlp->size-(long)INTSIZE))
- if(start < 1)
- {
- error("Randseed start parameter must be between 1 and %ld", mlp->size);
- return;
- }
-
- s = (unsigned long)clock_getlogicaltime(); // set seed to a new number
- my_srand(s); // reseed the 'random' generator
- rnum = (unsigned long)my_rand();
- n = (unsigned int)rnum;
- st = start;
-
- if(st+(t_int)INTSIZE > mlp->size)
- i = mlp->size - 1;
- else
- i = st+(t_int)INTSIZE - 1;
-
- // init the universe array from the back
- for(; i>=st-1; i--, n>>=1)
- {
- if(n & 01)
- mlp->universe[i] = 1;
- else
- mlp->universe[i] = 0;
-
- }
-}
-
-
-//
-// function to create an instance of the mlife class
-//
-static void *ml_new(t_floatarg size, t_floatarg view_start, t_floatarg view_size, t_floatarg closed)
-{
- long i;
- t_maxlife *mlp = (t_maxlife *)pd_new(mlife_class);
-
- // check all args...
- if((size>MAXSIZE) || (size<1))
- {
- post("mlife: size argument must be between 1 and %ld", MAXSIZE);
- size = 1.0;
- }
- if(view_start < 1)
- {
- post("mlife: view_start argument must be between 1 and %ld", size);
- view_start = 1.0;
- }
- if((view_size < 1) || (view_size+view_start > size+1))
- {
- post("mlife: viewsize argument must be between 1 and %ld", size-view_start);
- view_size = 1.0;
- }
-
-
- // set up our structure
- mlp->size = (t_int)size;
- mlp->view_start = (t_int)view_start;
- mlp->view_size = (t_int)view_size;
- mlp->rule_die_lo = DEFAULT_DIE_LO; // 2
- mlp->rule_die_hi = DEFAULT_DIE_HI; // 3
- mlp->neighbourhood_size = DEFAULT_N_SIZE; // 3
- mlp->closed = (t_int)closed;
- for(i=0; i<MAXSIZE; i++)
- mlp->universe[i] = 0;
-
- // create outlets - last first!
- for(i = 0; i < mlp->view_size; i++)
- mlp->out[i] = outlet_new(&mlp->ml_ob, gensym("float"));
-
-#ifdef DEBUG
- post("mlife: finished building object");
- post("mlife: INTSIZE=%ld, LONGSIZE=%ld", (long)INTSIZE, (long)LONGSIZE);
-#endif
-
- post("mlife: defaults are: lo=%ld, hi=%ld, nset=%ld", (long)DEFAULT_DIE_LO, (long)DEFAULT_DIE_HI, DEFAULT_N_SIZE);
-
- return(mlp); // always return a copy of the created object
-}
-
-static void ml_free(t_maxlife *mlp)
-{
- long i;
-
-#ifdef DEBUG
- post("mlife:freeing outlet memory");
-#endif
-/* for(i=mlp->view_size-1; i>=0; i--)
- freeobject(mlp->out[i]); */
-}
-
-#ifndef MAXLIB
-void mlife_setup(void)
-{
- mlife_class = class_new(gensym("mlife"), (t_newmethod)ml_new,
- (t_method)ml_free, sizeof(t_maxlife), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_randfill, gensym("randfill"), 0);
- class_addmethod(mlife_class, (t_method)ml_fill, gensym("fill"), A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_set_die_lo, gensym("lo"), A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_set_die_hi, gensym("hi"), A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_set_neighbourhood, gensym("nset"), A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_randseed, gensym("randseed"), A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_seed, gensym("seed"), A_FLOAT, A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_display, gensym("display"), 0);
- class_addfloat(mlife_class, ml_int);
- class_addbang(mlife_class, ml_bang);
-
- post(version);
-}
-#else
-void maxlib_mlife_setup(void)
-{
- mlife_class = class_new(gensym("maxlib_mlife"), (t_newmethod)ml_new,
- (t_method)ml_free, sizeof(t_maxlife), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)ml_new, gensym("mlife"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_randfill, gensym("randfill"), 0);
- class_addmethod(mlife_class, (t_method)ml_fill, gensym("fill"), A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_set_die_lo, gensym("lo"), A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_set_die_hi, gensym("hi"), A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_set_neighbourhood, gensym("nset"), A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_randseed, gensym("randseed"), A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_seed, gensym("seed"), A_FLOAT, A_FLOAT, 0);
- class_addmethod(mlife_class, (t_method)ml_display, gensym("display"), 0);
- class_addfloat(mlife_class, ml_int);
- class_addbang(mlife_class, ml_bang);
- class_sethelpsymbol(mlife_class, gensym("maxlib/mlife-help.pd"));
-}
-#endif
+/* ------------------------- mlife ------------------------------------------ */
+/* */
+/* A linear cellular automata object for PureData. */
+/* Based on 'mlife' by pauld@koncon.nl */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+#include "m_pd.h"
+
+
+static char *version = "mlife v0.1, a linear cellular automata object for Pd\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+#undef DEBUG
+//#define DEBUG
+
+
+#define INTSIZE sizeof(unsigned int) * 8
+#define LONGSIZE sizeof(unsigned long) * 8
+#define DEFAULT_DIE_LO 2
+#define DEFAULT_DIE_HI 3
+#define DEFAULT_N_SIZE 3
+
+#define MAXSIZE 1024
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* -------------------- random stuff -------------------- */
+static union {
+ unsigned long next;
+ struct {
+ unsigned short : 1;
+ unsigned short n : 15;
+ } bits;
+} seed = { 1 };
+
+
+/*
+ * rand - pseudo-random number generator
+ *
+ */
+
+static int my_rand(void)
+{
+ seed.next = seed.next * 1103515245 + 12345;
+ return(seed.bits.n);
+}
+
+
+/*
+ * srand - seed pseudo-random number generator
+ *
+ */
+
+static void my_srand(unsigned n)
+{
+ seed.next = n;
+}
+/* --------------------------------------------------------- */
+
+//
+// Maxlife object data structure
+//
+typedef struct maxlife
+{
+ t_object ml_ob; // must begin every object
+ t_int universe[MAXSIZE]; // array of cells - alive and dead
+ t_outlet *out[MAXSIZE]; // outlets
+ t_int size; // size of the CA field/world
+ t_int view_start; // Start of viewport
+ t_int view_size; // length of viewport and number of outlets
+ t_int rule_die_lo; // death if less than this
+ t_int rule_die_hi; // death if greater then this
+ t_int neighbourhood_size; // # of cells either side to check
+ t_int closed; // closed universe if true
+} t_maxlife;
+
+//
+// Function prototypes for our methods and functions
+//
+static t_class *mlife_class; // global variable that points to the Maxlife class
+
+//
+// ml_nextgeneration
+// Step through the array, applying the rules and reset each cell
+// accordingly. For each cell:
+// - Check the number of neighbours (watch for "closed")
+// using neighbourhood_size
+//
+// - If neighbours < rule_die_lo the cell is cleared (0)
+//
+// - If neighbours > rule_die_hi the cell is cleared (0)
+//
+// - Else the cell is filled (1)
+//
+// not called by Pd itself
+//
+static void ml_nextgeneration(t_maxlife *mlp)
+{
+ register long i, j, k;
+ register long size, neighbourhood_size, max_neighbours, min_neighbours, neighbours;
+ register int closed, out_of_bounds;
+
+ // get the important info a little closer to hand
+ size = mlp->size;
+ closed = mlp->closed;
+ neighbourhood_size = mlp->neighbourhood_size;
+ max_neighbours = mlp->rule_die_hi;
+ min_neighbours = mlp->rule_die_lo;
+
+#ifdef DEBUG
+ post("mlife:next_generation called, vars n_size=%ld, n_max=%ld, n_min=%ld",
+ neighbourhood_size, max_neighbours, min_neighbours);
+#endif
+ // for each cell...
+ for(i=0; i<size; i++)
+ {
+ neighbours = 0L; // reset count of neighbours
+
+ // for each neighbourhood, count the neighbours
+ for(j = i-neighbourhood_size; j <= i+neighbourhood_size; j++)
+ {
+ k = j; // k is the index into the array, decoupled from j
+ // don't go outside our array, or wrap if closed
+ if(closed)
+ {
+ if(j < 0)
+ k = size + j; // j is a negative number. size-1?
+ if(j > size-1L)
+ k = j - size - 1L; // not size-1 ???
+
+ if(j != i) // skip our own location in this roundup
+ if(mlp->universe[k]) // if there's a neighbour inc count
+ neighbours++;
+ }
+ else // not closed
+ {
+ out_of_bounds = 0;
+ if(k < 0L) // start of array
+ {
+ out_of_bounds = 1;
+ k = 0L;
+ }
+ if(k > size-1L)
+ {
+ out_of_bounds = 1;
+ k = size-1L; // end of array
+ }
+
+ if((j != i) && !out_of_bounds) // skip our own location in this roundup
+ if(mlp->universe[k]) // if there's a neighbour inc count
+ neighbours++;
+ }
+
+ } // end of neighbour search
+
+ // based on number of neighbours, fill or clear this cell (i)
+ if((neighbours < min_neighbours) || (neighbours > max_neighbours))
+ mlp->universe[i] = 0;
+ else
+ mlp->universe[i] = 1;
+ }
+}
+
+//
+// method to set the die_lo number
+//
+static void ml_set_die_lo(t_maxlife *mlp, t_floatarg die_lo)
+{
+ mlp->rule_die_lo = (t_int)die_lo;
+}
+
+//
+// method to set the die_hi number
+//
+static void ml_set_die_hi(t_maxlife *mlp, t_floatarg die_hi)
+{
+ mlp->rule_die_hi = (t_int)die_hi;
+}
+
+//
+// method to set the die_lo number
+//
+static void ml_set_neighbourhood(t_maxlife *mlp, t_floatarg n_size)
+{
+ mlp->neighbourhood_size = (t_int)n_size;
+}
+
+//
+// bang method outputs bangs for filled cells within the view port
+//
+static void ml_bang(t_maxlife *mlp) // argument is a pointer to an instance
+{
+ register long i, view_start;
+
+#ifdef DEBUG
+ post("mlife:ml_bang called, sending bangs");
+#endif
+
+ view_start = mlp->view_start;
+
+ // loop through the outlets right->left sending bangs if alive
+ for(i=view_start+mlp->view_size-2; i>=view_start-1; i--)
+ {
+ // send a bang out the appropriate outlet
+ if(mlp->universe[i])
+ outlet_bang(mlp->out[i-view_start+1]);
+ }
+
+ ml_nextgeneration(mlp);
+}
+
+//
+// int method outputs ints for ALL cells in the view port (1=filled, 0=not)
+//
+static void ml_int(t_maxlife *mlp, t_floatarg dummy)
+{
+ t_int i, view_start;
+
+#ifdef DEBUG
+ post("mlife:ml_int method called");
+#endif
+
+ view_start = mlp->view_start;
+
+ // loop through the outlets right -> left sending ints
+ for(i = view_start + mlp->view_size - 2; i >= view_start - 1; i--)
+ {
+ //outlet_int(mlp->out[i-view_start+1], mlp->universe[i]);
+ if(mlp->universe[i] == 1)
+ outlet_float(mlp->out[i-view_start+1], 1);
+ else if(mlp->universe[i] == 0)
+ outlet_float(mlp->out[i-view_start+1], 0);
+ else
+ error("mlife: corrupted data in universe[] array!");
+ }
+
+ ml_nextgeneration(mlp);
+}
+
+
+//
+// method to print out the array
+//
+static void ml_display(t_maxlife *mlp)
+{
+ register long i;
+ char s[MAXSIZE];
+
+#ifdef DEBUG
+ post("mlife: display method called");
+#endif
+
+ for(i = 0; i < mlp->size; i++) // print the universe array
+ {
+ //s[i] = itoa(mlp->universe[i]); // my very primitive itoa()
+ if(mlp->universe[i])
+ s[i] = '1';
+ else
+ s[i] = '0';
+ }
+ s[mlp->size] = '\0'; // null terminate the string
+ post("%s", s);
+}
+
+//
+// method to fill the array with a number
+//
+static void ml_fill(t_maxlife *mlp, t_floatarg fill_no)
+{
+ t_int n;
+ register long i, j;
+
+ for(i=mlp->size-1; i >= 0; i--) // fill the universe array from the back
+ {
+ n = (t_int)fill_no;
+
+ for(j=(long)INTSIZE; j>0; j--, i--, n>>=1)
+ {
+ if(i < 0L)
+ {
+ return;
+ }
+ if(n & 01)
+ mlp->universe[i] = 1;
+ else
+ mlp->universe[i] = 0;
+ }
+ }
+}
+
+//
+// method to fill the array with a random number
+//
+static void ml_randfill(t_maxlife *mlp)
+{
+ unsigned int s, rnum;
+ register unsigned int n;
+ register long i, j;
+
+#ifdef DEBUG
+ post("mlife: randfill method called");
+#endif
+
+ s = (unsigned int)clock_getlogicaltime(); // set seed to a new number
+ my_srand(s); // reseed the 'random' generator
+ rnum = (unsigned int)my_rand();
+
+ for(i=mlp->size - 1; i>=0; i--) // fill the universe array from the back
+ {
+ n = rnum;
+
+ for(j=(long)INTSIZE; j>0; j--, i--, n>>=1)
+ {
+ if(i < 0L)
+ {
+ return;
+ }
+ if(n & 01)
+ mlp->universe[i] = 1;
+ else
+ mlp->universe[i] = 0;
+ }
+ }
+}
+
+//
+// method to seed the array with a number
+//
+static void ml_seed(t_maxlife *mlp, t_floatarg start, t_floatarg fill_no)
+{
+ t_int n;
+ register long i, st, end;
+
+#ifdef DEBUG
+ post("mlife: seed method called");
+#endif
+
+ st = (t_int)start;
+ n = (t_int)fill_no;
+
+ if(st+(t_int)INTSIZE > mlp->size)
+ i = mlp->size - 1;
+ else
+ i = st+(long)INTSIZE - 1;
+
+ // init the universe array from the back i>=start?
+ for(; i >= start - 1; i--, n>>=1)
+ {
+ if(n & 01)
+ mlp->universe[i] = 1;
+ else
+ mlp->universe[i] = 0;
+ }
+}
+
+//
+// method to seed the array with a random number
+//
+static void ml_randseed(t_maxlife *mlp, t_floatarg start)
+{
+ unsigned long s, rnum;
+ register unsigned long n;
+ register long i, st;
+
+#ifdef DEBUG
+ post("mlife: randseed method called, INTSIZE=%ld", (long)INTSIZE);
+#endif
+ //if((start < 1) || (start > mlp->size-(long)INTSIZE))
+ if(start < 1)
+ {
+ error("Randseed start parameter must be between 1 and %ld", mlp->size);
+ return;
+ }
+
+ s = (unsigned long)clock_getlogicaltime(); // set seed to a new number
+ my_srand(s); // reseed the 'random' generator
+ rnum = (unsigned long)my_rand();
+ n = (unsigned int)rnum;
+ st = start;
+
+ if(st+(t_int)INTSIZE > mlp->size)
+ i = mlp->size - 1;
+ else
+ i = st+(t_int)INTSIZE - 1;
+
+ // init the universe array from the back
+ for(; i>=st-1; i--, n>>=1)
+ {
+ if(n & 01)
+ mlp->universe[i] = 1;
+ else
+ mlp->universe[i] = 0;
+
+ }
+}
+
+
+//
+// function to create an instance of the mlife class
+//
+static void *ml_new(t_floatarg size, t_floatarg view_start, t_floatarg view_size, t_floatarg closed)
+{
+ long i;
+ t_maxlife *mlp = (t_maxlife *)pd_new(mlife_class);
+
+ // check all args...
+ if((size>MAXSIZE) || (size<1))
+ {
+ post("mlife: size argument must be between 1 and %ld", MAXSIZE);
+ size = 1.0;
+ }
+ if(view_start < 1)
+ {
+ post("mlife: view_start argument must be between 1 and %ld", size);
+ view_start = 1.0;
+ }
+ if((view_size < 1) || (view_size+view_start > size+1))
+ {
+ post("mlife: viewsize argument must be between 1 and %ld", size-view_start);
+ view_size = 1.0;
+ }
+
+
+ // set up our structure
+ mlp->size = (t_int)size;
+ mlp->view_start = (t_int)view_start;
+ mlp->view_size = (t_int)view_size;
+ mlp->rule_die_lo = DEFAULT_DIE_LO; // 2
+ mlp->rule_die_hi = DEFAULT_DIE_HI; // 3
+ mlp->neighbourhood_size = DEFAULT_N_SIZE; // 3
+ mlp->closed = (t_int)closed;
+ for(i=0; i<MAXSIZE; i++)
+ mlp->universe[i] = 0;
+
+ // create outlets - last first!
+ for(i = 0; i < mlp->view_size; i++)
+ mlp->out[i] = outlet_new(&mlp->ml_ob, gensym("float"));
+
+#ifdef DEBUG
+ post("mlife: finished building object");
+ post("mlife: INTSIZE=%ld, LONGSIZE=%ld", (long)INTSIZE, (long)LONGSIZE);
+#endif
+
+ post("mlife: defaults are: lo=%ld, hi=%ld, nset=%ld", (long)DEFAULT_DIE_LO, (long)DEFAULT_DIE_HI, DEFAULT_N_SIZE);
+
+ return(mlp); // always return a copy of the created object
+}
+
+static void ml_free(t_maxlife *mlp)
+{
+ long i;
+
+#ifdef DEBUG
+ post("mlife:freeing outlet memory");
+#endif
+/* for(i=mlp->view_size-1; i>=0; i--)
+ freeobject(mlp->out[i]); */
+}
+
+#ifndef MAXLIB
+void mlife_setup(void)
+{
+ mlife_class = class_new(gensym("mlife"), (t_newmethod)ml_new,
+ (t_method)ml_free, sizeof(t_maxlife), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_randfill, gensym("randfill"), 0);
+ class_addmethod(mlife_class, (t_method)ml_fill, gensym("fill"), A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_set_die_lo, gensym("lo"), A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_set_die_hi, gensym("hi"), A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_set_neighbourhood, gensym("nset"), A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_randseed, gensym("randseed"), A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_seed, gensym("seed"), A_FLOAT, A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_display, gensym("display"), 0);
+ class_addfloat(mlife_class, ml_int);
+ class_addbang(mlife_class, ml_bang);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_mlife_setup(void)
+{
+ mlife_class = class_new(gensym("maxlib_mlife"), (t_newmethod)ml_new,
+ (t_method)ml_free, sizeof(t_maxlife), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)ml_new, gensym("mlife"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_randfill, gensym("randfill"), 0);
+ class_addmethod(mlife_class, (t_method)ml_fill, gensym("fill"), A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_set_die_lo, gensym("lo"), A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_set_die_hi, gensym("hi"), A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_set_neighbourhood, gensym("nset"), A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_randseed, gensym("randseed"), A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_seed, gensym("seed"), A_FLOAT, A_FLOAT, 0);
+ class_addmethod(mlife_class, (t_method)ml_display, gensym("display"), 0);
+ class_addfloat(mlife_class, ml_int);
+ class_addbang(mlife_class, ml_bang);
+ class_sethelpsymbol(mlife_class, gensym("maxlib/mlife-help.pd"));
+}
+#endif
diff --git a/multi.c b/multi.c
index a29e80f..6cfbadf 100644
--- a/multi.c
+++ b/multi.c
@@ -1,110 +1,110 @@
-/* -------------------------- multi ------------------------------------------ */
-/* */
-/* Like '*', but calculates output whenever _any_ of the inlets changes. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-
-#define MAXSIZE 32
-
-static char *version = "multi v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct multi
-{
- t_object x_ob;
- t_inlet *x_inleft; /* leftmost inlet */
- t_inlet *x_inright; /* right inlet */
- t_outlet *x_outlet; /* result */
- t_int x_numvalues; /* number of values / inlets */
-
- t_float x_multivalue[MAXSIZE];
-
-} t_multi;
-
-static void multi_bang(t_multi *x)
-{
- int i;
- t_float result = x->x_multivalue[0];
- for(i = 1; i < x->x_numvalues; i++)
- result *= x->x_multivalue[i];
- outlet_float(x->x_outlet, result);
-}
-
-static void multi_float(t_multi *x, t_floatarg f)
-{
- x->x_multivalue[0] = f;
- multi_bang(x); /* calculate result */
-}
-
-static void multi_ft1(t_multi *x, t_floatarg f)
-{
- x->x_multivalue[1] = f;
- multi_bang(x); /* calculate result */
-}
-
-static t_class *multi_class;
-
-static void *multi_new(t_symbol *s, t_int argc, t_atom* argv)
-{
- int i;
-
- t_multi *x = (t_multi *)pd_new(multi_class);
- x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- for(i = 2; i < argc; i++) /* create additional inlets, if any */
- {
- floatinlet_new(&x->x_ob, &x->x_multivalue[i]);
- }
- x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
-
- for(i = 0; i < argc; i++)
- {
- x->x_multivalue[i] = atom_getfloatarg(i, argc, argv);;
- }
- x->x_numvalues = i;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void multi_setup(void)
-{
- multi_class = class_new(gensym("multi"), (t_newmethod)multi_new,
- 0, sizeof(t_multi), 0, A_GIMME, 0);
- class_addfloat(multi_class, multi_float);
- class_addmethod(multi_class, (t_method)multi_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addbang(multi_class, (t_method)multi_bang);
-
- post(version);
-}
-#else
-void maxlib_multi_setup(void)
-{
- multi_class = class_new(gensym("maxlib_multi"), (t_newmethod)multi_new,
- 0, sizeof(t_multi), 0, A_GIMME, 0);
- class_addcreator((t_newmethod)multi_new, gensym("multi"), A_GIMME, 0);
- class_addfloat(multi_class, multi_float);
- class_addmethod(multi_class, (t_method)multi_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addbang(multi_class, (t_method)multi_bang);
- class_sethelpsymbol(multi_class, gensym("maxlib/multi-help.pd"));
-}
-#endif
+/* -------------------------- multi ------------------------------------------ */
+/* */
+/* Like '*', but calculates output whenever _any_ of the inlets changes. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+
+#define MAXSIZE 32
+
+static char *version = "multi v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct multi
+{
+ t_object x_ob;
+ t_inlet *x_inleft; /* leftmost inlet */
+ t_inlet *x_inright; /* right inlet */
+ t_outlet *x_outlet; /* result */
+ t_int x_numvalues; /* number of values / inlets */
+
+ t_float x_multivalue[MAXSIZE];
+
+} t_multi;
+
+static void multi_bang(t_multi *x)
+{
+ int i;
+ t_float result = x->x_multivalue[0];
+ for(i = 1; i < x->x_numvalues; i++)
+ result *= x->x_multivalue[i];
+ outlet_float(x->x_outlet, result);
+}
+
+static void multi_float(t_multi *x, t_floatarg f)
+{
+ x->x_multivalue[0] = f;
+ multi_bang(x); /* calculate result */
+}
+
+static void multi_ft1(t_multi *x, t_floatarg f)
+{
+ x->x_multivalue[1] = f;
+ multi_bang(x); /* calculate result */
+}
+
+static t_class *multi_class;
+
+static void *multi_new(t_symbol *s, t_int argc, t_atom* argv)
+{
+ int i;
+
+ t_multi *x = (t_multi *)pd_new(multi_class);
+ x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ for(i = 2; i < argc; i++) /* create additional inlets, if any */
+ {
+ floatinlet_new(&x->x_ob, &x->x_multivalue[i]);
+ }
+ x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
+
+ for(i = 0; i < argc; i++)
+ {
+ x->x_multivalue[i] = atom_getfloatarg(i, argc, argv);;
+ }
+ x->x_numvalues = i;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void multi_setup(void)
+{
+ multi_class = class_new(gensym("multi"), (t_newmethod)multi_new,
+ 0, sizeof(t_multi), 0, A_GIMME, 0);
+ class_addfloat(multi_class, multi_float);
+ class_addmethod(multi_class, (t_method)multi_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addbang(multi_class, (t_method)multi_bang);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_multi_setup(void)
+{
+ multi_class = class_new(gensym("maxlib_multi"), (t_newmethod)multi_new,
+ 0, sizeof(t_multi), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)multi_new, gensym("multi"), A_GIMME, 0);
+ class_addfloat(multi_class, multi_float);
+ class_addmethod(multi_class, (t_method)multi_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addbang(multi_class, (t_method)multi_bang);
+ class_sethelpsymbol(multi_class, gensym("maxlib/multi-help.pd"));
+}
+#endif
diff --git a/nchange.c b/nchange.c
index 57945b1..5ede0c0 100644
--- a/nchange.c
+++ b/nchange.c
@@ -1,205 +1,205 @@
-/* ------------------------- ignore ------------------------------------------- */
-/* */
-/* A 'new' change object for more than just floats. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#define A_LIST 254;
-#define A_ANYTHING 255;
-
-#include "m_pd.h"
-
-// #include <string.h>
-// #include <stdio.h>
-
-/* -------------------------- nchange ------------------------------ */
-static char *version = "nchange v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-static t_class *nchange_class;
-
-typedef struct _nchange
-{
- t_object x_obj;
- t_atom x_a[256];
- int x_c;
- int x_type;
-} t_nchange;
-
-static void *nchange_new(t_symbol *s)
-{
- int i;
-
- t_nchange *x = (t_nchange *)pd_new(nchange_class);
-
- if(s == gensym("s"))
- {
- x->x_type = A_SYMBOL;
- outlet_new(&x->x_obj, &s_symbol);
- }
- else if(s == gensym("f"))
- {
- x->x_type = A_FLOAT;
- outlet_new(&x->x_obj, &s_float);
- }
- else if(s == gensym("l"))
- {
- x->x_type = A_LIST;
- outlet_new(&x->x_obj, &s_list);
- }
- else
- {
- x->x_type = A_ANYTHING;
- outlet_new(&x->x_obj, &s_anything);
- }
-
- return (x);
-}
-
-static void nchange_bang(t_nchange *x)
-{
- if (x->x_type == A_FLOAT)
- outlet_float(x->x_obj.ob_outlet, x->x_a->a_w.w_float);
- else if (x->x_type == A_SYMBOL)
- outlet_symbol(x->x_obj.ob_outlet, x->x_a->a_w.w_symbol);
- else
- outlet_list(x->x_obj.ob_outlet, NULL, x->x_c, x->x_a);
-}
-
-static void nchange_float(t_nchange *x, t_float f)
-{
- if (x->x_type == A_FLOAT)
- {
- if (f != x->x_a->a_w.w_float)
- {
- // x->x_f = f;
- SETFLOAT(x->x_a, f);
- outlet_float(x->x_obj.ob_outlet, x->x_a->a_w.w_float);
- }
- }
-}
-
-static void nchange_symbol(t_nchange *x, t_symbol *s)
-{
- if (x->x_type == A_SYMBOL)
- {
- if (s != x->x_a->a_w.w_symbol)
- {
- // x->x_s = s;
- SETSYMBOL(x->x_a, s);
- outlet_symbol(x->x_obj.ob_outlet, x->x_a->a_w.w_symbol);
- }
- }
-}
-
-static void nchange_list(t_nchange *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i, change = 0;
- int c = argc;
-
- if(c == x->x_c) // same number of elements
- for (i = 0; i < c; i++)
- {
- /* if(x->x_a[i].a_type != argv[i].a_type)
- {
- change = 1;
- break;
- } */
- if (x->x_a[i].a_type == A_FLOAT)
- {
- if (argv[i].a_type != A_FLOAT || x->x_a[i].a_w.w_float != argv[i].a_w.w_float)
- {
- change = 1;
- break;
- }
- }
- else if (x->x_a[i].a_type == A_SYMBOL)
- {
- if (argv[i].a_type != A_SYMBOL || x->x_a[i].a_w.w_symbol != argv[i].a_w.w_symbol)
- {
- change = 1;
- break;
- }
- }
- }
- else change = 1; // different number of elems.
-
- if (change)
- {
- x->x_c = c;
- for (i = 0; i < c; i++) // same new list
- {
- x->x_a[i] = argv[i];
- }
- outlet_list(x->x_obj.ob_outlet, s, argc, argv);
- }
-}
-
-static void nchange_set(t_nchange *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i;
-
- if (x->x_type == A_SYMBOL)
- {
- SETSYMBOL(x->x_a, argv->a_w.w_symbol);
- }
- else if (x->x_type == A_FLOAT)
- {
- SETFLOAT(x->x_a, argv->a_w.w_float);
- }
- else // list or anything
- {
- x->x_c = argc;
- for (i = 0; i < argc; i++)
- {
- x->x_a[i] = argv[i];
- }
- }
-}
-
-#ifndef MAXLIB
-void nchange_setup(void)
-{
- nchange_class = class_new(gensym("nchange"), (t_newmethod)nchange_new, 0,
- sizeof(t_nchange), 0, A_SYMBOL, 0);
- class_addbang(nchange_class, nchange_bang);
- class_addfloat(nchange_class, nchange_float);
- class_addsymbol(nchange_class, nchange_symbol);
- class_addlist(nchange_class, nchange_list);
- class_addanything(nchange_class, nchange_list);
- class_addmethod(nchange_class, (t_method)nchange_set, gensym("set"), A_GIMME, 0);
-
- post(version);
-}
-#else
-void maxlib_nchange_setup(void)
-{
- nchange_class = class_new(gensym("maxlib_nchange"), (t_newmethod)nchange_new, 0,
- sizeof(t_nchange), 0, A_SYMBOL, 0);
- class_addcreator((t_newmethod)nchange_new, gensym("nchange"), A_SYMBOL, 0);
- class_addbang(nchange_class, nchange_bang);
- class_addfloat(nchange_class, nchange_float);
- class_addsymbol(nchange_class, nchange_symbol);
- class_addlist(nchange_class, nchange_list);
- class_addanything(nchange_class, nchange_list);
- class_addmethod(nchange_class, (t_method)nchange_set, gensym("set"), A_GIMME, 0);
- class_sethelpsymbol(nchange_class, gensym("maxlib/nchange-help.pd"));
-}
-#endif
+/* ------------------------- ignore ------------------------------------------- */
+/* */
+/* A 'new' change object for more than just floats. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#define A_LIST 254;
+#define A_ANYTHING 255;
+
+#include "m_pd.h"
+
+// #include <string.h>
+// #include <stdio.h>
+
+/* -------------------------- nchange ------------------------------ */
+static char *version = "nchange v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+static t_class *nchange_class;
+
+typedef struct _nchange
+{
+ t_object x_obj;
+ t_atom x_a[256];
+ int x_c;
+ int x_type;
+} t_nchange;
+
+static void *nchange_new(t_symbol *s)
+{
+ int i;
+
+ t_nchange *x = (t_nchange *)pd_new(nchange_class);
+
+ if(s == gensym("s"))
+ {
+ x->x_type = A_SYMBOL;
+ outlet_new(&x->x_obj, &s_symbol);
+ }
+ else if(s == gensym("f"))
+ {
+ x->x_type = A_FLOAT;
+ outlet_new(&x->x_obj, &s_float);
+ }
+ else if(s == gensym("l"))
+ {
+ x->x_type = A_LIST;
+ outlet_new(&x->x_obj, &s_list);
+ }
+ else
+ {
+ x->x_type = A_ANYTHING;
+ outlet_new(&x->x_obj, &s_anything);
+ }
+
+ return (x);
+}
+
+static void nchange_bang(t_nchange *x)
+{
+ if (x->x_type == A_FLOAT)
+ outlet_float(x->x_obj.ob_outlet, x->x_a->a_w.w_float);
+ else if (x->x_type == A_SYMBOL)
+ outlet_symbol(x->x_obj.ob_outlet, x->x_a->a_w.w_symbol);
+ else
+ outlet_list(x->x_obj.ob_outlet, NULL, x->x_c, x->x_a);
+}
+
+static void nchange_float(t_nchange *x, t_float f)
+{
+ if (x->x_type == A_FLOAT)
+ {
+ if (f != x->x_a->a_w.w_float)
+ {
+ // x->x_f = f;
+ SETFLOAT(x->x_a, f);
+ outlet_float(x->x_obj.ob_outlet, x->x_a->a_w.w_float);
+ }
+ }
+}
+
+static void nchange_symbol(t_nchange *x, t_symbol *s)
+{
+ if (x->x_type == A_SYMBOL)
+ {
+ if (s != x->x_a->a_w.w_symbol)
+ {
+ // x->x_s = s;
+ SETSYMBOL(x->x_a, s);
+ outlet_symbol(x->x_obj.ob_outlet, x->x_a->a_w.w_symbol);
+ }
+ }
+}
+
+static void nchange_list(t_nchange *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i, change = 0;
+ int c = argc;
+
+ if(c == x->x_c) // same number of elements
+ for (i = 0; i < c; i++)
+ {
+ /* if(x->x_a[i].a_type != argv[i].a_type)
+ {
+ change = 1;
+ break;
+ } */
+ if (x->x_a[i].a_type == A_FLOAT)
+ {
+ if (argv[i].a_type != A_FLOAT || x->x_a[i].a_w.w_float != argv[i].a_w.w_float)
+ {
+ change = 1;
+ break;
+ }
+ }
+ else if (x->x_a[i].a_type == A_SYMBOL)
+ {
+ if (argv[i].a_type != A_SYMBOL || x->x_a[i].a_w.w_symbol != argv[i].a_w.w_symbol)
+ {
+ change = 1;
+ break;
+ }
+ }
+ }
+ else change = 1; // different number of elems.
+
+ if (change)
+ {
+ x->x_c = c;
+ for (i = 0; i < c; i++) // same new list
+ {
+ x->x_a[i] = argv[i];
+ }
+ outlet_list(x->x_obj.ob_outlet, s, argc, argv);
+ }
+}
+
+static void nchange_set(t_nchange *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+
+ if (x->x_type == A_SYMBOL)
+ {
+ SETSYMBOL(x->x_a, argv->a_w.w_symbol);
+ }
+ else if (x->x_type == A_FLOAT)
+ {
+ SETFLOAT(x->x_a, argv->a_w.w_float);
+ }
+ else // list or anything
+ {
+ x->x_c = argc;
+ for (i = 0; i < argc; i++)
+ {
+ x->x_a[i] = argv[i];
+ }
+ }
+}
+
+#ifndef MAXLIB
+void nchange_setup(void)
+{
+ nchange_class = class_new(gensym("nchange"), (t_newmethod)nchange_new, 0,
+ sizeof(t_nchange), 0, A_SYMBOL, 0);
+ class_addbang(nchange_class, nchange_bang);
+ class_addfloat(nchange_class, nchange_float);
+ class_addsymbol(nchange_class, nchange_symbol);
+ class_addlist(nchange_class, nchange_list);
+ class_addanything(nchange_class, nchange_list);
+ class_addmethod(nchange_class, (t_method)nchange_set, gensym("set"), A_GIMME, 0);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_nchange_setup(void)
+{
+ nchange_class = class_new(gensym("maxlib_nchange"), (t_newmethod)nchange_new, 0,
+ sizeof(t_nchange), 0, A_SYMBOL, 0);
+ class_addcreator((t_newmethod)nchange_new, gensym("nchange"), A_SYMBOL, 0);
+ class_addbang(nchange_class, nchange_bang);
+ class_addfloat(nchange_class, nchange_float);
+ class_addsymbol(nchange_class, nchange_symbol);
+ class_addlist(nchange_class, nchange_list);
+ class_addanything(nchange_class, nchange_list);
+ class_addmethod(nchange_class, (t_method)nchange_set, gensym("set"), A_GIMME, 0);
+ class_sethelpsymbol(nchange_class, gensym("maxlib/nchange-help.pd"));
+}
+#endif
diff --git a/netclient.c b/netclient.c
index 3a024cd..7436aed 100644
--- a/netclient.c
+++ b/netclient.c
@@ -1,396 +1,396 @@
-/* -------------------------- netclient ------------------------------------- */
-/* */
-/* Extended 'netsend', connects to 'netserver'. */
-/* Uses child thread to connect to server. Thus needs pd0.35-test17 or later. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* -------------------------- netclient ------------------------------------- */
+/* */
+/* Extended 'netsend', connects to 'netserver'. */
+/* Uses child thread to connect to server. Thus needs pd0.35-test17 or later. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
/* Get source at */
/* http://pure-data.svn.sourceforge.net/viewvc/pure-data/trunk/externals/maxlib/src/netclient.c */
/* March 26 2010 */
/* Additional fixes and improvements by Ivica Ico Bukvic <ico@bukvic.net> */
/* for the purpose of L2Ork http://l2ork.music.vt.edu */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-/* Changes: use circular message buffer for receive */
-/* using pollfunction instead of clock (suggested by HCS) */
-
-#include "m_pd.h"
-#include "s_stuff.h"
-#include "m_imp.h"
-
-#include <sys/types.h>
-#include <string.h>
-#include <pthread.h>
-#ifdef WIN32
-#include <winsock.h>
-#else
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <unistd.h>
-#define SOCKET_ERROR -1
-#endif
-
-#define INBUFSIZE 4096 /* maximum numbers of characters to read */
-
-static char *version = "netclient v0.3.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-static t_class *netclient_class;
-static t_binbuf *inbinbuf;
-static int netclient_instance_count;
-
-typedef struct _netclient
-{
- t_object x_obj;
- t_clock *x_clock;
- t_outlet *x_outdata;
- t_outlet *x_outconnect;
- int x_fd;
- char *x_hostname;
- int x_connectstate;
- int x_port;
- int x_protocol;
- char x_inbuf[INBUFSIZE]; /* circular message buffer for received data */
- int x_intail;
- int x_inhead;
- /* multithread stuff */
- pthread_t x_threadid; /* id of child thread */
- pthread_attr_t x_threadattr; /* attributes of child thread */
-} t_netclient;
-
- /* one lonely prototype */
-static void netclient_rcv(t_netclient *x);
-
-
- /* gets called when connection status has changed */
-static void netclient_tick(t_netclient *x)
-{
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+/* Changes: use circular message buffer for receive */
+/* using pollfunction instead of clock (suggested by HCS) */
+
+#include "m_pd.h"
+#include "s_stuff.h"
+#include "m_imp.h"
+
+#include <sys/types.h>
+#include <string.h>
+#include <pthread.h>
+#ifdef WIN32
+#include <winsock.h>
+#else
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <unistd.h>
+#define SOCKET_ERROR -1
+#endif
+
+#define INBUFSIZE 4096 /* maximum numbers of characters to read */
+
+static char *version = "netclient v0.3.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+static t_class *netclient_class;
+static t_binbuf *inbinbuf;
+static int netclient_instance_count;
+
+typedef struct _netclient
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ t_outlet *x_outdata;
+ t_outlet *x_outconnect;
+ int x_fd;
+ char *x_hostname;
+ int x_connectstate;
+ int x_port;
+ int x_protocol;
+ char x_inbuf[INBUFSIZE]; /* circular message buffer for received data */
+ int x_intail;
+ int x_inhead;
+ /* multithread stuff */
+ pthread_t x_threadid; /* id of child thread */
+ pthread_attr_t x_threadattr; /* attributes of child thread */
+} t_netclient;
+
+ /* one lonely prototype */
+static void netclient_rcv(t_netclient *x);
+
+
+ /* gets called when connection status has changed */
+static void netclient_tick(t_netclient *x)
+{
outlet_float(x->x_outconnect, x->x_connectstate);
/* add pollfunction for checking for input */
if (x->x_connectstate == 1)
{
sys_addpollfn(x->x_fd, (t_fdpollfn)netclient_rcv, x);
}
-}
-
-static void *netclient_child_connect(void *w)
-{
- t_netclient *x = (t_netclient*) w;
- struct sockaddr_in server;
- struct hostent *hp;
- int sockfd;
- int portno = x->x_port;
- if (x->x_fd >= 0)
- {
- error("netclient_connect: already connected");
- return (x);
- }
-
- /* create a socket */
- sockfd = socket(AF_INET, x->x_protocol, 0);
-#if 0
- fprintf(stderr, "send socket %d\n", sockfd);
-#endif
- if (sockfd < 0)
- {
- sys_sockerror("socket");
- return (x);
- }
- /* connect socket using hostname provided in command line */
- server.sin_family = AF_INET;
- hp = gethostbyname(x->x_hostname);
- if (hp == 0)
- {
- post("bad host?\n");
- return (x);
- }
- memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
-
- /* assign client port number */
- server.sin_port = htons((u_short)portno);
-
- post("connecting to port %d", portno);
- /* try to connect */
- if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0)
- {
- sys_sockerror("connecting stream socket");
- sys_closesocket(sockfd);
- return (x);
- }
- x->x_fd = sockfd;
- /* outlet_float is not threadsafe ! */
- // outlet_float(x->x_obj.ob_outlet, 1);
- x->x_connectstate = 1;
- /* use callback instead to set outlet */
- clock_delay(x->x_clock, 0);
- return (x);
-}
-
-static void netclient_connect(t_netclient *x, t_symbol *hostname,
- t_floatarg fportno)
-{
- /* we get hostname and port and pass them on
- to the child thread that establishes the connection */
- x->x_hostname = hostname->s_name;
- x->x_port = fportno;
- x->x_connectstate = 0;
- /* start child thread */
- if(pthread_create( &x->x_threadid, &x->x_threadattr, netclient_child_connect, x) < 0)
- post("netclient: could not create new thread");
-}
-
-static void netclient_disconnect(t_netclient *x)
-{
- if (x->x_fd >= 0)
- {
- sys_rmpollfn(x->x_fd);
- sys_closesocket(x->x_fd);
- x->x_fd = -1;
- x->x_connectstate = 0;
- //outlet_float(x->x_outconnect, 0);
+}
+
+static void *netclient_child_connect(void *w)
+{
+ t_netclient *x = (t_netclient*) w;
+ struct sockaddr_in server;
+ struct hostent *hp;
+ int sockfd;
+ int portno = x->x_port;
+ if (x->x_fd >= 0)
+ {
+ error("netclient_connect: already connected");
+ return (x);
+ }
+
+ /* create a socket */
+ sockfd = socket(AF_INET, x->x_protocol, 0);
+#if 0
+ fprintf(stderr, "send socket %d\n", sockfd);
+#endif
+ if (sockfd < 0)
+ {
+ sys_sockerror("socket");
+ return (x);
+ }
+ /* connect socket using hostname provided in command line */
+ server.sin_family = AF_INET;
+ hp = gethostbyname(x->x_hostname);
+ if (hp == 0)
+ {
+ post("bad host?\n");
+ return (x);
+ }
+ memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
+
+ /* assign client port number */
+ server.sin_port = htons((u_short)portno);
+
+ post("connecting to port %d", portno);
+ /* try to connect */
+ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0)
+ {
+ sys_sockerror("connecting stream socket");
+ sys_closesocket(sockfd);
+ return (x);
+ }
+ x->x_fd = sockfd;
+ /* outlet_float is not threadsafe ! */
+ // outlet_float(x->x_obj.ob_outlet, 1);
+ x->x_connectstate = 1;
+ /* use callback instead to set outlet */
+ clock_delay(x->x_clock, 0);
+ return (x);
+}
+
+static void netclient_connect(t_netclient *x, t_symbol *hostname,
+ t_floatarg fportno)
+{
+ /* we get hostname and port and pass them on
+ to the child thread that establishes the connection */
+ x->x_hostname = hostname->s_name;
+ x->x_port = fportno;
+ x->x_connectstate = 0;
+ /* start child thread */
+ if(pthread_create( &x->x_threadid, &x->x_threadattr, netclient_child_connect, x) < 0)
+ post("netclient: could not create new thread");
+}
+
+static void netclient_disconnect(t_netclient *x)
+{
+ if (x->x_fd >= 0)
+ {
+ sys_rmpollfn(x->x_fd);
+ sys_closesocket(x->x_fd);
+ x->x_fd = -1;
+ x->x_connectstate = 0;
+ //outlet_float(x->x_outconnect, 0);
clock_delay(x->x_clock, 0); /* output connect state later */
- }
-}
-
-static void netclient_send(t_netclient *x, t_symbol *s, int argc, t_atom *argv)
-{
- if (x->x_fd >= 0)
- {
- t_binbuf *b = binbuf_new();
- char *buf, *bp;
- int length, sent;
- t_atom at;
- binbuf_add(b, argc, argv);
- SETSEMI(&at);
- binbuf_add(b, 1, &at);
- binbuf_gettext(b, &buf, &length);
- for (bp = buf, sent = 0; sent < length;)
- {
- static double lastwarntime;
- static double pleasewarn;
- double timebefore = sys_getrealtime();
- int res = send(x->x_fd, buf, length-sent, 0);
- double timeafter = sys_getrealtime();
- int late = (timeafter - timebefore > 0.005);
- if (late || pleasewarn)
- {
- if (timeafter > lastwarntime + 2)
- {
- post("netclient blocked %d msec",
- (int)(1000 * ((timeafter - timebefore) + pleasewarn)));
- pleasewarn = 0;
- lastwarntime = timeafter;
- }
- else if (late) pleasewarn += timeafter - timebefore;
- }
- if (res <= 0)
- {
- sys_sockerror("netclient");
- netclient_disconnect(x);
- break;
- }
- else
- {
- sent += res;
- bp += res;
- }
- }
- t_freebytes(buf, length);
- binbuf_free(b);
- }
- else error("netclient: not connected");
-}
-
- /* this is in a separately called subroutine so that the buffer isn't
- sitting on the stack while the messages are getting passed. */
-static int netclient_doread(t_netclient *x)
-{
- char messbuf[INBUFSIZE], *bp = messbuf;
- int indx;
- int inhead = x->x_inhead;
- int intail = x->x_intail;
- char *inbuf = x->x_inbuf;
- if (intail == inhead) return (0);
- for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1))
- {
- char c = *bp++ = inbuf[indx];
- if (c == ';' && (!indx || inbuf[indx-1] != '\\'))
- {
- intail = (indx+1)&(INBUFSIZE-1);
- binbuf_text(inbinbuf, messbuf, bp - messbuf);
- x->x_inhead = inhead;
- x->x_intail = intail;
- return (1);
- }
- }
- return (0);
-}
-
-static void netclient_rcv(t_netclient *x)
-{
- int fd = x->x_fd;
- int ret;
- fd_set readset;
- fd_set exceptset;
- struct timeval ztout;
- /* output data */
- int msg, natom;
- t_atom *at;
-
- if(x->x_connectstate)
- {
- /* check if we can read/write from/to the socket */
- FD_ZERO(&readset);
- FD_ZERO(&exceptset);
- FD_SET(fd, &readset );
- FD_SET(fd, &exceptset );
-
- ztout.tv_sec = 0;
- ztout.tv_usec = 0;
- ret = select(fd+1, &readset, NULL, &exceptset, &ztout);
- if(ret < 0)
- {
- error("netclient: can not read from socket");
+ }
+}
+
+static void netclient_send(t_netclient *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if (x->x_fd >= 0)
+ {
+ t_binbuf *b = binbuf_new();
+ char *buf, *bp;
+ int length, sent;
+ t_atom at;
+ binbuf_add(b, argc, argv);
+ SETSEMI(&at);
+ binbuf_add(b, 1, &at);
+ binbuf_gettext(b, &buf, &length);
+ for (bp = buf, sent = 0; sent < length;)
+ {
+ static double lastwarntime;
+ static double pleasewarn;
+ double timebefore = sys_getrealtime();
+ int res = send(x->x_fd, buf, length-sent, 0);
+ double timeafter = sys_getrealtime();
+ int late = (timeafter - timebefore > 0.005);
+ if (late || pleasewarn)
+ {
+ if (timeafter > lastwarntime + 2)
+ {
+ post("netclient blocked %d msec",
+ (int)(1000 * ((timeafter - timebefore) + pleasewarn)));
+ pleasewarn = 0;
+ lastwarntime = timeafter;
+ }
+ else if (late) pleasewarn += timeafter - timebefore;
+ }
+ if (res <= 0)
+ {
+ sys_sockerror("netclient");
+ netclient_disconnect(x);
+ break;
+ }
+ else
+ {
+ sent += res;
+ bp += res;
+ }
+ }
+ t_freebytes(buf, length);
+ binbuf_free(b);
+ }
+ else error("netclient: not connected");
+}
+
+ /* this is in a separately called subroutine so that the buffer isn't
+ sitting on the stack while the messages are getting passed. */
+static int netclient_doread(t_netclient *x)
+{
+ char messbuf[INBUFSIZE], *bp = messbuf;
+ int indx;
+ int inhead = x->x_inhead;
+ int intail = x->x_intail;
+ char *inbuf = x->x_inbuf;
+ if (intail == inhead) return (0);
+ for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1))
+ {
+ char c = *bp++ = inbuf[indx];
+ if (c == ';' && (!indx || inbuf[indx-1] != '\\'))
+ {
+ intail = (indx+1)&(INBUFSIZE-1);
+ binbuf_text(inbinbuf, messbuf, bp - messbuf);
+ x->x_inhead = inhead;
+ x->x_intail = intail;
+ return (1);
+ }
+ }
+ return (0);
+}
+
+static void netclient_rcv(t_netclient *x)
+{
+ int fd = x->x_fd;
+ int ret;
+ fd_set readset;
+ fd_set exceptset;
+ struct timeval ztout;
+ /* output data */
+ int msg, natom;
+ t_atom *at;
+
+ if(x->x_connectstate)
+ {
+ /* check if we can read/write from/to the socket */
+ FD_ZERO(&readset);
+ FD_ZERO(&exceptset);
+ FD_SET(fd, &readset );
+ FD_SET(fd, &exceptset );
+
+ ztout.tv_sec = 0;
+ ztout.tv_usec = 0;
+ ret = select(fd+1, &readset, NULL, &exceptset, &ztout);
+ if(ret < 0)
+ {
+ error("netclient: can not read from socket");
//sys_closesocket(fd);
- netclient_disconnect(x);
- return;
- }
- if(FD_ISSET(fd, &readset) || FD_ISSET(fd, &exceptset))
- {
- int readto = (x->x_inhead >= x->x_intail ? INBUFSIZE : x->x_intail-1);
-
- ret = recv(fd, x->x_inbuf + x->x_inhead, readto - x->x_inhead, 0);
- if (ret < 0)
- {
- sys_sockerror("recv");
- //sys_rmpollfn(fd);
+ netclient_disconnect(x);
+ return;
+ }
+ if(FD_ISSET(fd, &readset) || FD_ISSET(fd, &exceptset))
+ {
+ int readto = (x->x_inhead >= x->x_intail ? INBUFSIZE : x->x_intail-1);
+
+ ret = recv(fd, x->x_inbuf + x->x_inhead, readto - x->x_inhead, 0);
+ if (ret < 0)
+ {
+ sys_sockerror("recv");
+ //sys_rmpollfn(fd);
//sys_closesocket(fd);
- netclient_disconnect(x);
- }
- else if (ret == 0)
- {
- post("netclient: connection closed on socket %d", fd);
- //sys_rmpollfn(fd);
- //sys_closesocket(fd);
- netclient_disconnect(x);
- }
- else
- {
- x->x_inhead += ret;
- if (x->x_inhead >= INBUFSIZE) x->x_inhead = 0;
- while (netclient_doread(x))
- {
- /* output binbuf */
- natom = binbuf_getnatom(inbinbuf); /* get number of atoms */
- at = binbuf_getvec(inbinbuf); /* get the atoms */
- /* now split it into several parts at every A_SEMI because
- we probably received more than one message at a time */
- 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 ii;
- for (ii = msg; ii < emsg; ii++)
- if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM)
- {
- pd_error(x, "netserver: -- got dollar sign in message");
- goto nodice;
- }
- if (at[msg].a_type == A_FLOAT)
- {
- if (emsg > msg + 1)
- outlet_list(x->x_outdata, 0, emsg-msg, at + msg);
- else outlet_float(x->x_outdata, at[msg].a_w.w_float);
- }
- else if (at[msg].a_type == A_SYMBOL)
- outlet_anything(x->x_outdata, at[msg].a_w.w_symbol,
- emsg-msg-1, at + msg + 1);
- }
- nodice:
- msg = emsg + 1;
- }
- }
- }
- }
- }
- else post("netclient: not connected");
-}
-
-static void *netclient_new(t_floatarg udpflag)
-{
- t_netclient *x = (t_netclient *)pd_new(netclient_class);
- x->x_outdata = outlet_new(&x->x_obj, &s_anything); /* received data */
- x->x_outconnect = outlet_new(&x->x_obj, &s_float); /* connection state */
- x->x_clock = clock_new(x, (t_method)netclient_tick);
- if(netclient_instance_count == 0)
- inbinbuf = binbuf_new();
- x->x_fd = -1;
- x->x_protocol = (udpflag != 0 ? SOCK_DGRAM : SOCK_STREAM);
- /* prepare child thread */
- if(pthread_attr_init(&x->x_threadattr) < 0)
- post("netclient: warning: could not prepare child thread" );
- if(pthread_attr_setdetachstate(&x->x_threadattr, PTHREAD_CREATE_DETACHED) < 0)
- post("netclient: warning: could not prepare child thread" );
- netclient_instance_count++;
- return (x);
-}
-
-static void netclient_free(t_netclient *x)
-{
- netclient_disconnect(x);
- clock_free(x->x_clock);
- netclient_instance_count--;
- if(netclient_instance_count == 0)
- binbuf_free(inbinbuf);
-}
-
-#ifndef MAXLIB
-void netclient_setup(void)
-{
- netclient_class = class_new(gensym("netclient"), (t_newmethod)netclient_new,
- (t_method)netclient_free,
- sizeof(t_netclient), 0, A_DEFFLOAT, 0);
- class_addmethod(netclient_class, (t_method)netclient_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(netclient_class, (t_method)netclient_disconnect, gensym("disconnect"), 0);
- class_addmethod(netclient_class, (t_method)netclient_send, gensym("send"), A_GIMME, 0);
- class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("receive"), 0);
- class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("rcv"), 0);
-
- post(version);
-}
-#else
-void maxlib_netclient_setup(void)
-{
- netclient_class = class_new(gensym("maxlib_netclient"), (t_newmethod)netclient_new,
- (t_method)netclient_free,
- sizeof(t_netclient), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)netclient_new, gensym("netclient"), A_DEFFLOAT, 0);
- class_addmethod(netclient_class, (t_method)netclient_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(netclient_class, (t_method)netclient_disconnect, gensym("disconnect"), 0);
- class_addmethod(netclient_class, (t_method)netclient_send, gensym("send"), A_GIMME, 0);
- class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("receive"), 0);
- class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("rcv"), 0);
- class_sethelpsymbol(netclient_class, gensym("maxlib/netclient-help.pd"));
-}
-#endif
+ netclient_disconnect(x);
+ }
+ else if (ret == 0)
+ {
+ post("netclient: connection closed on socket %d", fd);
+ //sys_rmpollfn(fd);
+ //sys_closesocket(fd);
+ netclient_disconnect(x);
+ }
+ else
+ {
+ x->x_inhead += ret;
+ if (x->x_inhead >= INBUFSIZE) x->x_inhead = 0;
+ while (netclient_doread(x))
+ {
+ /* output binbuf */
+ natom = binbuf_getnatom(inbinbuf); /* get number of atoms */
+ at = binbuf_getvec(inbinbuf); /* get the atoms */
+ /* now split it into several parts at every A_SEMI because
+ we probably received more than one message at a time */
+ 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 ii;
+ for (ii = msg; ii < emsg; ii++)
+ if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM)
+ {
+ pd_error(x, "netserver: -- got dollar sign in message");
+ goto nodice;
+ }
+ if (at[msg].a_type == A_FLOAT)
+ {
+ if (emsg > msg + 1)
+ outlet_list(x->x_outdata, 0, emsg-msg, at + msg);
+ else outlet_float(x->x_outdata, at[msg].a_w.w_float);
+ }
+ else if (at[msg].a_type == A_SYMBOL)
+ outlet_anything(x->x_outdata, at[msg].a_w.w_symbol,
+ emsg-msg-1, at + msg + 1);
+ }
+ nodice:
+ msg = emsg + 1;
+ }
+ }
+ }
+ }
+ }
+ else post("netclient: not connected");
+}
+
+static void *netclient_new(t_floatarg udpflag)
+{
+ t_netclient *x = (t_netclient *)pd_new(netclient_class);
+ x->x_outdata = outlet_new(&x->x_obj, &s_anything); /* received data */
+ x->x_outconnect = outlet_new(&x->x_obj, &s_float); /* connection state */
+ x->x_clock = clock_new(x, (t_method)netclient_tick);
+ if(netclient_instance_count == 0)
+ inbinbuf = binbuf_new();
+ x->x_fd = -1;
+ x->x_protocol = (udpflag != 0 ? SOCK_DGRAM : SOCK_STREAM);
+ /* prepare child thread */
+ if(pthread_attr_init(&x->x_threadattr) < 0)
+ post("netclient: warning: could not prepare child thread" );
+ if(pthread_attr_setdetachstate(&x->x_threadattr, PTHREAD_CREATE_DETACHED) < 0)
+ post("netclient: warning: could not prepare child thread" );
+ netclient_instance_count++;
+ return (x);
+}
+
+static void netclient_free(t_netclient *x)
+{
+ netclient_disconnect(x);
+ clock_free(x->x_clock);
+ netclient_instance_count--;
+ if(netclient_instance_count == 0)
+ binbuf_free(inbinbuf);
+}
+
+#ifndef MAXLIB
+void netclient_setup(void)
+{
+ netclient_class = class_new(gensym("netclient"), (t_newmethod)netclient_new,
+ (t_method)netclient_free,
+ sizeof(t_netclient), 0, A_DEFFLOAT, 0);
+ class_addmethod(netclient_class, (t_method)netclient_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0);
+ class_addmethod(netclient_class, (t_method)netclient_disconnect, gensym("disconnect"), 0);
+ class_addmethod(netclient_class, (t_method)netclient_send, gensym("send"), A_GIMME, 0);
+ class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("receive"), 0);
+ class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("rcv"), 0);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_netclient_setup(void)
+{
+ netclient_class = class_new(gensym("maxlib_netclient"), (t_newmethod)netclient_new,
+ (t_method)netclient_free,
+ sizeof(t_netclient), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)netclient_new, gensym("netclient"), A_DEFFLOAT, 0);
+ class_addmethod(netclient_class, (t_method)netclient_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0);
+ class_addmethod(netclient_class, (t_method)netclient_disconnect, gensym("disconnect"), 0);
+ class_addmethod(netclient_class, (t_method)netclient_send, gensym("send"), A_GIMME, 0);
+ class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("receive"), 0);
+ class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("rcv"), 0);
+ class_sethelpsymbol(netclient_class, gensym("maxlib/netclient-help.pd"));
+}
+#endif
diff --git a/netdist.c b/netdist.c
index 866dc36..2f2bf50 100644
--- a/netdist.c
+++ b/netdist.c
@@ -1,313 +1,313 @@
-/* -------------------------- netdist --------------------------------------- */
-/* */
-/* Distributes incoming data to a changeable list of netreceive objects. */
-/* Uses child thread to connect to clients. Thus needs pd0.35-test17 or later. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-
-#include "m_pd.h"
-
-#include <sys/types.h>
-#include <string.h>
-#include <pthread.h>
-#ifdef WIN32
-#include <winsock.h>
-#else
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <unistd.h>
-#define SOCKET_ERROR -1
-#endif
-
-#define MAX_REC 32
-
-static char *version = "netdist v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-static t_class *netdist_class;
-
-typedef struct _netdist
-{
- t_object x_obj;
- t_clock *x_clock;
- int x_fd[MAX_REC];
- char *x_hostname[MAX_REC];
- int x_numconnect;
- int x_port[MAX_REC];
- int x_protocol;
- /* multithread stuff */
- pthread_t x_threadid; /* id of child thread */
- pthread_attr_t x_threadattr; /* attributes of child thread */
-} t_netdist;
-
-static void sys_sockerror(char *s)
-{
-#ifdef WIN32
- int err = WSAGetLastError();
- if (err == 10054) return;
-#else
- int err = errno;
-#endif
- post("%s: %s (%d)\n", s, strerror(err), err);
-}
-
-static void sys_closesocket(int fd) {
-
-#ifdef WIN32
- closesocket(fd);
-#else
- close(fd);
-#endif
-}
-
-
-static void netdist_tick(t_netdist *x)
-{
- outlet_float(x->x_obj.ob_outlet, x->x_numconnect + 1);
-}
-
-static void *netdist_new(t_floatarg udpflag)
-{
- int i;
- t_netdist *x = (t_netdist *)pd_new(netdist_class);
- outlet_new(&x->x_obj, &s_float);
- x->x_clock = clock_new(x, (t_method)netdist_tick);
- for(i = 0; i < MAX_REC; i++)x->x_fd[i] = -1;
- x->x_numconnect = -1;
- x->x_protocol = (udpflag != 0 ? SOCK_DGRAM : SOCK_STREAM);
-
- /* prepare child thread */
- if(pthread_attr_init(&x->x_threadattr) < 0)
- post("netdist: warning: could not prepare child thread" );
- if(pthread_attr_setdetachstate(&x->x_threadattr, PTHREAD_CREATE_DETACHED) < 0)
- post("netdist: warning: could not prepare child thread" );
- return (x);
-}
-
-static void *netdist_child_connect(void *w)
-{
- int i;
-
- t_netdist *x = (t_netdist*) w;
- struct sockaddr_in server;
- struct hostent *hp;
- int sockfd;
- int portno;
- i = x->x_numconnect + 1;
- portno = x->x_port[i];
- /* create a socket */
- sockfd = socket(AF_INET, x->x_protocol, 0);
-#if 0
- fprintf(stderr, "send socket %d\n", sockfd);
-#endif
- if (sockfd < 0)
- {
- sys_sockerror("socket");
- return (x);
- }
- /* connect socket using hostname provided in command line */
- server.sin_family = AF_INET;
- hp = gethostbyname(x->x_hostname[i]);
- if (hp == 0)
- {
- post("bad host?\n");
- return (x);
- }
- memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
-
- /* assign client port number */
- server.sin_port = htons((u_short)portno);
-
- post("connecting to port %d", portno);
- /* try to connect */
- if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0)
- {
- sys_sockerror("connecting stream socket");
- sys_closesocket(sockfd);
- return (x);
- }
- x->x_fd[i] = sockfd;
- /* outlet_float is not threadsafe ! */
- // outlet_float(x->x_obj.ob_outlet, 1);
- x->x_numconnect++; /* count connection */
- /* use callback instead to set outlet */
- clock_delay(x->x_clock, 0);
- return (x);
-}
-
-static void netdist_connect(t_netdist *x, t_symbol *hostname,
- t_floatarg fportno)
-{
- int i;
- /* we get hostname and port and pass them on
- to the child thread that establishes the connection */
- for(i = 0; i <= x->x_numconnect; i++)
- { /* check if we are already connected */
- if (hostname->s_name == x->x_hostname[i] && fportno == x->x_port[i])
- {
- error("netdist_connect: already connected");
- return;
- }
- }
- x->x_hostname[x->x_numconnect + 1] = hostname->s_name;
- x->x_port[x->x_numconnect + 1] = fportno;
-
- /* start child thread */
- if(pthread_create( &x->x_threadid, &x->x_threadattr, netdist_child_connect, x) < 0)
- post("netdist: could not create new thread");
-}
-
-static void netdist_disconnect(t_netdist *x, t_symbol *hostname, t_floatarg port)
-{
- int i, j;
- for(i = 0; i <= x->x_numconnect; i++)
- {
- if((hostname->s_name == x->x_hostname[i]) && ((int)port == x->x_port[i]))
- {
- /* search for connection */
- if (x->x_fd[i] >= 0)
- {
- sys_closesocket(x->x_fd[i]);
- x->x_fd[i] = -1;
- x->x_numconnect--;
- outlet_float(x->x_obj.ob_outlet, x->x_numconnect + 1);
- for(j = i; j <= x->x_numconnect; j++)
- {
- x->x_hostname[j] = x->x_hostname[j + 1];
- x->x_port[j] = x->x_port[j + 1];
- x->x_fd[j] = x->x_fd[j + 1];
- }
- }
- }
- }
-}
-
-static void netdist_send(t_netdist *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i = 0;
-
- for(i = 0; i <= x->x_numconnect; i++)
- {
- if (x->x_fd[i] >= 0)
- {
- t_binbuf *b = binbuf_new();
- char *buf, *bp;
- int length, sent;
- t_atom at;
- binbuf_add(b, argc, argv);
- SETSEMI(&at);
- binbuf_add(b, 1, &at);
- binbuf_gettext(b, &buf, &length);
- for (bp = buf, sent = 0; sent < length;)
- {
- static double lastwarntime;
- static double pleasewarn;
- double timebefore = clock_getlogicaltime();
- int res = send(x->x_fd[i], buf, length-sent, 0);
- double timeafter = clock_getlogicaltime();
- int late = (timeafter - timebefore > 0.005);
- if (late || pleasewarn)
- {
- if (timeafter > lastwarntime + 2)
- {
- post("netdist blocked %d msec",
- (int)(1000 * ((timeafter - timebefore) + pleasewarn)));
- pleasewarn = 0;
- lastwarntime = timeafter;
- }
- else if (late) pleasewarn += timeafter - timebefore;
- }
- if (res <= 0)
- {
- sys_sockerror("netdist");
- netdist_disconnect(x, gensym(x->x_hostname[i]), x->x_port[i]);
- break;
- }
- else
- {
- sent += res;
- bp += res;
- }
- }
- t_freebytes(buf, length);
- binbuf_free(b);
- }
- }
- if(x->x_numconnect == -1) error("netdist: not connected");
-}
-
- /* disconnect all */
-static void netdist_clear(t_netdist *x)
-{
- int i, j, n;
- n = x->x_numconnect;
- for (i = n; i >= 0; i--)
- {
- netdist_disconnect(x, gensym(x->x_hostname[i]), x->x_port[i]);
- }
-}
-
-static void netdist_print(t_netdist *x)
-{
- int i;
- post("netdist: %d connection(s) established:", x->x_numconnect + 1);
- for (i = x->x_numconnect; i >= 0; i--)
- {
- post(" \"%s\", port %d",x->x_hostname[i], x->x_port[i]);
- }
-}
-
-static void netdist_free(t_netdist *x)
-{
- netdist_clear(x);
- clock_free(x->x_clock);
-}
-
-#ifndef MAXLIB
-void netdist_setup(void)
-{
- netdist_class = class_new(gensym("netdist"), (t_newmethod)netdist_new,
- (t_method)netdist_free, sizeof(t_netdist), 0, A_DEFFLOAT, 0);
- class_addmethod(netdist_class, (t_method)netdist_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(netdist_class, (t_method)netdist_disconnect, gensym("disconnect"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(netdist_class, (t_method)netdist_send, gensym("send"), A_GIMME, 0);
- class_addmethod(netdist_class, (t_method)netdist_clear, gensym("clear"), 0);
- class_addmethod(netdist_class, (t_method)netdist_print, gensym("print"), 0);
-
- post(version);
-}
-#else
-void maxlib_netdist_setup(void)
-{
- netdist_class = class_new(gensym("maxlib_netdist"), (t_newmethod)netdist_new,
- (t_method)netdist_free, sizeof(t_netdist), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)netdist_new, gensym("netdist"), A_DEFFLOAT, 0);
- class_addmethod(netdist_class, (t_method)netdist_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(netdist_class, (t_method)netdist_disconnect, gensym("disconnect"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(netdist_class, (t_method)netdist_send, gensym("send"), A_GIMME, 0);
- class_addmethod(netdist_class, (t_method)netdist_clear, gensym("clear"), 0);
- class_addmethod(netdist_class, (t_method)netdist_print, gensym("print"), 0);
- class_sethelpsymbol(netdist_class, gensym("maxlib/netdist-help.pd"));
-}
-#endif
+/* -------------------------- netdist --------------------------------------- */
+/* */
+/* Distributes incoming data to a changeable list of netreceive objects. */
+/* Uses child thread to connect to clients. Thus needs pd0.35-test17 or later. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+
+#include "m_pd.h"
+
+#include <sys/types.h>
+#include <string.h>
+#include <pthread.h>
+#ifdef WIN32
+#include <winsock.h>
+#else
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <unistd.h>
+#define SOCKET_ERROR -1
+#endif
+
+#define MAX_REC 32
+
+static char *version = "netdist v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+static t_class *netdist_class;
+
+typedef struct _netdist
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ int x_fd[MAX_REC];
+ char *x_hostname[MAX_REC];
+ int x_numconnect;
+ int x_port[MAX_REC];
+ int x_protocol;
+ /* multithread stuff */
+ pthread_t x_threadid; /* id of child thread */
+ pthread_attr_t x_threadattr; /* attributes of child thread */
+} t_netdist;
+
+static void sys_sockerror(char *s)
+{
+#ifdef WIN32
+ int err = WSAGetLastError();
+ if (err == 10054) return;
+#else
+ int err = errno;
+#endif
+ post("%s: %s (%d)\n", s, strerror(err), err);
+}
+
+static void sys_closesocket(int fd) {
+
+#ifdef WIN32
+ closesocket(fd);
+#else
+ close(fd);
+#endif
+}
+
+
+static void netdist_tick(t_netdist *x)
+{
+ outlet_float(x->x_obj.ob_outlet, x->x_numconnect + 1);
+}
+
+static void *netdist_new(t_floatarg udpflag)
+{
+ int i;
+ t_netdist *x = (t_netdist *)pd_new(netdist_class);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_clock = clock_new(x, (t_method)netdist_tick);
+ for(i = 0; i < MAX_REC; i++)x->x_fd[i] = -1;
+ x->x_numconnect = -1;
+ x->x_protocol = (udpflag != 0 ? SOCK_DGRAM : SOCK_STREAM);
+
+ /* prepare child thread */
+ if(pthread_attr_init(&x->x_threadattr) < 0)
+ post("netdist: warning: could not prepare child thread" );
+ if(pthread_attr_setdetachstate(&x->x_threadattr, PTHREAD_CREATE_DETACHED) < 0)
+ post("netdist: warning: could not prepare child thread" );
+ return (x);
+}
+
+static void *netdist_child_connect(void *w)
+{
+ int i;
+
+ t_netdist *x = (t_netdist*) w;
+ struct sockaddr_in server;
+ struct hostent *hp;
+ int sockfd;
+ int portno;
+ i = x->x_numconnect + 1;
+ portno = x->x_port[i];
+ /* create a socket */
+ sockfd = socket(AF_INET, x->x_protocol, 0);
+#if 0
+ fprintf(stderr, "send socket %d\n", sockfd);
+#endif
+ if (sockfd < 0)
+ {
+ sys_sockerror("socket");
+ return (x);
+ }
+ /* connect socket using hostname provided in command line */
+ server.sin_family = AF_INET;
+ hp = gethostbyname(x->x_hostname[i]);
+ if (hp == 0)
+ {
+ post("bad host?\n");
+ return (x);
+ }
+ memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
+
+ /* assign client port number */
+ server.sin_port = htons((u_short)portno);
+
+ post("connecting to port %d", portno);
+ /* try to connect */
+ if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0)
+ {
+ sys_sockerror("connecting stream socket");
+ sys_closesocket(sockfd);
+ return (x);
+ }
+ x->x_fd[i] = sockfd;
+ /* outlet_float is not threadsafe ! */
+ // outlet_float(x->x_obj.ob_outlet, 1);
+ x->x_numconnect++; /* count connection */
+ /* use callback instead to set outlet */
+ clock_delay(x->x_clock, 0);
+ return (x);
+}
+
+static void netdist_connect(t_netdist *x, t_symbol *hostname,
+ t_floatarg fportno)
+{
+ int i;
+ /* we get hostname and port and pass them on
+ to the child thread that establishes the connection */
+ for(i = 0; i <= x->x_numconnect; i++)
+ { /* check if we are already connected */
+ if (hostname->s_name == x->x_hostname[i] && fportno == x->x_port[i])
+ {
+ error("netdist_connect: already connected");
+ return;
+ }
+ }
+ x->x_hostname[x->x_numconnect + 1] = hostname->s_name;
+ x->x_port[x->x_numconnect + 1] = fportno;
+
+ /* start child thread */
+ if(pthread_create( &x->x_threadid, &x->x_threadattr, netdist_child_connect, x) < 0)
+ post("netdist: could not create new thread");
+}
+
+static void netdist_disconnect(t_netdist *x, t_symbol *hostname, t_floatarg port)
+{
+ int i, j;
+ for(i = 0; i <= x->x_numconnect; i++)
+ {
+ if((hostname->s_name == x->x_hostname[i]) && ((int)port == x->x_port[i]))
+ {
+ /* search for connection */
+ if (x->x_fd[i] >= 0)
+ {
+ sys_closesocket(x->x_fd[i]);
+ x->x_fd[i] = -1;
+ x->x_numconnect--;
+ outlet_float(x->x_obj.ob_outlet, x->x_numconnect + 1);
+ for(j = i; j <= x->x_numconnect; j++)
+ {
+ x->x_hostname[j] = x->x_hostname[j + 1];
+ x->x_port[j] = x->x_port[j + 1];
+ x->x_fd[j] = x->x_fd[j + 1];
+ }
+ }
+ }
+ }
+}
+
+static void netdist_send(t_netdist *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i = 0;
+
+ for(i = 0; i <= x->x_numconnect; i++)
+ {
+ if (x->x_fd[i] >= 0)
+ {
+ t_binbuf *b = binbuf_new();
+ char *buf, *bp;
+ int length, sent;
+ t_atom at;
+ binbuf_add(b, argc, argv);
+ SETSEMI(&at);
+ binbuf_add(b, 1, &at);
+ binbuf_gettext(b, &buf, &length);
+ for (bp = buf, sent = 0; sent < length;)
+ {
+ static double lastwarntime;
+ static double pleasewarn;
+ double timebefore = clock_getlogicaltime();
+ int res = send(x->x_fd[i], buf, length-sent, 0);
+ double timeafter = clock_getlogicaltime();
+ int late = (timeafter - timebefore > 0.005);
+ if (late || pleasewarn)
+ {
+ if (timeafter > lastwarntime + 2)
+ {
+ post("netdist blocked %d msec",
+ (int)(1000 * ((timeafter - timebefore) + pleasewarn)));
+ pleasewarn = 0;
+ lastwarntime = timeafter;
+ }
+ else if (late) pleasewarn += timeafter - timebefore;
+ }
+ if (res <= 0)
+ {
+ sys_sockerror("netdist");
+ netdist_disconnect(x, gensym(x->x_hostname[i]), x->x_port[i]);
+ break;
+ }
+ else
+ {
+ sent += res;
+ bp += res;
+ }
+ }
+ t_freebytes(buf, length);
+ binbuf_free(b);
+ }
+ }
+ if(x->x_numconnect == -1) error("netdist: not connected");
+}
+
+ /* disconnect all */
+static void netdist_clear(t_netdist *x)
+{
+ int i, j, n;
+ n = x->x_numconnect;
+ for (i = n; i >= 0; i--)
+ {
+ netdist_disconnect(x, gensym(x->x_hostname[i]), x->x_port[i]);
+ }
+}
+
+static void netdist_print(t_netdist *x)
+{
+ int i;
+ post("netdist: %d connection(s) established:", x->x_numconnect + 1);
+ for (i = x->x_numconnect; i >= 0; i--)
+ {
+ post(" \"%s\", port %d",x->x_hostname[i], x->x_port[i]);
+ }
+}
+
+static void netdist_free(t_netdist *x)
+{
+ netdist_clear(x);
+ clock_free(x->x_clock);
+}
+
+#ifndef MAXLIB
+void netdist_setup(void)
+{
+ netdist_class = class_new(gensym("netdist"), (t_newmethod)netdist_new,
+ (t_method)netdist_free, sizeof(t_netdist), 0, A_DEFFLOAT, 0);
+ class_addmethod(netdist_class, (t_method)netdist_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0);
+ class_addmethod(netdist_class, (t_method)netdist_disconnect, gensym("disconnect"), A_SYMBOL, A_FLOAT, 0);
+ class_addmethod(netdist_class, (t_method)netdist_send, gensym("send"), A_GIMME, 0);
+ class_addmethod(netdist_class, (t_method)netdist_clear, gensym("clear"), 0);
+ class_addmethod(netdist_class, (t_method)netdist_print, gensym("print"), 0);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_netdist_setup(void)
+{
+ netdist_class = class_new(gensym("maxlib_netdist"), (t_newmethod)netdist_new,
+ (t_method)netdist_free, sizeof(t_netdist), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)netdist_new, gensym("netdist"), A_DEFFLOAT, 0);
+ class_addmethod(netdist_class, (t_method)netdist_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0);
+ class_addmethod(netdist_class, (t_method)netdist_disconnect, gensym("disconnect"), A_SYMBOL, A_FLOAT, 0);
+ class_addmethod(netdist_class, (t_method)netdist_send, gensym("send"), A_GIMME, 0);
+ class_addmethod(netdist_class, (t_method)netdist_clear, gensym("clear"), 0);
+ class_addmethod(netdist_class, (t_method)netdist_print, gensym("print"), 0);
+ class_sethelpsymbol(netdist_class, gensym("maxlib/netdist-help.pd"));
+}
+#endif
diff --git a/netrec.c b/netrec.c
index 9e89521..91f8dd7 100644
--- a/netrec.c
+++ b/netrec.c
@@ -1,447 +1,447 @@
-/* -------------------------- netrec ---------------------------------------- */
-/* */
-/* A 'netreceive' that tells the IP of the connecting netsend. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include "s_stuff.h"
-#include "m_imp.h"
-
-#include <sys/types.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#ifdef WIN32
-#include <io.h>
-#include <fcntl.h>
-#include <winsock.h>
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#define SOCKET_ERROR -1
-#endif
-
-#define MAX_CONNECT 32 /* maximum number of connections */
-#define INBUFSIZE 4096 /* size of receiving data buffer */
-
-static char *version = "netrec v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-/* ----------------------------- netrec ------------------------- */
-
-static t_class *netrec_class;
-static t_binbuf *inbinbuf;
-
-typedef void (*t_netrec_socketnotifier)(void *x);
-typedef void (*t_netrec_socketreceivefn)(void *x, t_binbuf *b);
-
-typedef struct _netrec
-{
- t_object x_obj;
- t_outlet *x_msgout;
- t_outlet *x_connectout;
- t_outlet *x_clientno;
- t_outlet *x_connectionip;
- t_symbol *x_host[MAX_CONNECT];
- t_int x_fd[MAX_CONNECT];
- t_int x_sock_fd;
- int x_connectsocket;
- int x_nconnections;
- int x_udp;
-} t_netrec;
-
-typedef struct _netrec_socketreceiver
-{
- char *sr_inbuf;
- int sr_inhead;
- int sr_intail;
- void *sr_owner;
- int sr_udp;
- t_netrec_socketnotifier sr_notifier;
- t_netrec_socketreceivefn sr_socketreceivefn;
-} t_netrec_socketreceiver;
-
-static t_netrec_socketreceiver *netrec_socketreceiver_new(void *owner, t_netrec_socketnotifier notifier,
- t_netrec_socketreceivefn socketreceivefn, int udp)
-{
- t_netrec_socketreceiver *x = (t_netrec_socketreceiver *)getbytes(sizeof(*x));
- x->sr_inhead = x->sr_intail = 0;
- x->sr_owner = owner;
- x->sr_notifier = notifier;
- x->sr_socketreceivefn = socketreceivefn;
- x->sr_udp = udp;
- if (!(x->sr_inbuf = malloc(INBUFSIZE))) bug("t_netrec_socketreceiver");
- return (x);
-}
-
- /* this is in a separately called subroutine so that the buffer isn't
- sitting on the stack while the messages are getting passed. */
-static int netrec_socketreceiver_doread(t_netrec_socketreceiver *x)
-{
- char messbuf[INBUFSIZE], *bp = messbuf;
- int indx;
- int inhead = x->sr_inhead;
- int intail = x->sr_intail;
- char *inbuf = x->sr_inbuf;
- if (intail == inhead) return (0);
- for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1))
- {
- char c = *bp++ = inbuf[indx];
- if (c == ';' && (!indx || inbuf[indx-1] != '\\'))
- {
- intail = (indx+1)&(INBUFSIZE-1);
- binbuf_text(inbinbuf, messbuf, bp - messbuf);
- x->sr_inhead = inhead;
- x->sr_intail = intail;
- return (1);
- }
- }
- return (0);
-}
-
-static void netrec_socketreceiver_getudp(t_netrec_socketreceiver *x, int fd)
-{
- char buf[INBUFSIZE+1];
- int ret = recv(fd, buf, INBUFSIZE, 0);
- if (ret < 0)
- {
- sys_sockerror("recv");
- sys_rmpollfn(fd);
- sys_closesocket(fd);
- }
- else if (ret > 0)
- {
- buf[ret] = 0;
-#if 0
- post("%s", buf);
-#endif
- if (buf[ret-1] != '\n')
- {
-#if 0
- buf[ret] = 0;
- error("dropped bad buffer %s\n", buf);
-#endif
- }
- else
- {
- char *semi = strchr(buf, ';');
- if (semi)
- *semi = 0;
- binbuf_text(inbinbuf, buf, strlen(buf));
- outlet_setstacklim();
- if (x->sr_socketreceivefn)
- (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf);
- else bug("netrec_socketreceiver_getudp");
- }
- }
-}
-
-static void netrec_socketreceiver_read(t_netrec_socketreceiver *x, int fd)
-{
- if (x->sr_udp) /* UDP ("datagram") socket protocol */
- netrec_socketreceiver_getudp(x, fd);
- else /* TCP ("streaming") socket protocol */
- {
- char *semi;
- int readto =
- (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
- int ret;
-
- t_netrec *y = x->sr_owner;
-
- y->x_sock_fd = fd;
-
- /* the input buffer might be full. If so, drop the whole thing */
- if (readto == x->sr_inhead)
- {
- fprintf(stderr, "netrec: dropped message");
- x->sr_inhead = x->sr_intail = 0;
- readto = INBUFSIZE;
- }
- else
- {
- ret = recv(fd, x->sr_inbuf + x->sr_inhead,
- readto - x->sr_inhead, 0);
- if (ret < 0)
- {
- sys_sockerror("recv");
- if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
- sys_rmpollfn(fd);
- sys_closesocket(fd);
- }
- else if (ret == 0)
- {
- post("netrec: connection closed on socket %d", fd);
- if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
- sys_rmpollfn(fd);
- sys_closesocket(fd);
- }
- else
- {
- x->sr_inhead += ret;
- if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0;
- while (netrec_socketreceiver_doread(x))
- {
- outlet_setstacklim();
- if (x->sr_socketreceivefn)
- (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf);
- else binbuf_eval(inbinbuf, 0, 0, 0);
- }
- }
- }
- }
-}
-
-static void netrec_socketreceiver_free(t_netrec_socketreceiver *x)
-{
- free(x->sr_inbuf);
- freebytes(x, sizeof(*x));
-}
-
-/* ---------------- main netrec stuff --------------------- */
-
-static void netrec_notify(t_netrec *x)
-{
- int i, k;
- /* remove connection from list */
- for(i = 0; i < x->x_nconnections; i++)
- {
- if(x->x_fd[i] == x->x_sock_fd)
- {
- x->x_nconnections--;
- post("netrec: \"%s\" removed from list of clients", x->x_host[i]->s_name);
- x->x_host[i] = NULL; /* delete entry */
- x->x_fd[i] = -1;
- /* rearrange list now: move entries to close the gap */
- for(k = i; k < x->x_nconnections; k++)
- {
- x->x_host[k] = x->x_host[k + 1];
- x->x_fd[k] = x->x_fd[k + 1];
- }
- }
- }
- outlet_float(x->x_connectout, x->x_nconnections);
-}
-
-static void netrec_doit(void *z, t_binbuf *b)
-{
- t_atom messbuf[1024];
- t_netrec *x = (t_netrec *)z;
- int msg, natom = binbuf_getnatom(b);
- t_atom *at = binbuf_getvec(b);
- int i;
- /* output clients IP and socket no */
- for(i = 0; i < x->x_nconnections; i++)
- {
- if(x->x_fd[i] == x->x_sock_fd)
- {
- outlet_symbol(x->x_connectionip, x->x_host[i]);
- break;
- }
- }
- outlet_float(x->x_clientno, x->x_sock_fd);
- /* process data */
- 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 ii;
- for (ii = msg; ii < emsg; ii++)
- if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM)
- {
- pd_error(x, "netrec: got dollar sign in message");
- goto nodice;
- }
- if (at[msg].a_type == A_FLOAT)
- {
- if (emsg > msg + 1)
- outlet_list(x->x_msgout, 0, emsg-msg, at + msg);
- else outlet_float(x->x_msgout, at[msg].a_w.w_float);
- }
- else if (at[msg].a_type == A_SYMBOL)
- outlet_anything(x->x_msgout, at[msg].a_w.w_symbol,
- emsg-msg-1, at + msg + 1);
- }
- nodice:
- msg = emsg + 1;
- }
-}
-
-static void netrec_connectpoll(t_netrec *x)
-{
- struct sockaddr_in incomer_address;
- int sockaddrl = (int) sizeof( struct sockaddr );
- int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl);
- if (fd < 0) post("netrec: accept failed");
- else
- {
- t_netrec_socketreceiver *y = netrec_socketreceiver_new((void *)x,
- (t_netrec_socketnotifier)netrec_notify,
- (x->x_msgout ? netrec_doit : 0), 0);
- sys_addpollfn(fd, (t_fdpollfn)netrec_socketreceiver_read, y);
- x->x_nconnections++;
- x->x_host[x->x_nconnections - 1] = gensym(inet_ntoa(incomer_address.sin_addr));
- x->x_fd[x->x_nconnections - 1] = fd;
-
- // outlet_symbol( x->x_connectionip, x->x_host[x->x_nconnections - 1]);
- post("netrec: accepted connection from %s on socket %d",
- x->x_host[x->x_nconnections - 1]->s_name, x->x_fd[x->x_nconnections - 1]);
- outlet_float(x->x_connectout, x->x_nconnections);
- }
-}
-
-static void netrec_print(t_netrec *x)
-{
- int i;
- if(x->x_nconnections > 0)
- {
- post("netrec: %d open connections:", x->x_nconnections);
-
- for(i = 0; i < x->x_nconnections; i++)
- {
- post(" \"%s\" on socket %d",
- x->x_host[i]->s_name, x->x_fd[i]);
- }
- } else post("netrec: no open connections");
-}
-
-static void *netrec_new(t_symbol *compatflag,
- t_floatarg fportno, t_floatarg udpflag)
-{
- t_netrec *x;
- int i;
- struct sockaddr_in server;
- int sockfd, portno = fportno, udp = (udpflag != 0);
- int old = !strcmp(compatflag->s_name , "old");
- /* create a socket */
- sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0);
-#if 1
- post("netrec: receive socket %d\n", sockfd);
-#endif
- if (sockfd < 0)
- {
- sys_sockerror("socket");
- return (0);
- }
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = INADDR_ANY;
-
-#ifdef IRIX
- /* this seems to work only in IRIX but is unnecessary in
- Linux. Not sure what NT needs in place of this. */
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
- post("setsockopt failed\n");
-#endif
-
- /* assign server port number */
- server.sin_port = htons((u_short)portno);
-
- /* name the socket */
- if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
- {
- sys_sockerror("bind");
- sys_closesocket(sockfd);
- return (0);
- }
- x = (t_netrec *)pd_new(netrec_class);
- if (old)
- {
- /* old style, nonsecure version */
- x->x_msgout = 0;
- }
- else x->x_msgout = outlet_new(&x->x_obj, &s_anything);
-
- if (udp) /* datagram protocol */
- {
- t_netrec_socketreceiver *y = netrec_socketreceiver_new((void *)x,
- (t_netrec_socketnotifier)netrec_notify,
- (x->x_msgout ? netrec_doit : 0), 1);
- sys_addpollfn(sockfd, (t_fdpollfn)netrec_socketreceiver_read, y);
- x->x_connectout = 0;
- }
- else /* streaming protocol */
- {
- if (listen(sockfd, 5) < 0)
- {
- sys_sockerror("listen");
- sys_closesocket(sockfd);
- sockfd = -1;
- }
- else
- {
- sys_addpollfn(sockfd, (t_fdpollfn)netrec_connectpoll, x);
- x->x_connectout = outlet_new(&x->x_obj, &s_float);
- x->x_clientno = outlet_new(&x->x_obj, &s_float);
- x->x_connectionip = outlet_new(&x->x_obj, &s_symbol);
- inbinbuf = binbuf_new();
- }
- }
- x->x_connectsocket = sockfd;
- x->x_nconnections = 0;
- x->x_udp = udp;
- for(i = 0; i < MAX_CONNECT; i++)x->x_fd[i] = -1;
-
- return (x);
-}
-
-static void netrec_free(t_netrec *x)
-{
- /* LATER make me clean up open connections */
- if (x->x_connectsocket >= 0)
- {
- sys_rmpollfn(x->x_connectsocket);
- sys_closesocket(x->x_connectsocket);
- }
- binbuf_free(inbinbuf);
-}
-
-#ifndef MAXLIB
-void netrec_setup(void)
-{
- netrec_class = class_new(gensym("netrec"),(t_newmethod)netrec_new, (t_method)netrec_free,
- sizeof(t_netrec), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYM, 0);
- class_addmethod(netrec_class, (t_method)netrec_print, gensym("print"), 0);
-
- post(version);
-}
-#else
-void maxlib_netrec_setup(void)
-{
- netrec_class = class_new(gensym("maxlib_netrec"),(t_newmethod)netrec_new, (t_method)netrec_free,
- sizeof(t_netrec), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYM, 0);
- class_addcreator((t_newmethod)netrec_new, gensym("netrec"), A_DEFFLOAT, A_DEFFLOAT, A_DEFSYM, 0);
- class_addmethod(netrec_class, (t_method)netrec_print, gensym("print"), 0);
- class_sethelpsymbol(netrec_class, gensym("maxlib/netrec-help.pd"));
-}
-#endif
+/* -------------------------- netrec ---------------------------------------- */
+/* */
+/* A 'netreceive' that tells the IP of the connecting netsend. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include "s_stuff.h"
+#include "m_imp.h"
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#include <winsock.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#define SOCKET_ERROR -1
+#endif
+
+#define MAX_CONNECT 32 /* maximum number of connections */
+#define INBUFSIZE 4096 /* size of receiving data buffer */
+
+static char *version = "netrec v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* ----------------------------- netrec ------------------------- */
+
+static t_class *netrec_class;
+static t_binbuf *inbinbuf;
+
+typedef void (*t_netrec_socketnotifier)(void *x);
+typedef void (*t_netrec_socketreceivefn)(void *x, t_binbuf *b);
+
+typedef struct _netrec
+{
+ t_object x_obj;
+ t_outlet *x_msgout;
+ t_outlet *x_connectout;
+ t_outlet *x_clientno;
+ t_outlet *x_connectionip;
+ t_symbol *x_host[MAX_CONNECT];
+ t_int x_fd[MAX_CONNECT];
+ t_int x_sock_fd;
+ int x_connectsocket;
+ int x_nconnections;
+ int x_udp;
+} t_netrec;
+
+typedef struct _netrec_socketreceiver
+{
+ char *sr_inbuf;
+ int sr_inhead;
+ int sr_intail;
+ void *sr_owner;
+ int sr_udp;
+ t_netrec_socketnotifier sr_notifier;
+ t_netrec_socketreceivefn sr_socketreceivefn;
+} t_netrec_socketreceiver;
+
+static t_netrec_socketreceiver *netrec_socketreceiver_new(void *owner, t_netrec_socketnotifier notifier,
+ t_netrec_socketreceivefn socketreceivefn, int udp)
+{
+ t_netrec_socketreceiver *x = (t_netrec_socketreceiver *)getbytes(sizeof(*x));
+ x->sr_inhead = x->sr_intail = 0;
+ x->sr_owner = owner;
+ x->sr_notifier = notifier;
+ x->sr_socketreceivefn = socketreceivefn;
+ x->sr_udp = udp;
+ if (!(x->sr_inbuf = malloc(INBUFSIZE))) bug("t_netrec_socketreceiver");
+ return (x);
+}
+
+ /* this is in a separately called subroutine so that the buffer isn't
+ sitting on the stack while the messages are getting passed. */
+static int netrec_socketreceiver_doread(t_netrec_socketreceiver *x)
+{
+ char messbuf[INBUFSIZE], *bp = messbuf;
+ int indx;
+ int inhead = x->sr_inhead;
+ int intail = x->sr_intail;
+ char *inbuf = x->sr_inbuf;
+ if (intail == inhead) return (0);
+ for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1))
+ {
+ char c = *bp++ = inbuf[indx];
+ if (c == ';' && (!indx || inbuf[indx-1] != '\\'))
+ {
+ intail = (indx+1)&(INBUFSIZE-1);
+ binbuf_text(inbinbuf, messbuf, bp - messbuf);
+ x->sr_inhead = inhead;
+ x->sr_intail = intail;
+ return (1);
+ }
+ }
+ return (0);
+}
+
+static void netrec_socketreceiver_getudp(t_netrec_socketreceiver *x, int fd)
+{
+ char buf[INBUFSIZE+1];
+ int ret = recv(fd, buf, INBUFSIZE, 0);
+ if (ret < 0)
+ {
+ sys_sockerror("recv");
+ sys_rmpollfn(fd);
+ sys_closesocket(fd);
+ }
+ else if (ret > 0)
+ {
+ buf[ret] = 0;
+#if 0
+ post("%s", buf);
+#endif
+ if (buf[ret-1] != '\n')
+ {
+#if 0
+ buf[ret] = 0;
+ error("dropped bad buffer %s\n", buf);
+#endif
+ }
+ else
+ {
+ char *semi = strchr(buf, ';');
+ if (semi)
+ *semi = 0;
+ binbuf_text(inbinbuf, buf, strlen(buf));
+ outlet_setstacklim();
+ if (x->sr_socketreceivefn)
+ (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf);
+ else bug("netrec_socketreceiver_getudp");
+ }
+ }
+}
+
+static void netrec_socketreceiver_read(t_netrec_socketreceiver *x, int fd)
+{
+ if (x->sr_udp) /* UDP ("datagram") socket protocol */
+ netrec_socketreceiver_getudp(x, fd);
+ else /* TCP ("streaming") socket protocol */
+ {
+ char *semi;
+ int readto =
+ (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
+ int ret;
+
+ t_netrec *y = x->sr_owner;
+
+ y->x_sock_fd = fd;
+
+ /* the input buffer might be full. If so, drop the whole thing */
+ if (readto == x->sr_inhead)
+ {
+ fprintf(stderr, "netrec: dropped message");
+ x->sr_inhead = x->sr_intail = 0;
+ readto = INBUFSIZE;
+ }
+ else
+ {
+ ret = recv(fd, x->sr_inbuf + x->sr_inhead,
+ readto - x->sr_inhead, 0);
+ if (ret < 0)
+ {
+ sys_sockerror("recv");
+ if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
+ sys_rmpollfn(fd);
+ sys_closesocket(fd);
+ }
+ else if (ret == 0)
+ {
+ post("netrec: connection closed on socket %d", fd);
+ if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
+ sys_rmpollfn(fd);
+ sys_closesocket(fd);
+ }
+ else
+ {
+ x->sr_inhead += ret;
+ if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0;
+ while (netrec_socketreceiver_doread(x))
+ {
+ outlet_setstacklim();
+ if (x->sr_socketreceivefn)
+ (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf);
+ else binbuf_eval(inbinbuf, 0, 0, 0);
+ }
+ }
+ }
+ }
+}
+
+static void netrec_socketreceiver_free(t_netrec_socketreceiver *x)
+{
+ free(x->sr_inbuf);
+ freebytes(x, sizeof(*x));
+}
+
+/* ---------------- main netrec stuff --------------------- */
+
+static void netrec_notify(t_netrec *x)
+{
+ int i, k;
+ /* remove connection from list */
+ for(i = 0; i < x->x_nconnections; i++)
+ {
+ if(x->x_fd[i] == x->x_sock_fd)
+ {
+ x->x_nconnections--;
+ post("netrec: \"%s\" removed from list of clients", x->x_host[i]->s_name);
+ x->x_host[i] = NULL; /* delete entry */
+ x->x_fd[i] = -1;
+ /* rearrange list now: move entries to close the gap */
+ for(k = i; k < x->x_nconnections; k++)
+ {
+ x->x_host[k] = x->x_host[k + 1];
+ x->x_fd[k] = x->x_fd[k + 1];
+ }
+ }
+ }
+ outlet_float(x->x_connectout, x->x_nconnections);
+}
+
+static void netrec_doit(void *z, t_binbuf *b)
+{
+ t_atom messbuf[1024];
+ t_netrec *x = (t_netrec *)z;
+ int msg, natom = binbuf_getnatom(b);
+ t_atom *at = binbuf_getvec(b);
+ int i;
+ /* output clients IP and socket no */
+ for(i = 0; i < x->x_nconnections; i++)
+ {
+ if(x->x_fd[i] == x->x_sock_fd)
+ {
+ outlet_symbol(x->x_connectionip, x->x_host[i]);
+ break;
+ }
+ }
+ outlet_float(x->x_clientno, x->x_sock_fd);
+ /* process data */
+ 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 ii;
+ for (ii = msg; ii < emsg; ii++)
+ if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM)
+ {
+ pd_error(x, "netrec: got dollar sign in message");
+ goto nodice;
+ }
+ if (at[msg].a_type == A_FLOAT)
+ {
+ if (emsg > msg + 1)
+ outlet_list(x->x_msgout, 0, emsg-msg, at + msg);
+ else outlet_float(x->x_msgout, at[msg].a_w.w_float);
+ }
+ else if (at[msg].a_type == A_SYMBOL)
+ outlet_anything(x->x_msgout, at[msg].a_w.w_symbol,
+ emsg-msg-1, at + msg + 1);
+ }
+ nodice:
+ msg = emsg + 1;
+ }
+}
+
+static void netrec_connectpoll(t_netrec *x)
+{
+ struct sockaddr_in incomer_address;
+ int sockaddrl = (int) sizeof( struct sockaddr );
+ int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl);
+ if (fd < 0) post("netrec: accept failed");
+ else
+ {
+ t_netrec_socketreceiver *y = netrec_socketreceiver_new((void *)x,
+ (t_netrec_socketnotifier)netrec_notify,
+ (x->x_msgout ? netrec_doit : 0), 0);
+ sys_addpollfn(fd, (t_fdpollfn)netrec_socketreceiver_read, y);
+ x->x_nconnections++;
+ x->x_host[x->x_nconnections - 1] = gensym(inet_ntoa(incomer_address.sin_addr));
+ x->x_fd[x->x_nconnections - 1] = fd;
+
+ // outlet_symbol( x->x_connectionip, x->x_host[x->x_nconnections - 1]);
+ post("netrec: accepted connection from %s on socket %d",
+ x->x_host[x->x_nconnections - 1]->s_name, x->x_fd[x->x_nconnections - 1]);
+ outlet_float(x->x_connectout, x->x_nconnections);
+ }
+}
+
+static void netrec_print(t_netrec *x)
+{
+ int i;
+ if(x->x_nconnections > 0)
+ {
+ post("netrec: %d open connections:", x->x_nconnections);
+
+ for(i = 0; i < x->x_nconnections; i++)
+ {
+ post(" \"%s\" on socket %d",
+ x->x_host[i]->s_name, x->x_fd[i]);
+ }
+ } else post("netrec: no open connections");
+}
+
+static void *netrec_new(t_symbol *compatflag,
+ t_floatarg fportno, t_floatarg udpflag)
+{
+ t_netrec *x;
+ int i;
+ struct sockaddr_in server;
+ int sockfd, portno = fportno, udp = (udpflag != 0);
+ int old = !strcmp(compatflag->s_name , "old");
+ /* create a socket */
+ sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0);
+#if 1
+ post("netrec: receive socket %d\n", sockfd);
+#endif
+ if (sockfd < 0)
+ {
+ sys_sockerror("socket");
+ return (0);
+ }
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+
+#ifdef IRIX
+ /* this seems to work only in IRIX but is unnecessary in
+ Linux. Not sure what NT needs in place of this. */
+ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
+ post("setsockopt failed\n");
+#endif
+
+ /* assign server port number */
+ server.sin_port = htons((u_short)portno);
+
+ /* name the socket */
+ if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
+ {
+ sys_sockerror("bind");
+ sys_closesocket(sockfd);
+ return (0);
+ }
+ x = (t_netrec *)pd_new(netrec_class);
+ if (old)
+ {
+ /* old style, nonsecure version */
+ x->x_msgout = 0;
+ }
+ else x->x_msgout = outlet_new(&x->x_obj, &s_anything);
+
+ if (udp) /* datagram protocol */
+ {
+ t_netrec_socketreceiver *y = netrec_socketreceiver_new((void *)x,
+ (t_netrec_socketnotifier)netrec_notify,
+ (x->x_msgout ? netrec_doit : 0), 1);
+ sys_addpollfn(sockfd, (t_fdpollfn)netrec_socketreceiver_read, y);
+ x->x_connectout = 0;
+ }
+ else /* streaming protocol */
+ {
+ if (listen(sockfd, 5) < 0)
+ {
+ sys_sockerror("listen");
+ sys_closesocket(sockfd);
+ sockfd = -1;
+ }
+ else
+ {
+ sys_addpollfn(sockfd, (t_fdpollfn)netrec_connectpoll, x);
+ x->x_connectout = outlet_new(&x->x_obj, &s_float);
+ x->x_clientno = outlet_new(&x->x_obj, &s_float);
+ x->x_connectionip = outlet_new(&x->x_obj, &s_symbol);
+ inbinbuf = binbuf_new();
+ }
+ }
+ x->x_connectsocket = sockfd;
+ x->x_nconnections = 0;
+ x->x_udp = udp;
+ for(i = 0; i < MAX_CONNECT; i++)x->x_fd[i] = -1;
+
+ return (x);
+}
+
+static void netrec_free(t_netrec *x)
+{
+ /* LATER make me clean up open connections */
+ if (x->x_connectsocket >= 0)
+ {
+ sys_rmpollfn(x->x_connectsocket);
+ sys_closesocket(x->x_connectsocket);
+ }
+ binbuf_free(inbinbuf);
+}
+
+#ifndef MAXLIB
+void netrec_setup(void)
+{
+ netrec_class = class_new(gensym("netrec"),(t_newmethod)netrec_new, (t_method)netrec_free,
+ sizeof(t_netrec), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYM, 0);
+ class_addmethod(netrec_class, (t_method)netrec_print, gensym("print"), 0);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_netrec_setup(void)
+{
+ netrec_class = class_new(gensym("maxlib_netrec"),(t_newmethod)netrec_new, (t_method)netrec_free,
+ sizeof(t_netrec), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYM, 0);
+ class_addcreator((t_newmethod)netrec_new, gensym("netrec"), A_DEFFLOAT, A_DEFFLOAT, A_DEFSYM, 0);
+ class_addmethod(netrec_class, (t_method)netrec_print, gensym("print"), 0);
+ class_sethelpsymbol(netrec_class, gensym("maxlib/netrec-help.pd"));
+}
+#endif
diff --git a/netserver.c b/netserver.c
index 196d29f..4fca399 100644
--- a/netserver.c
+++ b/netserver.c
@@ -1,670 +1,670 @@
-/* -------------------------- netserver ------------------------------------- */
-/* */
-/* A server for bidirectional communication from within Pd. */
-/* Allows to send back data to specific clients connected to the server. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include "s_stuff.h"
-#include "m_imp.h"
-
-#include <sys/types.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <pthread.h>
-#ifdef WIN32
-#include <io.h>
-#include <fcntl.h>
-#include <winsock.h>
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#define SOCKET_ERROR -1
-#endif
-
-#define MAX_CONNECT 32 /* maximum number of connections */
-#define INBUFSIZE 4096 /* size of receiving data buffer */
-
-/* message levels from syslog.h */
-#define LOG_EMERG 0 /* system is unusable */
-#define LOG_ALERT 1 /* action must be taken immediately */
-#define LOG_CRIT 2 /* critical conditions */
-#define LOG_ERR 3 /* error conditions */
-#define LOG_WARNING 4 /* warning conditions */
-#define LOG_NOTICE 5 /* normal but significant condition */
-#define LOG_INFO 6 /* informational */
-#define LOG_DEBUG 7 /* debug-level messages */
-
-static char *version =
- "netserver v0.2.hcs1 :: bidirectional communication for Pd\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>\n"
- " syslogging by Hans-Christoph Steiner <hans@eds.org> ";
-
-/* ----------------------------- netserver ------------------------- */
-
-static t_class *netserver_class;
-static t_binbuf *inbinbuf;
-
-typedef void (*t_netserver_socketnotifier)(void *x);
-typedef void (*t_netserver_socketreceivefn)(void *x, t_binbuf *b);
-
-typedef struct _netserver
-{
- t_object x_obj;
- t_outlet *x_msgout;
- t_outlet *x_connectout;
- t_outlet *x_clientno;
- t_outlet *x_connectionip;
- t_symbol *x_host[MAX_CONNECT];
- t_int x_fd[MAX_CONNECT];
- t_int x_sock_fd;
- t_int x_connectsocket;
- t_int x_nconnections;
-/* for syslog style logging priorities */
- t_int x_log_pri;
-} t_netserver;
-
-typedef struct _netserver_socketreceiver
-{
- char *sr_inbuf;
- int sr_inhead;
- int sr_intail;
- void *sr_owner;
- t_netserver_socketnotifier sr_notifier;
- t_netserver_socketreceivefn sr_socketreceivefn;
-} t_netserver_socketreceiver;
-
-static t_netserver_socketreceiver *netserver_socketreceiver_new(void *owner, t_netserver_socketnotifier notifier,
- t_netserver_socketreceivefn socketreceivefn)
-{
- t_netserver_socketreceiver *x = (t_netserver_socketreceiver *)getbytes(sizeof(*x));
- x->sr_inhead = x->sr_intail = 0;
- x->sr_owner = owner;
- x->sr_notifier = notifier;
- x->sr_socketreceivefn = socketreceivefn;
- if (!(x->sr_inbuf = malloc(INBUFSIZE))) bug("t_netserver_socketreceiver");
- return (x);
-}
-
-/* this is in a separately called subroutine so that the buffer isn't
- sitting on the stack while the messages are getting passed. */
-static int netserver_socketreceiver_doread(t_netserver_socketreceiver *x)
-{
- char messbuf[INBUFSIZE], *bp = messbuf;
- int indx;
- int inhead = x->sr_inhead;
- int intail = x->sr_intail;
- char *inbuf = x->sr_inbuf;
- if (intail == inhead) return (0);
- for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1))
- {
- char c = *bp++ = inbuf[indx];
- if (c == ';' && (!indx || inbuf[indx-1] != '\\'))
- {
- intail = (indx+1)&(INBUFSIZE-1);
- binbuf_text(inbinbuf, messbuf, bp - messbuf);
- x->sr_inhead = inhead;
- x->sr_intail = intail;
- return (1);
- }
- }
- return (0);
-}
-
-static void netserver_socketreceiver_read(t_netserver_socketreceiver *x, int fd)
-{
- char *semi;
- int readto = (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
- int ret;
-
- t_netserver *y = x->sr_owner;
-
- y->x_sock_fd = fd;
-
- /* the input buffer might be full. If so, drop the whole thing */
- if (readto == x->sr_inhead)
- {
- if (y->x_log_pri >= LOG_ERR)
- post("netserver: dropped message");
- x->sr_inhead = x->sr_intail = 0;
- readto = INBUFSIZE;
- }
- else
- {
- ret = recv(fd, x->sr_inbuf + x->sr_inhead,
- readto - x->sr_inhead, 0);
- if (ret < 0)
- {
- sys_sockerror("recv");
- if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
- sys_rmpollfn(fd);
- sys_closesocket(fd);
- }
- else if (ret == 0)
- {
- if (y->x_log_pri >= LOG_NOTICE)
- post("netserver: << connection closed on socket %d", fd);
- if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
- sys_rmpollfn(fd);
- sys_closesocket(fd);
- }
- else
- {
- x->sr_inhead += ret;
- if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0;
- while (netserver_socketreceiver_doread(x))
- {
- outlet_setstacklim();
- if (x->sr_socketreceivefn)
- (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf);
- else binbuf_eval(inbinbuf, 0, 0, 0);
- }
- }
- }
-}
-
-static void netserver_socketreceiver_free(t_netserver_socketreceiver *x)
-{
- free(x->sr_inbuf);
- freebytes(x, sizeof(*x));
-}
-
-/* ---------------- main netserver (send) stuff --------------------- */
-
-/* send message to client using socket number */
-static void netserver_send(t_netserver *x, t_symbol *s, int argc, t_atom *argv)
-{
- int sockfd, client = -1, i;
- if(x->x_nconnections < 0)
- {
- if (x->x_log_pri >= LOG_WARNING)
- post("netserver: no clients connected");
- return;
- }
- if(argc < 2)
- {
- if (x->x_log_pri >= LOG_WARNING)
- post("netserver: nothing to send");
- return;
- }
- /* get socket number of connection (first element in list) */
- if(argv[0].a_type == A_FLOAT)
- {
- sockfd = atom_getfloatarg(0, argc, argv);
- for(i = 0; i < x->x_nconnections; i++) /* check if connection exists */
- {
- if(x->x_fd[i] == sockfd)
- {
- client = i; /* the client we're sending to */
- break;
- }
- }
- if(client == -1)
- {
- if (x->x_log_pri >= LOG_CRIT)
- post("netserver: no connection on socket %d", sockfd);
- return;
- }
- }
- else
- {
- if (x->x_log_pri >= LOG_CRIT)
- post("netserver: no socket specified");
- return;
- }
- /* process & send data */
- if(sockfd > 0)
- {
- t_binbuf *b = binbuf_new();
- char *buf, *bp;
- int length, sent;
- t_atom at;
- binbuf_add(b, argc - 1, argv + 1); /* skip first element */
- SETSEMI(&at);
- binbuf_add(b, 1, &at);
- binbuf_gettext(b, &buf, &length);
-
- if (x->x_log_pri >= LOG_DEBUG)
- {
- post("netserver: sending data to client %d on socket %d", client + 1, sockfd);
- post("netserver: sending \"%s\"", buf);
- }
-
- for (bp = buf, sent = 0; sent < length;)
- {
- static double lastwarntime;
- static double pleasewarn;
- double timebefore = clock_getlogicaltime();
- int res = send(sockfd, buf, length-sent, 0);
- double timeafter = clock_getlogicaltime();
- int late = (timeafter - timebefore > 0.005);
- if (late || pleasewarn)
- {
- if (timeafter > lastwarntime + 2)
- {
- if (x->x_log_pri >= LOG_WARNING)
- post("netserver blocked %d msec",
- (int)(1000 * ((timeafter - timebefore) + pleasewarn)));
- pleasewarn = 0;
- lastwarntime = timeafter;
- }
- else if (late) pleasewarn += timeafter - timebefore;
- }
- if (res <= 0)
- {
- sys_sockerror("netserver");
- if (x->x_log_pri >= LOG_ERR)
- post("netserver: could not send data to client");
- break;
- }
- else
- {
- sent += res;
- bp += res;
- }
- }
- t_freebytes(buf, length);
- binbuf_free(b);
- }
- else if (x->x_log_pri >= LOG_CRIT)
- post("netserver: not a valid socket number (%d)", sockfd);
-}
-
-/* send message to client using client number
- note that the client numbers might change in case a client disconnects! */
-static void netserver_client_send(t_netserver *x, t_symbol *s, int argc, t_atom *argv)
-{
- int sockfd, client;
- if(x->x_nconnections < 0)
- {
- if (x->x_log_pri >= LOG_WARNING)
- post("netserver: no clients connected");
- return;
- }
- if(argc < 2)
- {
- if (x->x_log_pri >= LOG_WARNING)
- post("netserver: nothing to send");
- return;
- }
- /* get number of client (first element in list) */
- if(argv[0].a_type == A_FLOAT)
- client = atom_getfloatarg(0, argc, argv);
- else
- {
- if (x->x_log_pri >= LOG_WARNING)
- post("netserver: no client specified");
- return;
- }
- sockfd = x->x_fd[client - 1]; /* get socket number for that client */
-
- /* process & send data */
- if(sockfd > 0)
- {
- t_binbuf *b = binbuf_new();
- char *buf, *bp;
- int length, sent;
- t_atom at;
- binbuf_add(b, argc - 1, argv + 1); /* skip first element */
- SETSEMI(&at);
- binbuf_add(b, 1, &at);
- binbuf_gettext(b, &buf, &length);
-
- if (x->x_log_pri >= LOG_DEBUG)
- {
- post("netserver: sending data to client %d on socket %d", client, sockfd);
- post("netserver: >> sending \"%s\"", buf);
- }
-
- for (bp = buf, sent = 0; sent < length;)
- {
- static double lastwarntime;
- static double pleasewarn;
- double timebefore = clock_getlogicaltime();
- int res = send(sockfd, buf, length-sent, 0);
- double timeafter = clock_getlogicaltime();
- int late = (timeafter - timebefore > 0.005);
- if (late || pleasewarn)
- {
- if (timeafter > lastwarntime + 2)
- {
- if (x->x_log_pri >= LOG_WARNING)
- post("netserver blocked %d msec",
- (int)(1000 * ((timeafter - timebefore) + pleasewarn)));
- pleasewarn = 0;
- lastwarntime = timeafter;
- }
- else if (late) pleasewarn += timeafter - timebefore;
- }
- if (res <= 0)
- {
- sys_sockerror("netserver");
- if (x->x_log_pri >= LOG_ERR)
- post("netserver: could not send data to cient");
- break;
- }
- else
- {
- sent += res;
- bp += res;
- }
- }
- t_freebytes(buf, length);
- binbuf_free(b);
- }
- else if (x->x_log_pri >= LOG_CRIT)
- post("netserver: not a valid socket number (%d)", sockfd);
-}
-
-/* broadcasts a message to all connected clients */
-static void netserver_broadcast(t_netserver *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i, client = x->x_nconnections; /* number of clients to send to */
- t_atom at[256];
- for(i = 0; i < argc; i++)
- {
- at[i + 1] = argv[i];
- }
- argc++;
- /* enumerate through the clients and send each the message */
- while(client--)
- {
- SETFLOAT(at, client + 1); /* prepend number of client */
- netserver_client_send(x, s, argc, at);
- }
-}
-
-
-/* ---------------- main netserver (receive) stuff --------------------- */
-
-static void netserver_notify(t_netserver *x)
-{
- int i, k;
- /* remove connection from list */
- for(i = 0; i < x->x_nconnections; i++)
- {
- if(x->x_fd[i] == x->x_sock_fd)
- {
- x->x_nconnections--;
- if (x->x_log_pri >= LOG_NOTICE)
- post("netserver: \"%s\" removed from list of clients", x->x_host[i]->s_name);
- x->x_host[i] = NULL; /* delete entry */
- x->x_fd[i] = -1;
- /* rearrange list now: move entries to close the gap */
- for(k = i; k < x->x_nconnections; k++)
- {
- x->x_host[k] = x->x_host[k + 1];
- x->x_fd[k] = x->x_fd[k + 1];
- }
- }
- }
- outlet_float(x->x_connectout, x->x_nconnections);
-}
-
-static void netserver_doit(void *z, t_binbuf *b)
-{
- t_atom messbuf[1024];
- t_netserver *x = (t_netserver *)z;
- int msg, natom = binbuf_getnatom(b);
- t_atom *at = binbuf_getvec(b);
- int i;
- /* output clients IP and socket no. */
- for(i = 0; i < x->x_nconnections; i++) /* search for corresponding IP */
- {
- if(x->x_fd[i] == x->x_sock_fd)
- {
- outlet_symbol(x->x_connectionip, x->x_host[i]);
- break;
- }
- }
- outlet_float(x->x_clientno, x->x_sock_fd); /* the socket number */
- /* process data */
- 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 ii;
- for (ii = msg; ii < emsg; ii++)
- if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM)
- {
- pd_error(x, "netserver: got dollar sign in message");
- goto nodice;
- }
- if (at[msg].a_type == A_FLOAT)
- {
- if (emsg > msg + 1)
- outlet_list(x->x_msgout, 0, emsg-msg, at + msg);
- else outlet_float(x->x_msgout, at[msg].a_w.w_float);
- }
- else if (at[msg].a_type == A_SYMBOL)
- outlet_anything(x->x_msgout, at[msg].a_w.w_symbol,
- emsg-msg-1, at + msg + 1);
- }
- nodice:
- msg = emsg + 1;
- }
-}
-
-static void netserver_connectpoll(t_netserver *x)
-{
- struct sockaddr_in incomer_address;
- int sockaddrl = (int) sizeof( struct sockaddr );
- int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl);
- if (fd < 0) post("netserver: accept failed");
- else
- {
- t_netserver_socketreceiver *y = netserver_socketreceiver_new((void *)x,
- (t_netserver_socketnotifier)netserver_notify,
- (x->x_msgout ? netserver_doit : 0));
- sys_addpollfn(fd, (t_fdpollfn)netserver_socketreceiver_read, y);
- x->x_nconnections++;
- x->x_host[x->x_nconnections - 1] = gensym(inet_ntoa(incomer_address.sin_addr));
- x->x_fd[x->x_nconnections - 1] = fd;
-
- if (x->x_log_pri >= LOG_NOTICE)
- post("netserver: ** accepted connection from %s on socket %d",
- x->x_host[x->x_nconnections - 1]->s_name, x->x_fd[x->x_nconnections - 1]);
- outlet_float(x->x_connectout, x->x_nconnections);
- }
-}
-
-static void netserver_print(t_netserver *x)
-{
- int i;
- if(x->x_nconnections > 0)
- {
- post("netserver: %d open connections:", x->x_nconnections);
-
- for(i = 0; i < x->x_nconnections; i++)
- {
- post(" \"%s\" on socket %d",
- x->x_host[i]->s_name, x->x_fd[i]);
- }
- } else post("netserver: no open connections");
-}
-
-static void netserver_emerg(t_netserver *x)
-{
- x->x_log_pri = LOG_EMERG;
-}
-static void netserver_alert(t_netserver *x)
-{
- x->x_log_pri = LOG_ALERT;
-}
-static void netserver_crit(t_netserver *x)
-{
- x->x_log_pri = LOG_CRIT;
-}
-static void netserver_err(t_netserver *x)
-{
- x->x_log_pri = LOG_ERR;
-}
-static void netserver_warning(t_netserver *x)
-{
- x->x_log_pri = LOG_WARNING;
-}
-static void netserver_notice(t_netserver *x)
-{
- x->x_log_pri = LOG_NOTICE;
-}
-static void netserver_info(t_netserver *x)
-{
- x->x_log_pri = LOG_INFO;
-}
-static void netserver_debug(t_netserver *x)
-{
- x->x_log_pri = LOG_DEBUG;
-}
-
-static void *netserver_new(t_floatarg fportno)
-{
- t_netserver *x;
- int i;
- struct sockaddr_in server;
- int sockfd, portno = fportno;
-
- x = (t_netserver *)pd_new(netserver_class);
-/* set default debug message level */
- x->x_log_pri = LOG_ERR;
-/* create a socket */
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (x->x_log_pri >= LOG_NOTICE)
- post("netserver: receive socket %d", sockfd);
- if (sockfd < 0)
- {
- sys_sockerror("socket");
- return (0);
- }
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = INADDR_ANY;
-
-#ifdef IRIX
- /* this seems to work only in IRIX but is unnecessary in
- Linux. Not sure what NT needs in place of this. */
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
- post("setsockopt failed\n");
-#endif
-
- /* assign server port number */
- server.sin_port = htons((u_short)portno);
-
- /* name the socket */
- if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
- {
- sys_sockerror("bind");
- sys_closesocket(sockfd);
- return (0);
- }
- x->x_msgout = outlet_new(&x->x_obj, &s_anything);
-
- /* streaming protocol */
- if (listen(sockfd, 5) < 0)
- {
- sys_sockerror("listen");
- sys_closesocket(sockfd);
- sockfd = -1;
- }
- else
- {
- sys_addpollfn(sockfd, (t_fdpollfn)netserver_connectpoll, x);
- x->x_connectout = outlet_new(&x->x_obj, &s_float);
- x->x_clientno = outlet_new(&x->x_obj, &s_float);
- x->x_connectionip = outlet_new(&x->x_obj, &s_symbol);
- inbinbuf = binbuf_new();
- }
- x->x_connectsocket = sockfd;
- x->x_nconnections = 0;
- for(i = 0; i < MAX_CONNECT; i++)x->x_fd[i] = -1;
-
- return (x);
-}
-
-static void netserver_free(t_netserver *x)
-{
- int i;
- for(i = 0; i < x->x_nconnections; i++)
- {
- sys_rmpollfn(x->x_fd[i]);
- sys_closesocket(x->x_fd[i]);
- }
- if (x->x_connectsocket >= 0)
- {
- sys_rmpollfn(x->x_connectsocket);
- sys_closesocket(x->x_connectsocket);
- }
- binbuf_free(inbinbuf);
-}
-
-#ifndef MAXLIB
-void netserver_setup(void)
-{
- netserver_class = class_new(gensym("netserver"),(t_newmethod)netserver_new, (t_method)netserver_free,
- sizeof(t_netserver), 0, A_DEFFLOAT, 0);
- class_addmethod(netserver_class, (t_method)netserver_print, gensym("print"), 0);
- class_addmethod(netserver_class, (t_method)netserver_send, gensym("send"), A_GIMME, 0);
- class_addmethod(netserver_class, (t_method)netserver_client_send, gensym("client"), A_GIMME, 0);
- class_addmethod(netserver_class, (t_method)netserver_broadcast, gensym("broadcast"), A_GIMME, 0);
-/* syslog log level messages */
- class_addmethod(netserver_class, (t_method)netserver_emerg, gensym("emerg"), 0);
- class_addmethod(netserver_class, (t_method)netserver_emerg, gensym("emergency"), 0);
- class_addmethod(netserver_class, (t_method)netserver_alert, gensym("alert"), 0);
- class_addmethod(netserver_class, (t_method)netserver_crit, gensym("crit"), 0);
- class_addmethod(netserver_class, (t_method)netserver_crit, gensym("critical"), 0);
- class_addmethod(netserver_class, (t_method)netserver_err, gensym("err"), 0);
- class_addmethod(netserver_class, (t_method)netserver_err, gensym("error"), 0);
- class_addmethod(netserver_class, (t_method)netserver_err, gensym("quiet"), 0);
- class_addmethod(netserver_class, (t_method)netserver_warning, gensym("warning"), 0);
- class_addmethod(netserver_class, (t_method)netserver_notice, gensym("notice"), 0);
- class_addmethod(netserver_class, (t_method)netserver_info, gensym("info"), 0);
- class_addmethod(netserver_class, (t_method)netserver_info, gensym("verbose"), 0);
- class_addmethod(netserver_class, (t_method)netserver_debug, gensym("debug"), 0);
-
-
- post(version);
-}
-#else
-void maxlib_netserver_setup(void)
-{
- netserver_class = class_new(gensym("maxlib_netserver"),(t_newmethod)netserver_new, (t_method)netserver_free,
- sizeof(t_netserver), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)netserver_new, gensym("netserver"), A_DEFFLOAT, 0);
- class_addmethod(netserver_class, (t_method)netserver_print, gensym("print"), 0);
- class_addmethod(netserver_class, (t_method)netserver_send, gensym("send"), A_GIMME, 0);
- class_addmethod(netserver_class, (t_method)netserver_client_send, gensym("client"), A_GIMME, 0);
- class_addmethod(netserver_class, (t_method)netserver_broadcast, gensym("broadcast"), A_GIMME, 0);
- class_sethelpsymbol(netserver_class, gensym("maxlib/netserver-help.pd"));
-}
-#endif
+/* -------------------------- netserver ------------------------------------- */
+/* */
+/* A server for bidirectional communication from within Pd. */
+/* Allows to send back data to specific clients connected to the server. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include "s_stuff.h"
+#include "m_imp.h"
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <pthread.h>
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#include <winsock.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#define SOCKET_ERROR -1
+#endif
+
+#define MAX_CONNECT 32 /* maximum number of connections */
+#define INBUFSIZE 4096 /* size of receiving data buffer */
+
+/* message levels from syslog.h */
+#define LOG_EMERG 0 /* system is unusable */
+#define LOG_ALERT 1 /* action must be taken immediately */
+#define LOG_CRIT 2 /* critical conditions */
+#define LOG_ERR 3 /* error conditions */
+#define LOG_WARNING 4 /* warning conditions */
+#define LOG_NOTICE 5 /* normal but significant condition */
+#define LOG_INFO 6 /* informational */
+#define LOG_DEBUG 7 /* debug-level messages */
+
+static char *version =
+ "netserver v0.2.hcs1 :: bidirectional communication for Pd\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>\n"
+ " syslogging by Hans-Christoph Steiner <hans@eds.org> ";
+
+/* ----------------------------- netserver ------------------------- */
+
+static t_class *netserver_class;
+static t_binbuf *inbinbuf;
+
+typedef void (*t_netserver_socketnotifier)(void *x);
+typedef void (*t_netserver_socketreceivefn)(void *x, t_binbuf *b);
+
+typedef struct _netserver
+{
+ t_object x_obj;
+ t_outlet *x_msgout;
+ t_outlet *x_connectout;
+ t_outlet *x_clientno;
+ t_outlet *x_connectionip;
+ t_symbol *x_host[MAX_CONNECT];
+ t_int x_fd[MAX_CONNECT];
+ t_int x_sock_fd;
+ t_int x_connectsocket;
+ t_int x_nconnections;
+/* for syslog style logging priorities */
+ t_int x_log_pri;
+} t_netserver;
+
+typedef struct _netserver_socketreceiver
+{
+ char *sr_inbuf;
+ int sr_inhead;
+ int sr_intail;
+ void *sr_owner;
+ t_netserver_socketnotifier sr_notifier;
+ t_netserver_socketreceivefn sr_socketreceivefn;
+} t_netserver_socketreceiver;
+
+static t_netserver_socketreceiver *netserver_socketreceiver_new(void *owner, t_netserver_socketnotifier notifier,
+ t_netserver_socketreceivefn socketreceivefn)
+{
+ t_netserver_socketreceiver *x = (t_netserver_socketreceiver *)getbytes(sizeof(*x));
+ x->sr_inhead = x->sr_intail = 0;
+ x->sr_owner = owner;
+ x->sr_notifier = notifier;
+ x->sr_socketreceivefn = socketreceivefn;
+ if (!(x->sr_inbuf = malloc(INBUFSIZE))) bug("t_netserver_socketreceiver");
+ return (x);
+}
+
+/* this is in a separately called subroutine so that the buffer isn't
+ sitting on the stack while the messages are getting passed. */
+static int netserver_socketreceiver_doread(t_netserver_socketreceiver *x)
+{
+ char messbuf[INBUFSIZE], *bp = messbuf;
+ int indx;
+ int inhead = x->sr_inhead;
+ int intail = x->sr_intail;
+ char *inbuf = x->sr_inbuf;
+ if (intail == inhead) return (0);
+ for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1))
+ {
+ char c = *bp++ = inbuf[indx];
+ if (c == ';' && (!indx || inbuf[indx-1] != '\\'))
+ {
+ intail = (indx+1)&(INBUFSIZE-1);
+ binbuf_text(inbinbuf, messbuf, bp - messbuf);
+ x->sr_inhead = inhead;
+ x->sr_intail = intail;
+ return (1);
+ }
+ }
+ return (0);
+}
+
+static void netserver_socketreceiver_read(t_netserver_socketreceiver *x, int fd)
+{
+ char *semi;
+ int readto = (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
+ int ret;
+
+ t_netserver *y = x->sr_owner;
+
+ y->x_sock_fd = fd;
+
+ /* the input buffer might be full. If so, drop the whole thing */
+ if (readto == x->sr_inhead)
+ {
+ if (y->x_log_pri >= LOG_ERR)
+ post("netserver: dropped message");
+ x->sr_inhead = x->sr_intail = 0;
+ readto = INBUFSIZE;
+ }
+ else
+ {
+ ret = recv(fd, x->sr_inbuf + x->sr_inhead,
+ readto - x->sr_inhead, 0);
+ if (ret < 0)
+ {
+ sys_sockerror("recv");
+ if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
+ sys_rmpollfn(fd);
+ sys_closesocket(fd);
+ }
+ else if (ret == 0)
+ {
+ if (y->x_log_pri >= LOG_NOTICE)
+ post("netserver: << connection closed on socket %d", fd);
+ if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
+ sys_rmpollfn(fd);
+ sys_closesocket(fd);
+ }
+ else
+ {
+ x->sr_inhead += ret;
+ if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0;
+ while (netserver_socketreceiver_doread(x))
+ {
+ outlet_setstacklim();
+ if (x->sr_socketreceivefn)
+ (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf);
+ else binbuf_eval(inbinbuf, 0, 0, 0);
+ }
+ }
+ }
+}
+
+static void netserver_socketreceiver_free(t_netserver_socketreceiver *x)
+{
+ free(x->sr_inbuf);
+ freebytes(x, sizeof(*x));
+}
+
+/* ---------------- main netserver (send) stuff --------------------- */
+
+/* send message to client using socket number */
+static void netserver_send(t_netserver *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int sockfd, client = -1, i;
+ if(x->x_nconnections < 0)
+ {
+ if (x->x_log_pri >= LOG_WARNING)
+ post("netserver: no clients connected");
+ return;
+ }
+ if(argc < 2)
+ {
+ if (x->x_log_pri >= LOG_WARNING)
+ post("netserver: nothing to send");
+ return;
+ }
+ /* get socket number of connection (first element in list) */
+ if(argv[0].a_type == A_FLOAT)
+ {
+ sockfd = atom_getfloatarg(0, argc, argv);
+ for(i = 0; i < x->x_nconnections; i++) /* check if connection exists */
+ {
+ if(x->x_fd[i] == sockfd)
+ {
+ client = i; /* the client we're sending to */
+ break;
+ }
+ }
+ if(client == -1)
+ {
+ if (x->x_log_pri >= LOG_CRIT)
+ post("netserver: no connection on socket %d", sockfd);
+ return;
+ }
+ }
+ else
+ {
+ if (x->x_log_pri >= LOG_CRIT)
+ post("netserver: no socket specified");
+ return;
+ }
+ /* process & send data */
+ if(sockfd > 0)
+ {
+ t_binbuf *b = binbuf_new();
+ char *buf, *bp;
+ int length, sent;
+ t_atom at;
+ binbuf_add(b, argc - 1, argv + 1); /* skip first element */
+ SETSEMI(&at);
+ binbuf_add(b, 1, &at);
+ binbuf_gettext(b, &buf, &length);
+
+ if (x->x_log_pri >= LOG_DEBUG)
+ {
+ post("netserver: sending data to client %d on socket %d", client + 1, sockfd);
+ post("netserver: sending \"%s\"", buf);
+ }
+
+ for (bp = buf, sent = 0; sent < length;)
+ {
+ static double lastwarntime;
+ static double pleasewarn;
+ double timebefore = clock_getlogicaltime();
+ int res = send(sockfd, buf, length-sent, 0);
+ double timeafter = clock_getlogicaltime();
+ int late = (timeafter - timebefore > 0.005);
+ if (late || pleasewarn)
+ {
+ if (timeafter > lastwarntime + 2)
+ {
+ if (x->x_log_pri >= LOG_WARNING)
+ post("netserver blocked %d msec",
+ (int)(1000 * ((timeafter - timebefore) + pleasewarn)));
+ pleasewarn = 0;
+ lastwarntime = timeafter;
+ }
+ else if (late) pleasewarn += timeafter - timebefore;
+ }
+ if (res <= 0)
+ {
+ sys_sockerror("netserver");
+ if (x->x_log_pri >= LOG_ERR)
+ post("netserver: could not send data to client");
+ break;
+ }
+ else
+ {
+ sent += res;
+ bp += res;
+ }
+ }
+ t_freebytes(buf, length);
+ binbuf_free(b);
+ }
+ else if (x->x_log_pri >= LOG_CRIT)
+ post("netserver: not a valid socket number (%d)", sockfd);
+}
+
+/* send message to client using client number
+ note that the client numbers might change in case a client disconnects! */
+static void netserver_client_send(t_netserver *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int sockfd, client;
+ if(x->x_nconnections < 0)
+ {
+ if (x->x_log_pri >= LOG_WARNING)
+ post("netserver: no clients connected");
+ return;
+ }
+ if(argc < 2)
+ {
+ if (x->x_log_pri >= LOG_WARNING)
+ post("netserver: nothing to send");
+ return;
+ }
+ /* get number of client (first element in list) */
+ if(argv[0].a_type == A_FLOAT)
+ client = atom_getfloatarg(0, argc, argv);
+ else
+ {
+ if (x->x_log_pri >= LOG_WARNING)
+ post("netserver: no client specified");
+ return;
+ }
+ sockfd = x->x_fd[client - 1]; /* get socket number for that client */
+
+ /* process & send data */
+ if(sockfd > 0)
+ {
+ t_binbuf *b = binbuf_new();
+ char *buf, *bp;
+ int length, sent;
+ t_atom at;
+ binbuf_add(b, argc - 1, argv + 1); /* skip first element */
+ SETSEMI(&at);
+ binbuf_add(b, 1, &at);
+ binbuf_gettext(b, &buf, &length);
+
+ if (x->x_log_pri >= LOG_DEBUG)
+ {
+ post("netserver: sending data to client %d on socket %d", client, sockfd);
+ post("netserver: >> sending \"%s\"", buf);
+ }
+
+ for (bp = buf, sent = 0; sent < length;)
+ {
+ static double lastwarntime;
+ static double pleasewarn;
+ double timebefore = clock_getlogicaltime();
+ int res = send(sockfd, buf, length-sent, 0);
+ double timeafter = clock_getlogicaltime();
+ int late = (timeafter - timebefore > 0.005);
+ if (late || pleasewarn)
+ {
+ if (timeafter > lastwarntime + 2)
+ {
+ if (x->x_log_pri >= LOG_WARNING)
+ post("netserver blocked %d msec",
+ (int)(1000 * ((timeafter - timebefore) + pleasewarn)));
+ pleasewarn = 0;
+ lastwarntime = timeafter;
+ }
+ else if (late) pleasewarn += timeafter - timebefore;
+ }
+ if (res <= 0)
+ {
+ sys_sockerror("netserver");
+ if (x->x_log_pri >= LOG_ERR)
+ post("netserver: could not send data to cient");
+ break;
+ }
+ else
+ {
+ sent += res;
+ bp += res;
+ }
+ }
+ t_freebytes(buf, length);
+ binbuf_free(b);
+ }
+ else if (x->x_log_pri >= LOG_CRIT)
+ post("netserver: not a valid socket number (%d)", sockfd);
+}
+
+/* broadcasts a message to all connected clients */
+static void netserver_broadcast(t_netserver *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i, client = x->x_nconnections; /* number of clients to send to */
+ t_atom at[256];
+ for(i = 0; i < argc; i++)
+ {
+ at[i + 1] = argv[i];
+ }
+ argc++;
+ /* enumerate through the clients and send each the message */
+ while(client--)
+ {
+ SETFLOAT(at, client + 1); /* prepend number of client */
+ netserver_client_send(x, s, argc, at);
+ }
+}
+
+
+/* ---------------- main netserver (receive) stuff --------------------- */
+
+static void netserver_notify(t_netserver *x)
+{
+ int i, k;
+ /* remove connection from list */
+ for(i = 0; i < x->x_nconnections; i++)
+ {
+ if(x->x_fd[i] == x->x_sock_fd)
+ {
+ x->x_nconnections--;
+ if (x->x_log_pri >= LOG_NOTICE)
+ post("netserver: \"%s\" removed from list of clients", x->x_host[i]->s_name);
+ x->x_host[i] = NULL; /* delete entry */
+ x->x_fd[i] = -1;
+ /* rearrange list now: move entries to close the gap */
+ for(k = i; k < x->x_nconnections; k++)
+ {
+ x->x_host[k] = x->x_host[k + 1];
+ x->x_fd[k] = x->x_fd[k + 1];
+ }
+ }
+ }
+ outlet_float(x->x_connectout, x->x_nconnections);
+}
+
+static void netserver_doit(void *z, t_binbuf *b)
+{
+ t_atom messbuf[1024];
+ t_netserver *x = (t_netserver *)z;
+ int msg, natom = binbuf_getnatom(b);
+ t_atom *at = binbuf_getvec(b);
+ int i;
+ /* output clients IP and socket no. */
+ for(i = 0; i < x->x_nconnections; i++) /* search for corresponding IP */
+ {
+ if(x->x_fd[i] == x->x_sock_fd)
+ {
+ outlet_symbol(x->x_connectionip, x->x_host[i]);
+ break;
+ }
+ }
+ outlet_float(x->x_clientno, x->x_sock_fd); /* the socket number */
+ /* process data */
+ 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 ii;
+ for (ii = msg; ii < emsg; ii++)
+ if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM)
+ {
+ pd_error(x, "netserver: got dollar sign in message");
+ goto nodice;
+ }
+ if (at[msg].a_type == A_FLOAT)
+ {
+ if (emsg > msg + 1)
+ outlet_list(x->x_msgout, 0, emsg-msg, at + msg);
+ else outlet_float(x->x_msgout, at[msg].a_w.w_float);
+ }
+ else if (at[msg].a_type == A_SYMBOL)
+ outlet_anything(x->x_msgout, at[msg].a_w.w_symbol,
+ emsg-msg-1, at + msg + 1);
+ }
+ nodice:
+ msg = emsg + 1;
+ }
+}
+
+static void netserver_connectpoll(t_netserver *x)
+{
+ struct sockaddr_in incomer_address;
+ int sockaddrl = (int) sizeof( struct sockaddr );
+ int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl);
+ if (fd < 0) post("netserver: accept failed");
+ else
+ {
+ t_netserver_socketreceiver *y = netserver_socketreceiver_new((void *)x,
+ (t_netserver_socketnotifier)netserver_notify,
+ (x->x_msgout ? netserver_doit : 0));
+ sys_addpollfn(fd, (t_fdpollfn)netserver_socketreceiver_read, y);
+ x->x_nconnections++;
+ x->x_host[x->x_nconnections - 1] = gensym(inet_ntoa(incomer_address.sin_addr));
+ x->x_fd[x->x_nconnections - 1] = fd;
+
+ if (x->x_log_pri >= LOG_NOTICE)
+ post("netserver: ** accepted connection from %s on socket %d",
+ x->x_host[x->x_nconnections - 1]->s_name, x->x_fd[x->x_nconnections - 1]);
+ outlet_float(x->x_connectout, x->x_nconnections);
+ }
+}
+
+static void netserver_print(t_netserver *x)
+{
+ int i;
+ if(x->x_nconnections > 0)
+ {
+ post("netserver: %d open connections:", x->x_nconnections);
+
+ for(i = 0; i < x->x_nconnections; i++)
+ {
+ post(" \"%s\" on socket %d",
+ x->x_host[i]->s_name, x->x_fd[i]);
+ }
+ } else post("netserver: no open connections");
+}
+
+static void netserver_emerg(t_netserver *x)
+{
+ x->x_log_pri = LOG_EMERG;
+}
+static void netserver_alert(t_netserver *x)
+{
+ x->x_log_pri = LOG_ALERT;
+}
+static void netserver_crit(t_netserver *x)
+{
+ x->x_log_pri = LOG_CRIT;
+}
+static void netserver_err(t_netserver *x)
+{
+ x->x_log_pri = LOG_ERR;
+}
+static void netserver_warning(t_netserver *x)
+{
+ x->x_log_pri = LOG_WARNING;
+}
+static void netserver_notice(t_netserver *x)
+{
+ x->x_log_pri = LOG_NOTICE;
+}
+static void netserver_info(t_netserver *x)
+{
+ x->x_log_pri = LOG_INFO;
+}
+static void netserver_debug(t_netserver *x)
+{
+ x->x_log_pri = LOG_DEBUG;
+}
+
+static void *netserver_new(t_floatarg fportno)
+{
+ t_netserver *x;
+ int i;
+ struct sockaddr_in server;
+ int sockfd, portno = fportno;
+
+ x = (t_netserver *)pd_new(netserver_class);
+/* set default debug message level */
+ x->x_log_pri = LOG_ERR;
+/* create a socket */
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (x->x_log_pri >= LOG_NOTICE)
+ post("netserver: receive socket %d", sockfd);
+ if (sockfd < 0)
+ {
+ sys_sockerror("socket");
+ return (0);
+ }
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+
+#ifdef IRIX
+ /* this seems to work only in IRIX but is unnecessary in
+ Linux. Not sure what NT needs in place of this. */
+ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
+ post("setsockopt failed\n");
+#endif
+
+ /* assign server port number */
+ server.sin_port = htons((u_short)portno);
+
+ /* name the socket */
+ if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
+ {
+ sys_sockerror("bind");
+ sys_closesocket(sockfd);
+ return (0);
+ }
+ x->x_msgout = outlet_new(&x->x_obj, &s_anything);
+
+ /* streaming protocol */
+ if (listen(sockfd, 5) < 0)
+ {
+ sys_sockerror("listen");
+ sys_closesocket(sockfd);
+ sockfd = -1;
+ }
+ else
+ {
+ sys_addpollfn(sockfd, (t_fdpollfn)netserver_connectpoll, x);
+ x->x_connectout = outlet_new(&x->x_obj, &s_float);
+ x->x_clientno = outlet_new(&x->x_obj, &s_float);
+ x->x_connectionip = outlet_new(&x->x_obj, &s_symbol);
+ inbinbuf = binbuf_new();
+ }
+ x->x_connectsocket = sockfd;
+ x->x_nconnections = 0;
+ for(i = 0; i < MAX_CONNECT; i++)x->x_fd[i] = -1;
+
+ return (x);
+}
+
+static void netserver_free(t_netserver *x)
+{
+ int i;
+ for(i = 0; i < x->x_nconnections; i++)
+ {
+ sys_rmpollfn(x->x_fd[i]);
+ sys_closesocket(x->x_fd[i]);
+ }
+ if (x->x_connectsocket >= 0)
+ {
+ sys_rmpollfn(x->x_connectsocket);
+ sys_closesocket(x->x_connectsocket);
+ }
+ binbuf_free(inbinbuf);
+}
+
+#ifndef MAXLIB
+void netserver_setup(void)
+{
+ netserver_class = class_new(gensym("netserver"),(t_newmethod)netserver_new, (t_method)netserver_free,
+ sizeof(t_netserver), 0, A_DEFFLOAT, 0);
+ class_addmethod(netserver_class, (t_method)netserver_print, gensym("print"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_send, gensym("send"), A_GIMME, 0);
+ class_addmethod(netserver_class, (t_method)netserver_client_send, gensym("client"), A_GIMME, 0);
+ class_addmethod(netserver_class, (t_method)netserver_broadcast, gensym("broadcast"), A_GIMME, 0);
+/* syslog log level messages */
+ class_addmethod(netserver_class, (t_method)netserver_emerg, gensym("emerg"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_emerg, gensym("emergency"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_alert, gensym("alert"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_crit, gensym("crit"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_crit, gensym("critical"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_err, gensym("err"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_err, gensym("error"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_err, gensym("quiet"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_warning, gensym("warning"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_notice, gensym("notice"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_info, gensym("info"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_info, gensym("verbose"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_debug, gensym("debug"), 0);
+
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_netserver_setup(void)
+{
+ netserver_class = class_new(gensym("maxlib_netserver"),(t_newmethod)netserver_new, (t_method)netserver_free,
+ sizeof(t_netserver), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)netserver_new, gensym("netserver"), A_DEFFLOAT, 0);
+ class_addmethod(netserver_class, (t_method)netserver_print, gensym("print"), 0);
+ class_addmethod(netserver_class, (t_method)netserver_send, gensym("send"), A_GIMME, 0);
+ class_addmethod(netserver_class, (t_method)netserver_client_send, gensym("client"), A_GIMME, 0);
+ class_addmethod(netserver_class, (t_method)netserver_broadcast, gensym("broadcast"), A_GIMME, 0);
+ class_sethelpsymbol(netserver_class, gensym("maxlib/netserver-help.pd"));
+}
+#endif
diff --git a/nroute.c b/nroute.c
index 5c85f6c..60bcea8 100644
--- a/nroute.c
+++ b/nroute.c
@@ -1,179 +1,179 @@
-/* ------------------------- nroute ------------------------------------------ */
-/* */
-/* Route input according to Nth element. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Based on code found on the web. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-/*
- inlet 1: anything to be routed
- inlet 2: anything to be matched to
- inlet 3: position to match
- out 1: input if match found
- out 2: input if match not found
-*/
-
-#include "m_pd.h"
-
-static char *version = "nroute v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct nroute
-{
- t_object x_obj;
- t_outlet *out1;
- t_outlet *out2;
- t_int pos;
- t_atom match;
-} t_nroute;
-
-typedef struct proxy
-{
- t_object obj;
- t_int index; /* number of proxy inlet(s) */
- t_nroute *x; /* we'll put the other struct in here */
-} t_proxy;
-
-
- /* this is the routine that actually does the routing / matching */
- /* it get's called by all other routines that get any input and */
- /* even handles the second (proxy) inlet ! */
-static void nroute_any(t_nroute *x, t_symbol *s, int argc, t_atom *argv)
-{
- if(s)
- {
- if (x->pos == 1 && x->match.a_type == A_SYMBOL && x->match.a_w.w_symbol == s)
- outlet_anything (x->out1,s,argc,argv);
- else if (x->pos > 1 && x->pos <= argc + 1 &&
- argv[x->pos-2].a_type == x->match.a_type &&
- argv[x->pos-2].a_w.w_float == x->match.a_w.w_float)
- outlet_anything (x->out1,s,argc,argv);
- else outlet_anything (x->out2,s,argc,argv);
- }
- else
- {
- if (x->pos > 0 && x->pos <= argc &&
- argv[x->pos-1].a_type == x->match.a_type &&
- argv[x->pos-1].a_w.w_float == x->match.a_w.w_float)
- outlet_list (x->out1,0,argc,argv);
- else outlet_list (x->out2,0,argc,argv);
- }
-}
-
-static void nroute_float(t_nroute *x, float f)
-{
- t_atom a;
-
- SETFLOAT (&a,f);
- nroute_any(x,0,1,&a);
-}
-
-static void nroute_list(t_nroute *x, t_symbol *s, int argc, t_atom *argv)
-{
- nroute_any(x,0,argc,argv);
-}
-
-static void nroute_setmatch(t_proxy *p, t_symbol *s, int argc, t_atom *argv)
-{
- t_nroute *x = (t_nroute *)(p->x);
-
- if(argc == 0) /* have to match a symbol */
- {
- x->match.a_type = A_SYMBOL;
- x->match.a_w.w_symbol = s;
- }
- else /* got a float */
- {
- if(argc > 1)
- {
- post("nroute: middle inlet accepts only (float,symbol) for match");
- return;
- }
- x->match.a_type = A_FLOAT;
- x->match.a_w.w_float = argv[0].a_w.w_float;
- }
-}
-
-static void nroute_setpos(t_nroute *x, t_floatarg f)
-{
- x->pos = (t_int)f;
-}
-
-static t_class *nroute_class;
-static t_class *proxy_class;
-
-static void *nroute_new(t_symbol *s, int argc, t_atom *argv)
-{
- t_nroute *x = (t_nroute *)pd_new(nroute_class);
- t_proxy *inlet = (t_proxy *)pd_new(proxy_class); /* for the proxy inlet */
-
- inlet->x = x; /* make x visible to the proxy inlets */
-
- x->pos = 1;
- x->match.a_type = A_NULL;
- if (argc > 2) { error ("nroute: extra arguments"); return 0; }
- if (argc > 1) {
- if (argv[1].a_type == A_FLOAT) x->pos = argv[1].a_w.w_float;
- else { post ("nroute: second argument must be (int) position"); return 0; }
- }
- if (argc > 0) {
- x->match.a_type = argv[0].a_type;
- x->match.a_w.w_float = argv[0].a_w.w_float;
- }
- inlet->index = 0; /* we are going to create a proxy inlet no. 0 */
- /* it belongs to the object t_nroute but the destination is t_proxy */
- inlet_new(&x->x_obj, &inlet->obj.ob_pd, 0,0);
- /* and now a 'normal' third inlet */
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("right"));
- x->out1 = outlet_new(&x->x_obj, gensym("list"));
- x->out2 = outlet_new(&x->x_obj, gensym("list"));
- return (x);
-}
-
-#ifndef MAXLIB
-void nroute_setup(void)
-{
- /* the object's class: */
- nroute_class = class_new(gensym("nroute"), (t_newmethod)nroute_new,
- 0, sizeof(t_nroute), 0, A_GIMME, 0);
-#else
-void maxlib_nroute_setup(void)
-{
- /* the object's class: */
- nroute_class = class_new(gensym("maxlib_nroute"), (t_newmethod)nroute_new,
- 0, sizeof(t_nroute), 0, A_GIMME, 0);
- class_addcreator((t_newmethod)nroute_new, gensym("nroute"), A_GIMME, 0);
-#endif
- /* a class for the proxy inlet: */
- proxy_class = class_new(gensym("maxlib_nroute_proxy"), NULL, NULL, sizeof(t_proxy),
- CLASS_PD|CLASS_NOINLET, A_NULL);
-
- class_addmethod(nroute_class, (t_method)nroute_setpos, gensym("right"), A_FLOAT, 0);
- class_addfloat(nroute_class, nroute_float);
- class_addlist(nroute_class, nroute_list);
- class_addanything(nroute_class, nroute_any);
- class_addanything(proxy_class, nroute_setmatch);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_sethelpsymbol(nroute_class, gensym("maxlib/nroute-help.pd"));
-#endif
-}
+/* ------------------------- nroute ------------------------------------------ */
+/* */
+/* Route input according to Nth element. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Based on code found on the web. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+/*
+ inlet 1: anything to be routed
+ inlet 2: anything to be matched to
+ inlet 3: position to match
+ out 1: input if match found
+ out 2: input if match not found
+*/
+
+#include "m_pd.h"
+
+static char *version = "nroute v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct nroute
+{
+ t_object x_obj;
+ t_outlet *out1;
+ t_outlet *out2;
+ t_int pos;
+ t_atom match;
+} t_nroute;
+
+typedef struct proxy
+{
+ t_object obj;
+ t_int index; /* number of proxy inlet(s) */
+ t_nroute *x; /* we'll put the other struct in here */
+} t_proxy;
+
+
+ /* this is the routine that actually does the routing / matching */
+ /* it get's called by all other routines that get any input and */
+ /* even handles the second (proxy) inlet ! */
+static void nroute_any(t_nroute *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if(s)
+ {
+ if (x->pos == 1 && x->match.a_type == A_SYMBOL && x->match.a_w.w_symbol == s)
+ outlet_anything (x->out1,s,argc,argv);
+ else if (x->pos > 1 && x->pos <= argc + 1 &&
+ argv[x->pos-2].a_type == x->match.a_type &&
+ argv[x->pos-2].a_w.w_float == x->match.a_w.w_float)
+ outlet_anything (x->out1,s,argc,argv);
+ else outlet_anything (x->out2,s,argc,argv);
+ }
+ else
+ {
+ if (x->pos > 0 && x->pos <= argc &&
+ argv[x->pos-1].a_type == x->match.a_type &&
+ argv[x->pos-1].a_w.w_float == x->match.a_w.w_float)
+ outlet_list (x->out1,0,argc,argv);
+ else outlet_list (x->out2,0,argc,argv);
+ }
+}
+
+static void nroute_float(t_nroute *x, float f)
+{
+ t_atom a;
+
+ SETFLOAT (&a,f);
+ nroute_any(x,0,1,&a);
+}
+
+static void nroute_list(t_nroute *x, t_symbol *s, int argc, t_atom *argv)
+{
+ nroute_any(x,0,argc,argv);
+}
+
+static void nroute_setmatch(t_proxy *p, t_symbol *s, int argc, t_atom *argv)
+{
+ t_nroute *x = (t_nroute *)(p->x);
+
+ if(argc == 0) /* have to match a symbol */
+ {
+ x->match.a_type = A_SYMBOL;
+ x->match.a_w.w_symbol = s;
+ }
+ else /* got a float */
+ {
+ if(argc > 1)
+ {
+ post("nroute: middle inlet accepts only (float,symbol) for match");
+ return;
+ }
+ x->match.a_type = A_FLOAT;
+ x->match.a_w.w_float = argv[0].a_w.w_float;
+ }
+}
+
+static void nroute_setpos(t_nroute *x, t_floatarg f)
+{
+ x->pos = (t_int)f;
+}
+
+static t_class *nroute_class;
+static t_class *proxy_class;
+
+static void *nroute_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_nroute *x = (t_nroute *)pd_new(nroute_class);
+ t_proxy *inlet = (t_proxy *)pd_new(proxy_class); /* for the proxy inlet */
+
+ inlet->x = x; /* make x visible to the proxy inlets */
+
+ x->pos = 1;
+ x->match.a_type = A_NULL;
+ if (argc > 2) { error ("nroute: extra arguments"); return 0; }
+ if (argc > 1) {
+ if (argv[1].a_type == A_FLOAT) x->pos = argv[1].a_w.w_float;
+ else { post ("nroute: second argument must be (int) position"); return 0; }
+ }
+ if (argc > 0) {
+ x->match.a_type = argv[0].a_type;
+ x->match.a_w.w_float = argv[0].a_w.w_float;
+ }
+ inlet->index = 0; /* we are going to create a proxy inlet no. 0 */
+ /* it belongs to the object t_nroute but the destination is t_proxy */
+ inlet_new(&x->x_obj, &inlet->obj.ob_pd, 0,0);
+ /* and now a 'normal' third inlet */
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("right"));
+ x->out1 = outlet_new(&x->x_obj, gensym("list"));
+ x->out2 = outlet_new(&x->x_obj, gensym("list"));
+ return (x);
+}
+
+#ifndef MAXLIB
+void nroute_setup(void)
+{
+ /* the object's class: */
+ nroute_class = class_new(gensym("nroute"), (t_newmethod)nroute_new,
+ 0, sizeof(t_nroute), 0, A_GIMME, 0);
+#else
+void maxlib_nroute_setup(void)
+{
+ /* the object's class: */
+ nroute_class = class_new(gensym("maxlib_nroute"), (t_newmethod)nroute_new,
+ 0, sizeof(t_nroute), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)nroute_new, gensym("nroute"), A_GIMME, 0);
+#endif
+ /* a class for the proxy inlet: */
+ proxy_class = class_new(gensym("maxlib_nroute_proxy"), NULL, NULL, sizeof(t_proxy),
+ CLASS_PD|CLASS_NOINLET, A_NULL);
+
+ class_addmethod(nroute_class, (t_method)nroute_setpos, gensym("right"), A_FLOAT, 0);
+ class_addfloat(nroute_class, nroute_float);
+ class_addlist(nroute_class, nroute_list);
+ class_addanything(nroute_class, nroute_any);
+ class_addanything(proxy_class, nroute_setmatch);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(nroute_class, gensym("maxlib/nroute-help.pd"));
+#endif
+}
diff --git a/pitch.c b/pitch.c
index c584f7b..2eed248 100644
--- a/pitch.c
+++ b/pitch.c
@@ -1,114 +1,114 @@
-/* ------------------------- pitch ------------------------------------------ */
-/* */
-/* Get a lot of info about an incoming pitch (class, register, interval...). */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-
-static char *version = "pitch v0.1b, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct pitch
-{
- t_object x_ob;
- t_inlet *x_inpitch; /* inlet for pitch */
- t_outlet *x_outpitchval; /* pitch as MIDI note number */
- t_outlet *x_outpitchname; /* pitch name, e.g. "C1" */
- t_outlet *x_outpitchclass; /* pitch class */
- t_outlet *x_outintv; /* interval */
- t_outlet *x_outregister; /* register */
-
- t_int x_lastpitch;
-
-} t_pitch;
-
-static void pitch_float(t_pitch *x, t_floatarg f) {
-
- char buf[8];
- int r, c, interval = 0, pitch;
-
- char* notes_up[12] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
- char* notes_down[12] = {"C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"};
-
- pitch = (t_int)f;
- if(pitch < 1) pitch = 0;
- if(pitch > 127) pitch = 127;
-
- if(x->x_lastpitch != 0)interval = pitch - x->x_lastpitch;
- x->x_lastpitch = pitch;
-
- r = (pitch / 12) - 1;
- c = pitch % 12;
- if(interval >= 0)
- {
- sprintf(buf, "%s%d", notes_up[c], r);
- }
- else
- {
- sprintf(buf, "%s%d", notes_down[c], r);
- }
- // post("note: %s %d", notes[c], r);
-
- /* output values from right to left */
- outlet_float(x->x_outregister, r);
- outlet_float(x->x_outintv, interval);
- outlet_float(x->x_outpitchclass, c);
- outlet_symbol(x->x_outpitchname, gensym(buf));
- outlet_float(x->x_outpitchval, pitch);
-}
-
-static t_class *pitch_class;
-
-static void *pitch_new(t_floatarg f)
-{
- t_pitch *x = (t_pitch *)pd_new(pitch_class);
- x->x_inpitch = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- x->x_outpitchval = outlet_new(&x->x_ob, gensym("float"));
- x->x_outpitchname = outlet_new(&x->x_ob, gensym("symbol"));
- x->x_outpitchclass = outlet_new(&x->x_ob, gensym("float"));
- x->x_outintv = outlet_new(&x->x_ob, gensym("float"));
- x->x_outregister = outlet_new(&x->x_ob, gensym("float"));
-
- x->x_lastpitch = f;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void pitch_setup(void)
-{
- pitch_class = class_new(gensym("pitch"), (t_newmethod)pitch_new,
- 0, sizeof(t_pitch), 0, A_DEFFLOAT, 0);
- class_addfloat(pitch_class, pitch_float);
-
- post(version);
-}
-#else
-void maxlib_pitch_setup(void)
-{
- pitch_class = class_new(gensym("maxlib_pitch"), (t_newmethod)pitch_new,
- 0, sizeof(t_pitch), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)pitch_new, gensym("pitch"), A_DEFFLOAT, 0);
- class_addfloat(pitch_class, pitch_float);
- class_sethelpsymbol(pitch_class, gensym("maxlib/pitch-help.pd"));
-}
-#endif
+/* ------------------------- pitch ------------------------------------------ */
+/* */
+/* Get a lot of info about an incoming pitch (class, register, interval...). */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+
+static char *version = "pitch v0.1b, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct pitch
+{
+ t_object x_ob;
+ t_inlet *x_inpitch; /* inlet for pitch */
+ t_outlet *x_outpitchval; /* pitch as MIDI note number */
+ t_outlet *x_outpitchname; /* pitch name, e.g. "C1" */
+ t_outlet *x_outpitchclass; /* pitch class */
+ t_outlet *x_outintv; /* interval */
+ t_outlet *x_outregister; /* register */
+
+ t_int x_lastpitch;
+
+} t_pitch;
+
+static void pitch_float(t_pitch *x, t_floatarg f) {
+
+ char buf[8];
+ int r, c, interval = 0, pitch;
+
+ char* notes_up[12] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
+ char* notes_down[12] = {"C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"};
+
+ pitch = (t_int)f;
+ if(pitch < 1) pitch = 0;
+ if(pitch > 127) pitch = 127;
+
+ if(x->x_lastpitch != 0)interval = pitch - x->x_lastpitch;
+ x->x_lastpitch = pitch;
+
+ r = (pitch / 12) - 1;
+ c = pitch % 12;
+ if(interval >= 0)
+ {
+ sprintf(buf, "%s%d", notes_up[c], r);
+ }
+ else
+ {
+ sprintf(buf, "%s%d", notes_down[c], r);
+ }
+ // post("note: %s %d", notes[c], r);
+
+ /* output values from right to left */
+ outlet_float(x->x_outregister, r);
+ outlet_float(x->x_outintv, interval);
+ outlet_float(x->x_outpitchclass, c);
+ outlet_symbol(x->x_outpitchname, gensym(buf));
+ outlet_float(x->x_outpitchval, pitch);
+}
+
+static t_class *pitch_class;
+
+static void *pitch_new(t_floatarg f)
+{
+ t_pitch *x = (t_pitch *)pd_new(pitch_class);
+ x->x_inpitch = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ x->x_outpitchval = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outpitchname = outlet_new(&x->x_ob, gensym("symbol"));
+ x->x_outpitchclass = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outintv = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outregister = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_lastpitch = f;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void pitch_setup(void)
+{
+ pitch_class = class_new(gensym("pitch"), (t_newmethod)pitch_new,
+ 0, sizeof(t_pitch), 0, A_DEFFLOAT, 0);
+ class_addfloat(pitch_class, pitch_float);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_pitch_setup(void)
+{
+ pitch_class = class_new(gensym("maxlib_pitch"), (t_newmethod)pitch_new,
+ 0, sizeof(t_pitch), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)pitch_new, gensym("pitch"), A_DEFFLOAT, 0);
+ class_addfloat(pitch_class, pitch_float);
+ class_sethelpsymbol(pitch_class, gensym("maxlib/pitch-help.pd"));
+}
+#endif
diff --git a/plus.c b/plus.c
index 1a03171..5095d89 100644
--- a/plus.c
+++ b/plus.c
@@ -1,110 +1,110 @@
-/* --------------------------- plus ------------------------------------------ */
-/* */
-/* Like '+', but calculates output whenever _any_ of the inlets changes. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-
-#define MAXSIZE 32
-
-static char *version = "plus v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct plus
-{
- t_object x_ob;
- t_inlet *x_inleft; /* leftmost inlet */
- t_inlet *x_inright; /* right inlet */
- t_outlet *x_outlet; /* result */
- t_int x_numvalues; /* number of values / inlets */
-
- t_float x_plusvalue[MAXSIZE];
-
-} t_plus;
-
-static void plus_bang(t_plus *x)
-{
- int i;
- t_float result = x->x_plusvalue[0];
- for(i = 1; i < x->x_numvalues; i++)
- result += x->x_plusvalue[i];
- outlet_float(x->x_outlet, result);
-}
-
-static void plus_float(t_plus *x, t_floatarg f)
-{
- x->x_plusvalue[0] = f;
- plus_bang(x); /* calculate result */
-}
-
-static void plus_ft1(t_plus *x, t_floatarg f)
-{
- x->x_plusvalue[1] = f;
- plus_bang(x); /* calculate result */
-}
-
-static t_class *plus_class;
-
-static void *plus_new(t_symbol *s, t_int argc, t_atom* argv)
-{
- int i;
-
- t_plus *x = (t_plus *)pd_new(plus_class);
- x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- for(i = 2; i < argc; i++) /* create additional inlets, if any */
- {
- floatinlet_new(&x->x_ob, &x->x_plusvalue[i]);
- }
- x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
-
- for(i = 0; i < argc; i++)
- {
- x->x_plusvalue[i] = atom_getfloatarg(i, argc, argv);;
- }
- x->x_numvalues = i;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void plus_setup(void)
-{
- plus_class = class_new(gensym("plus"), (t_newmethod)plus_new,
- 0, sizeof(t_plus), 0, A_GIMME, 0);
- class_addfloat(plus_class, plus_float);
- class_addmethod(plus_class, (t_method)plus_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addbang(plus_class, (t_method)plus_bang);
-
- post(version);
-}
-#else
-void maxlib_plus_setup(void)
-{
- plus_class = class_new(gensym("maxlib_plus"), (t_newmethod)plus_new,
- 0, sizeof(t_plus), 0, A_GIMME, 0);
- class_addcreator((t_newmethod)plus_new, gensym("plus"), A_GIMME, 0);
- class_addfloat(plus_class, plus_float);
- class_addmethod(plus_class, (t_method)plus_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addbang(plus_class, (t_method)plus_bang);
- class_sethelpsymbol(plus_class, gensym("maxlib/plus-help.pd"));
-}
-#endif
+/* --------------------------- plus ------------------------------------------ */
+/* */
+/* Like '+', but calculates output whenever _any_ of the inlets changes. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+
+#define MAXSIZE 32
+
+static char *version = "plus v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct plus
+{
+ t_object x_ob;
+ t_inlet *x_inleft; /* leftmost inlet */
+ t_inlet *x_inright; /* right inlet */
+ t_outlet *x_outlet; /* result */
+ t_int x_numvalues; /* number of values / inlets */
+
+ t_float x_plusvalue[MAXSIZE];
+
+} t_plus;
+
+static void plus_bang(t_plus *x)
+{
+ int i;
+ t_float result = x->x_plusvalue[0];
+ for(i = 1; i < x->x_numvalues; i++)
+ result += x->x_plusvalue[i];
+ outlet_float(x->x_outlet, result);
+}
+
+static void plus_float(t_plus *x, t_floatarg f)
+{
+ x->x_plusvalue[0] = f;
+ plus_bang(x); /* calculate result */
+}
+
+static void plus_ft1(t_plus *x, t_floatarg f)
+{
+ x->x_plusvalue[1] = f;
+ plus_bang(x); /* calculate result */
+}
+
+static t_class *plus_class;
+
+static void *plus_new(t_symbol *s, t_int argc, t_atom* argv)
+{
+ int i;
+
+ t_plus *x = (t_plus *)pd_new(plus_class);
+ x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ for(i = 2; i < argc; i++) /* create additional inlets, if any */
+ {
+ floatinlet_new(&x->x_ob, &x->x_plusvalue[i]);
+ }
+ x->x_outlet = outlet_new(&x->x_ob, gensym("float"));
+
+ for(i = 0; i < argc; i++)
+ {
+ x->x_plusvalue[i] = atom_getfloatarg(i, argc, argv);;
+ }
+ x->x_numvalues = i;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void plus_setup(void)
+{
+ plus_class = class_new(gensym("plus"), (t_newmethod)plus_new,
+ 0, sizeof(t_plus), 0, A_GIMME, 0);
+ class_addfloat(plus_class, plus_float);
+ class_addmethod(plus_class, (t_method)plus_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addbang(plus_class, (t_method)plus_bang);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_plus_setup(void)
+{
+ plus_class = class_new(gensym("maxlib_plus"), (t_newmethod)plus_new,
+ 0, sizeof(t_plus), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)plus_new, gensym("plus"), A_GIMME, 0);
+ class_addfloat(plus_class, plus_float);
+ class_addmethod(plus_class, (t_method)plus_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addbang(plus_class, (t_method)plus_bang);
+ class_sethelpsymbol(plus_class, gensym("maxlib/plus-help.pd"));
+}
+#endif
diff --git a/poisson.c b/poisson.c
index ce2e33b..499886c 100644
--- a/poisson.c
+++ b/poisson.c
@@ -1,91 +1,91 @@
-/* ---------------------------- rand_poisson ---------------------------------- */
-/* */
-/* rand_poisson generates a poisson distributed random variable. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-#define fran() (t_float)rand()/(t_float)RAND_MAX
-#ifndef M_PI
-#define M_PI 3.1415927
-#endif
-
-static char *version = "poisson v0.1, generates a poisson distributed random variable\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-/* -------------------------- rand_poisson ------------------------------ */
-
-static t_class *rand_poisson_class;
-
-typedef struct _rand_poisson
-{
- t_object x_obj;
- t_float x_lambda;
-} t_rand_poisson;
-
-static void *rand_poisson_new(t_floatarg f)
-{
- t_rand_poisson *x = (t_rand_poisson *)pd_new(rand_poisson_class);
- srand( (unsigned)time( NULL ) );
- floatinlet_new(&x->x_obj, &x->x_lambda);
- outlet_new(&x->x_obj, &s_float);
- x->x_lambda = f;
- return (x);
-}
-
-static void rand_poisson_bang(t_rand_poisson *x)
-{
- t_float u, v;
- t_int n = 0;
- v = exp(-x->x_lambda);
- u = fran();
- while(u > v)
- {
- u *= fran();
- n++;
- }
- outlet_float(x->x_obj.ob_outlet, n);
-}
-
-#ifndef MAXLIB
-void poisson_setup(void)
-{
- rand_poisson_class = class_new(gensym("poisson"), (t_newmethod)rand_poisson_new, 0,
- sizeof(t_rand_poisson), 0, A_DEFFLOAT, 0);
- class_addbang(rand_poisson_class, rand_poisson_bang);
- class_sethelpsymbol(rand_poisson_class, gensym("poisson-help.pd"));
- post(version);
-}
-#else
-void maxlib_poisson_setup(void)
-{
- rand_poisson_class = class_new(gensym("maxlib_poisson"), (t_newmethod)rand_poisson_new, 0,
- sizeof(t_rand_poisson), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)rand_poisson_new, gensym("poisson"), A_DEFFLOAT, 0);
- class_addbang(rand_poisson_class, rand_poisson_bang);
- class_sethelpsymbol(rand_poisson_class, gensym("maxlib/poisson-help.pd"));
-}
-#endif
+/* ---------------------------- rand_poisson ---------------------------------- */
+/* */
+/* rand_poisson generates a poisson distributed random variable. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+
+#define fran() (t_float)rand()/(t_float)RAND_MAX
+#ifndef M_PI
+#define M_PI 3.1415927
+#endif
+
+static char *version = "poisson v0.1, generates a poisson distributed random variable\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- rand_poisson ------------------------------ */
+
+static t_class *rand_poisson_class;
+
+typedef struct _rand_poisson
+{
+ t_object x_obj;
+ t_float x_lambda;
+} t_rand_poisson;
+
+static void *rand_poisson_new(t_floatarg f)
+{
+ t_rand_poisson *x = (t_rand_poisson *)pd_new(rand_poisson_class);
+ srand( (unsigned)time( NULL ) );
+ floatinlet_new(&x->x_obj, &x->x_lambda);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_lambda = f;
+ return (x);
+}
+
+static void rand_poisson_bang(t_rand_poisson *x)
+{
+ t_float u, v;
+ t_int n = 0;
+ v = exp(-x->x_lambda);
+ u = fran();
+ while(u > v)
+ {
+ u *= fran();
+ n++;
+ }
+ outlet_float(x->x_obj.ob_outlet, n);
+}
+
+#ifndef MAXLIB
+void poisson_setup(void)
+{
+ rand_poisson_class = class_new(gensym("poisson"), (t_newmethod)rand_poisson_new, 0,
+ sizeof(t_rand_poisson), 0, A_DEFFLOAT, 0);
+ class_addbang(rand_poisson_class, rand_poisson_bang);
+ class_sethelpsymbol(rand_poisson_class, gensym("poisson-help.pd"));
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_poisson_setup(void)
+{
+ rand_poisson_class = class_new(gensym("maxlib_poisson"), (t_newmethod)rand_poisson_new, 0,
+ sizeof(t_rand_poisson), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)rand_poisson_new, gensym("poisson"), A_DEFFLOAT, 0);
+ class_addbang(rand_poisson_class, rand_poisson_bang);
+ class_sethelpsymbol(rand_poisson_class, gensym("maxlib/poisson-help.pd"));
+}
+#endif
diff --git a/pong.c b/pong.c
index a30e892..6ee6a24 100644
--- a/pong.c
+++ b/pong.c
@@ -1,332 +1,332 @@
-/* --------------------------- pong ------------------------------------------ */
-/* */
-/* A virtual bouncing ball. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Based on pong (for Max) version 1.5 written by Richard Dudas. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-
-static char *version = "pong v0.1, ported by Olaf Matthes <olaf.matthes@gmx.de>\n"
- " written for Max by Richard Dudas";
-
-typedef struct pong
-{
- t_object x_obj;
- t_outlet *p_bounceout;
- t_outlet *p_handout;
- t_outlet *p_velout;
- t_outlet *p_heightout;
- t_clock *p_klok;
-
- t_int p_ms; // ms count
- t_float p_time; // current time div by warp
- t_float p_timegrain; // timegrain in seconds
- t_float p_timegrainin; // timegrain in ms
- t_float p_warp; // timewarp in ms
-
- t_float p_dinit; // init distance
- t_float p_vinit; // init velocity
- t_float p_ainit; // base acceleration def -100
- t_float p_damping; // realtime multiplicative damping
- t_float p_dhand; // virtual hand distance
- t_float p_force; // force of hand 1.0 = no force
-
- t_float p_accel; // current accel value
- t_float p_vi; // current velocity
- t_float p_di; // current distance
- t_float p_dt; // distance out
- t_float p_dtprev; // previous distance out for accel computation
- t_float p_vt; // velocity out
- t_int p_prevchg; // for logical transition
-} t_pong;
-
-/* ---------------------------------------------------------- */
-/* ---- this stuff is mainly for the timer, on off etc... --- */
-/* ---------------------------------------------------------- */
-
-static void pong_reset(t_pong *x)
-{
- x->p_di = x->p_dinit;
- x->p_dt = x->p_dinit; // added
- x->p_dtprev = x->p_dinit; // added
- x->p_vi = x->p_vinit;
- x->p_vt = x->p_vinit; // added
- x->p_ms = 0;
- x->p_time = 0.;
- x->p_ainit = -100.; // added, but currently disabled
- x->p_accel = -100.; // reactivated (?)
- x->p_damping = 1.; // i.e. no initial damping
- x->p_prevchg = 0; // added
-
-/* x->p_ms = 0;
- x->p_time = 0.;
- x->p_timegrain = 0.05; // if ms grain = 50
- x->p_timegrainin = 50;
-
- x->p_vinit = 0.;
- x->p_dinit = 100.;
- x->p_ainit = -100.;
- x->p_damping = 1.; // i.e. no initial damping
- x->p_dhand = 100.;
- x->p_force = 1.; // i.e. hand does nothing initially
-
- x->p_accel = -100.;
- x->p_vi = 0.;
- x->p_di = 100.;
-
- x->p_dt = 100.; // changed from 0 to 100
- x->p_dtprev = 100.; // changed from 0 to 100
- x->p_vt = 0.;
- x->p_prevchg = 0;
-*/
-}
-
-/* ---------------------------------------------------------- */
-
-static void pong_timein(t_pong *x, t_floatarg n)
-{
- int thischg;
-
- x->p_time = n / x->p_warp;
-
- x->p_dt = ((x->p_accel * (x->p_time*x->p_time)) + (x->p_time * x->p_vi) + x->p_di);
- x->p_vt = ((x->p_dt - x->p_dtprev) / x->p_timegrain);
-
- if (x->p_dt < 0.)
- {
- x->p_dt *= -1.;
-
- x->p_di = 0.;
- x->p_vi = x->p_vt * (-1. * x->p_damping); // -1 will eventually be a damping variable
- //post("vel at bounce %f", x->p_vi);
- outlet_bang(x->p_bounceout);
- x->p_ms = 0;
- //x->p_dtprev= 0.;
- }
- //else
- x->p_dtprev = x->p_dt;
-
- /* ---------------------------------- virtual hand below ------------ */
-
- if (x->p_dt > x->p_dhand) // presuming the hand is initially equal to the dinit
- thischg = 1;
- else
- thischg = 0;
-
- if (thischg != x->p_prevchg)
- {
- x->p_ms = 0;
- x->p_vi = x->p_vt;
- x->p_di = x->p_dhand;
-
- if (thischg == 0)
- {
- x->p_accel = -100.; // x->p_ainit in lieu of -100.
- outlet_float(x->p_handout, 0);
- }
- else
- {
- x->p_accel = (x->p_force * -100.); // x->p_ainit in lieu of -100.
- outlet_float(x->p_handout, 1);
- }
- }
-
- x->p_prevchg = thischg;
- outlet_float(x->p_velout, x->p_vt);
- outlet_float(x->p_heightout, x->p_dt);
-}
-
-static void pong_onoff(t_pong *x, t_floatarg n)
-{
- if (n != 0)
- clock_delay(x->p_klok, 0);
- else
- clock_unset(x->p_klok);
-}
-
-/* ---------------------------------------------------------- */
-
-static void pong_bang(t_pong *x)
-{
- x->p_ms = 0;
- clock_delay(x->p_klok, 0);
-}
-
-static void pong_stop(t_pong *x)
-{
- clock_unset(x->p_klok);
-}
-
-/* ---------------------------------------------------------- */
-
-static void pong_tick(t_pong *x)
-{
- clock_delay(x->p_klok, (t_int)x->p_timegrainin);
- pong_timein(x, x->p_ms);
- //outlet_float(x->p_heightout, (float)x->p_ms);
- x->p_ms = x->p_ms + x->p_timegrainin;
-}
-
-/* ---------------------------------------------------------- */
-
-static void pong_tgrain(t_pong *x, t_floatarg n)
-{
- x->p_timegrain = n / x->p_warp;
- x->p_timegrainin = n;
- post("timegrain %f", x->p_timegrain);
-}
-
-/* ---------------------------------------------------------- */
-
-static void pong_warpin(t_pong *x, t_floatarg n)
-{
- x->p_warp = n;
- x->p_timegrain = x->p_timegrainin / x->p_warp;
- post("timewarp %f ms = one sec", x->p_warp);
-}
-
-/* ---------------------------------------------------------- */
-/* ----- these are to receive and store the init values ----- */
-/* ---------------------------------------------------------- */
-
-static void pong_initdist(t_pong *x, t_floatarg n)
-{
- x->p_dinit = n;
-}
-
-static void pong_initvel(t_pong *x, t_floatarg n)
-{
- x->p_vinit = n;
-}
-
-static void pong_damp(t_pong *x, t_floatarg n)
-{
- x->p_damping = n;
-}
-
-/* ---------------------------------------------------------- */
-
-static void pong_baseacc(t_pong *x, t_floatarg n)
-{
- //post ("baseaccel currently disabled", 0);
- x->p_ainit = n;
- x->p_accel = x->p_ainit;
-}
-
-/* ---------------------------------------------------------- */
-
-static void pong_hand(t_pong *x, t_floatarg n)
-{
- x->p_dhand = n;
-}
-
-static void pong_force(t_pong *x, t_floatarg n)
-{
- x->p_force = n;
-}
-
-/* ---------------------------------------------------------- */
-
-
-static t_class *pong_class;
-
-static void *pong_new(t_floatarg n)
-{
- t_pong *x = (t_pong *)pd_new(pong_class);
-
- x->p_klok = clock_new(x, (t_method)pong_tick);
-
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("dist")); // distance
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("velo")); // velocity
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("damp")); // damping
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("force")); // hand force 1.0 = no force
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("hand")); // virtual hand (distance)
-
-
- if (n > 0)
- x->p_warp = n;
- else
- x->p_warp = 1000.;
-
- x->p_ms = 0;
- x->p_time = 0.;
- x->p_timegrain = 0.05; // if ms grain = 50
- x->p_timegrainin = 50.0;
-
- x->p_vinit = 0.;
- x->p_dinit = 100.;
- x->p_ainit = -100.;
- x->p_damping = 1.; // i.e. no initial damping
- x->p_dhand = 100.;
- x->p_force = 1.; // i.e. hand does nothing initially
-
- x->p_accel = -100.;
- x->p_vi = 0.;
- x->p_di = 100.;
-
- x->p_dt = 100.; // changed from 0 to 100
- x->p_dtprev = 100.; // changed from 0 to 100
- x->p_vt = 0.;
- x->p_prevchg = 0;
-
- x->p_bounceout = outlet_new(&x->x_obj, gensym("bang"));
- x->p_handout = outlet_new(&x->x_obj, gensym("float"));
- x->p_velout = outlet_new(&x->x_obj, gensym("float"));
- x->p_heightout = outlet_new(&x->x_obj, gensym("float"));
-
- return (x);
-}
-
-#ifndef MAXLIB
-void pong_setup(void)
-{
- pong_class = class_new(gensym("pong"), (t_newmethod)pong_new,
- 0, sizeof(t_pong), 0, A_DEFFLOAT, 0);
-#else
-void maxlib_pong_setup(void)
-{
- pong_class = class_new(gensym("maxlib_pong"), (t_newmethod)pong_new,
- 0, sizeof(t_pong), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)pong_new, gensym("pong"), A_DEFFLOAT, 0);
-#endif
- /* method handlers for inlets */
- class_addmethod(pong_class, (t_method)pong_initdist, gensym("dist"), A_FLOAT, 0);
- class_addmethod(pong_class, (t_method)pong_initvel, gensym("velo"), A_FLOAT, 0);
- class_addmethod(pong_class, (t_method)pong_damp, gensym("damp"), A_FLOAT, 0);
- class_addmethod(pong_class, (t_method)pong_force, gensym("force"), A_FLOAT, 0);
- class_addmethod(pong_class, (t_method)pong_hand, gensym("hand"), A_FLOAT, 0);
- /* method handlers for other messages to first inlet */
- class_addmethod(pong_class, (t_method)pong_tgrain, gensym("timegrain"), A_FLOAT, 0);
- class_addmethod(pong_class, (t_method)pong_warpin, gensym("timewarp"), A_FLOAT, 0);
- class_addmethod(pong_class, (t_method)pong_baseacc, gensym("baseaccel"), A_FLOAT, 0);
- class_addmethod(pong_class, (t_method)pong_reset, gensym("reset"), 0);
- class_addmethod(pong_class, (t_method)pong_stop, gensym("stop"), 0);
-
- class_addfloat(pong_class, pong_onoff);
- class_addbang(pong_class, pong_bang);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_sethelpsymbol(pong_class, gensym("maxlib/pong-help.pd"));
-#endif
-}
+/* --------------------------- pong ------------------------------------------ */
+/* */
+/* A virtual bouncing ball. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Based on pong (for Max) version 1.5 written by Richard Dudas. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+static char *version = "pong v0.1, ported by Olaf Matthes <olaf.matthes@gmx.de>\n"
+ " written for Max by Richard Dudas";
+
+typedef struct pong
+{
+ t_object x_obj;
+ t_outlet *p_bounceout;
+ t_outlet *p_handout;
+ t_outlet *p_velout;
+ t_outlet *p_heightout;
+ t_clock *p_klok;
+
+ t_int p_ms; // ms count
+ t_float p_time; // current time div by warp
+ t_float p_timegrain; // timegrain in seconds
+ t_float p_timegrainin; // timegrain in ms
+ t_float p_warp; // timewarp in ms
+
+ t_float p_dinit; // init distance
+ t_float p_vinit; // init velocity
+ t_float p_ainit; // base acceleration def -100
+ t_float p_damping; // realtime multiplicative damping
+ t_float p_dhand; // virtual hand distance
+ t_float p_force; // force of hand 1.0 = no force
+
+ t_float p_accel; // current accel value
+ t_float p_vi; // current velocity
+ t_float p_di; // current distance
+ t_float p_dt; // distance out
+ t_float p_dtprev; // previous distance out for accel computation
+ t_float p_vt; // velocity out
+ t_int p_prevchg; // for logical transition
+} t_pong;
+
+/* ---------------------------------------------------------- */
+/* ---- this stuff is mainly for the timer, on off etc... --- */
+/* ---------------------------------------------------------- */
+
+static void pong_reset(t_pong *x)
+{
+ x->p_di = x->p_dinit;
+ x->p_dt = x->p_dinit; // added
+ x->p_dtprev = x->p_dinit; // added
+ x->p_vi = x->p_vinit;
+ x->p_vt = x->p_vinit; // added
+ x->p_ms = 0;
+ x->p_time = 0.;
+ x->p_ainit = -100.; // added, but currently disabled
+ x->p_accel = -100.; // reactivated (?)
+ x->p_damping = 1.; // i.e. no initial damping
+ x->p_prevchg = 0; // added
+
+/* x->p_ms = 0;
+ x->p_time = 0.;
+ x->p_timegrain = 0.05; // if ms grain = 50
+ x->p_timegrainin = 50;
+
+ x->p_vinit = 0.;
+ x->p_dinit = 100.;
+ x->p_ainit = -100.;
+ x->p_damping = 1.; // i.e. no initial damping
+ x->p_dhand = 100.;
+ x->p_force = 1.; // i.e. hand does nothing initially
+
+ x->p_accel = -100.;
+ x->p_vi = 0.;
+ x->p_di = 100.;
+
+ x->p_dt = 100.; // changed from 0 to 100
+ x->p_dtprev = 100.; // changed from 0 to 100
+ x->p_vt = 0.;
+ x->p_prevchg = 0;
+*/
+}
+
+/* ---------------------------------------------------------- */
+
+static void pong_timein(t_pong *x, t_floatarg n)
+{
+ int thischg;
+
+ x->p_time = n / x->p_warp;
+
+ x->p_dt = ((x->p_accel * (x->p_time*x->p_time)) + (x->p_time * x->p_vi) + x->p_di);
+ x->p_vt = ((x->p_dt - x->p_dtprev) / x->p_timegrain);
+
+ if (x->p_dt < 0.)
+ {
+ x->p_dt *= -1.;
+
+ x->p_di = 0.;
+ x->p_vi = x->p_vt * (-1. * x->p_damping); // -1 will eventually be a damping variable
+ //post("vel at bounce %f", x->p_vi);
+ outlet_bang(x->p_bounceout);
+ x->p_ms = 0;
+ //x->p_dtprev= 0.;
+ }
+ //else
+ x->p_dtprev = x->p_dt;
+
+ /* ---------------------------------- virtual hand below ------------ */
+
+ if (x->p_dt > x->p_dhand) // presuming the hand is initially equal to the dinit
+ thischg = 1;
+ else
+ thischg = 0;
+
+ if (thischg != x->p_prevchg)
+ {
+ x->p_ms = 0;
+ x->p_vi = x->p_vt;
+ x->p_di = x->p_dhand;
+
+ if (thischg == 0)
+ {
+ x->p_accel = -100.; // x->p_ainit in lieu of -100.
+ outlet_float(x->p_handout, 0);
+ }
+ else
+ {
+ x->p_accel = (x->p_force * -100.); // x->p_ainit in lieu of -100.
+ outlet_float(x->p_handout, 1);
+ }
+ }
+
+ x->p_prevchg = thischg;
+ outlet_float(x->p_velout, x->p_vt);
+ outlet_float(x->p_heightout, x->p_dt);
+}
+
+static void pong_onoff(t_pong *x, t_floatarg n)
+{
+ if (n != 0)
+ clock_delay(x->p_klok, 0);
+ else
+ clock_unset(x->p_klok);
+}
+
+/* ---------------------------------------------------------- */
+
+static void pong_bang(t_pong *x)
+{
+ x->p_ms = 0;
+ clock_delay(x->p_klok, 0);
+}
+
+static void pong_stop(t_pong *x)
+{
+ clock_unset(x->p_klok);
+}
+
+/* ---------------------------------------------------------- */
+
+static void pong_tick(t_pong *x)
+{
+ clock_delay(x->p_klok, (t_int)x->p_timegrainin);
+ pong_timein(x, x->p_ms);
+ //outlet_float(x->p_heightout, (float)x->p_ms);
+ x->p_ms = x->p_ms + x->p_timegrainin;
+}
+
+/* ---------------------------------------------------------- */
+
+static void pong_tgrain(t_pong *x, t_floatarg n)
+{
+ x->p_timegrain = n / x->p_warp;
+ x->p_timegrainin = n;
+ post("timegrain %f", x->p_timegrain);
+}
+
+/* ---------------------------------------------------------- */
+
+static void pong_warpin(t_pong *x, t_floatarg n)
+{
+ x->p_warp = n;
+ x->p_timegrain = x->p_timegrainin / x->p_warp;
+ post("timewarp %f ms = one sec", x->p_warp);
+}
+
+/* ---------------------------------------------------------- */
+/* ----- these are to receive and store the init values ----- */
+/* ---------------------------------------------------------- */
+
+static void pong_initdist(t_pong *x, t_floatarg n)
+{
+ x->p_dinit = n;
+}
+
+static void pong_initvel(t_pong *x, t_floatarg n)
+{
+ x->p_vinit = n;
+}
+
+static void pong_damp(t_pong *x, t_floatarg n)
+{
+ x->p_damping = n;
+}
+
+/* ---------------------------------------------------------- */
+
+static void pong_baseacc(t_pong *x, t_floatarg n)
+{
+ //post ("baseaccel currently disabled", 0);
+ x->p_ainit = n;
+ x->p_accel = x->p_ainit;
+}
+
+/* ---------------------------------------------------------- */
+
+static void pong_hand(t_pong *x, t_floatarg n)
+{
+ x->p_dhand = n;
+}
+
+static void pong_force(t_pong *x, t_floatarg n)
+{
+ x->p_force = n;
+}
+
+/* ---------------------------------------------------------- */
+
+
+static t_class *pong_class;
+
+static void *pong_new(t_floatarg n)
+{
+ t_pong *x = (t_pong *)pd_new(pong_class);
+
+ x->p_klok = clock_new(x, (t_method)pong_tick);
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("dist")); // distance
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("velo")); // velocity
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("damp")); // damping
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("force")); // hand force 1.0 = no force
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("hand")); // virtual hand (distance)
+
+
+ if (n > 0)
+ x->p_warp = n;
+ else
+ x->p_warp = 1000.;
+
+ x->p_ms = 0;
+ x->p_time = 0.;
+ x->p_timegrain = 0.05; // if ms grain = 50
+ x->p_timegrainin = 50.0;
+
+ x->p_vinit = 0.;
+ x->p_dinit = 100.;
+ x->p_ainit = -100.;
+ x->p_damping = 1.; // i.e. no initial damping
+ x->p_dhand = 100.;
+ x->p_force = 1.; // i.e. hand does nothing initially
+
+ x->p_accel = -100.;
+ x->p_vi = 0.;
+ x->p_di = 100.;
+
+ x->p_dt = 100.; // changed from 0 to 100
+ x->p_dtprev = 100.; // changed from 0 to 100
+ x->p_vt = 0.;
+ x->p_prevchg = 0;
+
+ x->p_bounceout = outlet_new(&x->x_obj, gensym("bang"));
+ x->p_handout = outlet_new(&x->x_obj, gensym("float"));
+ x->p_velout = outlet_new(&x->x_obj, gensym("float"));
+ x->p_heightout = outlet_new(&x->x_obj, gensym("float"));
+
+ return (x);
+}
+
+#ifndef MAXLIB
+void pong_setup(void)
+{
+ pong_class = class_new(gensym("pong"), (t_newmethod)pong_new,
+ 0, sizeof(t_pong), 0, A_DEFFLOAT, 0);
+#else
+void maxlib_pong_setup(void)
+{
+ pong_class = class_new(gensym("maxlib_pong"), (t_newmethod)pong_new,
+ 0, sizeof(t_pong), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)pong_new, gensym("pong"), A_DEFFLOAT, 0);
+#endif
+ /* method handlers for inlets */
+ class_addmethod(pong_class, (t_method)pong_initdist, gensym("dist"), A_FLOAT, 0);
+ class_addmethod(pong_class, (t_method)pong_initvel, gensym("velo"), A_FLOAT, 0);
+ class_addmethod(pong_class, (t_method)pong_damp, gensym("damp"), A_FLOAT, 0);
+ class_addmethod(pong_class, (t_method)pong_force, gensym("force"), A_FLOAT, 0);
+ class_addmethod(pong_class, (t_method)pong_hand, gensym("hand"), A_FLOAT, 0);
+ /* method handlers for other messages to first inlet */
+ class_addmethod(pong_class, (t_method)pong_tgrain, gensym("timegrain"), A_FLOAT, 0);
+ class_addmethod(pong_class, (t_method)pong_warpin, gensym("timewarp"), A_FLOAT, 0);
+ class_addmethod(pong_class, (t_method)pong_baseacc, gensym("baseaccel"), A_FLOAT, 0);
+ class_addmethod(pong_class, (t_method)pong_reset, gensym("reset"), 0);
+ class_addmethod(pong_class, (t_method)pong_stop, gensym("stop"), 0);
+
+ class_addfloat(pong_class, pong_onoff);
+ class_addbang(pong_class, pong_bang);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(pong_class, gensym("maxlib/pong-help.pd"));
+#endif
+}
diff --git a/pulse.c b/pulse.c
index 4205315..6b7ca62 100644
--- a/pulse.c
+++ b/pulse.c
@@ -1,301 +1,301 @@
-/* --------------------------- pong ------------------------------------------ */
-/* */
-/* A more accurate replacement for the tempo object. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Based on pulse for Max written by James McCartney. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-/* pulse.c ---- a more accurate replacement for the tempo object */
-/* updated for CW 68K / PPC summer 96 -RD */
-/* written for Max by James McCartney */
-
-#include "m_pd.h"
-#include <stdio.h>
-
-static char *version = "pulse v0.1b, written by James McCartney for Max <james@clyde.as.utexas.edu>\n"
- " ported to Pd by Olaf Matthes <olaf.matthes@gmx.de>";
-
-/* Pulse object data structure */
-typedef struct pulse
-{
- t_object p_ob;
- t_clock *p_clock;
- t_outlet *p_out1; /* outlet */
- t_outlet *p_out2; /* outlet */
- t_int p_onoff, p_changenumer, p_changedenom;
- t_int p_tempo, p_durnumer, p_durdenom, p_maxbeats, p_count;
- double p_starttime, p_endtime, p_startremain, p_endremain, p_mspbquotient;
- t_int p_newdurnumer, p_newdurdenom;
- t_int p_mspbnumer, p_mspbdenom, p_mspbremainder;
-} Pulse;
-
-static t_class *pulse_class;
-
-static void durcalc(Pulse *x)
-{
- /* recalc duration */
- x->p_mspbnumer = 240000 * x->p_durnumer;
- if (x->p_tempo * x->p_durdenom != 0) /* bug fix by Frank Barknecht */
- x->p_mspbdenom = x->p_tempo * x->p_durdenom;
- x->p_mspbquotient = x->p_mspbnumer / x->p_mspbdenom;
- x->p_mspbremainder = x->p_mspbnumer % x->p_mspbdenom;
- if (x->p_mspbquotient < 5) {
- x->p_mspbquotient = 5;
- x->p_mspbremainder = 0;
- }
-}
-
-static void pulse_onoff(Pulse *x, t_floatarg f)
-{
- int i = (int)f;
- if (i && !x->p_onoff) {
- x->p_onoff = 1;
- x->p_count = 0;
- outlet_float(x->p_out1, x->p_count);
- if (x->p_changedenom) {
- x->p_durdenom = x->p_newdurdenom;
- x->p_changedenom = 0;
- }
- if (x->p_changenumer) {
- x->p_durnumer = x->p_newdurnumer;
- x->p_changenumer = 0;
- }
- durcalc(x);
- x->p_startremain = 0;
- x->p_endremain = x->p_mspbremainder;
- x->p_starttime = clock_getlogicaltime();
- x->p_endtime = x->p_starttime + x->p_mspbquotient;
- // clock_set(x->p_clock, x->p_endtime);
- clock_delay(x->p_clock, x->p_mspbquotient);
- } else if (i==0 && x->p_onoff) {
- x->p_onoff = 0;
- clock_unset(x->p_clock);
- }
-}
-
-static void pulse_bang(Pulse *x)
-{
- if (!x->p_onoff) {
- x->p_onoff = 1;
- x->p_count = 0;
- outlet_float(x->p_out1, x->p_count);
- if (x->p_changedenom) {
- x->p_durdenom = x->p_newdurdenom;
- x->p_changedenom = 0;
- }
- if (x->p_changenumer) {
- x->p_durnumer = x->p_newdurnumer;
- x->p_changenumer = 0;
- }
- durcalc(x);
- x->p_startremain = 0;
- x->p_endremain = x->p_mspbremainder;
- x->p_starttime = clock_getlogicaltime();
- x->p_endtime = x->p_starttime + x->p_mspbquotient;
- clock_set(x->p_clock, x->p_endtime);
- } else {
- x->p_onoff = 0;
- clock_unset(x->p_clock);
- }
-}
-
-/* clock tick routine */
-static void pulse_tick(Pulse *x)
-{
- x->p_count ++;
- if ((x->p_maxbeats > 0) && (x->p_count >= x->p_maxbeats)) { /* turn off time */
- x->p_onoff = 0;
- outlet_bang(x->p_out2);
- } else {
- outlet_float(x->p_out1, x->p_count);
- x->p_startremain = x->p_endremain; /* save in case we have to re do it */
- if (x->p_changenumer || x->p_changedenom) { /* duration changed */
- if (x->p_changedenom) {
- /* this statement may cause a slight drift of (1/(tempo*denom) msecs) */
- x->p_startremain = (x->p_startremain * x->p_newdurdenom + (x->p_durdenom>>1))
- /x->p_durdenom;
- x->p_durdenom = x->p_newdurdenom;
- x->p_changedenom = 0;
- }
- if (x->p_changenumer) {
- x->p_durnumer = x->p_newdurnumer;
- x->p_changenumer = 0;
- }
- durcalc(x);
- }
- x->p_endremain = x->p_startremain + x->p_mspbremainder;
- x->p_starttime = x->p_endtime;
- x->p_endtime = x->p_starttime + x->p_mspbquotient;
- if (x->p_endremain >= x->p_mspbdenom) {
- x->p_endremain -= x->p_mspbdenom;
- x->p_endtime ++;
- }
- // clock_set(x->p_clock, x->p_endtime);
- clock_delay(x->p_clock, x->p_mspbquotient);
- }
-}
-
-/* deal with tempo change */
-static void pulse_tempo(Pulse *x, t_floatarg t)
-{
- double time, msecdur, tickdur, fracremain;
- t_int fracnumer, fracquotient, oldtempo;
- oldtempo = x->p_tempo;
- x->p_tempo = (t<5) ? 5 : ((t>500) ? 500 : t);
- if (x->p_onoff) {
- /* calculate fraction of the beat we have done */
- time = clock_getlogicaltime();
- if (time != x->p_endtime) {
- /* if pulse_tempo is called as a result of a call from pulse_tick
- (call chain from outlet_float())
- then this stuff doesn't need to be done (time will == x->p_endtime)
- */
- msecdur = time - x->p_starttime;
- tickdur = msecdur * x->p_mspbdenom - x->p_startremain;
- fracnumer = (t_int)(x->p_mspbnumer - tickdur);
-
- durcalc(x);
-
- /* calculate end time */
- fracquotient = fracnumer / x->p_mspbdenom;
- fracremain = fracnumer % x->p_mspbdenom;
-
- x->p_endtime = time + fracquotient;
- x->p_endremain = fracremain;
-
- /* recalculate starttime so future tempo changes work */
- x->p_starttime = x->p_endtime - x->p_mspbquotient;
- x->p_startremain = x->p_mspbdenom - x->p_mspbremainder + fracremain;
- if (x->p_mspbremainder > fracremain) {
- x->p_startremain = x->p_mspbdenom - x->p_mspbremainder + fracremain;
- x->p_starttime --;
- } else {
- x->p_startremain = fracremain - x->p_mspbremainder;
- }
- clock_unset(x->p_clock);
- clock_set(x->p_clock, x->p_endtime);
- // clock_delay(x->p_clock, fracquotient);
- }
- }
-}
-
-static void pulse_numer(Pulse *x, t_floatarg n)
-{
- int i = (t_int)n;
- if(i >= 0)
- {
- if (x->p_onoff) {
- if (x->p_durnumer != i) {
- x->p_changenumer = 1;
- x->p_newdurnumer = i;
- }
- } else {
- x->p_durnumer = i;
- }
- }
-}
-
-static void pulse_denom(Pulse *x, t_floatarg n)
-{
- int i = (t_int)n;
- if(i >= 0)
- {
- if (x->p_onoff) {
- if (x->p_durdenom != i) {
- x->p_changedenom = 1;
- x->p_newdurdenom = i;
- }
- } else {
- x->p_durdenom = i;
- }
- }
-}
-
-static void pulse_beat(Pulse *x, t_floatarg n)
-{
- int i = (t_int)n;
- if(i >= 0)
- {
- x->p_maxbeats = i;
- }
-}
-
-
-static void pulse_free(Pulse *x)
-{
- clock_free(x->p_clock);
-}
-
-
-/* function run to create a new instance of the Pulse class */
-static void *pulse_new(t_floatarg t, t_floatarg n, t_floatarg d, t_floatarg b)
-{
- Pulse *x;
-
- x = (Pulse *)pd_new(pulse_class); /* allocates memory and sticks in an inlet */
-
- inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("tempo"));
- inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("numer"));
- inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("denom"));
- inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("beat"));
- x->p_out1 = outlet_new(&x->p_ob, gensym("float"));
- x->p_out2 = outlet_new(&x->p_ob, gensym("float"));
- x->p_clock = clock_new(x, (t_method)pulse_tick);
- x->p_tempo = (t==0) ? 120 : ((t<5) ? 5 : ((t>500) ? 500 : t));
- x->p_durnumer = (n<=0) ? 1 : n;
- x->p_durdenom = (d<=0) ? 4 : d;
- x->p_maxbeats = (b<=0) ? 0 : b;
- x->p_changenumer = 0;
- x->p_changedenom = 0;
- x->p_onoff = 0;
-
- return (x); /* always return a copy of the created object */
-}
-
-#ifndef MAXLIB
-void pulse_setup(void)
-{
- pulse_class = class_new(gensym("pulse"), (t_newmethod)pulse_new,
- (t_method)pulse_free, sizeof(Pulse), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(pulse_class, (t_method)pulse_beat, gensym("beat"), A_FLOAT, 0);
- class_addmethod(pulse_class, (t_method)pulse_denom, gensym("denom"), A_FLOAT, 0);
- class_addmethod(pulse_class, (t_method)pulse_numer, gensym("numer"), A_FLOAT, 0);
- class_addmethod(pulse_class, (t_method)pulse_tempo, gensym("tempo"), A_FLOAT, 0);
- class_addfloat(pulse_class, pulse_onoff);
- class_addbang(pulse_class, pulse_bang);
-
- post(version);
-}
-#else
-void maxlib_pulse_setup(void)
-{
- pulse_class = class_new(gensym("maxlib_pulse"), (t_newmethod)pulse_new,
- (t_method)pulse_free, sizeof(Pulse), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)pulse_new, gensym("pulse"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(pulse_class, (t_method)pulse_beat, gensym("beat"), A_FLOAT, 0);
- class_addmethod(pulse_class, (t_method)pulse_denom, gensym("denom"), A_FLOAT, 0);
- class_addmethod(pulse_class, (t_method)pulse_numer, gensym("numer"), A_FLOAT, 0);
- class_addmethod(pulse_class, (t_method)pulse_tempo, gensym("tempo"), A_FLOAT, 0);
- class_addfloat(pulse_class, pulse_onoff);
- class_addbang(pulse_class, pulse_bang);
- class_sethelpsymbol(pulse_class, gensym("maxlib/pulse-help.pd"));
-}
-#endif
+/* --------------------------- pong ------------------------------------------ */
+/* */
+/* A more accurate replacement for the tempo object. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Based on pulse for Max written by James McCartney. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+/* pulse.c ---- a more accurate replacement for the tempo object */
+/* updated for CW 68K / PPC summer 96 -RD */
+/* written for Max by James McCartney */
+
+#include "m_pd.h"
+#include <stdio.h>
+
+static char *version = "pulse v0.1b, written by James McCartney for Max <james@clyde.as.utexas.edu>\n"
+ " ported to Pd by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* Pulse object data structure */
+typedef struct pulse
+{
+ t_object p_ob;
+ t_clock *p_clock;
+ t_outlet *p_out1; /* outlet */
+ t_outlet *p_out2; /* outlet */
+ t_int p_onoff, p_changenumer, p_changedenom;
+ t_int p_tempo, p_durnumer, p_durdenom, p_maxbeats, p_count;
+ double p_starttime, p_endtime, p_startremain, p_endremain, p_mspbquotient;
+ t_int p_newdurnumer, p_newdurdenom;
+ t_int p_mspbnumer, p_mspbdenom, p_mspbremainder;
+} Pulse;
+
+static t_class *pulse_class;
+
+static void durcalc(Pulse *x)
+{
+ /* recalc duration */
+ x->p_mspbnumer = 240000 * x->p_durnumer;
+ if (x->p_tempo * x->p_durdenom != 0) /* bug fix by Frank Barknecht */
+ x->p_mspbdenom = x->p_tempo * x->p_durdenom;
+ x->p_mspbquotient = x->p_mspbnumer / x->p_mspbdenom;
+ x->p_mspbremainder = x->p_mspbnumer % x->p_mspbdenom;
+ if (x->p_mspbquotient < 5) {
+ x->p_mspbquotient = 5;
+ x->p_mspbremainder = 0;
+ }
+}
+
+static void pulse_onoff(Pulse *x, t_floatarg f)
+{
+ int i = (int)f;
+ if (i && !x->p_onoff) {
+ x->p_onoff = 1;
+ x->p_count = 0;
+ outlet_float(x->p_out1, x->p_count);
+ if (x->p_changedenom) {
+ x->p_durdenom = x->p_newdurdenom;
+ x->p_changedenom = 0;
+ }
+ if (x->p_changenumer) {
+ x->p_durnumer = x->p_newdurnumer;
+ x->p_changenumer = 0;
+ }
+ durcalc(x);
+ x->p_startremain = 0;
+ x->p_endremain = x->p_mspbremainder;
+ x->p_starttime = clock_getlogicaltime();
+ x->p_endtime = x->p_starttime + x->p_mspbquotient;
+ // clock_set(x->p_clock, x->p_endtime);
+ clock_delay(x->p_clock, x->p_mspbquotient);
+ } else if (i==0 && x->p_onoff) {
+ x->p_onoff = 0;
+ clock_unset(x->p_clock);
+ }
+}
+
+static void pulse_bang(Pulse *x)
+{
+ if (!x->p_onoff) {
+ x->p_onoff = 1;
+ x->p_count = 0;
+ outlet_float(x->p_out1, x->p_count);
+ if (x->p_changedenom) {
+ x->p_durdenom = x->p_newdurdenom;
+ x->p_changedenom = 0;
+ }
+ if (x->p_changenumer) {
+ x->p_durnumer = x->p_newdurnumer;
+ x->p_changenumer = 0;
+ }
+ durcalc(x);
+ x->p_startremain = 0;
+ x->p_endremain = x->p_mspbremainder;
+ x->p_starttime = clock_getlogicaltime();
+ x->p_endtime = x->p_starttime + x->p_mspbquotient;
+ clock_set(x->p_clock, x->p_endtime);
+ } else {
+ x->p_onoff = 0;
+ clock_unset(x->p_clock);
+ }
+}
+
+/* clock tick routine */
+static void pulse_tick(Pulse *x)
+{
+ x->p_count ++;
+ if ((x->p_maxbeats > 0) && (x->p_count >= x->p_maxbeats)) { /* turn off time */
+ x->p_onoff = 0;
+ outlet_bang(x->p_out2);
+ } else {
+ outlet_float(x->p_out1, x->p_count);
+ x->p_startremain = x->p_endremain; /* save in case we have to re do it */
+ if (x->p_changenumer || x->p_changedenom) { /* duration changed */
+ if (x->p_changedenom) {
+ /* this statement may cause a slight drift of (1/(tempo*denom) msecs) */
+ x->p_startremain = (x->p_startremain * x->p_newdurdenom + (x->p_durdenom>>1))
+ /x->p_durdenom;
+ x->p_durdenom = x->p_newdurdenom;
+ x->p_changedenom = 0;
+ }
+ if (x->p_changenumer) {
+ x->p_durnumer = x->p_newdurnumer;
+ x->p_changenumer = 0;
+ }
+ durcalc(x);
+ }
+ x->p_endremain = x->p_startremain + x->p_mspbremainder;
+ x->p_starttime = x->p_endtime;
+ x->p_endtime = x->p_starttime + x->p_mspbquotient;
+ if (x->p_endremain >= x->p_mspbdenom) {
+ x->p_endremain -= x->p_mspbdenom;
+ x->p_endtime ++;
+ }
+ // clock_set(x->p_clock, x->p_endtime);
+ clock_delay(x->p_clock, x->p_mspbquotient);
+ }
+}
+
+/* deal with tempo change */
+static void pulse_tempo(Pulse *x, t_floatarg t)
+{
+ double time, msecdur, tickdur, fracremain;
+ t_int fracnumer, fracquotient, oldtempo;
+ oldtempo = x->p_tempo;
+ x->p_tempo = (t<5) ? 5 : ((t>500) ? 500 : t);
+ if (x->p_onoff) {
+ /* calculate fraction of the beat we have done */
+ time = clock_getlogicaltime();
+ if (time != x->p_endtime) {
+ /* if pulse_tempo is called as a result of a call from pulse_tick
+ (call chain from outlet_float())
+ then this stuff doesn't need to be done (time will == x->p_endtime)
+ */
+ msecdur = time - x->p_starttime;
+ tickdur = msecdur * x->p_mspbdenom - x->p_startremain;
+ fracnumer = (t_int)(x->p_mspbnumer - tickdur);
+
+ durcalc(x);
+
+ /* calculate end time */
+ fracquotient = fracnumer / x->p_mspbdenom;
+ fracremain = fracnumer % x->p_mspbdenom;
+
+ x->p_endtime = time + fracquotient;
+ x->p_endremain = fracremain;
+
+ /* recalculate starttime so future tempo changes work */
+ x->p_starttime = x->p_endtime - x->p_mspbquotient;
+ x->p_startremain = x->p_mspbdenom - x->p_mspbremainder + fracremain;
+ if (x->p_mspbremainder > fracremain) {
+ x->p_startremain = x->p_mspbdenom - x->p_mspbremainder + fracremain;
+ x->p_starttime --;
+ } else {
+ x->p_startremain = fracremain - x->p_mspbremainder;
+ }
+ clock_unset(x->p_clock);
+ clock_set(x->p_clock, x->p_endtime);
+ // clock_delay(x->p_clock, fracquotient);
+ }
+ }
+}
+
+static void pulse_numer(Pulse *x, t_floatarg n)
+{
+ int i = (t_int)n;
+ if(i >= 0)
+ {
+ if (x->p_onoff) {
+ if (x->p_durnumer != i) {
+ x->p_changenumer = 1;
+ x->p_newdurnumer = i;
+ }
+ } else {
+ x->p_durnumer = i;
+ }
+ }
+}
+
+static void pulse_denom(Pulse *x, t_floatarg n)
+{
+ int i = (t_int)n;
+ if(i >= 0)
+ {
+ if (x->p_onoff) {
+ if (x->p_durdenom != i) {
+ x->p_changedenom = 1;
+ x->p_newdurdenom = i;
+ }
+ } else {
+ x->p_durdenom = i;
+ }
+ }
+}
+
+static void pulse_beat(Pulse *x, t_floatarg n)
+{
+ int i = (t_int)n;
+ if(i >= 0)
+ {
+ x->p_maxbeats = i;
+ }
+}
+
+
+static void pulse_free(Pulse *x)
+{
+ clock_free(x->p_clock);
+}
+
+
+/* function run to create a new instance of the Pulse class */
+static void *pulse_new(t_floatarg t, t_floatarg n, t_floatarg d, t_floatarg b)
+{
+ Pulse *x;
+
+ x = (Pulse *)pd_new(pulse_class); /* allocates memory and sticks in an inlet */
+
+ inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("tempo"));
+ inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("numer"));
+ inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("denom"));
+ inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("beat"));
+ x->p_out1 = outlet_new(&x->p_ob, gensym("float"));
+ x->p_out2 = outlet_new(&x->p_ob, gensym("float"));
+ x->p_clock = clock_new(x, (t_method)pulse_tick);
+ x->p_tempo = (t==0) ? 120 : ((t<5) ? 5 : ((t>500) ? 500 : t));
+ x->p_durnumer = (n<=0) ? 1 : n;
+ x->p_durdenom = (d<=0) ? 4 : d;
+ x->p_maxbeats = (b<=0) ? 0 : b;
+ x->p_changenumer = 0;
+ x->p_changedenom = 0;
+ x->p_onoff = 0;
+
+ return (x); /* always return a copy of the created object */
+}
+
+#ifndef MAXLIB
+void pulse_setup(void)
+{
+ pulse_class = class_new(gensym("pulse"), (t_newmethod)pulse_new,
+ (t_method)pulse_free, sizeof(Pulse), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(pulse_class, (t_method)pulse_beat, gensym("beat"), A_FLOAT, 0);
+ class_addmethod(pulse_class, (t_method)pulse_denom, gensym("denom"), A_FLOAT, 0);
+ class_addmethod(pulse_class, (t_method)pulse_numer, gensym("numer"), A_FLOAT, 0);
+ class_addmethod(pulse_class, (t_method)pulse_tempo, gensym("tempo"), A_FLOAT, 0);
+ class_addfloat(pulse_class, pulse_onoff);
+ class_addbang(pulse_class, pulse_bang);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_pulse_setup(void)
+{
+ pulse_class = class_new(gensym("maxlib_pulse"), (t_newmethod)pulse_new,
+ (t_method)pulse_free, sizeof(Pulse), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)pulse_new, gensym("pulse"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(pulse_class, (t_method)pulse_beat, gensym("beat"), A_FLOAT, 0);
+ class_addmethod(pulse_class, (t_method)pulse_denom, gensym("denom"), A_FLOAT, 0);
+ class_addmethod(pulse_class, (t_method)pulse_numer, gensym("numer"), A_FLOAT, 0);
+ class_addmethod(pulse_class, (t_method)pulse_tempo, gensym("tempo"), A_FLOAT, 0);
+ class_addfloat(pulse_class, pulse_onoff);
+ class_addbang(pulse_class, pulse_bang);
+ class_sethelpsymbol(pulse_class, gensym("maxlib/pulse-help.pd"));
+}
+#endif
diff --git a/remote.c b/remote.c
index 4cdcff5..a407d9c 100644
--- a/remote.c
+++ b/remote.c
@@ -1,108 +1,108 @@
-/* ------------------------ remote ------------------------------------------ */
-/* */
-/* Send data to receive obejct <name>. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.de/puredata/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-
-#include <string.h>
-#include <stdio.h>
-
-#define MAX_REC 64 /* maximum number of receive objects */
-#define MAX_ARG 64 /* maximum number of arguments to pass on */
-
-static char *version = "remote v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-static t_class *remote_class;
-
-typedef struct _remote
-{
- t_object x_obj;
- t_symbol *x_prefix;
- t_int x_prepend;
-} t_remote;
-
- /* send 'anything' to receiver */
-static void remote_anything(t_remote *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i;
- t_atom av[MAX_ARG]; /* the 'new' t_atom without first element */
- t_int ac = argc - 1; /* the 'new' number of arguments */
- char mysym[MAXPDSTRING];
- t_symbol *target;
-
- if(argc < 1) /* need <name> <data> */
- {
- post("remote: too few arguments!");
- return;
- }
- if(ac > MAX_ARG)
- {
- post("remote: too many arguments!");
- return;
- }
-
- for(i = 1; i < argc; i++)
- {
- av[i - 1] = argv[i]; /* just copy, don't care about types */
- }
- /* send only argument-part to receivers */
- if(x->x_prepend)
- {
- sprintf(mysym,"%s%s", x->x_prefix->s_name, s->s_name);
- target = gensym(mysym);
- if (target->s_thing) pd_forwardmess(target->s_thing, argc, argv);
- }
- else
- if (s->s_thing) pd_forwardmess(s->s_thing, argc, argv);
-}
-
-static void *remote_new(t_symbol *s)
-{
- t_remote *x = (t_remote *)pd_new(remote_class);
-
- x->x_prefix = s;
- if(x->x_prefix) x->x_prepend = 1;
- else x->x_prepend = 0;
-
- return (x);
-}
-
-#ifndef MAXLIB
-void remote_setup(void)
-{
- remote_class = class_new(gensym("remote"), (t_newmethod)remote_new, 0,
- sizeof(t_remote), 0, A_DEFSYM, 0);
- class_addanything(remote_class, remote_anything);
-
- post(version);
-}
-#else
-void maxlib_remote_setup(void)
-{
- remote_class = class_new(gensym("maxlib_remote"), (t_newmethod)remote_new, 0,
- sizeof(t_remote), 0, A_DEFSYM, 0);
- class_addcreator((t_newmethod)remote_new, gensym("remote"), A_DEFSYM, 0);
- class_addanything(remote_class, remote_anything);
- class_sethelpsymbol(remote_class, gensym("maxlib/remote-help.pd"));
-}
-#endif
+/* ------------------------ remote ------------------------------------------ */
+/* */
+/* Send data to receive obejct <name>. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.de/puredata/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#define MAX_REC 64 /* maximum number of receive objects */
+#define MAX_ARG 64 /* maximum number of arguments to pass on */
+
+static char *version = "remote v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+static t_class *remote_class;
+
+typedef struct _remote
+{
+ t_object x_obj;
+ t_symbol *x_prefix;
+ t_int x_prepend;
+} t_remote;
+
+ /* send 'anything' to receiver */
+static void remote_anything(t_remote *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ t_atom av[MAX_ARG]; /* the 'new' t_atom without first element */
+ t_int ac = argc - 1; /* the 'new' number of arguments */
+ char mysym[MAXPDSTRING];
+ t_symbol *target;
+
+ if(argc < 1) /* need <name> <data> */
+ {
+ post("remote: too few arguments!");
+ return;
+ }
+ if(ac > MAX_ARG)
+ {
+ post("remote: too many arguments!");
+ return;
+ }
+
+ for(i = 1; i < argc; i++)
+ {
+ av[i - 1] = argv[i]; /* just copy, don't care about types */
+ }
+ /* send only argument-part to receivers */
+ if(x->x_prepend)
+ {
+ sprintf(mysym,"%s%s", x->x_prefix->s_name, s->s_name);
+ target = gensym(mysym);
+ if (target->s_thing) pd_forwardmess(target->s_thing, argc, argv);
+ }
+ else
+ if (s->s_thing) pd_forwardmess(s->s_thing, argc, argv);
+}
+
+static void *remote_new(t_symbol *s)
+{
+ t_remote *x = (t_remote *)pd_new(remote_class);
+
+ x->x_prefix = s;
+ if(x->x_prefix) x->x_prepend = 1;
+ else x->x_prepend = 0;
+
+ return (x);
+}
+
+#ifndef MAXLIB
+void remote_setup(void)
+{
+ remote_class = class_new(gensym("remote"), (t_newmethod)remote_new, 0,
+ sizeof(t_remote), 0, A_DEFSYM, 0);
+ class_addanything(remote_class, remote_anything);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_remote_setup(void)
+{
+ remote_class = class_new(gensym("maxlib_remote"), (t_newmethod)remote_new, 0,
+ sizeof(t_remote), 0, A_DEFSYM, 0);
+ class_addcreator((t_newmethod)remote_new, gensym("remote"), A_DEFSYM, 0);
+ class_addanything(remote_class, remote_anything);
+ class_sethelpsymbol(remote_class, gensym("maxlib/remote-help.pd"));
+}
+#endif
diff --git a/rewrap.c b/rewrap.c
index e429dc0..40b7df5 100644
--- a/rewrap.c
+++ b/rewrap.c
@@ -1,155 +1,155 @@
-/* ------------------------- rewrap ------------------------------------------ */
-/* */
-/* rewraps input to lie within an output range. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <math.h>
-
-static char *version = "rewrap v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct rewrap
-{
- t_object x_ob;
- t_float x_min; /* low border of input range */
- t_float x_max; /* high border of input range */
- t_outlet *x_outlet1; /* path-through outlet */
- t_outlet *x_outlet2; /* rewrap outlet */
-} t_rewrap;
-
-static void rewrap_float(t_rewrap *x, t_floatarg f)
-{
- t_float min = x->x_min;
- t_float max = x->x_max;
- t_float range = 2.0f * (max - min);
- t_int i;
-
- if(range == 0.0f)
- {
- f = min;
- outlet_float(x->x_outlet2, 0);
- }
- else if(f < min)
- {
- float diff = min - f;
- float n = ceil(diff / range);
-
- f += n * range;
-
- if(f >= max)
- {
- f = 2 * max - f;
- n -= 0.5;
- }
-
- outlet_float(x->x_outlet2, (t_int)(-2.0f * n));
- }
- else if (f >= max)
- {
- float diff = f - max;
- float n = floor(diff / range) + 1.0f;
-
- f -= n * range;
-
- if(f < min)
- {
- f = 2 * min - f;
- n -= 0.5;
- }
-
- outlet_float(x->x_outlet2, (t_int)(2.0f * n));
- }
- else
- outlet_float(x->x_outlet2, 0.0f);
-
-
- outlet_float(x->x_outlet1, f);
-}
-
-static void rewrap_a(t_rewrap *x, t_floatarg a)
-{
- t_float max = x->x_max;
-
- if(a <= max)
- x->x_min = a;
- else
- {
- x->x_min = max;
- x->x_max = a;
- }
-}
-
-static void rewrap_b(t_rewrap *x, t_floatarg b)
-{
- t_float min = x->x_min;
-
- if(b >= min)
- x->x_max = b;
- else
- {
- x->x_max = min;
- x->x_min = b;
- }
-}
-
-static t_class *rewrap_class;
-
-static void *rewrap_new(t_floatarg fmin, t_floatarg fmax)
-{
- t_rewrap *x = (t_rewrap *)pd_new(rewrap_class);
-
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("a"));
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("b"));
-
- x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
- x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
-
- x->x_min = fmin;
- rewrap_b(x, fmax);
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void rewrap_setup(void)
-{
- rewrap_class = class_new(gensym("rewrap"), (t_newmethod)rewrap_new,
- 0, sizeof(t_rewrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addfloat(rewrap_class, rewrap_float);
- class_addmethod(rewrap_class, (t_method)rewrap_a, gensym("a"), A_FLOAT, 0);
- class_addmethod(rewrap_class, (t_method)rewrap_b, gensym("b"), A_FLOAT, 0);
-
- post(version);
-}
-#else
-void maxlib_rewrap_setup(void)
-{
- rewrap_class = class_new(gensym("maxlib_rewrap"), (t_newmethod)rewrap_new,
- 0, sizeof(t_rewrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)rewrap_new, gensym("rewrap"), A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addfloat(rewrap_class, rewrap_float);
- class_addmethod(rewrap_class, (t_method)rewrap_a, gensym("a"), A_FLOAT, 0);
- class_addmethod(rewrap_class, (t_method)rewrap_b, gensym("b"), A_FLOAT, 0);
- class_sethelpsymbol(rewrap_class, gensym("maxlib/rewrap-help.pd"));
-}
-#endif
+/* ------------------------- rewrap ------------------------------------------ */
+/* */
+/* rewraps input to lie within an output range. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+
+static char *version = "rewrap v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct rewrap
+{
+ t_object x_ob;
+ t_float x_min; /* low border of input range */
+ t_float x_max; /* high border of input range */
+ t_outlet *x_outlet1; /* path-through outlet */
+ t_outlet *x_outlet2; /* rewrap outlet */
+} t_rewrap;
+
+static void rewrap_float(t_rewrap *x, t_floatarg f)
+{
+ t_float min = x->x_min;
+ t_float max = x->x_max;
+ t_float range = 2.0f * (max - min);
+ t_int i;
+
+ if(range == 0.0f)
+ {
+ f = min;
+ outlet_float(x->x_outlet2, 0);
+ }
+ else if(f < min)
+ {
+ float diff = min - f;
+ float n = ceil(diff / range);
+
+ f += n * range;
+
+ if(f >= max)
+ {
+ f = 2 * max - f;
+ n -= 0.5;
+ }
+
+ outlet_float(x->x_outlet2, (t_int)(-2.0f * n));
+ }
+ else if (f >= max)
+ {
+ float diff = f - max;
+ float n = floor(diff / range) + 1.0f;
+
+ f -= n * range;
+
+ if(f < min)
+ {
+ f = 2 * min - f;
+ n -= 0.5;
+ }
+
+ outlet_float(x->x_outlet2, (t_int)(2.0f * n));
+ }
+ else
+ outlet_float(x->x_outlet2, 0.0f);
+
+
+ outlet_float(x->x_outlet1, f);
+}
+
+static void rewrap_a(t_rewrap *x, t_floatarg a)
+{
+ t_float max = x->x_max;
+
+ if(a <= max)
+ x->x_min = a;
+ else
+ {
+ x->x_min = max;
+ x->x_max = a;
+ }
+}
+
+static void rewrap_b(t_rewrap *x, t_floatarg b)
+{
+ t_float min = x->x_min;
+
+ if(b >= min)
+ x->x_max = b;
+ else
+ {
+ x->x_max = min;
+ x->x_min = b;
+ }
+}
+
+static t_class *rewrap_class;
+
+static void *rewrap_new(t_floatarg fmin, t_floatarg fmax)
+{
+ t_rewrap *x = (t_rewrap *)pd_new(rewrap_class);
+
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("a"));
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("b"));
+
+ x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_min = fmin;
+ rewrap_b(x, fmax);
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void rewrap_setup(void)
+{
+ rewrap_class = class_new(gensym("rewrap"), (t_newmethod)rewrap_new,
+ 0, sizeof(t_rewrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(rewrap_class, rewrap_float);
+ class_addmethod(rewrap_class, (t_method)rewrap_a, gensym("a"), A_FLOAT, 0);
+ class_addmethod(rewrap_class, (t_method)rewrap_b, gensym("b"), A_FLOAT, 0);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_rewrap_setup(void)
+{
+ rewrap_class = class_new(gensym("maxlib_rewrap"), (t_newmethod)rewrap_new,
+ 0, sizeof(t_rewrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)rewrap_new, gensym("rewrap"), A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(rewrap_class, rewrap_float);
+ class_addmethod(rewrap_class, (t_method)rewrap_a, gensym("a"), A_FLOAT, 0);
+ class_addmethod(rewrap_class, (t_method)rewrap_b, gensym("b"), A_FLOAT, 0);
+ class_sethelpsymbol(rewrap_class, gensym("maxlib/rewrap-help.pd"));
+}
+#endif
diff --git a/rhythm.c b/rhythm.c
index 197a143..774f07d 100644
--- a/rhythm.c
+++ b/rhythm.c
@@ -1,343 +1,343 @@
-/* --------------------------- rhythm ---------------------------------------- */
-/* */
-/* Detect the beats per minute of a MIDI stream. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code written by Robert Rowe. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <math.h>
-#ifndef _WIN32
-#include <stdlib.h>
-#endif
-
-#define ALPHA 10
-#define ADAPT_ARRAY_SIZE 1000
-
-#ifndef M_PI
-#define M_PI 3.14159265358979
-#endif
-#ifndef TWO_PI
-#define TWO_PI 2.0*M_PI
-#endif
-
-static char *version = "rhythm v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct rhythm
-{
- t_object x_ob;
- t_clock *x_tick;
- t_outlet *x_out_bpm; /* beats per minute */
- t_outlet *x_out_period; /* beats in milliseconds */
- t_outlet *x_out_pulse;
- t_int x_print; /* switch printing to console window on / off */
- t_int x_ticking; /* indicates if clock is ticking or not */
-
- t_int x_model; /* algorhythm to use: 0 - Large & Kolen, 1 - Toiviainen */
- t_float x_long_term[ADAPT_ARRAY_SIZE];
- t_float x_short_term[ADAPT_ARRAY_SIZE];
- t_float x_phi_at_pulse; /* phase at latest pulse */
- t_float x_phiVel_at_pulse; /* phase velocity */
-
- t_float x_adapt;
- t_float x_errFunc; /* error function */
- t_float x_etaLong; /* strength of long-term adaptation */
- t_float x_etaShort; /* strength of short-term adaptation */
- t_float x_gamma; /* gain parameter */
- double x_lastIoi; /* last inter-onset interval */
- double x_lastPulseTime; /* time of last pulse */
- t_float x_output; /* current output value of the oscillator */
- t_float x_phi; /* phase */
- double x_expected; /* estimated time of arrival */
- t_float x_period;
- t_float x_periodStrength;
- t_float x_phaseStrength;
- double x_startTime;
-
- t_int x_pitch;
- t_int x_velo;
- /* helpers needed to do the time calculations */
- double x_last_input;
-} t_rhythm;
-
-/* --------------- rhythm stuff ------------------------------------------------ */
- /* bang at the rhythm's pulse */
-static void rhythm_tick(t_rhythm *x)
-{
- outlet_bang(x->x_out_pulse);
- clock_delay(x->x_tick, x->x_period);
-}
-
-static t_float rhythm_get_adapt_long(t_rhythm *x, t_float arg)
-{
- int address;
- if (arg > 1.0)
- address = ADAPT_ARRAY_SIZE - 1;
- else if (arg < -1.0)
- address = ADAPT_ARRAY_SIZE - 1;
- else
- address = abs((int)(arg*1000.0));
- return x->x_long_term[address];
-}
-
-static t_float rhythm_get_adapt_short(t_rhythm *x, t_float arg)
-{
- int address;
- if (arg > 1.0)
- address = ADAPT_ARRAY_SIZE - 1;
- else if (arg < -1.0)
- address = ADAPT_ARRAY_SIZE - 1;
- else
- address = abs((int)(arg*1000.0));
- return x->x_short_term[address];
-}
-
-
- /* Large & Kolen adaptation model */
-static void rhythm_large(t_rhythm *x, t_int pulse, double time)
-{
- while (time > (x->x_expected+(x->x_period/2))) // move the expectation point
- x->x_expected += x->x_period; // to be within one period of onset
- x->x_phi = (t_float)(time - x->x_expected) / x->x_period; // calculate phi
-
- if (pulse) { // if this was an onset
- x->x_adapt = x->x_gamma * (cos(TWO_PI*x->x_phi)-1.0);
- x->x_adapt = 1.0 / cosh(x->x_adapt);
- x->x_adapt *= x->x_adapt;
- x->x_adapt *= sin(TWO_PI*x->x_phi);
- x->x_adapt *= (x->x_period / TWO_PI);
- x->x_period += (x->x_periodStrength*x->x_adapt); // update period
- x->x_expected += (x->x_phaseStrength *x->x_adapt); // and phase
- x->x_phi = (t_float)(time - x->x_expected) / x->x_period;
- }
-
- x->x_output = 1+tanh(x->x_gamma*(cos(TWO_PI*x->x_phi)-1.0)); // oscillator output
-}
- /* Toiviainen adaptation model */
-static void rhythm_toiviainen(t_rhythm *x, t_int pulse, double time)
-{
- t_float deltaTime, varPhi, adaptLong, adaptShort;
-
- /* if just starting, initialize phi */
- if(x->x_lastPulseTime < 0)
- {
- x->x_phi = x->x_phi_at_pulse + x->x_phiVel_at_pulse * ((t_float)(time-x->x_startTime) / 1000.0);
- }
- else
- {
- deltaTime = time - x->x_lastPulseTime;
- varPhi = (deltaTime/1000.0) * x->x_phiVel_at_pulse;
- adaptLong = rhythm_get_adapt_long(x, varPhi); // get long adaptation from table
- adaptShort = rhythm_get_adapt_short(x, varPhi); // get short adaptation from table
- x->x_phi = x->x_phi_at_pulse + varPhi + x->x_errFunc * (x->x_etaLong*adaptLong + x->x_etaShort*adaptShort);
- if (pulse) // change tempo if on pulse
- x->x_phiVel_at_pulse = x->x_phiVel_at_pulse * (1 + x->x_etaLong * x->x_errFunc * adaptShort);
- }
-
- if (pulse) {
- x->x_output = 1+tanh(x->x_gamma*(cos(TWO_PI*x->x_phi)-1.0));
- x->x_errFunc = x->x_output * (x->x_output - 2.0) * sin(TWO_PI * x->x_phi);
- x->x_phi_at_pulse = x->x_phi;
- }
-
- x->x_period = 1000.0 / x->x_phiVel_at_pulse; // update period
-}
-
-static void rhythm_move(t_rhythm *x, t_int pulse, double time)
-{
- switch (x->x_model) /* choose adaptation model */
- {
- case 0:
- rhythm_large(x, pulse, time);
- break;
-
- case 1:
- rhythm_toiviainen(x, pulse, time);
- break;
- }
-
- if(x->x_ticking == 0)
- {
- x->x_ticking = 1; /* prevent us from further calls */
- clock_delay(x->x_tick, 0); /* start pulse bangs */
- }
-}
-
- /* main processing function */
-static void rhythm_float(t_rhythm *x, t_floatarg f)
-{
- t_int velo = x->x_velo;
- double time = clock_gettimesince(x->x_last_input);
- x->x_pitch = (t_int)f;
-
- if(velo != 0) /* note-on received */
- {
- if (x->x_startTime == 0) {
- x->x_startTime = time;
- return;
- }
-
- if (x->x_period < 2.0) {
- x->x_period = (t_float)(time - x->x_startTime);
- x->x_phiVel_at_pulse = 1000.0 / x->x_period;
- }
-
- rhythm_move(x, 1, time);
-
- if (x->x_lastPulseTime >= 0)
- {
- x->x_lastIoi = time - x->x_lastPulseTime;
- }
- x->x_lastPulseTime = time;
- x->x_last_input = clock_getlogicaltime();
-
- outlet_float(x->x_out_period, x->x_period);
- outlet_float(x->x_out_bpm, 60000.0/x->x_period);
- }
- return;
-}
- /* get velocity */
-static void rhythm_ft1(t_rhythm *x, t_floatarg f)
-{
- x->x_velo = (t_int)f;
-}
-
- /* toggle printing on/off (not used right now!) */
-static void rhythm_print(t_rhythm *x)
-{
- if(x->x_print)x->x_print = 0;
- else x->x_print = 1;
-}
- /* initialise array for Toiviainen adaptation model */
-static void rhythm_calculate_adaptations(t_rhythm *x)
-{
- int i;
- t_float f;
-
- for(i = 0; i < ADAPT_ARRAY_SIZE; i++)
- {
- f = (t_float)i/(t_float)ADAPT_ARRAY_SIZE;
- x->x_long_term[i] = f+(ALPHA*f*f/2.0+2.0*f+3.0/ALPHA)*exp(-ALPHA*f)-3.0/ALPHA;
- x->x_short_term[i] = 1.0-(ALPHA*ALPHA*f*f/2.0+ALPHA*f+1.0)*exp(-ALPHA*f);
- }
-}
-
-static void rhythm_reset(t_rhythm *x)
-{
- if(x->x_ticking)clock_unset(x->x_tick);
- x->x_ticking = 0;
-
- x->x_gamma = 1.0; /* default value for gain parameter */
- x->x_phi = 0.0;
- x->x_output = 1+tanh(x->x_gamma*(cos(TWO_PI*x->x_phi)-1.0));
- x->x_expected = 0;
- x->x_lastIoi = 0;
- x->x_lastPulseTime = -1;
- x->x_period = 1.0;
- x->x_periodStrength = 0.2;
- x->x_phaseStrength = 0.2;
-
- x->x_errFunc = 0.0;
- x->x_etaLong = 0.2;
- x->x_etaShort = 0.2;
- x->x_phi_at_pulse = 0.0;
- x->x_phiVel_at_pulse = 0.9;
- x->x_startTime = 0;
-
- rhythm_calculate_adaptations(x);
-}
-
-static void rhythm_model(t_rhythm *x, t_floatarg f)
-{
- if(f == 1)
- {
- x->x_model = 1; /* Toiviainen model */
- rhythm_reset(x);
- post("rhythm: using \"Toiviainen\" adaptation model");
- }
- else
- {
- x->x_model = 0; /* Large and Kolen model */
- rhythm_reset(x);
- post("rhythm: using \"Large and Kolen\" adaptation model");
- }
-}
-
-static t_class *rhythm_class;
-
-static void rhythm_free(t_rhythm *x)
-{
- clock_free(x->x_tick);
-}
-
-static void *rhythm_new(t_floatarg f)
-{
- t_rhythm *x = (t_rhythm *)pd_new(rhythm_class);
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- x->x_out_bpm = outlet_new(&x->x_ob, gensym("float"));
- x->x_out_period = outlet_new(&x->x_ob, gensym("float"));
- x->x_out_pulse = outlet_new(&x->x_ob, gensym("bang"));
- x->x_tick = clock_new(x, (t_method)rhythm_tick);
-
- rhythm_reset(x);
-
- if(f == 1)
- {
- x->x_model = 1; /* Toiviainen model */
- post("rhythm: using \"Toiviainen\" adaptation model");
- }
- else
- {
- x->x_model = 0; /* Large and Kolen model */
- post("rhythm: using \"Large and Kolen\" adaptation model");
- }
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void rhythm_setup(void)
-{
- rhythm_class = class_new(gensym("rhythm"), (t_newmethod)rhythm_new,
- (t_method)rhythm_free, sizeof(t_rhythm), 0, A_DEFFLOAT, 0);
- class_addfloat(rhythm_class, rhythm_float);
- class_addmethod(rhythm_class, (t_method)rhythm_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addmethod(rhythm_class, (t_method)rhythm_model, gensym("model"), A_FLOAT, 0);
- class_addmethod(rhythm_class, (t_method)rhythm_reset, gensym("reset"), 0);
- class_addmethod(rhythm_class, (t_method)rhythm_print, gensym("print"), 0);
-
- post(version);
-}
-#else
-void maxlib_rhythm_setup(void)
-{
- rhythm_class = class_new(gensym("maxlib_rhythm"), (t_newmethod)rhythm_new,
- (t_method)rhythm_free, sizeof(t_rhythm), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)rhythm_new, gensym("rhythm"), A_DEFFLOAT, 0);
- class_addfloat(rhythm_class, rhythm_float);
- class_addmethod(rhythm_class, (t_method)rhythm_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addmethod(rhythm_class, (t_method)rhythm_model, gensym("model"), A_FLOAT, 0);
- class_addmethod(rhythm_class, (t_method)rhythm_reset, gensym("reset"), 0);
- class_addmethod(rhythm_class, (t_method)rhythm_print, gensym("print"), 0);
- class_sethelpsymbol(rhythm_class, gensym("maxlib/rhythm-help.pd"));
-}
-#endif
+/* --------------------------- rhythm ---------------------------------------- */
+/* */
+/* Detect the beats per minute of a MIDI stream. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code written by Robert Rowe. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+#ifndef _WIN32
+#include <stdlib.h>
+#endif
+
+#define ALPHA 10
+#define ADAPT_ARRAY_SIZE 1000
+
+#ifndef M_PI
+#define M_PI 3.14159265358979
+#endif
+#ifndef TWO_PI
+#define TWO_PI 2.0*M_PI
+#endif
+
+static char *version = "rhythm v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct rhythm
+{
+ t_object x_ob;
+ t_clock *x_tick;
+ t_outlet *x_out_bpm; /* beats per minute */
+ t_outlet *x_out_period; /* beats in milliseconds */
+ t_outlet *x_out_pulse;
+ t_int x_print; /* switch printing to console window on / off */
+ t_int x_ticking; /* indicates if clock is ticking or not */
+
+ t_int x_model; /* algorhythm to use: 0 - Large & Kolen, 1 - Toiviainen */
+ t_float x_long_term[ADAPT_ARRAY_SIZE];
+ t_float x_short_term[ADAPT_ARRAY_SIZE];
+ t_float x_phi_at_pulse; /* phase at latest pulse */
+ t_float x_phiVel_at_pulse; /* phase velocity */
+
+ t_float x_adapt;
+ t_float x_errFunc; /* error function */
+ t_float x_etaLong; /* strength of long-term adaptation */
+ t_float x_etaShort; /* strength of short-term adaptation */
+ t_float x_gamma; /* gain parameter */
+ double x_lastIoi; /* last inter-onset interval */
+ double x_lastPulseTime; /* time of last pulse */
+ t_float x_output; /* current output value of the oscillator */
+ t_float x_phi; /* phase */
+ double x_expected; /* estimated time of arrival */
+ t_float x_period;
+ t_float x_periodStrength;
+ t_float x_phaseStrength;
+ double x_startTime;
+
+ t_int x_pitch;
+ t_int x_velo;
+ /* helpers needed to do the time calculations */
+ double x_last_input;
+} t_rhythm;
+
+/* --------------- rhythm stuff ------------------------------------------------ */
+ /* bang at the rhythm's pulse */
+static void rhythm_tick(t_rhythm *x)
+{
+ outlet_bang(x->x_out_pulse);
+ clock_delay(x->x_tick, x->x_period);
+}
+
+static t_float rhythm_get_adapt_long(t_rhythm *x, t_float arg)
+{
+ int address;
+ if (arg > 1.0)
+ address = ADAPT_ARRAY_SIZE - 1;
+ else if (arg < -1.0)
+ address = ADAPT_ARRAY_SIZE - 1;
+ else
+ address = abs((int)(arg*1000.0));
+ return x->x_long_term[address];
+}
+
+static t_float rhythm_get_adapt_short(t_rhythm *x, t_float arg)
+{
+ int address;
+ if (arg > 1.0)
+ address = ADAPT_ARRAY_SIZE - 1;
+ else if (arg < -1.0)
+ address = ADAPT_ARRAY_SIZE - 1;
+ else
+ address = abs((int)(arg*1000.0));
+ return x->x_short_term[address];
+}
+
+
+ /* Large & Kolen adaptation model */
+static void rhythm_large(t_rhythm *x, t_int pulse, double time)
+{
+ while (time > (x->x_expected+(x->x_period/2))) // move the expectation point
+ x->x_expected += x->x_period; // to be within one period of onset
+ x->x_phi = (t_float)(time - x->x_expected) / x->x_period; // calculate phi
+
+ if (pulse) { // if this was an onset
+ x->x_adapt = x->x_gamma * (cos(TWO_PI*x->x_phi)-1.0);
+ x->x_adapt = 1.0 / cosh(x->x_adapt);
+ x->x_adapt *= x->x_adapt;
+ x->x_adapt *= sin(TWO_PI*x->x_phi);
+ x->x_adapt *= (x->x_period / TWO_PI);
+ x->x_period += (x->x_periodStrength*x->x_adapt); // update period
+ x->x_expected += (x->x_phaseStrength *x->x_adapt); // and phase
+ x->x_phi = (t_float)(time - x->x_expected) / x->x_period;
+ }
+
+ x->x_output = 1+tanh(x->x_gamma*(cos(TWO_PI*x->x_phi)-1.0)); // oscillator output
+}
+ /* Toiviainen adaptation model */
+static void rhythm_toiviainen(t_rhythm *x, t_int pulse, double time)
+{
+ t_float deltaTime, varPhi, adaptLong, adaptShort;
+
+ /* if just starting, initialize phi */
+ if(x->x_lastPulseTime < 0)
+ {
+ x->x_phi = x->x_phi_at_pulse + x->x_phiVel_at_pulse * ((t_float)(time-x->x_startTime) / 1000.0);
+ }
+ else
+ {
+ deltaTime = time - x->x_lastPulseTime;
+ varPhi = (deltaTime/1000.0) * x->x_phiVel_at_pulse;
+ adaptLong = rhythm_get_adapt_long(x, varPhi); // get long adaptation from table
+ adaptShort = rhythm_get_adapt_short(x, varPhi); // get short adaptation from table
+ x->x_phi = x->x_phi_at_pulse + varPhi + x->x_errFunc * (x->x_etaLong*adaptLong + x->x_etaShort*adaptShort);
+ if (pulse) // change tempo if on pulse
+ x->x_phiVel_at_pulse = x->x_phiVel_at_pulse * (1 + x->x_etaLong * x->x_errFunc * adaptShort);
+ }
+
+ if (pulse) {
+ x->x_output = 1+tanh(x->x_gamma*(cos(TWO_PI*x->x_phi)-1.0));
+ x->x_errFunc = x->x_output * (x->x_output - 2.0) * sin(TWO_PI * x->x_phi);
+ x->x_phi_at_pulse = x->x_phi;
+ }
+
+ x->x_period = 1000.0 / x->x_phiVel_at_pulse; // update period
+}
+
+static void rhythm_move(t_rhythm *x, t_int pulse, double time)
+{
+ switch (x->x_model) /* choose adaptation model */
+ {
+ case 0:
+ rhythm_large(x, pulse, time);
+ break;
+
+ case 1:
+ rhythm_toiviainen(x, pulse, time);
+ break;
+ }
+
+ if(x->x_ticking == 0)
+ {
+ x->x_ticking = 1; /* prevent us from further calls */
+ clock_delay(x->x_tick, 0); /* start pulse bangs */
+ }
+}
+
+ /* main processing function */
+static void rhythm_float(t_rhythm *x, t_floatarg f)
+{
+ t_int velo = x->x_velo;
+ double time = clock_gettimesince(x->x_last_input);
+ x->x_pitch = (t_int)f;
+
+ if(velo != 0) /* note-on received */
+ {
+ if (x->x_startTime == 0) {
+ x->x_startTime = time;
+ return;
+ }
+
+ if (x->x_period < 2.0) {
+ x->x_period = (t_float)(time - x->x_startTime);
+ x->x_phiVel_at_pulse = 1000.0 / x->x_period;
+ }
+
+ rhythm_move(x, 1, time);
+
+ if (x->x_lastPulseTime >= 0)
+ {
+ x->x_lastIoi = time - x->x_lastPulseTime;
+ }
+ x->x_lastPulseTime = time;
+ x->x_last_input = clock_getlogicaltime();
+
+ outlet_float(x->x_out_period, x->x_period);
+ outlet_float(x->x_out_bpm, 60000.0/x->x_period);
+ }
+ return;
+}
+ /* get velocity */
+static void rhythm_ft1(t_rhythm *x, t_floatarg f)
+{
+ x->x_velo = (t_int)f;
+}
+
+ /* toggle printing on/off (not used right now!) */
+static void rhythm_print(t_rhythm *x)
+{
+ if(x->x_print)x->x_print = 0;
+ else x->x_print = 1;
+}
+ /* initialise array for Toiviainen adaptation model */
+static void rhythm_calculate_adaptations(t_rhythm *x)
+{
+ int i;
+ t_float f;
+
+ for(i = 0; i < ADAPT_ARRAY_SIZE; i++)
+ {
+ f = (t_float)i/(t_float)ADAPT_ARRAY_SIZE;
+ x->x_long_term[i] = f+(ALPHA*f*f/2.0+2.0*f+3.0/ALPHA)*exp(-ALPHA*f)-3.0/ALPHA;
+ x->x_short_term[i] = 1.0-(ALPHA*ALPHA*f*f/2.0+ALPHA*f+1.0)*exp(-ALPHA*f);
+ }
+}
+
+static void rhythm_reset(t_rhythm *x)
+{
+ if(x->x_ticking)clock_unset(x->x_tick);
+ x->x_ticking = 0;
+
+ x->x_gamma = 1.0; /* default value for gain parameter */
+ x->x_phi = 0.0;
+ x->x_output = 1+tanh(x->x_gamma*(cos(TWO_PI*x->x_phi)-1.0));
+ x->x_expected = 0;
+ x->x_lastIoi = 0;
+ x->x_lastPulseTime = -1;
+ x->x_period = 1.0;
+ x->x_periodStrength = 0.2;
+ x->x_phaseStrength = 0.2;
+
+ x->x_errFunc = 0.0;
+ x->x_etaLong = 0.2;
+ x->x_etaShort = 0.2;
+ x->x_phi_at_pulse = 0.0;
+ x->x_phiVel_at_pulse = 0.9;
+ x->x_startTime = 0;
+
+ rhythm_calculate_adaptations(x);
+}
+
+static void rhythm_model(t_rhythm *x, t_floatarg f)
+{
+ if(f == 1)
+ {
+ x->x_model = 1; /* Toiviainen model */
+ rhythm_reset(x);
+ post("rhythm: using \"Toiviainen\" adaptation model");
+ }
+ else
+ {
+ x->x_model = 0; /* Large and Kolen model */
+ rhythm_reset(x);
+ post("rhythm: using \"Large and Kolen\" adaptation model");
+ }
+}
+
+static t_class *rhythm_class;
+
+static void rhythm_free(t_rhythm *x)
+{
+ clock_free(x->x_tick);
+}
+
+static void *rhythm_new(t_floatarg f)
+{
+ t_rhythm *x = (t_rhythm *)pd_new(rhythm_class);
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ x->x_out_bpm = outlet_new(&x->x_ob, gensym("float"));
+ x->x_out_period = outlet_new(&x->x_ob, gensym("float"));
+ x->x_out_pulse = outlet_new(&x->x_ob, gensym("bang"));
+ x->x_tick = clock_new(x, (t_method)rhythm_tick);
+
+ rhythm_reset(x);
+
+ if(f == 1)
+ {
+ x->x_model = 1; /* Toiviainen model */
+ post("rhythm: using \"Toiviainen\" adaptation model");
+ }
+ else
+ {
+ x->x_model = 0; /* Large and Kolen model */
+ post("rhythm: using \"Large and Kolen\" adaptation model");
+ }
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void rhythm_setup(void)
+{
+ rhythm_class = class_new(gensym("rhythm"), (t_newmethod)rhythm_new,
+ (t_method)rhythm_free, sizeof(t_rhythm), 0, A_DEFFLOAT, 0);
+ class_addfloat(rhythm_class, rhythm_float);
+ class_addmethod(rhythm_class, (t_method)rhythm_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(rhythm_class, (t_method)rhythm_model, gensym("model"), A_FLOAT, 0);
+ class_addmethod(rhythm_class, (t_method)rhythm_reset, gensym("reset"), 0);
+ class_addmethod(rhythm_class, (t_method)rhythm_print, gensym("print"), 0);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_rhythm_setup(void)
+{
+ rhythm_class = class_new(gensym("maxlib_rhythm"), (t_newmethod)rhythm_new,
+ (t_method)rhythm_free, sizeof(t_rhythm), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)rhythm_new, gensym("rhythm"), A_DEFFLOAT, 0);
+ class_addfloat(rhythm_class, rhythm_float);
+ class_addmethod(rhythm_class, (t_method)rhythm_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(rhythm_class, (t_method)rhythm_model, gensym("model"), A_FLOAT, 0);
+ class_addmethod(rhythm_class, (t_method)rhythm_reset, gensym("reset"), 0);
+ class_addmethod(rhythm_class, (t_method)rhythm_print, gensym("print"), 0);
+ class_sethelpsymbol(rhythm_class, gensym("maxlib/rhythm-help.pd"));
+}
+#endif
diff --git a/scale.c b/scale.c
index 890b38d..3654249 100644
--- a/scale.c
+++ b/scale.c
@@ -1,138 +1,138 @@
-/* ------------------------- scale ------------------------------------------ */
-/* */
-/* Scales input to lie within an output range. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <math.h>
-
-static char *version = "scale v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct scale
-{
- t_object x_ob;
- t_float x_f; /* current input value */
- t_float x_il; /* low border of input range */
- t_float x_ih; /* high border of input range */
- t_float x_ol; /* low border of output range */
- t_float x_oh; /* high border of output range */
- t_float x_logcoeff; /* log-coefficient */
- t_outlet *x_outlet1; /* result */
-} t_scale;
-
-static void scale_float(t_scale *x, t_floatarg f)
-{
- t_float ir = x->x_ih - x->x_il;
- t_float or = x->x_oh - x->x_ol;
- double oq;
- double result;
- double k;
- if(ir == 0)
- {
- post("scale: input range must not be 0");
- return;
- }
- /* we accept an output range of 0 in case someone really wants this */
- if(!x->x_logcoeff) /* linear */
- {
- k = (or / ir);
- result = ((f - x->x_il) * k) + x->x_ol;
- }
- else /* logarythmical scale */
- {
- oq = x->x_oh / x->x_ol;
- // k = (log((double)oq)/log(x->x_logcoeff))/((double)ir);
- k = log((double)oq)/((double)ir);
-
- if(x->x_ol)
- {
- // result = (double)x->x_ol*exp(k*(double)(f - x->x_il)*log(x->x_logcoeff));
- result = (double)x->x_ol*exp(k*(double)(f - x->x_il));
- }
- else
- {
- /* in case the low output is 0 we have to cheat... */
- /* okay, here's the chating: we calculate for a lower out limit
- of 1 and remove this shift after the calculation */
- result = ((double)(x->x_ol+1)*exp(k*(double)(f - x->x_il)))-1.0;
- }
- }
-
- x->x_f = f; /* save current input value */
-
- outlet_float(x->x_outlet1, result);
-}
-
-static void scale_bang(t_scale *x)
-{
- scale_float(x, x->x_f); /* recalculate result */
-}
-
-static t_class *scale_class;
-
-static void *scale_new(t_floatarg fil, t_floatarg fih, t_floatarg fol, t_floatarg foh, t_floatarg flc)
-{
- t_scale *x = (t_scale *)pd_new(scale_class);
-
- floatinlet_new(&x->x_ob, &x->x_il);
- floatinlet_new(&x->x_ob, &x->x_ih);
- floatinlet_new(&x->x_ob, &x->x_ol);
- floatinlet_new(&x->x_ob, &x->x_oh);
- floatinlet_new(&x->x_ob, &x->x_logcoeff);
-
- x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
-
- /* default values taken from Max's scale */
- x->x_il = fil;
- x->x_ih = fih;
- if(!x->x_ih)x->x_ih = 127.0;
- x->x_ol = fol;
- x->x_oh = foh;
- if(!x->x_oh)x->x_oh = 1.0;
- x->x_logcoeff = flc;
- x->x_f = 0;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void scale_setup(void)
-{
- scale_class = class_new(gensym("scale"), (t_newmethod)scale_new,
- 0, sizeof(t_scale), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addfloat(scale_class, scale_float);
- class_addbang(scale_class, scale_bang);
-
- post(version);
-#else
-void maxlib_scale_setup(void)
-{
- scale_class = class_new(gensym("maxlib_scale"), (t_newmethod)scale_new,
- 0, sizeof(t_scale), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)scale_new, gensym("scale"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addfloat(scale_class, scale_float);
- class_addbang(scale_class, scale_bang);
- class_sethelpsymbol(scale_class, gensym("maxlib/scale-help.pd"));
-#endif
-}
-
+/* ------------------------- scale ------------------------------------------ */
+/* */
+/* Scales input to lie within an output range. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+
+static char *version = "scale v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct scale
+{
+ t_object x_ob;
+ t_float x_f; /* current input value */
+ t_float x_il; /* low border of input range */
+ t_float x_ih; /* high border of input range */
+ t_float x_ol; /* low border of output range */
+ t_float x_oh; /* high border of output range */
+ t_float x_logcoeff; /* log-coefficient */
+ t_outlet *x_outlet1; /* result */
+} t_scale;
+
+static void scale_float(t_scale *x, t_floatarg f)
+{
+ t_float ir = x->x_ih - x->x_il;
+ t_float or = x->x_oh - x->x_ol;
+ double oq;
+ double result;
+ double k;
+ if(ir == 0)
+ {
+ post("scale: input range must not be 0");
+ return;
+ }
+ /* we accept an output range of 0 in case someone really wants this */
+ if(!x->x_logcoeff) /* linear */
+ {
+ k = (or / ir);
+ result = ((f - x->x_il) * k) + x->x_ol;
+ }
+ else /* logarythmical scale */
+ {
+ oq = x->x_oh / x->x_ol;
+ // k = (log((double)oq)/log(x->x_logcoeff))/((double)ir);
+ k = log((double)oq)/((double)ir);
+
+ if(x->x_ol)
+ {
+ // result = (double)x->x_ol*exp(k*(double)(f - x->x_il)*log(x->x_logcoeff));
+ result = (double)x->x_ol*exp(k*(double)(f - x->x_il));
+ }
+ else
+ {
+ /* in case the low output is 0 we have to cheat... */
+ /* okay, here's the chating: we calculate for a lower out limit
+ of 1 and remove this shift after the calculation */
+ result = ((double)(x->x_ol+1)*exp(k*(double)(f - x->x_il)))-1.0;
+ }
+ }
+
+ x->x_f = f; /* save current input value */
+
+ outlet_float(x->x_outlet1, result);
+}
+
+static void scale_bang(t_scale *x)
+{
+ scale_float(x, x->x_f); /* recalculate result */
+}
+
+static t_class *scale_class;
+
+static void *scale_new(t_floatarg fil, t_floatarg fih, t_floatarg fol, t_floatarg foh, t_floatarg flc)
+{
+ t_scale *x = (t_scale *)pd_new(scale_class);
+
+ floatinlet_new(&x->x_ob, &x->x_il);
+ floatinlet_new(&x->x_ob, &x->x_ih);
+ floatinlet_new(&x->x_ob, &x->x_ol);
+ floatinlet_new(&x->x_ob, &x->x_oh);
+ floatinlet_new(&x->x_ob, &x->x_logcoeff);
+
+ x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
+
+ /* default values taken from Max's scale */
+ x->x_il = fil;
+ x->x_ih = fih;
+ if(!x->x_ih)x->x_ih = 127.0;
+ x->x_ol = fol;
+ x->x_oh = foh;
+ if(!x->x_oh)x->x_oh = 1.0;
+ x->x_logcoeff = flc;
+ x->x_f = 0;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void scale_setup(void)
+{
+ scale_class = class_new(gensym("scale"), (t_newmethod)scale_new,
+ 0, sizeof(t_scale), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(scale_class, scale_float);
+ class_addbang(scale_class, scale_bang);
+
+ logpost(NULL, 4, version);
+#else
+void maxlib_scale_setup(void)
+{
+ scale_class = class_new(gensym("maxlib_scale"), (t_newmethod)scale_new,
+ 0, sizeof(t_scale), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)scale_new, gensym("scale"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(scale_class, scale_float);
+ class_addbang(scale_class, scale_bang);
+ class_sethelpsymbol(scale_class, gensym("maxlib/scale-help.pd"));
+#endif
+}
+
diff --git a/score-help.pd b/score-help.pd
index 7c981f7..0a799a9 100644
--- a/score-help.pd
+++ b/score-help.pd
@@ -25,7 +25,7 @@
#X restore 402 361 graph;
#X obj 30 235 score sco_array 2 300;
#X msg 130 173 set sco_array;
-#X msg 23 449 \; sco_array resize 25 \; sco_array read examplescore.txt
+#X msg 23 449 \; sco_array resize 25 \; sco_array read examples/score.txt
\;;
#X text 250 174 set to array that contains the score;
#X text 88 303 position on score;
diff --git a/score.c b/score.c
index 153b65a..04ef1ff 100644
--- a/score.c
+++ b/score.c
@@ -1,309 +1,309 @@
-/* ------------------------- score ------------------------------------------ */
-/* */
-/* Simple score following / orientation. Incoming data gets compared to a */
-/* score stored in an array or table. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-
-#define MAX_NOTES 32 /* maximum number of notes that can be stored */
-
-static char *version = "score v0.1, score follower written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct score
-{
- t_object x_ob;
- t_inlet *x_invelo; /* inlet for velocity */
- t_inlet *x_inreset; /* inlet to reset the object */
- t_outlet *x_outindex; /* index :: position in given score */
- t_outlet *x_outerror; /* indicates lost orientation */
- t_symbol *x_sym; /* name of array that contains the score */
- t_garray *x_buf; /* the above array itselfe */
-
- t_int x_state; /* indicates state of score following: */
- /* running = 1, record = -1, stop = 0 */
- t_int x_skipindex; /* max. number of notes to skip */
- t_float x_skiptime; /* max time in ms to skip */
- t_int x_index; /* position in array / score */
- t_int x_lastpitch;
- t_int x_error;
-
- t_int x_notecount;
- t_int x_pitch;
- t_int x_velo;
- /* helpers needed to do the calculations */
- double x_starttime[MAX_NOTES];
- double x_laststarttime;
- t_int x_alloctable[MAX_NOTES];
-
-} t_score;
-
-static void score_float(t_score *x, t_floatarg f)
-{
- /* This is the score following algorhythm:
-
- first, we check if the note we got is in the score. In case
- it's not the next note, we'll search 'skipnotes' in advance.
- In case that fails we go back 'skipnotes' and check them. As
- extra these notes have to be 'younger' than 'skiptime' (to
- avoid going back too far in case of slow melodies)
- As last resort we check if we probably just got the same not
- again (double trigger from keyboard or the like)
- */
-
- t_int velo = x->x_velo; /* get the velocity */
- t_garray *b = x->x_buf; /* make local copy of array */
- float *tab; /* we'll store notes in here */
- int items;
- int i, j, n, check;
-
- x->x_pitch = (t_int)f;
- x->x_error = 0;
-
- /* check our array */
- if (!b)
- {
- post("score: no array selected!");
- x->x_error = 1;
- goto output;
- }
- if (!garray_getfloatarray(b, &items, &tab))
- {
- post("score: couldn't read from array!");
- x->x_error = 1;
- goto output;
- }
-
- if (x->x_state) /* score follower is running */
- {
- n = check = x->x_notecount; /* make local copys */
-
- if (x->x_velo != 0) /* store note-on in alloctable */
- {
- /* store note in alloctable */
- x->x_alloctable[n] = (t_int)x->x_pitch;
- /* store note-on time */
- x->x_starttime[n] = clock_getlogicaltime();
- if(++x->x_notecount >= MAX_NOTES)x->x_notecount = 0; /* total number of notes has increased */
- } else return; /* we don't care about note-off's */
-
- /* first we try to find a match within the skip area */
- /* ( probably looking ahead in the score ) */
- for (i = x->x_index + 1; i < (x->x_index + x->x_skipindex + 1); i++)
- {
- // post("%d: %d -> %d", i, x->x_alloctable[n], (t_int)tab[i]);
- if(x->x_alloctable[n] == (t_int)tab[i])
- {
- if(i - x->x_index != 1) post("score: skipped %d notes!", i - x->x_index - 1);
- x->x_alloctable[n] = -1; /* delete note, we've matched it! */
- x->x_index = i;
- goto output;
- }
- }
-
- /* then we look back within the boudaries of skiptime */
- for (i = x->x_index - 1; i > (x->x_index - x->x_skipindex) - 1; i--)
- {
- check = n; /* get current notecount */
-
- for (j = 0; j < MAX_NOTES; j++) /* check with every note from our alloctable */
- {
- if (x->x_alloctable[check] == (t_int)tab[i]) /* this one would fit */
- {
- /* check the time restrictions */
- if (clock_gettimesince(x->x_starttime[check]) < x->x_skiptime)
- {
- if (i != x->x_index) post("score: skipped %d notes in score!", x->x_index - i);
- if (j != 0) post("score: skipped %d notes from input!", j);
- post("score: going back by %g milliseconds!", clock_gettimesince(x->x_starttime[check]));
- x->x_index = i;
- /* new notecount: we assume the notes we skipped are errors made by the */
- /* performer. new notes will be added right behind the last valid one */
- x->x_notecount = (check++) % MAX_NOTES;
- x->x_alloctable[x->x_notecount - 1] = -1; /* delete note since we've matched it */
- goto output;
- }
- else /* ough, too old ! */
- {
- post("score: matching note is too old! (ignored)");
- x->x_alloctable[check] = 0; /* delete note since it's too old */
- x->x_error = 1;
- goto output; /* stop with first match as all others would be far older */
- }
- }
- if(--check < 0) check = MAX_NOTES - 1; /* decrease counter */
- /* as we want to go back in time */
- }
- }
- /* or is it just the same note again ??? (double trigger...) */
- if(x->x_pitch == x->x_lastpitch)
- {
- post("score: repetition! (ignored)");
- x->x_alloctable[x->x_notecount - 1] = -1; /* forget this one */
- return;
- }
-
- /* in case we found nothing: indicate that! */
- x->x_error = 1;
- post("score: couldn't find any matches !");
- x->x_lastpitch = x->x_pitch;
- goto output;
- }
- else return;
-
-output:
- /* output index */
- outlet_float(x->x_outindex, x->x_index);
- /* bang in case of error */
- if(x->x_error) outlet_bang(x->x_outerror);
-}
-
-static void score_ft1(t_score *x, t_floatarg f)
-{
- x->x_velo = (t_int)f;
-}
-
- /* start following the previoisly recorded score */
-static void score_start(t_score *x, t_symbol *s, t_int argc, t_atom* argv)
-{
- x->x_index = (t_int)atom_getfloatarg(0, argc, argv);
- if(x->x_index > 0)
- {
- post("score: starting at note %d", x->x_index);
- }
- else post("score: start following");
- x->x_index--; /* because our array starts with 0 */
- x->x_state = 1;
-}
- /* resume following the previoisly recorded score */
-static void score_resume(t_score *x)
-{
- x->x_state = 1;
- post("score: resume following");
-}
-
- /* stop following the previoisly recorded score */
-static void score_stop(t_score *x)
-{
- x->x_state = 0;
- post("score: stop following");
-}
-
- /* choose the array that holds the score */
-void score_set(t_score *x, t_symbol *s)
-{
- t_garray *b;
-
- x->x_sym = s;
-
- if ((b = (t_garray *)pd_findbyclass(s, garray_class)))
- {
- post("score: array set to \"%s\"", s->s_name);
- x->x_buf = b;
- } else {
- post("score: no array \"%s\" (error %d)", s->s_name, b);
- x->x_buf = 0;
- }
-}
-
-static void score_reset(t_score *x)
-{
- int i;
-
- x->x_state = 0; /* don't follow */
- x->x_error = 0;
- x->x_index = -1;
- x->x_notecount = 0;
- x->x_lastpitch = 0;
- for(i = 0; i < MAX_NOTES; i++)x->x_alloctable[i] = -1;
-
- post("score: reset");
-}
-
-static void score_free(t_score *x)
-{
- // nothing to do
-}
-
-static t_class *score_class;
-
-static void *score_new(t_symbol *s, t_floatarg fskipindex, t_floatarg fskiptime)
-{
- int i;
-
- t_score *x = (t_score *)pd_new(score_class);
- x->x_invelo = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
- x->x_inreset = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("bang"), gensym("reset"));
- x->x_outindex = outlet_new(&x->x_ob, gensym("float"));
- x->x_outerror = outlet_new(&x->x_ob, gensym("float"));
-
- x->x_sym = s; /* get name of array */
- score_set(x,x->x_sym); /* set array */
- if(!fskipindex)fskipindex = 2;
- if(!fskiptime)fskiptime = 300.0;
- x->x_skipindex = (t_int)fskipindex;
- x->x_skiptime = (t_float)fskiptime;
- post("score: skipindex set to %d, skiptime set to %g milliseconds", x->x_skipindex, x->x_skiptime);
-
- x->x_state = 0; /* don't follow */
- x->x_error = 0;
- x->x_index = -1;
- x->x_notecount = 0;
- x->x_pitch = x->x_lastpitch = -1;
- for(i = 0; i < MAX_NOTES; i++)x->x_alloctable[i] = -1;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void score_setup(void)
-{
- score_class = class_new(gensym("score"), (t_newmethod)score_new,
- (t_method)score_free, sizeof(t_score), 0, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(score_class, (t_method)score_reset, gensym("reset"), 0);
- class_addmethod(score_class, (t_method)score_resume, gensym("resume"), 0);
- class_addmethod(score_class, (t_method)score_start, gensym("start"), A_GIMME, 0);
- class_addmethod(score_class, (t_method)score_stop, gensym("stop"), 0);
- class_addmethod(score_class, (t_method)score_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addmethod(score_class, (t_method)score_reset, gensym("reset"), A_GIMME, 0);
- class_addmethod(score_class, (t_method)score_set, gensym("set"), A_SYMBOL, 0);
- class_addfloat(score_class, score_float);
-
- post(version);
-}
-#else
-void maxlib_score_setup(void)
-{
- score_class = class_new(gensym("maxlib_score"), (t_newmethod)score_new,
- (t_method)score_free, sizeof(t_score), 0, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)score_new, gensym("score"), A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(score_class, (t_method)score_reset, gensym("reset"), 0);
- class_addmethod(score_class, (t_method)score_resume, gensym("resume"), 0);
- class_addmethod(score_class, (t_method)score_start, gensym("start"), A_GIMME, 0);
- class_addmethod(score_class, (t_method)score_stop, gensym("stop"), 0);
- class_addmethod(score_class, (t_method)score_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addmethod(score_class, (t_method)score_reset, gensym("reset"), A_GIMME, 0);
- class_addmethod(score_class, (t_method)score_set, gensym("set"), A_SYMBOL, 0);
- class_addfloat(score_class, score_float);
- class_sethelpsymbol(score_class, gensym("maxlib/score-help.pd"));
-}
-#endif
+/* ------------------------- score ------------------------------------------ */
+/* */
+/* Simple score following / orientation. Incoming data gets compared to a */
+/* score stored in an array or table. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+#define MAX_NOTES 32 /* maximum number of notes that can be stored */
+
+static char *version = "score v0.1, score follower written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct score
+{
+ t_object x_ob;
+ t_inlet *x_invelo; /* inlet for velocity */
+ t_inlet *x_inreset; /* inlet to reset the object */
+ t_outlet *x_outindex; /* index :: position in given score */
+ t_outlet *x_outerror; /* indicates lost orientation */
+ t_symbol *x_sym; /* name of array that contains the score */
+ t_garray *x_buf; /* the above array itselfe */
+
+ t_int x_state; /* indicates state of score following: */
+ /* running = 1, record = -1, stop = 0 */
+ t_int x_skipindex; /* max. number of notes to skip */
+ t_float x_skiptime; /* max time in ms to skip */
+ t_int x_index; /* position in array / score */
+ t_int x_lastpitch;
+ t_int x_error;
+
+ t_int x_notecount;
+ t_int x_pitch;
+ t_int x_velo;
+ /* helpers needed to do the calculations */
+ double x_starttime[MAX_NOTES];
+ double x_laststarttime;
+ t_int x_alloctable[MAX_NOTES];
+
+} t_score;
+
+static void score_float(t_score *x, t_floatarg f)
+{
+ /* This is the score following algorhythm:
+
+ first, we check if the note we got is in the score. In case
+ it's not the next note, we'll search 'skipnotes' in advance.
+ In case that fails we go back 'skipnotes' and check them. As
+ extra these notes have to be 'younger' than 'skiptime' (to
+ avoid going back too far in case of slow melodies)
+ As last resort we check if we probably just got the same not
+ again (double trigger from keyboard or the like)
+ */
+
+ t_int velo = x->x_velo; /* get the velocity */
+ t_garray *b = x->x_buf; /* make local copy of array */
+ float *tab; /* we'll store notes in here */
+ int items;
+ int i, j, n, check;
+
+ x->x_pitch = (t_int)f;
+ x->x_error = 0;
+
+ /* check our array */
+ if (!b)
+ {
+ post("score: no array selected!");
+ x->x_error = 1;
+ goto output;
+ }
+ if (!garray_getfloatarray(b, &items, &tab))
+ {
+ post("score: couldn't read from array!");
+ x->x_error = 1;
+ goto output;
+ }
+
+ if (x->x_state) /* score follower is running */
+ {
+ n = check = x->x_notecount; /* make local copys */
+
+ if (x->x_velo != 0) /* store note-on in alloctable */
+ {
+ /* store note in alloctable */
+ x->x_alloctable[n] = (t_int)x->x_pitch;
+ /* store note-on time */
+ x->x_starttime[n] = clock_getlogicaltime();
+ if(++x->x_notecount >= MAX_NOTES)x->x_notecount = 0; /* total number of notes has increased */
+ } else return; /* we don't care about note-off's */
+
+ /* first we try to find a match within the skip area */
+ /* ( probably looking ahead in the score ) */
+ for (i = x->x_index + 1; i < (x->x_index + x->x_skipindex + 1); i++)
+ {
+ // post("%d: %d -> %d", i, x->x_alloctable[n], (t_int)tab[i]);
+ if(x->x_alloctable[n] == (t_int)tab[i])
+ {
+ if(i - x->x_index != 1) post("score: skipped %d notes!", i - x->x_index - 1);
+ x->x_alloctable[n] = -1; /* delete note, we've matched it! */
+ x->x_index = i;
+ goto output;
+ }
+ }
+
+ /* then we look back within the boudaries of skiptime */
+ for (i = x->x_index - 1; i > (x->x_index - x->x_skipindex) - 1; i--)
+ {
+ check = n; /* get current notecount */
+
+ for (j = 0; j < MAX_NOTES; j++) /* check with every note from our alloctable */
+ {
+ if (x->x_alloctable[check] == (t_int)tab[i]) /* this one would fit */
+ {
+ /* check the time restrictions */
+ if (clock_gettimesince(x->x_starttime[check]) < x->x_skiptime)
+ {
+ if (i != x->x_index) post("score: skipped %d notes in score!", x->x_index - i);
+ if (j != 0) post("score: skipped %d notes from input!", j);
+ post("score: going back by %g milliseconds!", clock_gettimesince(x->x_starttime[check]));
+ x->x_index = i;
+ /* new notecount: we assume the notes we skipped are errors made by the */
+ /* performer. new notes will be added right behind the last valid one */
+ x->x_notecount = (check++) % MAX_NOTES;
+ x->x_alloctable[x->x_notecount - 1] = -1; /* delete note since we've matched it */
+ goto output;
+ }
+ else /* ough, too old ! */
+ {
+ post("score: matching note is too old! (ignored)");
+ x->x_alloctable[check] = 0; /* delete note since it's too old */
+ x->x_error = 1;
+ goto output; /* stop with first match as all others would be far older */
+ }
+ }
+ if(--check < 0) check = MAX_NOTES - 1; /* decrease counter */
+ /* as we want to go back in time */
+ }
+ }
+ /* or is it just the same note again ??? (double trigger...) */
+ if(x->x_pitch == x->x_lastpitch)
+ {
+ post("score: repetition! (ignored)");
+ x->x_alloctable[x->x_notecount - 1] = -1; /* forget this one */
+ return;
+ }
+
+ /* in case we found nothing: indicate that! */
+ x->x_error = 1;
+ post("score: couldn't find any matches !");
+ x->x_lastpitch = x->x_pitch;
+ goto output;
+ }
+ else return;
+
+output:
+ /* output index */
+ outlet_float(x->x_outindex, x->x_index);
+ /* bang in case of error */
+ if(x->x_error) outlet_bang(x->x_outerror);
+}
+
+static void score_ft1(t_score *x, t_floatarg f)
+{
+ x->x_velo = (t_int)f;
+}
+
+ /* start following the previoisly recorded score */
+static void score_start(t_score *x, t_symbol *s, t_int argc, t_atom* argv)
+{
+ x->x_index = (t_int)atom_getfloatarg(0, argc, argv);
+ if(x->x_index > 0)
+ {
+ post("score: starting at note %d", x->x_index);
+ }
+ else post("score: start following");
+ x->x_index--; /* because our array starts with 0 */
+ x->x_state = 1;
+}
+ /* resume following the previoisly recorded score */
+static void score_resume(t_score *x)
+{
+ x->x_state = 1;
+ post("score: resume following");
+}
+
+ /* stop following the previoisly recorded score */
+static void score_stop(t_score *x)
+{
+ x->x_state = 0;
+ post("score: stop following");
+}
+
+ /* choose the array that holds the score */
+void score_set(t_score *x, t_symbol *s)
+{
+ t_garray *b;
+
+ x->x_sym = s;
+
+ if ((b = (t_garray *)pd_findbyclass(s, garray_class)))
+ {
+ post("score: array set to \"%s\"", s->s_name);
+ x->x_buf = b;
+ } else {
+ post("score: no array \"%s\" (error %d)", s->s_name, b);
+ x->x_buf = 0;
+ }
+}
+
+static void score_reset(t_score *x)
+{
+ int i;
+
+ x->x_state = 0; /* don't follow */
+ x->x_error = 0;
+ x->x_index = -1;
+ x->x_notecount = 0;
+ x->x_lastpitch = 0;
+ for(i = 0; i < MAX_NOTES; i++)x->x_alloctable[i] = -1;
+
+ post("score: reset");
+}
+
+static void score_free(t_score *x)
+{
+ // nothing to do
+}
+
+static t_class *score_class;
+
+static void *score_new(t_symbol *s, t_floatarg fskipindex, t_floatarg fskiptime)
+{
+ int i;
+
+ t_score *x = (t_score *)pd_new(score_class);
+ x->x_invelo = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1"));
+ x->x_inreset = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("bang"), gensym("reset"));
+ x->x_outindex = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outerror = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_sym = s; /* get name of array */
+ score_set(x,x->x_sym); /* set array */
+ if(!fskipindex)fskipindex = 2;
+ if(!fskiptime)fskiptime = 300.0;
+ x->x_skipindex = (t_int)fskipindex;
+ x->x_skiptime = (t_float)fskiptime;
+ post("score: skipindex set to %d, skiptime set to %g milliseconds", x->x_skipindex, x->x_skiptime);
+
+ x->x_state = 0; /* don't follow */
+ x->x_error = 0;
+ x->x_index = -1;
+ x->x_notecount = 0;
+ x->x_pitch = x->x_lastpitch = -1;
+ for(i = 0; i < MAX_NOTES; i++)x->x_alloctable[i] = -1;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void score_setup(void)
+{
+ score_class = class_new(gensym("score"), (t_newmethod)score_new,
+ (t_method)score_free, sizeof(t_score), 0, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(score_class, (t_method)score_reset, gensym("reset"), 0);
+ class_addmethod(score_class, (t_method)score_resume, gensym("resume"), 0);
+ class_addmethod(score_class, (t_method)score_start, gensym("start"), A_GIMME, 0);
+ class_addmethod(score_class, (t_method)score_stop, gensym("stop"), 0);
+ class_addmethod(score_class, (t_method)score_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(score_class, (t_method)score_reset, gensym("reset"), A_GIMME, 0);
+ class_addmethod(score_class, (t_method)score_set, gensym("set"), A_SYMBOL, 0);
+ class_addfloat(score_class, score_float);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_score_setup(void)
+{
+ score_class = class_new(gensym("maxlib_score"), (t_newmethod)score_new,
+ (t_method)score_free, sizeof(t_score), 0, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)score_new, gensym("score"), A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(score_class, (t_method)score_reset, gensym("reset"), 0);
+ class_addmethod(score_class, (t_method)score_resume, gensym("resume"), 0);
+ class_addmethod(score_class, (t_method)score_start, gensym("start"), A_GIMME, 0);
+ class_addmethod(score_class, (t_method)score_stop, gensym("stop"), 0);
+ class_addmethod(score_class, (t_method)score_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(score_class, (t_method)score_reset, gensym("reset"), A_GIMME, 0);
+ class_addmethod(score_class, (t_method)score_set, gensym("set"), A_SYMBOL, 0);
+ class_addfloat(score_class, score_float);
+ class_sethelpsymbol(score_class, gensym("maxlib/score-help.pd"));
+}
+#endif
diff --git a/speedlim.c b/speedlim.c
index 72ad34c..4b917c0 100644
--- a/speedlim.c
+++ b/speedlim.c
@@ -1,235 +1,235 @@
-/* ------------------------- speedlim ----------------------------------------- */
-/* */
-/* Lets information through only every N milliseconds. */
-/* Written by Krzysztof Czaja for his cyclone library. */
-/* Modified to fit into maxlib by Olaf Matthes <olaf.matthes@gmx.de>. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* You should have received a copy of the GNU Lesser General Public */
-/* License along with this library; if not, write to the */
-/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
-/* Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-/* this is the original copyright notice: */
-
-/* Copyright (c) 1997-2002 Miller Puckette and others.
- * For information on usage and redistribution, and for a DISCLAIMER OF ALL
- * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
-
-
-#include <string.h>
-#include "m_pd.h"
-
-#define SPEEDLIM_INISIZE 32 /* LATER rethink */
-#define SPEEDLIM_MAXSIZE 256 /* not used */
-
-typedef struct _speedlim
-{
- t_object x_ob;
- int x_open;
- t_float x_delta;
- t_symbol *x_selector;
- t_float x_float;
- t_symbol *x_symbol;
- t_gpointer *x_pointer;
- int x_size; /* as allocated */
- int x_natoms; /* as used */
- t_atom *x_message;
- t_atom x_messini[SPEEDLIM_INISIZE];
- int x_entered;
- t_clock *x_clock;
-} t_speedlim;
-
-static t_class *speedlim_class;
-
-/* a caller must check for nrequested > *sizep */
-/* returns actual number of atoms: requested (success)
- or a default value of initial size (failure) */
-/* the result is guaranteed to be >= min(nrequested, inisize) */
-static int speedlim_grow(int nrequested, int *sizep, t_atom **bufp,
- int inisize, t_atom *bufini)
-{
- int newsize = *sizep * 2;
- while (newsize < nrequested) newsize *= 2;
- if (*bufp == bufini)
- *bufp = (t_atom *)getbytes(newsize * sizeof(**bufp));
- else
- *bufp = (t_atom *)resizebytes(*bufp, *sizep * sizeof(**bufp),
- newsize * sizeof(**bufp));
- if (*bufp)
- *sizep = newsize;
- else
- {
- *bufp = bufini;
- nrequested = *sizep = inisize;
- }
- return (nrequested);
-}
-
-static void speedlim_dooutput(t_speedlim *x, t_symbol *s, int ac, t_atom *av)
-{
- x->x_open = 0; /* so there will be no reentrant calls of dooutput */
- x->x_entered = 1; /* this prevents a message from being overridden */
- clock_unset(x->x_clock);
- if (s == &s_bang)
- outlet_bang(((t_object *)x)->ob_outlet);
- else if (s == &s_float)
- outlet_float(((t_object *)x)->ob_outlet, x->x_float);
- else if (s == &s_symbol && x->x_symbol)
- {
- /* if x_symbol is null, then symbol &s_ is passed
- by outlet_anything() -> typedmess() */
- outlet_symbol(((t_object *)x)->ob_outlet, x->x_symbol);
- x->x_symbol = 0;
- }
- else if (s == &s_pointer && x->x_pointer)
- {
- /* LATER */
- x->x_pointer = 0;
- }
- else if (s == &s_list)
- outlet_list(((t_object *)x)->ob_outlet, &s_list, ac, av);
- else if (s)
- outlet_anything(((t_object *)x)->ob_outlet, s, ac, av);
- x->x_selector = 0;
- x->x_natoms = 0;
- if (x->x_delta > 0)
- clock_delay(x->x_clock, x->x_delta);
- else
- x->x_open = 1;
- x->x_entered = 0;
-}
-
-static void speedlim_tick(t_speedlim *x)
-{
- if (x->x_selector)
- speedlim_dooutput(x, x->x_selector, x->x_natoms, x->x_message);
- else
- x->x_open = 1;
-}
-
-static void speedlim_anything(t_speedlim *x, t_symbol *s, int ac, t_atom *av)
-{
- if (x->x_open)
- speedlim_dooutput(x, s, ac, av);
- else if (s && s != &s_ && !x->x_entered)
- {
- if (ac > x->x_size)
- /* MAXSIZE not used, not even a warning...
- LATER consider clipping */
- ac = speedlim_grow(ac, &x->x_size, &x->x_message,
- SPEEDLIM_INISIZE, x->x_messini);
- x->x_selector = s;
- x->x_natoms = ac;
- if (ac)
- memcpy(x->x_message, av, ac * sizeof(*x->x_message));
- }
-}
-
-static void speedlim_bang(t_speedlim *x)
-{
- x->x_selector = &s_bang;
- speedlim_anything(x, x->x_selector, 0, 0);
-}
-
-static void speedlim_float(t_speedlim *x, t_float f)
-{
- x->x_selector = &s_float;
- x->x_float = f;
- speedlim_anything(x, x->x_selector, 0, 0);
-}
-
-static void speedlim_symbol(t_speedlim *x, t_symbol *s)
-{
- x->x_selector = &s_symbol;
- x->x_symbol = s;
- speedlim_anything(x, x->x_selector, 0, 0);
-}
-
-/* LATER gpointer */
-
-static void speedlim_list(t_speedlim *x, t_symbol *s, int ac, t_atom *av)
-{
- x->x_selector = &s_list;
- speedlim_anything(x, x->x_selector, ac, av);
-}
-
-static void speedlim_ft1(t_speedlim *x, t_floatarg f)
-{
- if (f < 0)
- f = 0; /* redundant (and CHECKED) */
- x->x_delta = f;
- /* CHECKED: no rearming --
- if clock is set, then new delta value is not used until next tick */
-}
-
-static void speedlim_free(t_speedlim *x)
-{
- if (x->x_message != x->x_messini)
- freebytes(x->x_message, x->x_size * sizeof(*x->x_message));
- if (x->x_clock)
- clock_free(x->x_clock);
-}
-
-static void *speedlim_new(t_floatarg f)
-{
- t_speedlim *x = (t_speedlim *)pd_new(speedlim_class);
- x->x_open = 1; /* CHECKED */
- x->x_delta = 0;
- x->x_selector = 0;
- x->x_float = 0;
- x->x_symbol = 0;
- x->x_pointer = 0;
- x->x_size = SPEEDLIM_INISIZE;
- x->x_natoms = 0;
- x->x_message = x->x_messini;
- x->x_entered = 0;
- inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1"));
- outlet_new((t_object *)x, &s_anything);
- x->x_clock = clock_new(x, (t_method)speedlim_tick);
- speedlim_ft1(x, f);
- return (x);
-}
-
-#ifndef MAXLIB
-void speedlim_setup(void)
-{
- speedlim_class = class_new(gensym("speedlim"), (t_newmethod)speedlim_new,
- (t_method)speedlim_free, sizeof(t_speedlim), 0, A_DEFFLOAT, 0);
-#else
-void maxlib_speedlim_setup(void)
-{
- speedlim_class = class_new(gensym("maxlib_speedlim"), (t_newmethod)speedlim_new,
- (t_method)speedlim_free, sizeof(t_speedlim), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)speedlim_new, gensym("speedlim"), A_DEFFLOAT, 0);
-#endif
- class_addbang(speedlim_class, speedlim_bang);
- class_addfloat(speedlim_class, speedlim_float);
- class_addsymbol(speedlim_class, speedlim_symbol);
- class_addlist(speedlim_class, speedlim_list);
- class_addanything(speedlim_class, speedlim_anything);
- class_addmethod(speedlim_class, (t_method)speedlim_ft1, gensym("ft1"), A_FLOAT, 0);
-#ifndef MAXLIB
-
-#else
- class_sethelpsymbol(speedlim_class, gensym("maxlib/speedlim-help.pd"));
-#endif
-}
+/* ------------------------- speedlim ----------------------------------------- */
+/* */
+/* Lets information through only every N milliseconds. */
+/* Written by Krzysztof Czaja for his cyclone library. */
+/* Modified to fit into maxlib by Olaf Matthes <olaf.matthes@gmx.de>. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* You should have received a copy of the GNU Lesser General Public */
+/* License along with this library; if not, write to the */
+/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
+/* Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+/* this is the original copyright notice: */
+
+/* Copyright (c) 1997-2002 Miller Puckette and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+
+#include <string.h>
+#include "m_pd.h"
+
+#define SPEEDLIM_INISIZE 32 /* LATER rethink */
+#define SPEEDLIM_MAXSIZE 256 /* not used */
+
+typedef struct _speedlim
+{
+ t_object x_ob;
+ int x_open;
+ t_float x_delta;
+ t_symbol *x_selector;
+ t_float x_float;
+ t_symbol *x_symbol;
+ t_gpointer *x_pointer;
+ int x_size; /* as allocated */
+ int x_natoms; /* as used */
+ t_atom *x_message;
+ t_atom x_messini[SPEEDLIM_INISIZE];
+ int x_entered;
+ t_clock *x_clock;
+} t_speedlim;
+
+static t_class *speedlim_class;
+
+/* a caller must check for nrequested > *sizep */
+/* returns actual number of atoms: requested (success)
+ or a default value of initial size (failure) */
+/* the result is guaranteed to be >= min(nrequested, inisize) */
+static int speedlim_grow(int nrequested, int *sizep, t_atom **bufp,
+ int inisize, t_atom *bufini)
+{
+ int newsize = *sizep * 2;
+ while (newsize < nrequested) newsize *= 2;
+ if (*bufp == bufini)
+ *bufp = (t_atom *)getbytes(newsize * sizeof(**bufp));
+ else
+ *bufp = (t_atom *)resizebytes(*bufp, *sizep * sizeof(**bufp),
+ newsize * sizeof(**bufp));
+ if (*bufp)
+ *sizep = newsize;
+ else
+ {
+ *bufp = bufini;
+ nrequested = *sizep = inisize;
+ }
+ return (nrequested);
+}
+
+static void speedlim_dooutput(t_speedlim *x, t_symbol *s, int ac, t_atom *av)
+{
+ x->x_open = 0; /* so there will be no reentrant calls of dooutput */
+ x->x_entered = 1; /* this prevents a message from being overridden */
+ clock_unset(x->x_clock);
+ if (s == &s_bang)
+ outlet_bang(((t_object *)x)->ob_outlet);
+ else if (s == &s_float)
+ outlet_float(((t_object *)x)->ob_outlet, x->x_float);
+ else if (s == &s_symbol && x->x_symbol)
+ {
+ /* if x_symbol is null, then symbol &s_ is passed
+ by outlet_anything() -> typedmess() */
+ outlet_symbol(((t_object *)x)->ob_outlet, x->x_symbol);
+ x->x_symbol = 0;
+ }
+ else if (s == &s_pointer && x->x_pointer)
+ {
+ /* LATER */
+ x->x_pointer = 0;
+ }
+ else if (s == &s_list)
+ outlet_list(((t_object *)x)->ob_outlet, &s_list, ac, av);
+ else if (s)
+ outlet_anything(((t_object *)x)->ob_outlet, s, ac, av);
+ x->x_selector = 0;
+ x->x_natoms = 0;
+ if (x->x_delta > 0)
+ clock_delay(x->x_clock, x->x_delta);
+ else
+ x->x_open = 1;
+ x->x_entered = 0;
+}
+
+static void speedlim_tick(t_speedlim *x)
+{
+ if (x->x_selector)
+ speedlim_dooutput(x, x->x_selector, x->x_natoms, x->x_message);
+ else
+ x->x_open = 1;
+}
+
+static void speedlim_anything(t_speedlim *x, t_symbol *s, int ac, t_atom *av)
+{
+ if (x->x_open)
+ speedlim_dooutput(x, s, ac, av);
+ else if (s && s != &s_ && !x->x_entered)
+ {
+ if (ac > x->x_size)
+ /* MAXSIZE not used, not even a warning...
+ LATER consider clipping */
+ ac = speedlim_grow(ac, &x->x_size, &x->x_message,
+ SPEEDLIM_INISIZE, x->x_messini);
+ x->x_selector = s;
+ x->x_natoms = ac;
+ if (ac)
+ memcpy(x->x_message, av, ac * sizeof(*x->x_message));
+ }
+}
+
+static void speedlim_bang(t_speedlim *x)
+{
+ x->x_selector = &s_bang;
+ speedlim_anything(x, x->x_selector, 0, 0);
+}
+
+static void speedlim_float(t_speedlim *x, t_float f)
+{
+ x->x_selector = &s_float;
+ x->x_float = f;
+ speedlim_anything(x, x->x_selector, 0, 0);
+}
+
+static void speedlim_symbol(t_speedlim *x, t_symbol *s)
+{
+ x->x_selector = &s_symbol;
+ x->x_symbol = s;
+ speedlim_anything(x, x->x_selector, 0, 0);
+}
+
+/* LATER gpointer */
+
+static void speedlim_list(t_speedlim *x, t_symbol *s, int ac, t_atom *av)
+{
+ x->x_selector = &s_list;
+ speedlim_anything(x, x->x_selector, ac, av);
+}
+
+static void speedlim_ft1(t_speedlim *x, t_floatarg f)
+{
+ if (f < 0)
+ f = 0; /* redundant (and CHECKED) */
+ x->x_delta = f;
+ /* CHECKED: no rearming --
+ if clock is set, then new delta value is not used until next tick */
+}
+
+static void speedlim_free(t_speedlim *x)
+{
+ if (x->x_message != x->x_messini)
+ freebytes(x->x_message, x->x_size * sizeof(*x->x_message));
+ if (x->x_clock)
+ clock_free(x->x_clock);
+}
+
+static void *speedlim_new(t_floatarg f)
+{
+ t_speedlim *x = (t_speedlim *)pd_new(speedlim_class);
+ x->x_open = 1; /* CHECKED */
+ x->x_delta = 0;
+ x->x_selector = 0;
+ x->x_float = 0;
+ x->x_symbol = 0;
+ x->x_pointer = 0;
+ x->x_size = SPEEDLIM_INISIZE;
+ x->x_natoms = 0;
+ x->x_message = x->x_messini;
+ x->x_entered = 0;
+ inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1"));
+ outlet_new((t_object *)x, &s_anything);
+ x->x_clock = clock_new(x, (t_method)speedlim_tick);
+ speedlim_ft1(x, f);
+ return (x);
+}
+
+#ifndef MAXLIB
+void speedlim_setup(void)
+{
+ speedlim_class = class_new(gensym("speedlim"), (t_newmethod)speedlim_new,
+ (t_method)speedlim_free, sizeof(t_speedlim), 0, A_DEFFLOAT, 0);
+#else
+void maxlib_speedlim_setup(void)
+{
+ speedlim_class = class_new(gensym("maxlib_speedlim"), (t_newmethod)speedlim_new,
+ (t_method)speedlim_free, sizeof(t_speedlim), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)speedlim_new, gensym("speedlim"), A_DEFFLOAT, 0);
+#endif
+ class_addbang(speedlim_class, speedlim_bang);
+ class_addfloat(speedlim_class, speedlim_float);
+ class_addsymbol(speedlim_class, speedlim_symbol);
+ class_addlist(speedlim_class, speedlim_list);
+ class_addanything(speedlim_class, speedlim_anything);
+ class_addmethod(speedlim_class, (t_method)speedlim_ft1, gensym("ft1"), A_FLOAT, 0);
+#ifndef MAXLIB
+
+#else
+ class_sethelpsymbol(speedlim_class, gensym("maxlib/speedlim-help.pd"));
+#endif
+}
diff --git a/split.c b/split.c
index 6b1b13a..de3f662 100644
--- a/split.c
+++ b/split.c
@@ -1,95 +1,95 @@
-/* ------------------------- split ------------------------------------------ */
-/* */
-/* splits input to lie within an output range. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <math.h>
-
-static char *version = "split v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct split
-{
- t_object x_ob;
- t_float x_min; /* low border of input range */
- t_float x_max; /* high border of input range */
- t_int x_revert; /* range is inverted */
- t_outlet *x_outlet1; /* path-through outlet */
- t_outlet *x_outlet2; /* split outlet */
-} t_split;
-
-static void split_float(t_split *x, t_floatarg f)
-{
- if(x->x_max >= x->x_min)
- {
- if(f <= x->x_max && f >= x->x_min)
- outlet_float(x->x_outlet1, f);
- else
- outlet_float(x->x_outlet2, f);
- }
- else
- {
- if(f >= x->x_max && f <= x->x_min)
- outlet_float(x->x_outlet1, f);
- else
- outlet_float(x->x_outlet2, f);
- }
-}
-
-static t_class *split_class;
-
-static void *split_new(t_floatarg fmin, t_floatarg fmax)
-{
- t_split *x = (t_split *)pd_new(split_class);
-
- floatinlet_new(&x->x_ob, &x->x_min);
- floatinlet_new(&x->x_ob, &x->x_max);
-
- x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
- x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
-
- x->x_min = fmin;
- x->x_max = fmax;
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void split_setup(void)
-{
- split_class = class_new(gensym("split"), (t_newmethod)split_new,
- 0, sizeof(t_split), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addfloat(split_class, split_float);
-
- post(version);
-}
-#else
-void maxlib_split_setup(void)
-{
- split_class = class_new(gensym("maxlib_split"), (t_newmethod)split_new,
- 0, sizeof(t_split), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)split_new, gensym("split"), A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addfloat(split_class, split_float);
- class_sethelpsymbol(split_class, gensym("maxlib/split-help.pd"));
-}
-#endif
+/* ------------------------- split ------------------------------------------ */
+/* */
+/* splits input to lie within an output range. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+
+static char *version = "split v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct split
+{
+ t_object x_ob;
+ t_float x_min; /* low border of input range */
+ t_float x_max; /* high border of input range */
+ t_int x_revert; /* range is inverted */
+ t_outlet *x_outlet1; /* path-through outlet */
+ t_outlet *x_outlet2; /* split outlet */
+} t_split;
+
+static void split_float(t_split *x, t_floatarg f)
+{
+ if(x->x_max >= x->x_min)
+ {
+ if(f <= x->x_max && f >= x->x_min)
+ outlet_float(x->x_outlet1, f);
+ else
+ outlet_float(x->x_outlet2, f);
+ }
+ else
+ {
+ if(f >= x->x_max && f <= x->x_min)
+ outlet_float(x->x_outlet1, f);
+ else
+ outlet_float(x->x_outlet2, f);
+ }
+}
+
+static t_class *split_class;
+
+static void *split_new(t_floatarg fmin, t_floatarg fmax)
+{
+ t_split *x = (t_split *)pd_new(split_class);
+
+ floatinlet_new(&x->x_ob, &x->x_min);
+ floatinlet_new(&x->x_ob, &x->x_max);
+
+ x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_min = fmin;
+ x->x_max = fmax;
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void split_setup(void)
+{
+ split_class = class_new(gensym("split"), (t_newmethod)split_new,
+ 0, sizeof(t_split), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(split_class, split_float);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_split_setup(void)
+{
+ split_class = class_new(gensym("maxlib_split"), (t_newmethod)split_new,
+ 0, sizeof(t_split), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)split_new, gensym("split"), A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(split_class, split_float);
+ class_sethelpsymbol(split_class, gensym("maxlib/split-help.pd"));
+}
+#endif
diff --git a/step.c b/step.c
index 3057347..cc44f7b 100644
--- a/step.c
+++ b/step.c
@@ -1,179 +1,179 @@
-/* -------------------------- step ------------------------------------------ */
-/* */
-/* Step to a new value in N milliseconds (similar to line). */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-
-/* -------------------------- step ------------------------------ */
-static char *version = "step v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-static t_class *step_class;
-
-typedef struct _step
-{
- t_object x_obj;
- t_clock *x_clock;
- double x_targettime;
- t_float x_targetval;
- double x_prevtime;
- t_float x_setval;
- int x_gotinlet;
- t_float x_grain; /* time interval for output */
- t_float x_step; /* step size for output */
- t_float x_steptime; /* length for one step */
- t_int x_stepcall;
- double x_1overtimediff;
- double x_in1val;
-} t_step;
-
-static void step_tick(t_step *x)
-{
- t_float outvalue;
- double timenow = clock_getsystime();
- double msectogo = - clock_gettimesince(x->x_targettime);
- if (msectogo < 1E-9)
- {
- outlet_float(x->x_obj.ob_outlet, x->x_targetval);
- }
- else
- {
- if(x->x_setval < x->x_targetval)
- { /* count upwards */
- outvalue = x->x_setval + x->x_stepcall * x->x_step;
- }
- else
- { /* count downwards */
- outvalue = x->x_setval - x->x_stepcall * x->x_step;
- }
- outlet_float(x->x_obj.ob_outlet, outvalue);
- clock_delay(x->x_clock, (x->x_steptime > msectogo ? msectogo : x->x_steptime));
- }
- x->x_stepcall++;
-}
-
-static void step_float(t_step *x, t_float f)
-{
- double timenow = clock_getsystime();
- if (x->x_gotinlet && x->x_in1val > 0 && x->x_step != 0 && f != x->x_setval)
- {
- if (timenow > x->x_targettime) x->x_setval = x->x_targetval;
- else x->x_setval = x->x_setval + x->x_1overtimediff *
- (timenow - x->x_prevtime)
- * (x->x_targetval - x->x_setval);
- x->x_prevtime = timenow;
- x->x_targetval = f; /* where to end */
- x->x_stepcall = 0;
- /* how long does it take ? */
- x->x_targettime = clock_getsystimeafter(x->x_in1val);
- if(x->x_setval < x->x_targetval)
- {
- x->x_steptime = x->x_in1val / (int)((x->x_targetval - x->x_setval) / x->x_step);
- }
- else
- {
- x->x_steptime = x->x_in1val / (int)((x->x_setval - x->x_targetval) / x->x_step);
- }
- // post("steptime %g", x->x_steptime);
- step_tick(x);
- x->x_gotinlet = 0;
- x->x_1overtimediff = 1./ (x->x_targettime - timenow);
- /* call tick function */
- clock_delay(x->x_clock, x->x_steptime);
-
- }
- else
- {
- clock_unset(x->x_clock);
- x->x_targetval = x->x_setval = f;
- outlet_float(x->x_obj.ob_outlet, f);
- }
- x->x_gotinlet = 0;
-}
-
-static void step_ft1(t_step *x, t_floatarg g)
-{
- x->x_in1val = g;
- x->x_gotinlet = 1;
-}
-
-static void step_ft2(t_step *x, t_floatarg g)
-{
- if (g <= 0) g = 1;
- x->x_step = g;
- x->x_gotinlet = 1;
-}
-
-static void step_stop(t_step *x)
-{
- x->x_targetval = x->x_setval;
- clock_unset(x->x_clock);
-}
-
-static void step_free(t_step *x)
-{
- clock_free(x->x_clock);
-}
-
-static void *step_new(t_floatarg f, t_floatarg step, t_floatarg grain)
-{
- t_step *x = (t_step *)pd_new(step_class);
- x->x_targetval = x->x_setval = f;
- x->x_gotinlet = 0;
- x->x_1overtimediff = 1;
- x->x_clock = clock_new(x, (t_method)step_tick);
- x->x_targettime = x->x_prevtime = clock_getsystime();
- if (grain <= 0) grain = 20;
- x->x_grain = grain;
- if (step <= 0) step = 1;
- x->x_step = step;
- outlet_new(&x->x_obj, gensym("float"));
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft2"));
- return (x);
-}
-
-#ifndef MAXLIB
-void step_setup(void)
-{
- step_class = class_new(gensym("step"), (t_newmethod)step_new,
- (t_method)step_free, sizeof(t_step), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(step_class, (t_method)step_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addmethod(step_class, (t_method)step_ft2, gensym("ft2"), A_FLOAT, 0);
- class_addmethod(step_class, (t_method)step_stop, gensym("stop"), 0);
- class_addfloat(step_class, (t_method)step_float);
-
- post(version);
-}
-#else
-void maxlib_step_setup(void)
-{
- step_class = class_new(gensym("maxlib_step"), (t_newmethod)step_new,
- (t_method)step_free, sizeof(t_step), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)step_new, gensym("step"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addmethod(step_class, (t_method)step_ft1, gensym("ft1"), A_FLOAT, 0);
- class_addmethod(step_class, (t_method)step_ft2, gensym("ft2"), A_FLOAT, 0);
- class_addmethod(step_class, (t_method)step_stop, gensym("stop"), 0);
- class_addfloat(step_class, (t_method)step_float);
- class_sethelpsymbol(step_class, gensym("maxlib/step-help.pd"));
-}
-#endif
+/* -------------------------- step ------------------------------------------ */
+/* */
+/* Step to a new value in N milliseconds (similar to line). */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+/* -------------------------- step ------------------------------ */
+static char *version = "step v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+static t_class *step_class;
+
+typedef struct _step
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ double x_targettime;
+ t_float x_targetval;
+ double x_prevtime;
+ t_float x_setval;
+ int x_gotinlet;
+ t_float x_grain; /* time interval for output */
+ t_float x_step; /* step size for output */
+ t_float x_steptime; /* length for one step */
+ t_int x_stepcall;
+ double x_1overtimediff;
+ double x_in1val;
+} t_step;
+
+static void step_tick(t_step *x)
+{
+ t_float outvalue;
+ double timenow = clock_getsystime();
+ double msectogo = - clock_gettimesince(x->x_targettime);
+ if (msectogo < 1E-9)
+ {
+ outlet_float(x->x_obj.ob_outlet, x->x_targetval);
+ }
+ else
+ {
+ if(x->x_setval < x->x_targetval)
+ { /* count upwards */
+ outvalue = x->x_setval + x->x_stepcall * x->x_step;
+ }
+ else
+ { /* count downwards */
+ outvalue = x->x_setval - x->x_stepcall * x->x_step;
+ }
+ outlet_float(x->x_obj.ob_outlet, outvalue);
+ clock_delay(x->x_clock, (x->x_steptime > msectogo ? msectogo : x->x_steptime));
+ }
+ x->x_stepcall++;
+}
+
+static void step_float(t_step *x, t_float f)
+{
+ double timenow = clock_getsystime();
+ if (x->x_gotinlet && x->x_in1val > 0 && x->x_step != 0 && f != x->x_setval)
+ {
+ if (timenow > x->x_targettime) x->x_setval = x->x_targetval;
+ else x->x_setval = x->x_setval + x->x_1overtimediff *
+ (timenow - x->x_prevtime)
+ * (x->x_targetval - x->x_setval);
+ x->x_prevtime = timenow;
+ x->x_targetval = f; /* where to end */
+ x->x_stepcall = 0;
+ /* how long does it take ? */
+ x->x_targettime = clock_getsystimeafter(x->x_in1val);
+ if(x->x_setval < x->x_targetval)
+ {
+ x->x_steptime = x->x_in1val / (int)((x->x_targetval - x->x_setval) / x->x_step);
+ }
+ else
+ {
+ x->x_steptime = x->x_in1val / (int)((x->x_setval - x->x_targetval) / x->x_step);
+ }
+ // post("steptime %g", x->x_steptime);
+ step_tick(x);
+ x->x_gotinlet = 0;
+ x->x_1overtimediff = 1./ (x->x_targettime - timenow);
+ /* call tick function */
+ clock_delay(x->x_clock, x->x_steptime);
+
+ }
+ else
+ {
+ clock_unset(x->x_clock);
+ x->x_targetval = x->x_setval = f;
+ outlet_float(x->x_obj.ob_outlet, f);
+ }
+ x->x_gotinlet = 0;
+}
+
+static void step_ft1(t_step *x, t_floatarg g)
+{
+ x->x_in1val = g;
+ x->x_gotinlet = 1;
+}
+
+static void step_ft2(t_step *x, t_floatarg g)
+{
+ if (g <= 0) g = 1;
+ x->x_step = g;
+ x->x_gotinlet = 1;
+}
+
+static void step_stop(t_step *x)
+{
+ x->x_targetval = x->x_setval;
+ clock_unset(x->x_clock);
+}
+
+static void step_free(t_step *x)
+{
+ clock_free(x->x_clock);
+}
+
+static void *step_new(t_floatarg f, t_floatarg step, t_floatarg grain)
+{
+ t_step *x = (t_step *)pd_new(step_class);
+ x->x_targetval = x->x_setval = f;
+ x->x_gotinlet = 0;
+ x->x_1overtimediff = 1;
+ x->x_clock = clock_new(x, (t_method)step_tick);
+ x->x_targettime = x->x_prevtime = clock_getsystime();
+ if (grain <= 0) grain = 20;
+ x->x_grain = grain;
+ if (step <= 0) step = 1;
+ x->x_step = step;
+ outlet_new(&x->x_obj, gensym("float"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft2"));
+ return (x);
+}
+
+#ifndef MAXLIB
+void step_setup(void)
+{
+ step_class = class_new(gensym("step"), (t_newmethod)step_new,
+ (t_method)step_free, sizeof(t_step), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(step_class, (t_method)step_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(step_class, (t_method)step_ft2, gensym("ft2"), A_FLOAT, 0);
+ class_addmethod(step_class, (t_method)step_stop, gensym("stop"), 0);
+ class_addfloat(step_class, (t_method)step_float);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_step_setup(void)
+{
+ step_class = class_new(gensym("maxlib_step"), (t_newmethod)step_new,
+ (t_method)step_free, sizeof(t_step), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)step_new, gensym("step"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(step_class, (t_method)step_ft1, gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(step_class, (t_method)step_ft2, gensym("ft2"), A_FLOAT, 0);
+ class_addmethod(step_class, (t_method)step_stop, gensym("stop"), 0);
+ class_addfloat(step_class, (t_method)step_float);
+ class_sethelpsymbol(step_class, gensym("maxlib/step-help.pd"));
+}
+#endif
diff --git a/subst.c b/subst.c
index 00fa9db..1bb4d45 100644
--- a/subst.c
+++ b/subst.c
@@ -1,424 +1,424 @@
-/* ------------------------- subst ------------------------------------------ */
-/* */
-/* Performs 'self-similar' substitution of a given list of values. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-#include "m_pd.h"
-
-
-static char *version = "subst v0.1, self-similar substitution of rows (list or array)\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-#undef DEBUG
-//#define DEBUG
-
-#define MAXSIZE 1024
-
-#include <stdio.h>
-#include <stdlib.h>
-
-
-//
-// Maxlife object data structure
-//
-typedef struct subst
-{
- t_object x_obj; // must begin every object
- t_outlet *x_outlist; // outlet for the processed list
- t_outlet *x_outlength;
- t_atom x_row[MAXSIZE]; // row of values to get processed
- t_int x_length; // length of row
- t_int x_order; // size of the CA field/world
- t_symbol *x_array; // name of array that holds the data
- t_garray *x_buf; // content of that array
-} t_subst;
-
-//
-// Function prototypes for our methods and functions
-//
-static t_class *subst_class; // global variable that points to the Maxlife class
-
-//
-// get the sum of intervals from no a to no b
-// Parameters: the row, it's length, intv a, intev b
-//
-static int sum_intv(t_atom *argv, int argc, int a, int b)
-{
- int i;
- int summe = 0; // sum of intervals
-
- if(a==b)
- return(0); // same index
- if(atom_getintarg(a, argc, argv) == atom_getintarg(b, argc, argv))
- return(0); // same value
-
- for(i=a;i<b;i++) // for all values from a to b....
- {
- if(atom_getintarg(i + 1, argc, argv) > atom_getintarg(i, argc, argv)) // positive intv.
- {
- summe += ((atom_getintarg(i + 1, argc, argv) - atom_getintarg(i, argc, argv)) % 12);
- }
- else // negative interval
- {
- summe -= ((atom_getintarg(i + 1, argc, argv) - atom_getintarg(i, argc, argv)) % 12);
- }
- }
- return(summe);
-}
-//----- Anzahl Partialreihen mit Interval d -------------------------------
-static int no_part(t_atom *argv, int argc, int a, int b, int d) // nn
-{
- int i,j,r = 0;
-
- if(a = b)return(0);
-
- for(i = a; i < b; i++)
- {
- for(j=a+1;j<b;j++)
- {
- if(sum_intv(argv, argc, i, j) == d)
- r++;
- }
- }
- return(r);
-}
-
-//----- n-te Partialreihe der Länge l mit Interval d -----------------------
-static int n_part_intv(t_atom *argv, int argc, int a, int b, int l, int d, int n) // nn
-{
- int i,j, r = 0;
- if(n > no_part(argv, argc, a, b, d))
- return(-1);
- for(i = 1; i = (b - a); i++)
- {
- for(j = 1; j = b; j++)
- {
- if(sum_intv(argv, argc, i, j) == d)
- r++;
- }
- }
- return(r);
-}
-//----- Test, ob Partialreihe der Ordnung o mit Interval d existiert ----------
-static int check_part_intv(t_atom *argv, int argc, int o, int d)
-{
- int z;
-
- for(z = 0; z < argc - o; z++)
- {
- if(sum_intv(argv, argc, z, z + o) == d)
- return(z); // Abstand von Reihenanfang
- }
-
- return(-1);
-}
-
-static int my_random(int range) {
- int ret = rand();
- ret = ret % range; // limit to desired output range
- return(ret);
-}
-
-//
-// the substitution algorhythm
-//
-static int subst_calc(t_subst *x, int n)
-{
- int i,j,k,l,o = x->x_order;
- int s = -1;
- int intv;
- t_atom newrow[MAXSIZE];
- t_garray *A = x->x_buf;
- int npoints;
- t_float *vec;
-
- if(x->x_length <= 1)
- {
- post("subst: need some data first!");
- return(-1);
- }
- srand((unsigned int)clock_getlogicaltime());
-
- if(n == -1) // no interval given: choose one by chance
- {
- do
- {
- n = my_random(x->x_length - 1); // choose interval
- intv = sum_intv(x->x_row, x->x_length, n, n + 1); // size of this interval
- }
- while(intv == 0); // ...until we found one that is not 0!
- }
- else intv = sum_intv(x->x_row, x->x_length, n, n + 1);
-
-#ifdef DEBUG
- post("subst: substitution of %dth interval (%d halftones)", n+1, intv);
-#endif
-
- /* for-Schleife für möglichst lange Substitutionen
- for(j=anzahlReihe(alteReihe);j>2;j--) */
- for(j = x->x_order; j < x->x_length; j++) // prefer lower orders (min. 2)
- { // search for possible order...
- s = check_part_intv(x->x_row, x->x_length, j, intv);
- if(s != -1) // check if there is a partial row with the interval we want
- {
- o = j; // save actual order, might be larger then x->x_order
- break; // ... do it!
- }
- if(o == j)break; // found one
- }
-
- for(i = 0; i < x->x_length; i++)
- {
- if(i <= n) // just copy values before substitution
- {
- newrow[i] = x->x_row[i];
- }
- if((i == n) && (s != -1)) // now substitute
- {
- for(k=1;k<o;k++) // well get order - 1 new values...
- {
- SETFLOAT(newrow + (i + k), (atom_getintarg((i + k - 1), 1024, newrow)
- + sum_intv(x->x_row, x->x_length, s+k-1, s+k)));
-#ifdef DEBUG
- post("subst: new interval[%d]: %d ", k, sum_intv(x->x_row, x->x_length, s+k-1, s+k));
-#endif
- }
- post("subst: replaced interval %d (%d halftones) with %d new intervals", n, intv, o);
- }
- else if((i == n) && (s == -1)) // not partial row found
- {
- o = 1; // order is 1 -> now substitution
- newrow[i] = x->x_row[i]; // copy the next value of the row
- post("subst: coundn't find any partial rows to fit in!");
- }
-
- if(i>n) // behind substitution
- {
- newrow[i+(o-1)] = x->x_row[i]; // copy rest or row
- }
- }
-
- // copy stuff back...
- x->x_length = l = x->x_length + o - 1;
- for(i = 0; i < x->x_length; i++)
- x->x_row[i] = newrow[i];
-
- // write to array
- if(x->x_array)if (!(A = (t_garray *)pd_findbyclass(x->x_array, garray_class)))
- error("subst: %s: no such array", x->x_array->s_name);
- else if (!garray_getfloatarray(A, &npoints, &vec))
- error("subst: %s: bad template ", x->x_array->s_name);
- else
- {
- i = 0;
-
- if (l >= npoints) // keep end of array
- {
- while(npoints--)
- {
- *vec++ = atom_getfloat(x->x_row + i);
- i++;
- }
- }
- else // update
- {
- npoints -= l;
- while (l--)
- {
- *vec++ = atom_getfloat(x->x_row + i);
- i++;
- }
- while (npoints--) *vec++ = 0;
- }
- garray_redraw(A);
- }
-
- // output stuff
- outlet_float(x->x_outlength, x->x_length);
- outlet_list(x->x_outlist, NULL, x->x_length, x->x_row);
-
- return(0);
-}
-
-static void subst_list(t_subst *x, t_symbol *s, int argc, t_atom *argv)
-{
- t_garray *b = x->x_buf; /* make local copy of array */
- float *tab; /* we'll store notes in here */
- int items;
- int i;
-
- for(i = 0; i < argc; i++)
- {
- x->x_row[i] = argv[i]; // just copy input
- }
- x->x_length = argc;
-
-}
-
-//
-// choose the array that holds the processed row (output!!)
-//
-void subst_set(t_subst *x, t_symbol *s)
-{
- t_garray *b;
-
- x->x_array = s;
-
- if ((b = (t_garray *)pd_findbyclass(s, garray_class)))
- {
- post("subst: array set to \"%s\"", s->s_name);
- x->x_buf = b;
- } else {
- post("subst: no array \"%s\" (error %d)", s->s_name, b);
- x->x_buf = 0;
- }
-}
-
-//
-// load row from array (input!!)
-//
-static void subst_load(t_subst *x, t_symbol *s)
-{
- t_garray *b; /* make local copy of array */
- t_float *tab; /* the content itselfe */
- int items, i;
-
- if ((b = (t_garray *)pd_findbyclass(s, garray_class)))
- {
- post("subst: array set to \"%s\"", s->s_name);
- } else {
- post("subst: no array \"%s\" (error %d)", s->s_name, b);
- return;
- }
-
- // read from our array
- if (!garray_getfloatarray(b, &items, &tab))
- {
- post("subst: couldn't read from array!");
- return;
- }
- for(i = 0; i < items; i++)
- {
- SETFLOAT(x->x_row + i, tab[i]); // copy array into x->x_row
- }
- x->x_length = items;
- post("subst: loaded %d values from array \"%s\"", items, s->s_name);
-}
-
-//
-// substitute an interval choosen by chance
-//
-static void subst_bang(t_subst *x)
-{
- subst_calc(x, -1);
-}
-
-//
-// substitute the Nth interval
-//
-static void subst_intv(t_subst *x, t_floatarg f)
-{
- int i = (int)f;
- if(i > x->x_length) i = x->x_length;
- subst_calc(x, i);
-}
-
-//
-// set the minimum order of substitution
-//
-static void subst_set_order(t_subst *x, t_floatarg f)
-{
- x->x_order = (t_int)f;
- if(x->x_order < 2)x->x_order = 2;
- post("subst: set order to %d", x->x_order);
-}
-
-//
-// method to print out: but what?
-//
-static void subst_display(t_subst *x)
-{
-}
-
-//
-// function to create an instance of the subst class
-//
-static void *subst_new(t_symbol *s, int argc, t_atom *argv)
-{
- long i;
- t_symbol *sym;
- t_subst *x = (t_subst *)pd_new(subst_class);
- // read in order...
- x->x_order = 3;
- if(argc == 1)
- {
- x->x_order = atom_getintarg(0, argc, argv);
- }
- else if(argc == 2)
- {
- sym = atom_getsymbolarg(0, argc, argv);
- x->x_order = atom_getintarg(1, argc, argv);
- subst_set(x, sym);
- }
-
- // create outlets
- x->x_outlist = outlet_new(&x->x_obj, gensym("list"));
- x->x_outlength = outlet_new(&x->x_obj, gensym("float"));
-
- return(x); // always return a copy of the created object
-}
-
-static void subst_free(t_subst *x)
-{
- /* nothing to do */
-}
-
-#ifndef MAXLIB
-void subst_setup(void)
-{
- subst_class = class_new(gensym("subst"), (t_newmethod)subst_new,
- (t_method)subst_free, sizeof(t_subst), 0, A_GIMME, 0);
- class_addmethod(subst_class, (t_method)subst_set_order, gensym("order"), A_FLOAT, 0);
- class_addmethod(subst_class, (t_method)subst_intv, gensym("interval"), A_FLOAT, 0);
- class_addmethod(subst_class, (t_method)subst_set, gensym("set"), A_SYMBOL, 0);
- class_addmethod(subst_class, (t_method)subst_load, gensym("load"), A_SYMBOL, 0);
- class_addmethod(subst_class, (t_method)subst_display, gensym("display"), 0);
- class_addlist(subst_class, subst_list);
- class_addbang(subst_class, subst_bang);
-
- post(version);
-}
-#else
-void maxlib_subst_setup(void)
-{
- subst_class = class_new(gensym("maxlib_subst"), (t_newmethod)subst_new,
- (t_method)subst_free, sizeof(t_subst), 0, A_GIMME, 0);
- class_addcreator((t_newmethod)subst_new, gensym("subst"), A_GIMME, 0);
- class_addmethod(subst_class, (t_method)subst_set_order, gensym("order"), A_FLOAT, 0);
- class_addmethod(subst_class, (t_method)subst_intv, gensym("interval"), A_FLOAT, 0);
- class_addmethod(subst_class, (t_method)subst_set, gensym("set"), A_SYMBOL, 0);
- class_addmethod(subst_class, (t_method)subst_load, gensym("load"), A_SYMBOL, 0);
- class_addmethod(subst_class, (t_method)subst_display, gensym("display"), 0);
- class_addlist(subst_class, subst_list);
- class_addbang(subst_class, subst_bang);
- class_sethelpsymbol(subst_class, gensym("maxlib/subst-help.pd"));
-}
-#endif
+/* ------------------------- subst ------------------------------------------ */
+/* */
+/* Performs 'self-similar' substitution of a given list of values. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+#include "m_pd.h"
+
+
+static char *version = "subst v0.1, self-similar substitution of rows (list or array)\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+#undef DEBUG
+//#define DEBUG
+
+#define MAXSIZE 1024
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+//
+// Maxlife object data structure
+//
+typedef struct subst
+{
+ t_object x_obj; // must begin every object
+ t_outlet *x_outlist; // outlet for the processed list
+ t_outlet *x_outlength;
+ t_atom x_row[MAXSIZE]; // row of values to get processed
+ t_int x_length; // length of row
+ t_int x_order; // size of the CA field/world
+ t_symbol *x_array; // name of array that holds the data
+ t_garray *x_buf; // content of that array
+} t_subst;
+
+//
+// Function prototypes for our methods and functions
+//
+static t_class *subst_class; // global variable that points to the Maxlife class
+
+//
+// get the sum of intervals from no a to no b
+// Parameters: the row, it's length, intv a, intev b
+//
+static int sum_intv(t_atom *argv, int argc, int a, int b)
+{
+ int i;
+ int summe = 0; // sum of intervals
+
+ if(a==b)
+ return(0); // same index
+ if(atom_getintarg(a, argc, argv) == atom_getintarg(b, argc, argv))
+ return(0); // same value
+
+ for(i=a;i<b;i++) // for all values from a to b....
+ {
+ if(atom_getintarg(i + 1, argc, argv) > atom_getintarg(i, argc, argv)) // positive intv.
+ {
+ summe += ((atom_getintarg(i + 1, argc, argv) - atom_getintarg(i, argc, argv)) % 12);
+ }
+ else // negative interval
+ {
+ summe -= ((atom_getintarg(i + 1, argc, argv) - atom_getintarg(i, argc, argv)) % 12);
+ }
+ }
+ return(summe);
+}
+//----- Anzahl Partialreihen mit Interval d -------------------------------
+static int no_part(t_atom *argv, int argc, int a, int b, int d) // nn
+{
+ int i,j,r = 0;
+
+ if(a = b)return(0);
+
+ for(i = a; i < b; i++)
+ {
+ for(j=a+1;j<b;j++)
+ {
+ if(sum_intv(argv, argc, i, j) == d)
+ r++;
+ }
+ }
+ return(r);
+}
+
+//----- n-te Partialreihe der Länge l mit Interval d -----------------------
+static int n_part_intv(t_atom *argv, int argc, int a, int b, int l, int d, int n) // nn
+{
+ int i,j, r = 0;
+ if(n > no_part(argv, argc, a, b, d))
+ return(-1);
+ for(i = 1; i = (b - a); i++)
+ {
+ for(j = 1; j = b; j++)
+ {
+ if(sum_intv(argv, argc, i, j) == d)
+ r++;
+ }
+ }
+ return(r);
+}
+//----- Test, ob Partialreihe der Ordnung o mit Interval d existiert ----------
+static int check_part_intv(t_atom *argv, int argc, int o, int d)
+{
+ int z;
+
+ for(z = 0; z < argc - o; z++)
+ {
+ if(sum_intv(argv, argc, z, z + o) == d)
+ return(z); // Abstand von Reihenanfang
+ }
+
+ return(-1);
+}
+
+static int my_random(int range) {
+ int ret = rand();
+ ret = ret % range; // limit to desired output range
+ return(ret);
+}
+
+//
+// the substitution algorhythm
+//
+static int subst_calc(t_subst *x, int n)
+{
+ int i,j,k,l,o = x->x_order;
+ int s = -1;
+ int intv;
+ t_atom newrow[MAXSIZE];
+ t_garray *A = x->x_buf;
+ int npoints;
+ t_float *vec;
+
+ if(x->x_length <= 1)
+ {
+ post("subst: need some data first!");
+ return(-1);
+ }
+ srand((unsigned int)clock_getlogicaltime());
+
+ if(n == -1) // no interval given: choose one by chance
+ {
+ do
+ {
+ n = my_random(x->x_length - 1); // choose interval
+ intv = sum_intv(x->x_row, x->x_length, n, n + 1); // size of this interval
+ }
+ while(intv == 0); // ...until we found one that is not 0!
+ }
+ else intv = sum_intv(x->x_row, x->x_length, n, n + 1);
+
+#ifdef DEBUG
+ post("subst: substitution of %dth interval (%d halftones)", n+1, intv);
+#endif
+
+ /* for-Schleife für möglichst lange Substitutionen
+ for(j=anzahlReihe(alteReihe);j>2;j--) */
+ for(j = x->x_order; j < x->x_length; j++) // prefer lower orders (min. 2)
+ { // search for possible order...
+ s = check_part_intv(x->x_row, x->x_length, j, intv);
+ if(s != -1) // check if there is a partial row with the interval we want
+ {
+ o = j; // save actual order, might be larger then x->x_order
+ break; // ... do it!
+ }
+ if(o == j)break; // found one
+ }
+
+ for(i = 0; i < x->x_length; i++)
+ {
+ if(i <= n) // just copy values before substitution
+ {
+ newrow[i] = x->x_row[i];
+ }
+ if((i == n) && (s != -1)) // now substitute
+ {
+ for(k=1;k<o;k++) // well get order - 1 new values...
+ {
+ SETFLOAT(newrow + (i + k), (atom_getintarg((i + k - 1), 1024, newrow)
+ + sum_intv(x->x_row, x->x_length, s+k-1, s+k)));
+#ifdef DEBUG
+ post("subst: new interval[%d]: %d ", k, sum_intv(x->x_row, x->x_length, s+k-1, s+k));
+#endif
+ }
+ post("subst: replaced interval %d (%d halftones) with %d new intervals", n, intv, o);
+ }
+ else if((i == n) && (s == -1)) // not partial row found
+ {
+ o = 1; // order is 1 -> now substitution
+ newrow[i] = x->x_row[i]; // copy the next value of the row
+ post("subst: coundn't find any partial rows to fit in!");
+ }
+
+ if(i>n) // behind substitution
+ {
+ newrow[i+(o-1)] = x->x_row[i]; // copy rest or row
+ }
+ }
+
+ // copy stuff back...
+ x->x_length = l = x->x_length + o - 1;
+ for(i = 0; i < x->x_length; i++)
+ x->x_row[i] = newrow[i];
+
+ // write to array
+ if(x->x_array)if (!(A = (t_garray *)pd_findbyclass(x->x_array, garray_class)))
+ error("subst: %s: no such array", x->x_array->s_name);
+ else if (!garray_getfloatarray(A, &npoints, &vec))
+ error("subst: %s: bad template ", x->x_array->s_name);
+ else
+ {
+ i = 0;
+
+ if (l >= npoints) // keep end of array
+ {
+ while(npoints--)
+ {
+ *vec++ = atom_getfloat(x->x_row + i);
+ i++;
+ }
+ }
+ else // update
+ {
+ npoints -= l;
+ while (l--)
+ {
+ *vec++ = atom_getfloat(x->x_row + i);
+ i++;
+ }
+ while (npoints--) *vec++ = 0;
+ }
+ garray_redraw(A);
+ }
+
+ // output stuff
+ outlet_float(x->x_outlength, x->x_length);
+ outlet_list(x->x_outlist, NULL, x->x_length, x->x_row);
+
+ return(0);
+}
+
+static void subst_list(t_subst *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_garray *b = x->x_buf; /* make local copy of array */
+ float *tab; /* we'll store notes in here */
+ int items;
+ int i;
+
+ for(i = 0; i < argc; i++)
+ {
+ x->x_row[i] = argv[i]; // just copy input
+ }
+ x->x_length = argc;
+
+}
+
+//
+// choose the array that holds the processed row (output!!)
+//
+void subst_set(t_subst *x, t_symbol *s)
+{
+ t_garray *b;
+
+ x->x_array = s;
+
+ if ((b = (t_garray *)pd_findbyclass(s, garray_class)))
+ {
+ post("subst: array set to \"%s\"", s->s_name);
+ x->x_buf = b;
+ } else {
+ post("subst: no array \"%s\" (error %d)", s->s_name, b);
+ x->x_buf = 0;
+ }
+}
+
+//
+// load row from array (input!!)
+//
+static void subst_load(t_subst *x, t_symbol *s)
+{
+ t_garray *b; /* make local copy of array */
+ t_float *tab; /* the content itselfe */
+ int items, i;
+
+ if ((b = (t_garray *)pd_findbyclass(s, garray_class)))
+ {
+ post("subst: array set to \"%s\"", s->s_name);
+ } else {
+ post("subst: no array \"%s\" (error %d)", s->s_name, b);
+ return;
+ }
+
+ // read from our array
+ if (!garray_getfloatarray(b, &items, &tab))
+ {
+ post("subst: couldn't read from array!");
+ return;
+ }
+ for(i = 0; i < items; i++)
+ {
+ SETFLOAT(x->x_row + i, tab[i]); // copy array into x->x_row
+ }
+ x->x_length = items;
+ post("subst: loaded %d values from array \"%s\"", items, s->s_name);
+}
+
+//
+// substitute an interval choosen by chance
+//
+static void subst_bang(t_subst *x)
+{
+ subst_calc(x, -1);
+}
+
+//
+// substitute the Nth interval
+//
+static void subst_intv(t_subst *x, t_floatarg f)
+{
+ int i = (int)f;
+ if(i > x->x_length) i = x->x_length;
+ subst_calc(x, i);
+}
+
+//
+// set the minimum order of substitution
+//
+static void subst_set_order(t_subst *x, t_floatarg f)
+{
+ x->x_order = (t_int)f;
+ if(x->x_order < 2)x->x_order = 2;
+ post("subst: set order to %d", x->x_order);
+}
+
+//
+// method to print out: but what?
+//
+static void subst_display(t_subst *x)
+{
+}
+
+//
+// function to create an instance of the subst class
+//
+static void *subst_new(t_symbol *s, int argc, t_atom *argv)
+{
+ long i;
+ t_symbol *sym;
+ t_subst *x = (t_subst *)pd_new(subst_class);
+ // read in order...
+ x->x_order = 3;
+ if(argc == 1)
+ {
+ x->x_order = atom_getintarg(0, argc, argv);
+ }
+ else if(argc == 2)
+ {
+ sym = atom_getsymbolarg(0, argc, argv);
+ x->x_order = atom_getintarg(1, argc, argv);
+ subst_set(x, sym);
+ }
+
+ // create outlets
+ x->x_outlist = outlet_new(&x->x_obj, gensym("list"));
+ x->x_outlength = outlet_new(&x->x_obj, gensym("float"));
+
+ return(x); // always return a copy of the created object
+}
+
+static void subst_free(t_subst *x)
+{
+ /* nothing to do */
+}
+
+#ifndef MAXLIB
+void subst_setup(void)
+{
+ subst_class = class_new(gensym("subst"), (t_newmethod)subst_new,
+ (t_method)subst_free, sizeof(t_subst), 0, A_GIMME, 0);
+ class_addmethod(subst_class, (t_method)subst_set_order, gensym("order"), A_FLOAT, 0);
+ class_addmethod(subst_class, (t_method)subst_intv, gensym("interval"), A_FLOAT, 0);
+ class_addmethod(subst_class, (t_method)subst_set, gensym("set"), A_SYMBOL, 0);
+ class_addmethod(subst_class, (t_method)subst_load, gensym("load"), A_SYMBOL, 0);
+ class_addmethod(subst_class, (t_method)subst_display, gensym("display"), 0);
+ class_addlist(subst_class, subst_list);
+ class_addbang(subst_class, subst_bang);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_subst_setup(void)
+{
+ subst_class = class_new(gensym("maxlib_subst"), (t_newmethod)subst_new,
+ (t_method)subst_free, sizeof(t_subst), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)subst_new, gensym("subst"), A_GIMME, 0);
+ class_addmethod(subst_class, (t_method)subst_set_order, gensym("order"), A_FLOAT, 0);
+ class_addmethod(subst_class, (t_method)subst_intv, gensym("interval"), A_FLOAT, 0);
+ class_addmethod(subst_class, (t_method)subst_set, gensym("set"), A_SYMBOL, 0);
+ class_addmethod(subst_class, (t_method)subst_load, gensym("load"), A_SYMBOL, 0);
+ class_addmethod(subst_class, (t_method)subst_display, gensym("display"), 0);
+ class_addlist(subst_class, subst_list);
+ class_addbang(subst_class, subst_bang);
+ class_sethelpsymbol(subst_class, gensym("maxlib/subst-help.pd"));
+}
+#endif
diff --git a/sync.c b/sync.c
index ccfb172..7024a95 100644
--- a/sync.c
+++ b/sync.c
@@ -1,294 +1,294 @@
-/* ------------------------- sync ------------------------------------------- */
-/* */
-/* syncronises outputs depending on inputs. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Based on 'sync' from jMax. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <math.h>
-
-#define SYNC_MAX_SIZE (int)(sizeof(unsigned int) * 8)
-
-static char *version = "sync v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>\n"
- " based on sync from jMax";
-
-typedef struct sync
-{
- t_object x_ob;
- t_float x_min; /* low border of input range */
- t_float x_max; /* high border of input range */
- t_outlet *x_outlet[SYNC_MAX_SIZE];
-
- t_int x_n;
- unsigned int x_trigger; /* control bits: trigger on input at given inlets */
- unsigned int x_require; /* control bits: require input on given inlets */
- unsigned int x_reset; /* control bits: reset memory of given inputs after on each input */
- unsigned int x_wait; /* status bits: wait for input at given inlet before output */
- t_atom x_a[SYNC_MAX_SIZE];
- enum {mode_all, mode_select} mode;
-} t_sync;
-
-typedef struct proxy
-{
- t_object obj;
- t_int index; /* number of proxy inlet(s) */
- t_sync *x; /* we'll put the other struct in here */
-} t_proxy;
-
-static void sync_output(t_sync *x)
-{
- int i;
-
- for(i=x->x_n-1; i>=0; i--)
- if(x->x_a[i].a_type != A_SEMI)
- outlet_list(x->x_outlet[i], NULL, 1, x->x_a + i);
-}
-
-static void sync_input(t_proxy *p, t_symbol *s, int ac, t_atom *at)
-{
- t_sync *x = (t_sync *)(p->x);
- int winlet = p->index;
-
- if(ac)
- {
- unsigned int bit = 1 << winlet;
-
- x->x_a[winlet] = at[0];
-
- x->x_wait &= ~bit;
-
- if(!x->x_wait && (x->x_trigger & bit))
- {
- sync_output(x);
- x->x_wait |= x->x_reset & x->x_require;
- }
- }
-}
-
-static void sync_float_input(t_proxy *p, t_floatarg f)
-{
- t_sync *x = (t_sync *)(p->x);
- int winlet = p->index;
-
- {
- unsigned int bit = 1 << winlet;
-
- SETFLOAT(x->x_a + winlet, f);
-
- x->x_wait &= ~bit;
-
- if(!x->x_wait && (x->x_trigger & bit))
- {
- sync_output(x);
- x->x_wait |= x->x_reset & x->x_require;
- }
- }
-}
-
-static void sync_set_bits(unsigned int *bits, int n, t_atom *at, int sign)
-{
- if(at->a_type == A_SYMBOL)
- {
- t_symbol *mode = atom_getsymbol(at);
-
- if(mode == gensym("all"))
- *bits = (1 << n) - 1;
- else if(mode == gensym("none"))
- *bits = 0;
- }
- else if(at->a_type == A_FLOAT)
- {
- int in = (int)atom_getfloat(at) * sign;
-
- if(in >= 0 && in < n)
- *bits = 1 << in;
- }
- else if(at->a_type == A_GIMME)
- {
- int size = n;
- int i;
-
- *bits = 0;
-
- for(i=0; i<size; i++)
- {
- if(at[i].a_type == A_FLOAT)
- {
- int in = atom_getfloatarg(i, size, at) * sign;
-
- if(in >= 0 && in < n)
- *bits |= 1 << in;
- }
- }
- }
-}
-
-static void sync_set_trigger(t_sync *x, t_symbol *s, int ac, t_atom *at)
-{
- sync_set_bits(&x->x_trigger, x->x_n, at, 1);
-}
-
-static void sync_set_require(t_sync *x, t_symbol *s, int ac, t_atom *at)
-{
- unsigned int once = 0;
-
- sync_set_bits(&x->x_require, x->x_n, at, 1);
- sync_set_bits(&once, x->x_n, at, -1);
-
- x->x_reset = ~once;
- x->x_wait = x->x_require | once;
-}
-
-static void sync_set_mode(t_sync *x, t_symbol *mode)
-{
- if(mode == gensym("any"))
- {
- x->x_trigger = (1 << x->x_n) - 1;
- x->x_reset = 0;
- x->x_require = 0;
- }
- else if(mode == gensym("all"))
- x->x_trigger = x->x_require = x->x_reset = x->x_wait = (1 << x->x_n) - 1;
- else if(mode == gensym("left"))
- {
- x->x_trigger = 1;
- x->x_reset = 0;
- x->x_require = 0;
- }
- else if(mode == gensym("right"))
- {
- x->x_trigger = (1 << (x->x_n - 1));
- x->x_reset = 0;
- x->x_require = 0;
- }
-
- x->x_wait = x->x_require;
-}
-
-static void sync_float(t_sync *x, t_floatarg f)
-{
- unsigned int bit = 1 << 0;
-
- SETFLOAT(x->x_a, f);
-
- x->x_wait &= ~bit;
-
- if(!x->x_wait && (x->x_trigger & bit))
- {
- sync_output(x);
- x->x_wait |= x->x_reset & x->x_require;
- }
-}
-
-static t_class *sync_class;
-static t_class *proxy_class;
-
-static void *sync_new(t_symbol *s, int ac, t_atom *at)
-{
- int n = 0;
- int i;
- t_sync *x = (t_sync *)pd_new(sync_class);
- t_proxy *inlet[SYNC_MAX_SIZE];
-
- /* void state - we fill with SEMI and treat this as 'void' */
- for(i=0; i<SYNC_MAX_SIZE; i++)
- SETSEMI(x->x_a + i);
-
- if(ac == 1)
- {
- if(at->a_type == A_FLOAT)
- {
- n = atom_getfloat(at);
-
- if(n < 2)
- n = 2;
- else if(n > SYNC_MAX_SIZE)
- n = SYNC_MAX_SIZE;
- }
- else
- {
- post("sync: wrong argument");
- return (0);
- }
- }
- else if(ac > 1)
- {
- if(ac > SYNC_MAX_SIZE)
- ac = SYNC_MAX_SIZE;
-
- n = ac;
-
- for(i=0; i<n; i++)
- x->x_a[i] = at[i];
- }
-
- x->x_n = n;
- x->x_trigger = x->x_require = x->x_reset = x->x_wait = (1 << n) - 1;
-
- x->x_outlet[0] = outlet_new(&x->x_ob, gensym("list"));
-
- for(i=1; i<n; i++)
- {
- inlet[i] = (t_proxy *)pd_new(proxy_class); /* create the proxy inlet */
- inlet[i]->x = x; /* make t_sync *x visible to the proxy inlets */
- inlet[i]->index = i; /* remember it's number */
- /* it belongs to the object t_sync but the destination is t_proxy */
- inlet_new(&x->x_ob, &inlet[i]->obj.ob_pd, 0,0);
-
- x->x_outlet[i] = outlet_new(&x->x_ob, gensym("list"));
- }
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void sync_setup(void)
-{
- sync_class = class_new(gensym("sync"), (t_newmethod)sync_new,
- 0, sizeof(t_sync), 0, A_GIMME, 0);
-#else
-void maxlib_sync_setup(void)
-{
- sync_class = class_new(gensym("maxlib_sync"), (t_newmethod)sync_new,
- 0, sizeof(t_sync), 0, A_GIMME, 0);
-#endif
- /* a class for the proxy inlet: */
- proxy_class = class_new(gensym("maxlib_sync_proxy"), NULL, NULL, sizeof(t_proxy),
- CLASS_PD|CLASS_NOINLET, A_NULL);
-
- class_addfloat(proxy_class, sync_float_input);
- class_addanything(proxy_class, sync_input);
-
- class_addfloat(sync_class, sync_float);
- class_addmethod(sync_class, (t_method)sync_set_trigger, gensym("trigger"), A_GIMME, 0);
- class_addmethod(sync_class, (t_method)sync_set_require, gensym("require"), A_GIMME, 0);
- class_addmethod(sync_class, (t_method)sync_set_mode, gensym("mode"), A_SYMBOL, 0);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_addcreator((t_newmethod)sync_new, gensym("sync"), A_GIMME, 0);
- class_sethelpsymbol(sync_class, gensym("maxlib/sync-help.pd"));
-#endif
-}
-
+/* ------------------------- sync ------------------------------------------- */
+/* */
+/* syncronises outputs depending on inputs. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Based on 'sync' from jMax. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+
+#define SYNC_MAX_SIZE (int)(sizeof(unsigned int) * 8)
+
+static char *version = "sync v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>\n"
+ " based on sync from jMax";
+
+typedef struct sync
+{
+ t_object x_ob;
+ t_float x_min; /* low border of input range */
+ t_float x_max; /* high border of input range */
+ t_outlet *x_outlet[SYNC_MAX_SIZE];
+
+ t_int x_n;
+ unsigned int x_trigger; /* control bits: trigger on input at given inlets */
+ unsigned int x_require; /* control bits: require input on given inlets */
+ unsigned int x_reset; /* control bits: reset memory of given inputs after on each input */
+ unsigned int x_wait; /* status bits: wait for input at given inlet before output */
+ t_atom x_a[SYNC_MAX_SIZE];
+ enum {mode_all, mode_select} mode;
+} t_sync;
+
+typedef struct proxy
+{
+ t_object obj;
+ t_int index; /* number of proxy inlet(s) */
+ t_sync *x; /* we'll put the other struct in here */
+} t_proxy;
+
+static void sync_output(t_sync *x)
+{
+ int i;
+
+ for(i=x->x_n-1; i>=0; i--)
+ if(x->x_a[i].a_type != A_SEMI)
+ outlet_list(x->x_outlet[i], NULL, 1, x->x_a + i);
+}
+
+static void sync_input(t_proxy *p, t_symbol *s, int ac, t_atom *at)
+{
+ t_sync *x = (t_sync *)(p->x);
+ int winlet = p->index;
+
+ if(ac)
+ {
+ unsigned int bit = 1 << winlet;
+
+ x->x_a[winlet] = at[0];
+
+ x->x_wait &= ~bit;
+
+ if(!x->x_wait && (x->x_trigger & bit))
+ {
+ sync_output(x);
+ x->x_wait |= x->x_reset & x->x_require;
+ }
+ }
+}
+
+static void sync_float_input(t_proxy *p, t_floatarg f)
+{
+ t_sync *x = (t_sync *)(p->x);
+ int winlet = p->index;
+
+ {
+ unsigned int bit = 1 << winlet;
+
+ SETFLOAT(x->x_a + winlet, f);
+
+ x->x_wait &= ~bit;
+
+ if(!x->x_wait && (x->x_trigger & bit))
+ {
+ sync_output(x);
+ x->x_wait |= x->x_reset & x->x_require;
+ }
+ }
+}
+
+static void sync_set_bits(unsigned int *bits, int n, t_atom *at, int sign)
+{
+ if(at->a_type == A_SYMBOL)
+ {
+ t_symbol *mode = atom_getsymbol(at);
+
+ if(mode == gensym("all"))
+ *bits = (1 << n) - 1;
+ else if(mode == gensym("none"))
+ *bits = 0;
+ }
+ else if(at->a_type == A_FLOAT)
+ {
+ int in = (int)atom_getfloat(at) * sign;
+
+ if(in >= 0 && in < n)
+ *bits = 1 << in;
+ }
+ else if(at->a_type == A_GIMME)
+ {
+ int size = n;
+ int i;
+
+ *bits = 0;
+
+ for(i=0; i<size; i++)
+ {
+ if(at[i].a_type == A_FLOAT)
+ {
+ int in = atom_getfloatarg(i, size, at) * sign;
+
+ if(in >= 0 && in < n)
+ *bits |= 1 << in;
+ }
+ }
+ }
+}
+
+static void sync_set_trigger(t_sync *x, t_symbol *s, int ac, t_atom *at)
+{
+ sync_set_bits(&x->x_trigger, x->x_n, at, 1);
+}
+
+static void sync_set_require(t_sync *x, t_symbol *s, int ac, t_atom *at)
+{
+ unsigned int once = 0;
+
+ sync_set_bits(&x->x_require, x->x_n, at, 1);
+ sync_set_bits(&once, x->x_n, at, -1);
+
+ x->x_reset = ~once;
+ x->x_wait = x->x_require | once;
+}
+
+static void sync_set_mode(t_sync *x, t_symbol *mode)
+{
+ if(mode == gensym("any"))
+ {
+ x->x_trigger = (1 << x->x_n) - 1;
+ x->x_reset = 0;
+ x->x_require = 0;
+ }
+ else if(mode == gensym("all"))
+ x->x_trigger = x->x_require = x->x_reset = x->x_wait = (1 << x->x_n) - 1;
+ else if(mode == gensym("left"))
+ {
+ x->x_trigger = 1;
+ x->x_reset = 0;
+ x->x_require = 0;
+ }
+ else if(mode == gensym("right"))
+ {
+ x->x_trigger = (1 << (x->x_n - 1));
+ x->x_reset = 0;
+ x->x_require = 0;
+ }
+
+ x->x_wait = x->x_require;
+}
+
+static void sync_float(t_sync *x, t_floatarg f)
+{
+ unsigned int bit = 1 << 0;
+
+ SETFLOAT(x->x_a, f);
+
+ x->x_wait &= ~bit;
+
+ if(!x->x_wait && (x->x_trigger & bit))
+ {
+ sync_output(x);
+ x->x_wait |= x->x_reset & x->x_require;
+ }
+}
+
+static t_class *sync_class;
+static t_class *proxy_class;
+
+static void *sync_new(t_symbol *s, int ac, t_atom *at)
+{
+ int n = 0;
+ int i;
+ t_sync *x = (t_sync *)pd_new(sync_class);
+ t_proxy *inlet[SYNC_MAX_SIZE];
+
+ /* void state - we fill with SEMI and treat this as 'void' */
+ for(i=0; i<SYNC_MAX_SIZE; i++)
+ SETSEMI(x->x_a + i);
+
+ if(ac == 1)
+ {
+ if(at->a_type == A_FLOAT)
+ {
+ n = atom_getfloat(at);
+
+ if(n < 2)
+ n = 2;
+ else if(n > SYNC_MAX_SIZE)
+ n = SYNC_MAX_SIZE;
+ }
+ else
+ {
+ post("sync: wrong argument");
+ return (0);
+ }
+ }
+ else if(ac > 1)
+ {
+ if(ac > SYNC_MAX_SIZE)
+ ac = SYNC_MAX_SIZE;
+
+ n = ac;
+
+ for(i=0; i<n; i++)
+ x->x_a[i] = at[i];
+ }
+
+ x->x_n = n;
+ x->x_trigger = x->x_require = x->x_reset = x->x_wait = (1 << n) - 1;
+
+ x->x_outlet[0] = outlet_new(&x->x_ob, gensym("list"));
+
+ for(i=1; i<n; i++)
+ {
+ inlet[i] = (t_proxy *)pd_new(proxy_class); /* create the proxy inlet */
+ inlet[i]->x = x; /* make t_sync *x visible to the proxy inlets */
+ inlet[i]->index = i; /* remember it's number */
+ /* it belongs to the object t_sync but the destination is t_proxy */
+ inlet_new(&x->x_ob, &inlet[i]->obj.ob_pd, 0,0);
+
+ x->x_outlet[i] = outlet_new(&x->x_ob, gensym("list"));
+ }
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void sync_setup(void)
+{
+ sync_class = class_new(gensym("sync"), (t_newmethod)sync_new,
+ 0, sizeof(t_sync), 0, A_GIMME, 0);
+#else
+void maxlib_sync_setup(void)
+{
+ sync_class = class_new(gensym("maxlib_sync"), (t_newmethod)sync_new,
+ 0, sizeof(t_sync), 0, A_GIMME, 0);
+#endif
+ /* a class for the proxy inlet: */
+ proxy_class = class_new(gensym("maxlib_sync_proxy"), NULL, NULL, sizeof(t_proxy),
+ CLASS_PD|CLASS_NOINLET, A_NULL);
+
+ class_addfloat(proxy_class, sync_float_input);
+ class_addanything(proxy_class, sync_input);
+
+ class_addfloat(sync_class, sync_float);
+ class_addmethod(sync_class, (t_method)sync_set_trigger, gensym("trigger"), A_GIMME, 0);
+ class_addmethod(sync_class, (t_method)sync_set_require, gensym("require"), A_GIMME, 0);
+ class_addmethod(sync_class, (t_method)sync_set_mode, gensym("mode"), A_SYMBOL, 0);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_addcreator((t_newmethod)sync_new, gensym("sync"), A_GIMME, 0);
+ class_sethelpsymbol(sync_class, gensym("maxlib/sync-help.pd"));
+#endif
+}
+
diff --git a/temperature.c b/temperature.c
index 78b7fe7..ac9287e 100644
--- a/temperature.c
+++ b/temperature.c
@@ -1,120 +1,120 @@
-/* -------------------------- temperature ------------------------------------- */
-/* */
-/* Calculates temperature: number of 'events' within N milliseconds. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <math.h>
-
-static char *version = "temperature v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct temperature
-{
- t_object x_ob;
- t_clock *x_clock;
- t_outlet *x_outfloat; /* output the temperature */
- t_int x_index; /* the number of elements to average */
- t_int x_time;
-
-} t_temperature;
-
-static void temperature_tick(t_temperature *x)
-{
- outlet_float(x->x_outfloat, x->x_index);
- x->x_index = 0;
- clock_delay(x->x_clock, x->x_time);
-}
-
-static void temperature_float(t_temperature *x, t_floatarg f)
-{
- x->x_index++; /* just count number of 'events' */
-}
-
-static void temperature_anything(t_temperature *x, t_symbol *s, int argc, t_atom *argv)
-{
- x->x_index++; /* just count number of 'events' */
-}
-
-static void temperature_time(t_temperature *x, t_floatarg f)
-{
- x->x_time = (t_int)f;
- if(x->x_time < 1) x->x_time = 1;
- clock_unset(x->x_clock);
- clock_delay(x->x_clock, x->x_time);
-}
-
-static void temperature_reset(t_temperature *x)
-{
- x->x_index = 0;
- post("temperature: reset");
-}
-
-static void temperature_free(t_temperature *x)
-{
- clock_free(x->x_clock);
-}
-
-static t_class *temperature_class;
-
-static void *temperature_new(t_floatarg f)
-{
- t_temperature *x = (t_temperature *)pd_new(temperature_class);
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("time"));
- x->x_outfloat = outlet_new(&x->x_ob, gensym("float"));
- x->x_clock = clock_new(x, (t_method)temperature_tick);
-
- x->x_time = (t_int)f;
- if(x->x_time < 1)
- {
- x->x_time = 1;
- post("temperature: set time to %d ms", x->x_time);
- }
- x->x_index = 0;
- clock_delay(x->x_clock, x->x_time);
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void temperature_setup(void)
-{
- temperature_class = class_new(gensym("temperature"), (t_newmethod)temperature_new,
- (t_method)temperature_free, sizeof(t_temperature), 0, A_DEFFLOAT, 0);
- class_addmethod(temperature_class, (t_method)temperature_reset, gensym("reset"), 0);
- class_addfloat(temperature_class, temperature_float);
- class_addmethod(temperature_class, (t_method)temperature_time, gensym("time"), A_FLOAT, 0);
- class_addanything(temperature_class, temperature_anything);
-
- post(version);
-}
-#else
-void maxlib_temperature_setup(void)
-{
- temperature_class = class_new(gensym("maxlib_temperature"), (t_newmethod)temperature_new,
- (t_method)temperature_free, sizeof(t_temperature), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)temperature_new, gensym("temperature"), A_DEFFLOAT, 0);
- class_addmethod(temperature_class, (t_method)temperature_reset, gensym("reset"), 0);
- class_addfloat(temperature_class, temperature_float);
- class_addmethod(temperature_class, (t_method)temperature_time, gensym("time"), A_FLOAT, 0);
- class_addanything(temperature_class, temperature_anything);
- class_sethelpsymbol(temperature_class, gensym("maxlib/temperature-help.pd"));
-}
-#endif
+/* -------------------------- temperature ------------------------------------- */
+/* */
+/* Calculates temperature: number of 'events' within N milliseconds. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <math.h>
+
+static char *version = "temperature v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct temperature
+{
+ t_object x_ob;
+ t_clock *x_clock;
+ t_outlet *x_outfloat; /* output the temperature */
+ t_int x_index; /* the number of elements to average */
+ t_int x_time;
+
+} t_temperature;
+
+static void temperature_tick(t_temperature *x)
+{
+ outlet_float(x->x_outfloat, x->x_index);
+ x->x_index = 0;
+ clock_delay(x->x_clock, x->x_time);
+}
+
+static void temperature_float(t_temperature *x, t_floatarg f)
+{
+ x->x_index++; /* just count number of 'events' */
+}
+
+static void temperature_anything(t_temperature *x, t_symbol *s, int argc, t_atom *argv)
+{
+ x->x_index++; /* just count number of 'events' */
+}
+
+static void temperature_time(t_temperature *x, t_floatarg f)
+{
+ x->x_time = (t_int)f;
+ if(x->x_time < 1) x->x_time = 1;
+ clock_unset(x->x_clock);
+ clock_delay(x->x_clock, x->x_time);
+}
+
+static void temperature_reset(t_temperature *x)
+{
+ x->x_index = 0;
+ post("temperature: reset");
+}
+
+static void temperature_free(t_temperature *x)
+{
+ clock_free(x->x_clock);
+}
+
+static t_class *temperature_class;
+
+static void *temperature_new(t_floatarg f)
+{
+ t_temperature *x = (t_temperature *)pd_new(temperature_class);
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("time"));
+ x->x_outfloat = outlet_new(&x->x_ob, gensym("float"));
+ x->x_clock = clock_new(x, (t_method)temperature_tick);
+
+ x->x_time = (t_int)f;
+ if(x->x_time < 1)
+ {
+ x->x_time = 1;
+ post("temperature: set time to %d ms", x->x_time);
+ }
+ x->x_index = 0;
+ clock_delay(x->x_clock, x->x_time);
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void temperature_setup(void)
+{
+ temperature_class = class_new(gensym("temperature"), (t_newmethod)temperature_new,
+ (t_method)temperature_free, sizeof(t_temperature), 0, A_DEFFLOAT, 0);
+ class_addmethod(temperature_class, (t_method)temperature_reset, gensym("reset"), 0);
+ class_addfloat(temperature_class, temperature_float);
+ class_addmethod(temperature_class, (t_method)temperature_time, gensym("time"), A_FLOAT, 0);
+ class_addanything(temperature_class, temperature_anything);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_temperature_setup(void)
+{
+ temperature_class = class_new(gensym("maxlib_temperature"), (t_newmethod)temperature_new,
+ (t_method)temperature_free, sizeof(t_temperature), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)temperature_new, gensym("temperature"), A_DEFFLOAT, 0);
+ class_addmethod(temperature_class, (t_method)temperature_reset, gensym("reset"), 0);
+ class_addfloat(temperature_class, temperature_float);
+ class_addmethod(temperature_class, (t_method)temperature_time, gensym("time"), A_FLOAT, 0);
+ class_addanything(temperature_class, temperature_anything);
+ class_sethelpsymbol(temperature_class, gensym("maxlib/temperature-help.pd"));
+}
+#endif
diff --git a/tilt.c b/tilt.c
index dde587d..a3a3ef5 100644
--- a/tilt.c
+++ b/tilt.c
@@ -1,189 +1,189 @@
-/* ------------------------- tilt --------------------------------------------- */
-/* */
-/* Monitor input for changes. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Inspired by code written by Trond Lossius. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-#define MAXSIZE 32
-
-static char *version = "tilt v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct tilt
-{
- t_object x_ob;
- t_outlet *x_out; /* result */
- t_clock *x_clock;
-
- t_float x_tilt; /* the result */
- t_float x_start_tilt;
- t_float x_t;
- t_float x_sa;
- t_float x_sb;
- t_float x_offset;
- t_float x_time;
- t_float x_wait;
- t_float x_hi_limit;
- t_float x_low_limit;
- t_float x_trip_point;
-} t_tilt;
-
-static void tilt_tick(t_tilt *x)
-{
- x->x_sb = x->x_t - x->x_offset;
- if((x->x_sb - x->x_sa) > x->x_hi_limit)
- {
- x->x_sa = x->x_sb;
- clock_delay(x->x_clock, x->x_wait);
- return;
- }
- else
- {
- if((x->x_sb - x->x_sa) > x->x_trip_point)
- {
- outlet_bang(x->x_out);
- clock_delay(x->x_clock, x->x_wait);
- return;
- }
- if((x->x_sb - x->x_sa) < x->x_low_limit)
- {
- x->x_time++;
- if(x->x_time > 15)
- {
- x->x_start_tilt = x->x_sa;
- x->x_time = 0;
- }
- }
- if((x->x_sb - x->x_start_tilt) > x->x_tilt)
- {
- outlet_bang(x->x_out);
- clock_delay(x->x_clock, x->x_wait);
- }
- else
- {
- x->x_sa = x->x_sb;
- clock_delay(x->x_clock, x->x_wait);
- return;
- }
- }
-}
-
-static void tilt_float(t_tilt *x, t_floatarg f)
-{
- x->x_t = f;
-}
-
-static void tilt_intv(t_tilt *x, t_floatarg f)
-{
- x->x_wait = f;
-}
-
-static void tilt_tilt(t_tilt *x, t_floatarg f)
-{
- x->x_tilt = f;
- post("tilt: set tilt to %g", x->x_tilt);
-}
-
-static void tilt_hi_limit(t_tilt *x, t_floatarg f)
-{
- x->x_hi_limit = f;
- post("tilt: set high limit to %g", x->x_hi_limit);
-}
-
-static void tilt_low_limit(t_tilt *x, t_floatarg f)
-{
- x->x_low_limit = f;
- post("tilt: set low limit to %g", x->x_low_limit);
-}
-
-static void tilt_trip_point(t_tilt *x, t_floatarg f)
-{
- x->x_trip_point = f;
- post("tilt: set trip point to %g", x->x_trip_point);
-}
-
-static void tilt_free(t_tilt *x)
-{
- clock_free(x->x_clock);
-}
-
-static t_class *tilt_class;
-
-static void *tilt_new(t_floatarg f, t_floatarg f2)
-{
- int i;
-
- t_tilt *x = (t_tilt *)pd_new(tilt_class);
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("intv"));
- x->x_out = outlet_new(&x->x_ob, gensym("float"));
- x->x_clock = clock_new(x, (t_method)tilt_tick);
-
- x->x_t = f; /* set initial value */
- if(f2 > 4)
- x->x_wait = f2;
- else
- x->x_wait = 4000;
- x->x_offset = 0;
- x->x_sa = 0;
- x->x_sb = 0;
- x->x_time = 0;
- x->x_tilt = 0;
- x->x_start_tilt = x->x_sa = x->x_t - x->x_offset;
- x->x_hi_limit = x->x_low_limit = x->x_trip_point = 0;
- clock_delay(x->x_clock, x->x_wait); /* wait 4 sec and start calculation */
-
- post("tilt: set interval to %g msec", x->x_wait);
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void tilt_setup(void)
-{
- tilt_class = class_new(gensym("tilt"), (t_newmethod)tilt_new,
- (t_method)tilt_free, sizeof(t_tilt), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addfloat(tilt_class, tilt_float);
- class_addmethod(tilt_class, (t_method)tilt_intv, gensym("intv"), A_FLOAT, 0);
- class_addmethod(tilt_class, (t_method)tilt_tilt, gensym("tilt"), A_FLOAT, 0);
- class_addmethod(tilt_class, (t_method)tilt_hi_limit, gensym("hi"), A_FLOAT, 0);
- class_addmethod(tilt_class, (t_method)tilt_low_limit, gensym("low"), A_FLOAT, 0);
- class_addmethod(tilt_class, (t_method)tilt_trip_point, gensym("trip"), A_FLOAT, 0);
-
- post(version);
-}
-#else
-void maxlib_tilt_setup(void)
-{
- tilt_class = class_new(gensym("maxlib_tilt"), (t_newmethod)tilt_new,
- (t_method)tilt_free, sizeof(t_tilt), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)tilt_new, gensym("tilt"), A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addfloat(tilt_class, tilt_float);
- class_addmethod(tilt_class, (t_method)tilt_intv, gensym("intv"), A_FLOAT, 0);
- class_addmethod(tilt_class, (t_method)tilt_tilt, gensym("tilt"), A_FLOAT, 0);
- class_addmethod(tilt_class, (t_method)tilt_hi_limit, gensym("hi"), A_FLOAT, 0);
- class_addmethod(tilt_class, (t_method)tilt_low_limit, gensym("low"), A_FLOAT, 0);
- class_addmethod(tilt_class, (t_method)tilt_trip_point, gensym("trip"), A_FLOAT, 0);
- class_sethelpsymbol(tilt_class, gensym("maxlib/tilt-help.pd"));
-}
-#endif
+/* ------------------------- tilt --------------------------------------------- */
+/* */
+/* Monitor input for changes. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Inspired by code written by Trond Lossius. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MAXSIZE 32
+
+static char *version = "tilt v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct tilt
+{
+ t_object x_ob;
+ t_outlet *x_out; /* result */
+ t_clock *x_clock;
+
+ t_float x_tilt; /* the result */
+ t_float x_start_tilt;
+ t_float x_t;
+ t_float x_sa;
+ t_float x_sb;
+ t_float x_offset;
+ t_float x_time;
+ t_float x_wait;
+ t_float x_hi_limit;
+ t_float x_low_limit;
+ t_float x_trip_point;
+} t_tilt;
+
+static void tilt_tick(t_tilt *x)
+{
+ x->x_sb = x->x_t - x->x_offset;
+ if((x->x_sb - x->x_sa) > x->x_hi_limit)
+ {
+ x->x_sa = x->x_sb;
+ clock_delay(x->x_clock, x->x_wait);
+ return;
+ }
+ else
+ {
+ if((x->x_sb - x->x_sa) > x->x_trip_point)
+ {
+ outlet_bang(x->x_out);
+ clock_delay(x->x_clock, x->x_wait);
+ return;
+ }
+ if((x->x_sb - x->x_sa) < x->x_low_limit)
+ {
+ x->x_time++;
+ if(x->x_time > 15)
+ {
+ x->x_start_tilt = x->x_sa;
+ x->x_time = 0;
+ }
+ }
+ if((x->x_sb - x->x_start_tilt) > x->x_tilt)
+ {
+ outlet_bang(x->x_out);
+ clock_delay(x->x_clock, x->x_wait);
+ }
+ else
+ {
+ x->x_sa = x->x_sb;
+ clock_delay(x->x_clock, x->x_wait);
+ return;
+ }
+ }
+}
+
+static void tilt_float(t_tilt *x, t_floatarg f)
+{
+ x->x_t = f;
+}
+
+static void tilt_intv(t_tilt *x, t_floatarg f)
+{
+ x->x_wait = f;
+}
+
+static void tilt_tilt(t_tilt *x, t_floatarg f)
+{
+ x->x_tilt = f;
+ post("tilt: set tilt to %g", x->x_tilt);
+}
+
+static void tilt_hi_limit(t_tilt *x, t_floatarg f)
+{
+ x->x_hi_limit = f;
+ post("tilt: set high limit to %g", x->x_hi_limit);
+}
+
+static void tilt_low_limit(t_tilt *x, t_floatarg f)
+{
+ x->x_low_limit = f;
+ post("tilt: set low limit to %g", x->x_low_limit);
+}
+
+static void tilt_trip_point(t_tilt *x, t_floatarg f)
+{
+ x->x_trip_point = f;
+ post("tilt: set trip point to %g", x->x_trip_point);
+}
+
+static void tilt_free(t_tilt *x)
+{
+ clock_free(x->x_clock);
+}
+
+static t_class *tilt_class;
+
+static void *tilt_new(t_floatarg f, t_floatarg f2)
+{
+ int i;
+
+ t_tilt *x = (t_tilt *)pd_new(tilt_class);
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("intv"));
+ x->x_out = outlet_new(&x->x_ob, gensym("float"));
+ x->x_clock = clock_new(x, (t_method)tilt_tick);
+
+ x->x_t = f; /* set initial value */
+ if(f2 > 4)
+ x->x_wait = f2;
+ else
+ x->x_wait = 4000;
+ x->x_offset = 0;
+ x->x_sa = 0;
+ x->x_sb = 0;
+ x->x_time = 0;
+ x->x_tilt = 0;
+ x->x_start_tilt = x->x_sa = x->x_t - x->x_offset;
+ x->x_hi_limit = x->x_low_limit = x->x_trip_point = 0;
+ clock_delay(x->x_clock, x->x_wait); /* wait 4 sec and start calculation */
+
+ post("tilt: set interval to %g msec", x->x_wait);
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void tilt_setup(void)
+{
+ tilt_class = class_new(gensym("tilt"), (t_newmethod)tilt_new,
+ (t_method)tilt_free, sizeof(t_tilt), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(tilt_class, tilt_float);
+ class_addmethod(tilt_class, (t_method)tilt_intv, gensym("intv"), A_FLOAT, 0);
+ class_addmethod(tilt_class, (t_method)tilt_tilt, gensym("tilt"), A_FLOAT, 0);
+ class_addmethod(tilt_class, (t_method)tilt_hi_limit, gensym("hi"), A_FLOAT, 0);
+ class_addmethod(tilt_class, (t_method)tilt_low_limit, gensym("low"), A_FLOAT, 0);
+ class_addmethod(tilt_class, (t_method)tilt_trip_point, gensym("trip"), A_FLOAT, 0);
+
+ logpost(NULL, 4, version);
+}
+#else
+void maxlib_tilt_setup(void)
+{
+ tilt_class = class_new(gensym("maxlib_tilt"), (t_newmethod)tilt_new,
+ (t_method)tilt_free, sizeof(t_tilt), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)tilt_new, gensym("tilt"), A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(tilt_class, tilt_float);
+ class_addmethod(tilt_class, (t_method)tilt_intv, gensym("intv"), A_FLOAT, 0);
+ class_addmethod(tilt_class, (t_method)tilt_tilt, gensym("tilt"), A_FLOAT, 0);
+ class_addmethod(tilt_class, (t_method)tilt_hi_limit, gensym("hi"), A_FLOAT, 0);
+ class_addmethod(tilt_class, (t_method)tilt_low_limit, gensym("low"), A_FLOAT, 0);
+ class_addmethod(tilt_class, (t_method)tilt_trip_point, gensym("trip"), A_FLOAT, 0);
+ class_sethelpsymbol(tilt_class, gensym("maxlib/tilt-help.pd"));
+}
+#endif
diff --git a/timebang.c b/timebang.c
index d70744a..2960ce9 100644
--- a/timebang.c
+++ b/timebang.c
@@ -1,174 +1,174 @@
-/* ------------------------- timebang --------------------------------------- */
-/* */
-/* Send out bangs at given times (time of day!). */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <math.h>
-#include <time.h>
-
-#define MAX_TIMES 256 /* maximum number of times to process */
-
-static char *version = "timebang v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct timebang
-{
- t_object x_ob;
- t_clock *x_clock;
- t_outlet *x_outlet[MAX_TIMES]; /* the bang outlets */
- t_int x_sec[MAX_TIMES]; /* seconds (0 - 59) */
- t_int x_min[MAX_TIMES]; /* minutes (0 - 59) */
- t_int x_hour[MAX_TIMES]; /* hours (0 - 11) */
- t_int x_mday[MAX_TIMES]; /* day of month (1 - 31) */
- t_int x_mon[MAX_TIMES]; /* month (0 - 11) */
- t_int x_year[MAX_TIMES]; /* year (current year minus 1900) */
- t_int x_wday[MAX_TIMES]; /* day of week (0 - 6, Sunday = 0, -1 = all days) */
- t_int x_over[MAX_TIMES]; /* indicate that time is over */
- t_int x_notimes; /* number of times to bang */
-} t_timebang;
-
-
-static void timebang_tick(t_timebang *x)
-{
- time_t now = time(NULL);
- struct tm *newtime;
- int i;
-
- newtime = localtime(&now); /* convert to local time. */
- for(i = 0; i < x->x_notimes; i++)
- {
- if(!x->x_over[i])
- {
- if(newtime->tm_hour == x->x_hour[i] &&
- newtime->tm_min == x->x_min[i] &&
- newtime->tm_sec >= x->x_sec[i])
- {
- x->x_over[i] = 1; /* mark as 'time is over' */
- outlet_bang(x->x_outlet[i]); /* send corresponding bang */
- }
- }
- else if(newtime->tm_hour != x->x_hour[i])
- x->x_over[i] = 0; /* reactivate time one hour later */
- }
-
- clock_delay(x->x_clock, 1000); /* come back in one second */
-}
-
-static void timebang_set(t_timebang *x, t_symbol *s, int ac, t_atom *av)
-{
- int i, j;
-
- if(ac == x->x_notimes * 3)
- {
- for(i = 0, j = 0; i < ac; i += 3, j++)
- {
- if (av[i].a_type == A_FLOAT) x->x_hour[j] = av[i].a_w.w_float;
- else { post ("timebang: first argument must be (int) hours"); return; }
- if (av[i+1].a_type == A_FLOAT) x->x_min[j] = av[i+1].a_w.w_float;
- else { post ("timebang: second argument must be (int) minutes"); return; }
- if (av[i+2].a_type == A_FLOAT) x->x_sec[j] = av[i+2].a_w.w_float;
- else { post ("timebang: third argument must be (int) seconds"); return; }
- x->x_over[i] = 0;
- }
- post("timebang: read in %d times of day:", x->x_notimes);
- for(i = 0; i < x->x_notimes; i++)
- {
- post(" %02d:%02d:%02d", x->x_hour[i], x->x_min[i], x->x_sec[i]);
- }
- }
- else post("timebang: wrong number of parameter");
-}
-
-static void timebang_bang(t_timebang *x)
-{
- time_t now = time(NULL);
- struct tm *newtime = localtime(&now); /* convert to local time. */
- post("timebang: local time is %02d:%02d:%02d", newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
-}
-
-static t_class *timebang_class;
-
-static void *timebang_new(t_symbol *s, int ac, t_atom *av)
-{
- int i;
- t_timebang *x = (t_timebang *)pd_new(timebang_class);
-
- x->x_clock = clock_new(x, (t_method)timebang_tick);
-
- if(ac > MAX_TIMES * 3)
- {
- post("timebang: too many creation arguments");
- ac = MAX_TIMES * 3;
- }
-
- x->x_notimes = 0;
- for(i = 0; i < ac; i += 3)
- {
- if (av[i].a_type == A_FLOAT) x->x_hour[x->x_notimes] = av[i].a_w.w_float;
- else { post ("timebang: first argument must be (int) hours"); return 0; }
- if (av[i+1].a_type == A_FLOAT) x->x_min[x->x_notimes] = av[i+1].a_w.w_float;
- else { post ("timebang: second argument must be (int) minutes"); return 0; }
- if (av[i+2].a_type == A_FLOAT) x->x_sec[x->x_notimes] = av[i+2].a_w.w_float;
- else { post ("timebang: third argument must be (int) seconds"); return 0; }
- x->x_over[x->x_notimes] = 0;
- x->x_notimes++;
- }
- post("timebang: read in %d times of day:", x->x_notimes);
- for(i = 0; i < x->x_notimes; i++)
- {
- x->x_outlet[i] = outlet_new(&x->x_ob, gensym("bang")); /* create specific bang outlet for time */
- post(" %02d:%02d:%02d", x->x_hour[i], x->x_min[i], x->x_sec[i]);
- }
-
- clock_set(x->x_clock, 0);
-
- return (void *)x;
-}
-
-static void timebang_free(t_timebang *x)
-{
- clock_free(x->x_clock);
-}
-
-#ifndef MAXLIB
-void timebang_setup(void)
-{
- timebang_class = class_new(gensym("timebang"), (t_newmethod)timebang_new,
- (t_method)timebang_free, sizeof(t_timebang), 0, A_GIMME, 0);
-#else
-void maxlib_timebang_setup(void)
-{
- timebang_class = class_new(gensym("maxlib_timebang"), (t_newmethod)timebang_new,
- (t_method)timebang_free, sizeof(t_timebang), 0, A_GIMME, 0);
- class_addcreator((t_newmethod)timebang_new, gensym("timebang"), A_GIMME, 0);
-#endif
- class_addmethod(timebang_class, (t_method)timebang_set, gensym("set"), A_GIMME, 0);
- class_addbang(timebang_class, (t_method)timebang_bang);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_sethelpsymbol(timebang_class, gensym("maxlib/timebang-help.pd"));
-#endif
-}
-
+/* ------------------------- timebang --------------------------------------- */
+/* */
+/* Send out bangs at given times (time of day!). */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+#include <time.h>
+
+#define MAX_TIMES 256 /* maximum number of times to process */
+
+static char *version = "timebang v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct timebang
+{
+ t_object x_ob;
+ t_clock *x_clock;
+ t_outlet *x_outlet[MAX_TIMES]; /* the bang outlets */
+ t_int x_sec[MAX_TIMES]; /* seconds (0 - 59) */
+ t_int x_min[MAX_TIMES]; /* minutes (0 - 59) */
+ t_int x_hour[MAX_TIMES]; /* hours (0 - 11) */
+ t_int x_mday[MAX_TIMES]; /* day of month (1 - 31) */
+ t_int x_mon[MAX_TIMES]; /* month (0 - 11) */
+ t_int x_year[MAX_TIMES]; /* year (current year minus 1900) */
+ t_int x_wday[MAX_TIMES]; /* day of week (0 - 6, Sunday = 0, -1 = all days) */
+ t_int x_over[MAX_TIMES]; /* indicate that time is over */
+ t_int x_notimes; /* number of times to bang */
+} t_timebang;
+
+
+static void timebang_tick(t_timebang *x)
+{
+ time_t now = time(NULL);
+ struct tm *newtime;
+ int i;
+
+ newtime = localtime(&now); /* convert to local time. */
+ for(i = 0; i < x->x_notimes; i++)
+ {
+ if(!x->x_over[i])
+ {
+ if(newtime->tm_hour == x->x_hour[i] &&
+ newtime->tm_min == x->x_min[i] &&
+ newtime->tm_sec >= x->x_sec[i])
+ {
+ x->x_over[i] = 1; /* mark as 'time is over' */
+ outlet_bang(x->x_outlet[i]); /* send corresponding bang */
+ }
+ }
+ else if(newtime->tm_hour != x->x_hour[i])
+ x->x_over[i] = 0; /* reactivate time one hour later */
+ }
+
+ clock_delay(x->x_clock, 1000); /* come back in one second */
+}
+
+static void timebang_set(t_timebang *x, t_symbol *s, int ac, t_atom *av)
+{
+ int i, j;
+
+ if(ac == x->x_notimes * 3)
+ {
+ for(i = 0, j = 0; i < ac; i += 3, j++)
+ {
+ if (av[i].a_type == A_FLOAT) x->x_hour[j] = av[i].a_w.w_float;
+ else { post ("timebang: first argument must be (int) hours"); return; }
+ if (av[i+1].a_type == A_FLOAT) x->x_min[j] = av[i+1].a_w.w_float;
+ else { post ("timebang: second argument must be (int) minutes"); return; }
+ if (av[i+2].a_type == A_FLOAT) x->x_sec[j] = av[i+2].a_w.w_float;
+ else { post ("timebang: third argument must be (int) seconds"); return; }
+ x->x_over[i] = 0;
+ }
+ post("timebang: read in %d times of day:", x->x_notimes);
+ for(i = 0; i < x->x_notimes; i++)
+ {
+ post(" %02d:%02d:%02d", x->x_hour[i], x->x_min[i], x->x_sec[i]);
+ }
+ }
+ else post("timebang: wrong number of parameter");
+}
+
+static void timebang_bang(t_timebang *x)
+{
+ time_t now = time(NULL);
+ struct tm *newtime = localtime(&now); /* convert to local time. */
+ post("timebang: local time is %02d:%02d:%02d", newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
+}
+
+static t_class *timebang_class;
+
+static void *timebang_new(t_symbol *s, int ac, t_atom *av)
+{
+ int i;
+ t_timebang *x = (t_timebang *)pd_new(timebang_class);
+
+ x->x_clock = clock_new(x, (t_method)timebang_tick);
+
+ if(ac > MAX_TIMES * 3)
+ {
+ post("timebang: too many creation arguments");
+ ac = MAX_TIMES * 3;
+ }
+
+ x->x_notimes = 0;
+ for(i = 0; i < ac; i += 3)
+ {
+ if (av[i].a_type == A_FLOAT) x->x_hour[x->x_notimes] = av[i].a_w.w_float;
+ else { post ("timebang: first argument must be (int) hours"); return 0; }
+ if (av[i+1].a_type == A_FLOAT) x->x_min[x->x_notimes] = av[i+1].a_w.w_float;
+ else { post ("timebang: second argument must be (int) minutes"); return 0; }
+ if (av[i+2].a_type == A_FLOAT) x->x_sec[x->x_notimes] = av[i+2].a_w.w_float;
+ else { post ("timebang: third argument must be (int) seconds"); return 0; }
+ x->x_over[x->x_notimes] = 0;
+ x->x_notimes++;
+ }
+ post("timebang: read in %d times of day:", x->x_notimes);
+ for(i = 0; i < x->x_notimes; i++)
+ {
+ x->x_outlet[i] = outlet_new(&x->x_ob, gensym("bang")); /* create specific bang outlet for time */
+ post(" %02d:%02d:%02d", x->x_hour[i], x->x_min[i], x->x_sec[i]);
+ }
+
+ clock_set(x->x_clock, 0);
+
+ return (void *)x;
+}
+
+static void timebang_free(t_timebang *x)
+{
+ clock_free(x->x_clock);
+}
+
+#ifndef MAXLIB
+void timebang_setup(void)
+{
+ timebang_class = class_new(gensym("timebang"), (t_newmethod)timebang_new,
+ (t_method)timebang_free, sizeof(t_timebang), 0, A_GIMME, 0);
+#else
+void maxlib_timebang_setup(void)
+{
+ timebang_class = class_new(gensym("maxlib_timebang"), (t_newmethod)timebang_new,
+ (t_method)timebang_free, sizeof(t_timebang), 0, A_GIMME, 0);
+ class_addcreator((t_newmethod)timebang_new, gensym("timebang"), A_GIMME, 0);
+#endif
+ class_addmethod(timebang_class, (t_method)timebang_set, gensym("set"), A_GIMME, 0);
+ class_addbang(timebang_class, (t_method)timebang_bang);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(timebang_class, gensym("maxlib/timebang-help.pd"));
+#endif
+}
+
diff --git a/triang.c b/triang.c
index 42e0766..77ec5e9 100644
--- a/triang.c
+++ b/triang.c
@@ -1,80 +1,80 @@
-/* ---------------------------- rand_triang ----------------------------------- */
-/* */
-/* rand_triang generates a triangularly distributed random variable. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-#define fran() (t_float)rand()/(t_float)RAND_MAX
-
-static char *version = "triang v0.1, generates triangularly distributed random variable\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-/* -------------------------- rand_triang ------------------------------ */
-
-static t_class *rand_triang_class;
-
-typedef struct _rand_triang
-{
- t_object x_obj;
-} t_rand_triang;
-
-static void *rand_triang_new(t_floatarg f)
-{
- t_rand_triang *x = (t_rand_triang *)pd_new(rand_triang_class);
- srand( (unsigned)time( NULL ) );
- outlet_new(&x->x_obj, &s_float);
- return (x);
-}
-
-static void rand_triang_bang(t_rand_triang *x)
-{
- t_float u1, u2;
- u1 = fran();
- u2 = fran();
- outlet_float(x->x_obj.ob_outlet, 0.5*(u1+u2));
-}
-
-#ifndef MAXLIB
-void triang_setup(void)
-{
- rand_triang_class = class_new(gensym("triang"), (t_newmethod)rand_triang_new, 0,
- sizeof(t_rand_triang), 0, A_DEFFLOAT, 0);
-#else
-void maxlib_triang_setup(void)
-{
- rand_triang_class = class_new(gensym("maxlib_triang"), (t_newmethod)rand_triang_new, 0,
- sizeof(t_rand_triang), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)rand_triang_new, gensym("triang"), A_DEFFLOAT, 0);
-#endif
- class_addbang(rand_triang_class, rand_triang_bang);
-#ifndef MAXLIB
- class_sethelpsymbol(rand_triang_class, gensym("triang-help.pd"));
- post(version);
-#else
- class_sethelpsymbol(rand_triang_class, gensym("maxlib/triang-help.pd"));
-#endif
-}
+/* ---------------------------- rand_triang ----------------------------------- */
+/* */
+/* rand_triang generates a triangularly distributed random variable. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+
+#define fran() (t_float)rand()/(t_float)RAND_MAX
+
+static char *version = "triang v0.1, generates triangularly distributed random variable\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- rand_triang ------------------------------ */
+
+static t_class *rand_triang_class;
+
+typedef struct _rand_triang
+{
+ t_object x_obj;
+} t_rand_triang;
+
+static void *rand_triang_new(t_floatarg f)
+{
+ t_rand_triang *x = (t_rand_triang *)pd_new(rand_triang_class);
+ srand( (unsigned)time( NULL ) );
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void rand_triang_bang(t_rand_triang *x)
+{
+ t_float u1, u2;
+ u1 = fran();
+ u2 = fran();
+ outlet_float(x->x_obj.ob_outlet, 0.5*(u1+u2));
+}
+
+#ifndef MAXLIB
+void triang_setup(void)
+{
+ rand_triang_class = class_new(gensym("triang"), (t_newmethod)rand_triang_new, 0,
+ sizeof(t_rand_triang), 0, A_DEFFLOAT, 0);
+#else
+void maxlib_triang_setup(void)
+{
+ rand_triang_class = class_new(gensym("maxlib_triang"), (t_newmethod)rand_triang_new, 0,
+ sizeof(t_rand_triang), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)rand_triang_new, gensym("triang"), A_DEFFLOAT, 0);
+#endif
+ class_addbang(rand_triang_class, rand_triang_bang);
+#ifndef MAXLIB
+ class_sethelpsymbol(rand_triang_class, gensym("triang-help.pd"));
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(rand_triang_class, gensym("maxlib/triang-help.pd"));
+#endif
+}
diff --git a/unroute.c b/unroute.c
index 96331a4..bc31c39 100644
--- a/unroute.c
+++ b/unroute.c
@@ -1,175 +1,175 @@
-/* -------------------------- unroute ------------------------------------- */
-/* */
-/* Opposit to croute. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-
-#define MAX_INLET 256
-
-static char *version = "unroute v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct unroute
-{
- t_object x_obj;
- t_outlet *x_outlet;
- t_int x_ninstance;
- t_atom x_id;
-} t_unroute;
-
-typedef struct proxy
-{
- t_object obj;
- t_int index; /* number of proxy inlet(s) */
- t_atom id;
- t_unroute *x; /* we'll put the other struct in here */
-} t_proxy;
-
-static void unroute_any(t_unroute *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i;
- t_atom at[MAXPDSTRING];
-
- for(i = 0; i < argc; i++)
- {
- at[i + 2] = argv[i];
- }
- argc += 2;
- SETSYMBOL(at+1, s);
-
- at[0] = x->x_id; /* prepend id of that inlet */
-
- outlet_list(x->x_outlet, NULL, argc, at);
-}
-
-static void unroute_list(t_unroute *x, t_symbol *s, int argc, t_atom *argv)
-{
- int i;
- t_atom at[MAXPDSTRING];
-
- for(i = 0; i < argc; i++)
- {
- at[i + 1] = argv[i];
- }
- argc++;
-
- at[0] = x->x_id; /* prepend id of that inlet */
-
- outlet_list(x->x_outlet, NULL, argc, at);
-}
-
-static void unroute_float(t_unroute *x, t_floatarg f)
-{
- t_atom list[2];
-
- list[0] = x->x_id; /* prepend id of that inlet */
- SETFLOAT(list+1, f);
- outlet_list(x->x_outlet, NULL, 2, list);
-}
-
-static void unroute_input(t_proxy *p, t_symbol *s, int argc, t_atom *argv)
-{
- t_unroute *x = (t_unroute *)(p->x);
- int i;
- t_atom at[MAXPDSTRING];
-
- if(s == gensym("list"))
- {
- for(i = 0; i < argc; i++)
- {
- at[i + 1] = argv[i];
- }
- argc++;
- }
- else
- {
- for(i = 0; i < argc; i++)
- {
- at[i + 2] = argv[i];
- }
- argc += 2;
- SETSYMBOL(at+1, s);
- }
-
- at[0] = p->id; /* prepend id for that inlet */
-
- outlet_list(x->x_outlet, NULL, argc, at);
-}
-
-
-static t_class *unroute_class;
-static t_class *proxy_class;
-
-static void *unroute_new(t_symbol *s, int argc, t_atom *argv)
-{
- int i;
-
- t_unroute *x = (t_unroute *)pd_new(unroute_class);
- t_proxy *inlet[MAX_INLET];
-
- x->x_ninstance = argc;
- x->x_id = argv[0];
-
- for(i = 0; i < x->x_ninstance - 1; i++)
- {
- inlet[i] = (t_proxy *)pd_new(proxy_class);
- inlet[i]->x = x; /* make x visible to the proxy inlets */
- inlet[i]->index = i; /* remember our number */
- inlet[i]->id = argv[i+1];
- /* the inlet we're going to create belongs to the object
- 't_unroute' but the destination is the instance 'i'
- of the proxy class 't_proxy' */
- inlet_new(&x->x_obj, &inlet[i]->obj.ob_pd, 0,0);
- }
- x->x_outlet = outlet_new(&x->x_obj, gensym("float"));
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void unroute_setup(void)
-{
- unroute_class = class_new(gensym("unroute"), (t_newmethod)unroute_new,
- 0, sizeof(t_unroute), 0, A_GIMME, 0);
-#else
-void maxlib_unroute_setup(void)
-{
- unroute_class = class_new(gensym("maxlib_unroute"), (t_newmethod)unroute_new,
- 0, sizeof(t_unroute), 0, A_GIMME, 0);
-#endif
- /* a class for the proxy inlet: */
- proxy_class = class_new(gensym("maxlib_unroute_proxy"), NULL, NULL, sizeof(t_proxy),
- CLASS_PD|CLASS_NOINLET, A_NULL);
-
- class_addanything(proxy_class, unroute_input);
-
- class_addfloat(unroute_class, unroute_float);
- class_addlist(unroute_class, unroute_list);
- class_addanything(unroute_class, unroute_any);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_addcreator((t_newmethod)unroute_new, gensym("unroute"), A_GIMME, 0);
- class_sethelpsymbol(unroute_class, gensym("maxlib/unroute-help.pd"));
-#endif
-}
+/* -------------------------- unroute ------------------------------------- */
+/* */
+/* Opposit to croute. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+#define MAX_INLET 256
+
+static char *version = "unroute v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct unroute
+{
+ t_object x_obj;
+ t_outlet *x_outlet;
+ t_int x_ninstance;
+ t_atom x_id;
+} t_unroute;
+
+typedef struct proxy
+{
+ t_object obj;
+ t_int index; /* number of proxy inlet(s) */
+ t_atom id;
+ t_unroute *x; /* we'll put the other struct in here */
+} t_proxy;
+
+static void unroute_any(t_unroute *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ t_atom at[MAXPDSTRING];
+
+ for(i = 0; i < argc; i++)
+ {
+ at[i + 2] = argv[i];
+ }
+ argc += 2;
+ SETSYMBOL(at+1, s);
+
+ at[0] = x->x_id; /* prepend id of that inlet */
+
+ outlet_list(x->x_outlet, NULL, argc, at);
+}
+
+static void unroute_list(t_unroute *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ t_atom at[MAXPDSTRING];
+
+ for(i = 0; i < argc; i++)
+ {
+ at[i + 1] = argv[i];
+ }
+ argc++;
+
+ at[0] = x->x_id; /* prepend id of that inlet */
+
+ outlet_list(x->x_outlet, NULL, argc, at);
+}
+
+static void unroute_float(t_unroute *x, t_floatarg f)
+{
+ t_atom list[2];
+
+ list[0] = x->x_id; /* prepend id of that inlet */
+ SETFLOAT(list+1, f);
+ outlet_list(x->x_outlet, NULL, 2, list);
+}
+
+static void unroute_input(t_proxy *p, t_symbol *s, int argc, t_atom *argv)
+{
+ t_unroute *x = (t_unroute *)(p->x);
+ int i;
+ t_atom at[MAXPDSTRING];
+
+ if(s == gensym("list"))
+ {
+ for(i = 0; i < argc; i++)
+ {
+ at[i + 1] = argv[i];
+ }
+ argc++;
+ }
+ else
+ {
+ for(i = 0; i < argc; i++)
+ {
+ at[i + 2] = argv[i];
+ }
+ argc += 2;
+ SETSYMBOL(at+1, s);
+ }
+
+ at[0] = p->id; /* prepend id for that inlet */
+
+ outlet_list(x->x_outlet, NULL, argc, at);
+}
+
+
+static t_class *unroute_class;
+static t_class *proxy_class;
+
+static void *unroute_new(t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+
+ t_unroute *x = (t_unroute *)pd_new(unroute_class);
+ t_proxy *inlet[MAX_INLET];
+
+ x->x_ninstance = argc;
+ x->x_id = argv[0];
+
+ for(i = 0; i < x->x_ninstance - 1; i++)
+ {
+ inlet[i] = (t_proxy *)pd_new(proxy_class);
+ inlet[i]->x = x; /* make x visible to the proxy inlets */
+ inlet[i]->index = i; /* remember our number */
+ inlet[i]->id = argv[i+1];
+ /* the inlet we're going to create belongs to the object
+ 't_unroute' but the destination is the instance 'i'
+ of the proxy class 't_proxy' */
+ inlet_new(&x->x_obj, &inlet[i]->obj.ob_pd, 0,0);
+ }
+ x->x_outlet = outlet_new(&x->x_obj, gensym("float"));
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void unroute_setup(void)
+{
+ unroute_class = class_new(gensym("unroute"), (t_newmethod)unroute_new,
+ 0, sizeof(t_unroute), 0, A_GIMME, 0);
+#else
+void maxlib_unroute_setup(void)
+{
+ unroute_class = class_new(gensym("maxlib_unroute"), (t_newmethod)unroute_new,
+ 0, sizeof(t_unroute), 0, A_GIMME, 0);
+#endif
+ /* a class for the proxy inlet: */
+ proxy_class = class_new(gensym("maxlib_unroute_proxy"), NULL, NULL, sizeof(t_proxy),
+ CLASS_PD|CLASS_NOINLET, A_NULL);
+
+ class_addanything(proxy_class, unroute_input);
+
+ class_addfloat(unroute_class, unroute_float);
+ class_addlist(unroute_class, unroute_list);
+ class_addanything(unroute_class, unroute_any);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_addcreator((t_newmethod)unroute_new, gensym("unroute"), A_GIMME, 0);
+ class_sethelpsymbol(unroute_class, gensym("maxlib/unroute-help.pd"));
+#endif
+}
diff --git a/urn.c b/urn.c
index 5522244..10a7651 100644
--- a/urn.c
+++ b/urn.c
@@ -1,152 +1,152 @@
-/* ------------------------------- urn -------------------------------------- */
-/* */
-/* urn - urn selection model (random numbers without repetition). */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-static char *version = "urn v0.1, urn selection model\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-/* -------------------------- urn ------------------------------ */
-
-static t_class *urn_class;
-
-typedef struct _urn
-{
- t_object x_obj;
- t_outlet *x_numberout;
- t_outlet *x_notify;
-
- t_float x_f; /* number of numbers in urn */
- t_int x_numbers; /* numbers left in urn */
- t_int *x_selected;
- unsigned int x_state;
-} t_urn;
-
-static int makeseed(void)
-{
- static unsigned int random_nextseed = 1489853723;
- random_nextseed = random_nextseed * 435898247 + 938284287;
- return (random_nextseed & 0x7fffffff);
-}
-
-static void *urn_new(t_floatarg f)
-{
- t_urn *x = (t_urn *)pd_new(urn_class);
- srand( (unsigned)time( NULL ) );
- x->x_numbers = x->x_f = f;
- if(x->x_f < 0)x->x_f = 0;
- x->x_selected = getbytes(((t_int)x->x_f+1)*sizeof(t_int));
-
- x->x_state = makeseed();
-
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("f"));
-
- x->x_numberout = outlet_new(&x->x_obj, &s_float);
- x->x_notify = outlet_new(&x->x_obj, &s_bang);
- return (x);
-}
-
- /* set new size of urn */
-static void urn_f(t_urn *x, t_floatarg f)
-{
- int i;
- if(f < 0)
- f = 0;
- freebytes(x->x_selected, ((t_int)x->x_f+1)*sizeof(t_int));
- x->x_numbers = x->x_f = f;
- x->x_selected = getbytes(((t_int)x->x_f+1)*sizeof(t_int));
- for(i = 0; i <= x->x_f; i++)
- x->x_selected[i] = 0;
-}
-
- /* clear (refill) urn */
-static void urn_clear(t_urn *x)
-{
- int i;
- x->x_numbers = x->x_f;
- for(i = 0; i <= x->x_f; i++)
- x->x_selected[i] = 0;
-}
-
-static void urn_seed(t_urn *x, float f, float glob)
-{
- x->x_state = f;
-}
-
- /* choose from urn */
-static void urn_bang(t_urn *x)
-{
- int n = x->x_f, nval;
- int range = (n < 1 ? 1 : n);
- unsigned int randval = x->x_state;
- if(x->x_numbers == 0)
- goto notify;
- do
- {
- x->x_state = randval = randval * 472940017 + 832416023;
- nval = ((double)range) * ((double)randval)
- * (1./4294967296.);
- if (nval >= range) nval = range-1;
- }
- while(x->x_selected[nval]);
-
- x->x_selected[nval] = 1;
-
- outlet_float(x->x_numberout, nval);
-
- if(--x->x_numbers == 0) /* urn is now empty */
- goto notify;
- return;
-
-notify:
- outlet_bang(x->x_notify);
-}
-
-#ifndef MAXLIB
-void urn_setup(void)
-{
- urn_class = class_new(gensym("urn"), (t_newmethod)urn_new, 0,
- sizeof(t_urn), 0, A_DEFFLOAT, 0);
-#else
-void maxlib_urn_setup(void)
-{
- urn_class = class_new(gensym("maxlib_urn"), (t_newmethod)urn_new, 0,
- sizeof(t_urn), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)urn_new, gensym("urn"), A_DEFFLOAT, 0);
-#endif
- class_addbang(urn_class, urn_bang);
- class_addmethod(urn_class, (t_method)urn_f, gensym("f"), A_FLOAT, 0);
- class_addmethod(urn_class, (t_method)urn_clear, gensym("clear"), 0);
- class_addmethod(urn_class, (t_method)urn_seed, gensym("seed"), A_FLOAT, 0);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_sethelpsymbol(urn_class, gensym("maxlib/urn-help.pd"));
-#endif
-}
+/* ------------------------------- urn -------------------------------------- */
+/* */
+/* urn - urn selection model (random numbers without repetition). */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+
+static char *version = "urn v0.1, urn selection model\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- urn ------------------------------ */
+
+static t_class *urn_class;
+
+typedef struct _urn
+{
+ t_object x_obj;
+ t_outlet *x_numberout;
+ t_outlet *x_notify;
+
+ t_float x_f; /* number of numbers in urn */
+ t_int x_numbers; /* numbers left in urn */
+ t_int *x_selected;
+ unsigned int x_state;
+} t_urn;
+
+static int makeseed(void)
+{
+ static unsigned int random_nextseed = 1489853723;
+ random_nextseed = random_nextseed * 435898247 + 938284287;
+ return (random_nextseed & 0x7fffffff);
+}
+
+static void *urn_new(t_floatarg f)
+{
+ t_urn *x = (t_urn *)pd_new(urn_class);
+ srand( (unsigned)time( NULL ) );
+ x->x_numbers = x->x_f = f;
+ if(x->x_f < 0)x->x_f = 0;
+ x->x_selected = getbytes(((t_int)x->x_f+1)*sizeof(t_int));
+
+ x->x_state = makeseed();
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("f"));
+
+ x->x_numberout = outlet_new(&x->x_obj, &s_float);
+ x->x_notify = outlet_new(&x->x_obj, &s_bang);
+ return (x);
+}
+
+ /* set new size of urn */
+static void urn_f(t_urn *x, t_floatarg f)
+{
+ int i;
+ if(f < 0)
+ f = 0;
+ freebytes(x->x_selected, ((t_int)x->x_f+1)*sizeof(t_int));
+ x->x_numbers = x->x_f = f;
+ x->x_selected = getbytes(((t_int)x->x_f+1)*sizeof(t_int));
+ for(i = 0; i <= x->x_f; i++)
+ x->x_selected[i] = 0;
+}
+
+ /* clear (refill) urn */
+static void urn_clear(t_urn *x)
+{
+ int i;
+ x->x_numbers = x->x_f;
+ for(i = 0; i <= x->x_f; i++)
+ x->x_selected[i] = 0;
+}
+
+static void urn_seed(t_urn *x, float f, float glob)
+{
+ x->x_state = f;
+}
+
+ /* choose from urn */
+static void urn_bang(t_urn *x)
+{
+ int n = x->x_f, nval;
+ int range = (n < 1 ? 1 : n);
+ unsigned int randval = x->x_state;
+ if(x->x_numbers == 0)
+ goto notify;
+ do
+ {
+ x->x_state = randval = randval * 472940017 + 832416023;
+ nval = ((double)range) * ((double)randval)
+ * (1./4294967296.);
+ if (nval >= range) nval = range-1;
+ }
+ while(x->x_selected[nval]);
+
+ x->x_selected[nval] = 1;
+
+ outlet_float(x->x_numberout, nval);
+
+ if(--x->x_numbers == 0) /* urn is now empty */
+ goto notify;
+ return;
+
+notify:
+ outlet_bang(x->x_notify);
+}
+
+#ifndef MAXLIB
+void urn_setup(void)
+{
+ urn_class = class_new(gensym("urn"), (t_newmethod)urn_new, 0,
+ sizeof(t_urn), 0, A_DEFFLOAT, 0);
+#else
+void maxlib_urn_setup(void)
+{
+ urn_class = class_new(gensym("maxlib_urn"), (t_newmethod)urn_new, 0,
+ sizeof(t_urn), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)urn_new, gensym("urn"), A_DEFFLOAT, 0);
+#endif
+ class_addbang(urn_class, urn_bang);
+ class_addmethod(urn_class, (t_method)urn_f, gensym("f"), A_FLOAT, 0);
+ class_addmethod(urn_class, (t_method)urn_clear, gensym("clear"), 0);
+ class_addmethod(urn_class, (t_method)urn_seed, gensym("seed"), A_FLOAT, 0);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(urn_class, gensym("maxlib/urn-help.pd"));
+#endif
+}
diff --git a/velocity.c b/velocity.c
index c04fab9..50163fa 100644
--- a/velocity.c
+++ b/velocity.c
@@ -1,112 +1,112 @@
-/* ------------------------- velocity ----------------------------------------- */
-/* */
-/* Get velocity of input in digits per second. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Originally written for Max by Trond Lossius. */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* You should have received a copy of the GNU Lesser General Public */
-/* License along with this library; if not, write to the */
-/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
-/* Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-// velocity.c: (1000*(x[n]-x[n-1]))/Æt
-// (C) Trond Lossius/BEK 2000
-// Last revision: 4/7 2000
-//
-// Input:
-// float
-// int (converted to float)
-// set (set new value but no output)
-// Argument (optional, defaults to 0):
-// Initial stored value
-// Output:
-// float: Velocity as change per second (not ms)
-
-#include "m_pd.h"
-
-static char *version = "velocity v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct velocity
-{
- t_object x_ob;
- t_outlet *x_out;
- t_float x_xn1; /* input (floats) */
- t_float x_xn;
- double x_lasttime;
-} t_velocity;
-
-static void velocity_bang(t_velocity *x)
-{
- double thistime;
- t_float vel;
-
- thistime = clock_getlogicaltime();
- vel = (1000 * (x->x_xn - x->x_xn1) ) / (clock_gettimesince(x->x_lasttime));
- x->x_lasttime = thistime;
- outlet_float(x->x_out, vel);
-}
-
-static void velocity_float(t_velocity *x, t_floatarg f)
-{
- x->x_xn1 = x->x_xn;
- x->x_xn = f;
- velocity_bang(x);
-}
-
-static void velocity_free(t_velocity *x)
-{
- // nothing to do
-}
-
-static t_class *velocity_class;
-
-static void *velocity_new(t_floatarg f)
-{
- t_velocity *x = (t_velocity *)pd_new(velocity_class);
- x->x_out = outlet_new(&x->x_ob, gensym("float"));
- x->x_lasttime = clock_getlogicaltime();
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void velocity_setup(void)
-{
- velocity_class = class_new(gensym("velocity"), (t_newmethod)velocity_new,
- (t_method)velocity_free, sizeof(t_velocity), 0, A_DEFFLOAT, 0);
-#else
-void maxlib_velocity_setup(void)
-{
- velocity_class = class_new(gensym("maxlib_velocity"), (t_newmethod)velocity_new,
- (t_method)velocity_free, sizeof(t_velocity), 0, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)velocity_new, gensym("velocity"), A_DEFFLOAT, 0);
-#endif
- class_addfloat(velocity_class, velocity_float);
- class_addbang(velocity_class, velocity_bang);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_sethelpsymbol(velocity_class, gensym("maxlib/velocity-help.pd"));
-#endif
-}
-
+/* ------------------------- velocity ----------------------------------------- */
+/* */
+/* Get velocity of input in digits per second. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Originally written for Max by Trond Lossius. */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* You should have received a copy of the GNU Lesser General Public */
+/* License along with this library; if not, write to the */
+/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
+/* Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+// velocity.c: (1000*(x[n]-x[n-1]))/Æt
+// (C) Trond Lossius/BEK 2000
+// Last revision: 4/7 2000
+//
+// Input:
+// float
+// int (converted to float)
+// set (set new value but no output)
+// Argument (optional, defaults to 0):
+// Initial stored value
+// Output:
+// float: Velocity as change per second (not ms)
+
+#include "m_pd.h"
+
+static char *version = "velocity v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct velocity
+{
+ t_object x_ob;
+ t_outlet *x_out;
+ t_float x_xn1; /* input (floats) */
+ t_float x_xn;
+ double x_lasttime;
+} t_velocity;
+
+static void velocity_bang(t_velocity *x)
+{
+ double thistime;
+ t_float vel;
+
+ thistime = clock_getlogicaltime();
+ vel = (1000 * (x->x_xn - x->x_xn1) ) / (clock_gettimesince(x->x_lasttime));
+ x->x_lasttime = thistime;
+ outlet_float(x->x_out, vel);
+}
+
+static void velocity_float(t_velocity *x, t_floatarg f)
+{
+ x->x_xn1 = x->x_xn;
+ x->x_xn = f;
+ velocity_bang(x);
+}
+
+static void velocity_free(t_velocity *x)
+{
+ // nothing to do
+}
+
+static t_class *velocity_class;
+
+static void *velocity_new(t_floatarg f)
+{
+ t_velocity *x = (t_velocity *)pd_new(velocity_class);
+ x->x_out = outlet_new(&x->x_ob, gensym("float"));
+ x->x_lasttime = clock_getlogicaltime();
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void velocity_setup(void)
+{
+ velocity_class = class_new(gensym("velocity"), (t_newmethod)velocity_new,
+ (t_method)velocity_free, sizeof(t_velocity), 0, A_DEFFLOAT, 0);
+#else
+void maxlib_velocity_setup(void)
+{
+ velocity_class = class_new(gensym("maxlib_velocity"), (t_newmethod)velocity_new,
+ (t_method)velocity_free, sizeof(t_velocity), 0, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)velocity_new, gensym("velocity"), A_DEFFLOAT, 0);
+#endif
+ class_addfloat(velocity_class, velocity_float);
+ class_addbang(velocity_class, velocity_bang);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(velocity_class, gensym("maxlib/velocity-help.pd"));
+#endif
+}
+
diff --git a/weibull.c b/weibull.c
index a6e8564..b3ff821 100644
--- a/weibull.c
+++ b/weibull.c
@@ -1,95 +1,95 @@
-/* ---------------------------- rand_weibull ---------------------------------- */
-/* */
-/* rand_weibull generates a weibull distributed random variable. */
-/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Based on code found in Dodge/Jerse "Computer Music" */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
+/* ---------------------------- rand_weibull ---------------------------------- */
+/* */
+/* rand_weibull generates a weibull distributed random variable. */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
#include "m_pd.h"
-#include <stdlib.h>
-#include <time.h>
-#include <math.h>
-
-#define fran() (t_float)rand()/(t_float)RAND_MAX
-#ifndef M_PI
-#define M_PI 3.1415927
-#endif
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
-static char *version = "weibull v0.1, generates a weibull distributed random variable\n"
- " written by Olaf Matthes <olaf.matthes@gmx.de>";
+#define fran() (t_float)rand()/(t_float)RAND_MAX
+#ifndef M_PI
+#define M_PI 3.1415927
+#endif
-/* -------------------------- rand_weibull ------------------------------ */
-
-static t_class *rand_weibull_class;
-
-typedef struct _rand_weibull
-{
- t_object x_obj;
- t_float x_s;
- t_float x_t;
-} t_rand_weibull;
-
-static void *rand_weibull_new(t_floatarg s, t_floatarg t)
-{
- t_rand_weibull *x = (t_rand_weibull *)pd_new(rand_weibull_class);
- srand( (unsigned)time( NULL ) );
- floatinlet_new(&x->x_obj, &x->x_s);
- floatinlet_new(&x->x_obj, &x->x_t);
- outlet_new(&x->x_obj, &s_float);
- x->x_s = s;
- x->x_t = t;
- return (x);
-}
-
-static void rand_weibull_bang(t_rand_weibull *x)
-{
- t_float u, a, t, tinv;
- t = (x->x_t <= 0 ? 0.0001 : x->x_t);
- tinv = 1/t;
- do
- {
- u = fran();
- }
- while(u == 0 || u == 1);
- a = 1/(1 - u);
- outlet_float(x->x_obj.ob_outlet, x->x_s*pow(log(a), tinv));
-}
-
-#ifndef MAXLIB
-void weibull_setup(void)
-{
- rand_weibull_class = class_new(gensym("weibull"), (t_newmethod)rand_weibull_new, 0,
- sizeof(t_rand_weibull), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
-#else
-void maxlib_weibull_setup(void)
-{
- rand_weibull_class = class_new(gensym("maxlib_weibull"), (t_newmethod)rand_weibull_new, 0,
- sizeof(t_rand_weibull), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)rand_weibull_new, gensym("weibull"), A_DEFFLOAT, A_DEFFLOAT, 0);
-#endif
- class_addbang(rand_weibull_class, rand_weibull_bang);
-#ifndef MAXLIB
- class_sethelpsymbol(rand_weibull_class, gensym("weibull-help.pd"));
- post(version);
-#else
- class_sethelpsymbol(rand_weibull_class, gensym("maxlib/weibull-help.pd"));
-#endif
-}
+static char *version = "weibull v0.1, generates a weibull distributed random variable\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- rand_weibull ------------------------------ */
+
+static t_class *rand_weibull_class;
+
+typedef struct _rand_weibull
+{
+ t_object x_obj;
+ t_float x_s;
+ t_float x_t;
+} t_rand_weibull;
+
+static void *rand_weibull_new(t_floatarg s, t_floatarg t)
+{
+ t_rand_weibull *x = (t_rand_weibull *)pd_new(rand_weibull_class);
+ srand( (unsigned)time( NULL ) );
+ floatinlet_new(&x->x_obj, &x->x_s);
+ floatinlet_new(&x->x_obj, &x->x_t);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_s = s;
+ x->x_t = t;
+ return (x);
+}
+
+static void rand_weibull_bang(t_rand_weibull *x)
+{
+ t_float u, a, t, tinv;
+ t = (x->x_t <= 0 ? 0.0001 : x->x_t);
+ tinv = 1/t;
+ do
+ {
+ u = fran();
+ }
+ while(u == 0 || u == 1);
+ a = 1/(1 - u);
+ outlet_float(x->x_obj.ob_outlet, x->x_s*pow(log(a), tinv));
+}
+
+#ifndef MAXLIB
+void weibull_setup(void)
+{
+ rand_weibull_class = class_new(gensym("weibull"), (t_newmethod)rand_weibull_new, 0,
+ sizeof(t_rand_weibull), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+#else
+void maxlib_weibull_setup(void)
+{
+ rand_weibull_class = class_new(gensym("maxlib_weibull"), (t_newmethod)rand_weibull_new, 0,
+ sizeof(t_rand_weibull), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)rand_weibull_new, gensym("weibull"), A_DEFFLOAT, A_DEFFLOAT, 0);
+#endif
+ class_addbang(rand_weibull_class, rand_weibull_bang);
+#ifndef MAXLIB
+ class_sethelpsymbol(rand_weibull_class, gensym("weibull-help.pd"));
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(rand_weibull_class, gensym("maxlib/weibull-help.pd"));
+#endif
+}
diff --git a/wrap.c b/wrap.c
index 2272045..b7a63c4 100644
--- a/wrap.c
+++ b/wrap.c
@@ -1,142 +1,142 @@
-/* ------------------------- wrap ------------------------------------------ */
-/* */
-/* wraps input to lie within an output range. */
-/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* */
-/* ---------------------------------------------------------------------------- */
-
-#include "m_pd.h"
-#include <stdio.h>
-#include <math.h>
-
-static char *version = "wrap v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
-
-typedef struct wrap
-{
- t_object x_ob;
- t_float x_min; /* low border of input range */
- t_float x_max; /* high border of input range */
- t_outlet *x_outlet1; /* path-through outlet */
- t_outlet *x_outlet2; /* wrap outlet */
-} t_wrap;
-
-static void wrap_float(t_wrap *x, t_floatarg f)
-{
- t_float min = x->x_min;
- t_float max = x->x_max;
- t_float range = max - min;
- t_int i;
-
- if(range == 0.0f)
- {
- f = min;
- outlet_float(x->x_outlet2, 0);
- }
- else if(f < min)
- {
- t_float diff = min - f;
- t_float n = ceil(diff / range);
-
- f += n * range;
-
- outlet_float(x->x_outlet2, -(t_int)n);
- }
- else if (f >= max)
- {
- t_float diff = f - max;
- t_float n = floor(diff / range) + 1.0f;
-
- f -= n * range;
-
- outlet_float(x->x_outlet2, (t_int)n);
- }
- else
- outlet_float(x->x_outlet2, 0.0f);
-
- outlet_float(x->x_outlet1, f);
-}
-
-static void wrap_a(t_wrap *x, t_floatarg a)
-{
- t_float max = x->x_max;
-
- if(a <= max)
- x->x_min = a;
- else
- {
- x->x_min = max;
- x->x_max = a;
- }
-}
-
-static void wrap_b(t_wrap *x, t_floatarg b)
-{
- t_float min = x->x_min;
-
- if(b >= min)
- x->x_max = b;
- else
- {
- x->x_max = min;
- x->x_min = b;
- }
-}
-
-static t_class *wrap_class;
-
-static void *wrap_new(t_floatarg fmin, t_floatarg fmax)
-{
- t_wrap *x = (t_wrap *)pd_new(wrap_class);
-
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("a"));
- inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("b"));
-
- x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
- x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
-
- x->x_min = fmin;
- wrap_b(x, fmax);
-
- return (void *)x;
-}
-
-#ifndef MAXLIB
-void wrap_setup(void)
-{
- wrap_class = class_new(gensym("wrap"), (t_newmethod)wrap_new,
- 0, sizeof(t_wrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
-#else
-void maxlib_wrap_setup(void)
-{
- wrap_class = class_new(gensym("maxlib_wrap"), (t_newmethod)wrap_new,
- 0, sizeof(t_wrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
- class_addcreator((t_newmethod)wrap_new, gensym("wrap"), A_DEFFLOAT, A_DEFFLOAT, 0);
-#endif
- class_addfloat(wrap_class, wrap_float);
- class_addmethod(wrap_class, (t_method)wrap_a, gensym("a"), A_FLOAT, 0);
- class_addmethod(wrap_class, (t_method)wrap_b, gensym("b"), A_FLOAT, 0);
-#ifndef MAXLIB
-
- post(version);
-#else
- class_sethelpsymbol(wrap_class, gensym("maxlib/wrap-help.pd"));
-#endif
-}
-
+/* ------------------------- wrap ------------------------------------------ */
+/* */
+/* wraps input to lie within an output range. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+
+static char *version = "wrap v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct wrap
+{
+ t_object x_ob;
+ t_float x_min; /* low border of input range */
+ t_float x_max; /* high border of input range */
+ t_outlet *x_outlet1; /* path-through outlet */
+ t_outlet *x_outlet2; /* wrap outlet */
+} t_wrap;
+
+static void wrap_float(t_wrap *x, t_floatarg f)
+{
+ t_float min = x->x_min;
+ t_float max = x->x_max;
+ t_float range = max - min;
+ t_int i;
+
+ if(range == 0.0f)
+ {
+ f = min;
+ outlet_float(x->x_outlet2, 0);
+ }
+ else if(f < min)
+ {
+ t_float diff = min - f;
+ t_float n = ceil(diff / range);
+
+ f += n * range;
+
+ outlet_float(x->x_outlet2, -(t_int)n);
+ }
+ else if (f >= max)
+ {
+ t_float diff = f - max;
+ t_float n = floor(diff / range) + 1.0f;
+
+ f -= n * range;
+
+ outlet_float(x->x_outlet2, (t_int)n);
+ }
+ else
+ outlet_float(x->x_outlet2, 0.0f);
+
+ outlet_float(x->x_outlet1, f);
+}
+
+static void wrap_a(t_wrap *x, t_floatarg a)
+{
+ t_float max = x->x_max;
+
+ if(a <= max)
+ x->x_min = a;
+ else
+ {
+ x->x_min = max;
+ x->x_max = a;
+ }
+}
+
+static void wrap_b(t_wrap *x, t_floatarg b)
+{
+ t_float min = x->x_min;
+
+ if(b >= min)
+ x->x_max = b;
+ else
+ {
+ x->x_max = min;
+ x->x_min = b;
+ }
+}
+
+static t_class *wrap_class;
+
+static void *wrap_new(t_floatarg fmin, t_floatarg fmax)
+{
+ t_wrap *x = (t_wrap *)pd_new(wrap_class);
+
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("a"));
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("b"));
+
+ x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_min = fmin;
+ wrap_b(x, fmax);
+
+ return (void *)x;
+}
+
+#ifndef MAXLIB
+void wrap_setup(void)
+{
+ wrap_class = class_new(gensym("wrap"), (t_newmethod)wrap_new,
+ 0, sizeof(t_wrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+#else
+void maxlib_wrap_setup(void)
+{
+ wrap_class = class_new(gensym("maxlib_wrap"), (t_newmethod)wrap_new,
+ 0, sizeof(t_wrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addcreator((t_newmethod)wrap_new, gensym("wrap"), A_DEFFLOAT, A_DEFFLOAT, 0);
+#endif
+ class_addfloat(wrap_class, wrap_float);
+ class_addmethod(wrap_class, (t_method)wrap_a, gensym("a"), A_FLOAT, 0);
+ class_addmethod(wrap_class, (t_method)wrap_b, gensym("b"), A_FLOAT, 0);
+#ifndef MAXLIB
+
+ logpost(NULL, 4, version);
+#else
+ class_sethelpsymbol(wrap_class, gensym("maxlib/wrap-help.pd"));
+#endif
+}
+