diff --git a/externals/pd-l2ork-TODO.txt b/externals/pd-l2ork-TODO.txt
index 72623d88525bfcb03e21a244123958a1b0584e4f..5a1da76da68364222eb739d79739f7150a0ad039 100644
--- a/externals/pd-l2ork-TODO.txt
+++ b/externals/pd-l2ork-TODO.txt
@@ -1,5 +1,5 @@
 Diff status between pd-l2ork externals source tree and main community pd svn
-AS OF October 7, 2014
+AS OF October 8, 2014
 
 DONE: (*denotes unique changes)
 creb
@@ -16,6 +16,7 @@ pdp_opencv
 pidip
 postlude
 sigpack
+vbap
 zexy
 
 MERGE:
diff --git a/externals/vbap/CHANGELOG.txt b/externals/vbap/CHANGELOG.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9956b0f3f6cadd0fe6b8409523078836d7235728
--- /dev/null
+++ b/externals/vbap/CHANGELOG.txt
@@ -0,0 +1,5 @@
+14 Aug. 2014 update from version 1.0.3.2 to version  1.1
+
+- changed vbap to allocate memory dynamically, to eliminate crash-producing memory overwrites when larger speaker configurations were defined (e.g. on OSX for speakers >  13 in 3D)   z.settel
+- eliminated a post to the console reporting azimuth updates
+
diff --git a/externals/vbap/LICENSE.txt b/externals/vbap/LICENSE.txt
index 7522f1cf706f827278d30456e28d4cc18680822e..94290493ab0591ca6de10529dc7d3811174bf7aa 100644
--- a/externals/vbap/LICENSE.txt
+++ b/externals/vbap/LICENSE.txt
@@ -1,4 +1,9 @@
-Copyright (c) 1998-2010 Ville Pulkki. All rights reserved.
+Copyright (c) 1998-2010 Ville Pulkki
+              2002, Juha Vehviläinen
+              2003, Olaf Matthes
+              2006-2010, Hans-Christoph Steiner
+              2007, Frank Barknecht
+ All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
diff --git a/externals/vbap/Makefile b/externals/vbap/Makefile
index d484487791e9b465c84f6cbac3050d59350e64b4..99be87bf86f3341cd5e9a4025be29fae683fa88f 100644
--- a/externals/vbap/Makefile
+++ b/externals/vbap/Makefile
@@ -1,10 +1,11 @@
-## Pd library template version 1.0.6
+## Pd library template version 1.0.14
 # For instructions on how to use this template, see:
 #  http://puredata.info/docs/developer/MakefileTemplate
 LIBRARY_NAME = vbap
 
 # add your .c source files, one object per file, to the SOURCES
-# variable, help files will be included automatically
+# variable, help files will be included automatically, and for GUI
+# objects, the matching .tcl file too
 SOURCES = vbap.c rvbap.c define_loudspeakers.c
 
 # list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
@@ -12,10 +13,10 @@ SOURCES = vbap.c rvbap.c define_loudspeakers.c
 PDOBJECTS = 
 
 # example patches and related files, in the 'examples' subfolder
-EXAMPLES = graph-to-aziele.pd high.pd playsample~.pd recent.pd vbap-demo.pd vbap-level-config.pd vbapmodule.pd vbapsnd.pd rvbap-demo.pd vbap.main.pd
+EXAMPLES =  graph-to-aziele.pd high.pd playsample~.pd recent.pd vbap-demo.pd vbap-level-config.pd vbapmodule.pd vbapsnd.pd rvbap-demo.pd vbap.main.pd
 
 # manuals and related files, in the 'manual' subfolder
-MANUAL = 
+MANUAL =
 
 # if you want to include any other files in the source and binary tarballs,
 # list them here.  This can be anything from header files, test patches,
@@ -23,6 +24,9 @@ MANUAL =
 # automatically included
 EXTRA_DIST = define_loudspeakers.h max2pd.h vbap.h makefile.irix so_locations
 
+# unit tests and related files here, in the 'unittests' subfolder
+UNITTESTS = define-loudspeaker-unittest.wav define_loudspeakers-unittest.pd rvbap-unittest.pd rvbap-unittest.wav vbap-unittest.pd vbap-unittest.wav vbap.wav
+
 
 
 #------------------------------------------------------------------------------#
@@ -31,9 +35,11 @@ EXTRA_DIST = define_loudspeakers.h max2pd.h vbap.h makefile.irix so_locations
 #
 #------------------------------------------------------------------------------#
 
-CFLAGS = -I"$(PD_INCLUDE)/pd" -Wall -W -g
-LDFLAGS =  
-LIBS = 
+ALL_CFLAGS = -I"$(PD_INCLUDE)"
+ALL_LDFLAGS =  
+SHARED_LDFLAGS =
+ALL_LIBS = 
+
 
 #------------------------------------------------------------------------------#
 #
@@ -41,12 +47,17 @@ LIBS =
 #
 #------------------------------------------------------------------------------#
 
+# these can be set from outside without (usually) breaking the build
+CFLAGS = -Wall -W -g
+LDFLAGS =
+LIBS =
+
 # get library version from meta file
 LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd)
 
-CFLAGS += -DPD -DVERSION='"$(LIBRARY_VERSION)"'
+ALL_CFLAGS += -DPD -DVERSION='"$(LIBRARY_VERSION)"'
 
-PD_INCLUDE = $(PD_PATH)/include
+PD_INCLUDE = $(PD_PATH)/include/pd
 # where to install the library, overridden below depending on platform
 prefix = /usr/local
 libdir = $(prefix)/lib
@@ -70,6 +81,7 @@ ifeq ($(UNAME),Darwin)
   ifeq ($(CPU),arm) # iPhone/iPod Touch
     SOURCES += $(SOURCES_iphoneos)
     EXTENSION = pd_darwin
+    SHARED_EXTENSION = dylib
     OS = iphoneos
     PD_PATH = /Applications/Pd-extended.app/Contents/Resources
     IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
@@ -79,14 +91,16 @@ ifeq ($(UNAME),Darwin)
     ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk
     IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6
     OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer
-	CFLAGS := $(IPHONE_CFLAGS) $(OPT_CFLAGS) $(CFLAGS)
-    LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT)
-    LIBS += -lc 
+    ALL_CFLAGS := $(IPHONE_CFLAGS) $(ALL_CFLAGS)
+    ALL_LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT)
+    SHARED_LDFLAGS += -arch armv6 -dynamiclib -undefined dynamic_lookup $(ISYSROOT)
+    ALL_LIBS += -lc $(LIBS_iphoneos)
     STRIP = strip -x
     DISTBINDIR=$(DISTDIR)-$(OS)
   else # Mac OS X
     SOURCES += $(SOURCES_macosx)
     EXTENSION = pd_darwin
+    SHARED_EXTENSION = dylib
     OS = macosx
     PD_PATH = /Applications/Pd-extended.app/Contents/Resources
     OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast
@@ -94,30 +108,74 @@ 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
-    CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include
-    LDFLAGS += $(FAT_FLAGS) -bundle -undefined dynamic_lookup -L/sw/lib
+    ALL_CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include
     # if the 'pd' binary exists, check the linking against it to aid with stripping
-    LDFLAGS += $(shell test -e $(PD_PATH)/bin/pd && echo -bundle_loader $(PD_PATH)/bin/pd)
-    LIBS += -lc 
+    BUNDLE_LOADER = $(shell test ! -e $(PD_PATH)/bin/pd || echo -bundle_loader $(PD_PATH)/bin/pd)
+    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)
     STRIP = strip -x
     DISTBINDIR=$(DISTDIR)-$(OS)
 # install into ~/Library/Pd on Mac OS X since /usr/local isn't used much
     pkglibdir=$(HOME)/Library/Pd
   endif
 endif
+# Tho Android uses Linux, we use this fake uname to provide an easy way to
+# setup all this things needed to cross-compile for Android using the NDK
+ifeq ($(UNAME),ANDROID)
+  CPU := arm
+  SOURCES += $(SOURCES_android)
+  EXTENSION = so
+  SHARED_EXTENSION = so
+  OS = android
+  PD_PATH = /usr
+  NDK_BASE := /opt/android-ndk
+  NDK_PLATFORM_LEVEL ?= 5
+  NDK_ABI=arm
+  NDK_COMPILER_VERSION = 4.6
+  NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_LEVEL)/arch-$(NDK_ABI)
+  NDK_UNAME:=$(shell uname -s | tr '[A-Z]' '[a-z]')
+  ifeq ($(NDK_ABI),x86)
+    HOST = i686-linux-android
+    NDK_TOOLCHAIN = $(NDK_ABI)-$(NDK_COMPILER_VERSION)
+  else
+    HOST = $(NDK_ABI)-linux-androideabi
+    NDK_TOOLCHAIN = $(HOST)-$(NDK_COMPILER_VERSION)
+  endif
+  NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/$(NDK_TOOLCHAIN)/prebuilt/$(NDK_UNAME)-$(NDK_PROCESSOR)
+  CC := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-gcc --sysroot=$(NDK_SYSROOT)
+  LD := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-ld
+  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/$(HOST)-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
+  SHARED_EXTENSION = so
   OS = linux
   PD_PATH = /usr
   OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
-  CFLAGS += -fPIC
-  LDFLAGS += -Wl,--export-dynamic  -shared -fPIC
-  LIBS += -lc
+  ALL_CFLAGS += -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
   DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
 endif
@@ -126,12 +184,14 @@ ifeq ($(UNAME),GNU)
   CPU := $(shell uname -m)
   SOURCES += $(SOURCES_linux)
   EXTENSION = pd_linux
+  SHARED_EXTENSION = so
   OS = linux
   PD_PATH = /usr
   OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
-  CFLAGS += -fPIC
-  LDFLAGS += -Wl,--export-dynamic  -shared -fPIC
-  LIBS += -lc
+  ALL_CFLAGS += -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
   DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
 endif
@@ -140,12 +200,14 @@ ifeq ($(UNAME),GNU/kFreeBSD)
   CPU := $(shell uname -m)
   SOURCES += $(SOURCES_linux)
   EXTENSION = pd_linux
+  SHARED_EXTENSION = so
   OS = linux
   PD_PATH = /usr
   OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
-  CFLAGS += -fPIC
-  LDFLAGS += -Wl,--export-dynamic  -shared -fPIC
-  LIBS += -lc
+  ALL_CFLAGS += -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
   DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
 endif
@@ -153,12 +215,14 @@ ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME)))
   CPU := $(shell uname -m)
   SOURCES += $(SOURCES_cygwin)
   EXTENSION = dll
+  SHARED_EXTENSION = dll
   OS = cygwin
-  PD_PATH = $(cygpath $(PROGRAMFILES))/pd
+  PD_PATH = $(shell cygpath $$PROGRAMFILES)/pd
   OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
-  CFLAGS += 
-  LDFLAGS += -Wl,--export-dynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin"
-  LIBS += -lc -lpd
+  ALL_CFLAGS += 
+  ALL_LDFLAGS += -rdynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin"
+  SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
+  ALL_LIBS += -lc -lpd $(LIBS_cygwin)
   STRIP = strip --strip-unneeded -R .note -R .comment
   DISTBINDIR=$(DISTDIR)-$(OS)
 endif
@@ -166,12 +230,17 @@ ifeq (MINGW,$(findstring MINGW,$(UNAME)))
   CPU := $(shell uname -m)
   SOURCES += $(SOURCES_windows)
   EXTENSION = dll
+  SHARED_EXTENSION = dll
   OS = windows
-  PD_PATH = $(shell cd "$(PROGRAMFILES)"/pd && pwd)
+  PD_PATH = $(shell cd "$$PROGRAMFILES/pd" && pwd)
+  # MinGW doesn't seem to include cc so force gcc
+  CC=gcc
   OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer
-  CFLAGS += -mms-bitfields
-  LDFLAGS += -s -shared -Wl,--enable-auto-import
-  LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" -lpd -lwsock32 -lkernel32 -luser32 -lgdi32
+  ALL_CFLAGS += -mms-bitfields
+  ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import
+  SHARED_LDFLAGS += -shared
+  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
@@ -179,42 +248,61 @@ endif
 # in case somebody manually set the HELPPATCHES above
 HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd)
 
-CFLAGS += $(OPT_CFLAGS)
+ALL_CFLAGS := $(ALL_CFLAGS) $(CFLAGS) $(OPT_CFLAGS)
+ALL_LDFLAGS := $(LDFLAGS) $(ALL_LDFLAGS)
+ALL_LIBS := $(LIBS) $(ALL_LIBS)
 
+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_TCL_LIB = $(wildcard lib$(LIBRARY_NAME).tcl)
 
-.PHONY = install libdir_install single_install install-doc install-exec install-examples install-manual clean 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))
+all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB)
 
 %.o: %.c
-	$(CC) $(CFLAGS) -o "$*.o" -c "$*.c"
+	$(CC) $(ALL_CFLAGS) -o "$*.o" -c "$*.c"
 
-%.$(EXTENSION): %.o
-	$(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o"  $(LIBS)
+%.$(EXTENSION): %.o $(SHARED_LIB)
+	$(CC) $(ALL_LDFLAGS) -o "$*.$(EXTENSION)" "$*.o"  $(ALL_LIBS) $(SHARED_LIB)
 	chmod a-x "$*.$(EXTENSION)"
 
 # this links everything into a single binary file
-$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o
-	$(CC) $(LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(LIBS)
+$(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) $(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)) 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)
 	test -z "$(strip $(SOURCES))" || (\
 		$(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \
 		$(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION))))
+	test -z "$(strip $(SHARED_LIB))" || \
+		$(INSTALL_DATA) $(SHARED_LIB) \
+			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	test -z "$(strip $(wildcard $(SOURCES:.c=.tcl)))" || \
+		$(INSTALL_DATA) $(wildcard $(SOURCES:.c=.tcl)) \
+			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
 	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-exec
+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)
@@ -241,12 +329,19 @@ 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)
+	-rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o) $(SHARED_SOURCE:.c=.o)
 	-rm -f -- $(SOURCES:.c=.$(EXTENSION))
 	-rm -f -- $(LIBRARY_NAME).o
 	-rm -f -- $(LIBRARY_NAME).$(EXTENSION)
+	-rm -f -- $(SHARED_LIB)
 
 distclean: clean
 	-rm -f -- $(DISTBINDIR).tar.gz
@@ -262,7 +357,7 @@ $(DISTBINDIR):
 
 libdir: all $(DISTBINDIR)
 	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd  $(DISTBINDIR)
-	$(INSTALL_DATA) $(SOURCES)  $(DISTBINDIR)
+	$(INSTALL_DATA) $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER) $(DISTBINDIR)
 	$(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR)
 	test -z "$(strip $(EXTRA_DIST))" || \
 		$(INSTALL_DATA) $(EXTRA_DIST)    $(DISTBINDIR)
@@ -281,6 +376,16 @@ dist: $(DISTDIR)
 	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd  $(DISTDIR)
 	test -z "$(strip $(ALLSOURCES))" || \
 		$(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))" || \
@@ -297,6 +402,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
@@ -309,23 +419,39 @@ 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)"
 	@echo "CFLAGS: $(CFLAGS)"
 	@echo "LDFLAGS: $(LDFLAGS)"
 	@echo "LIBS: $(LIBS)"
+	@echo "ALL_CFLAGS: $(ALL_CFLAGS)"
+	@echo "ALL_LDFLAGS: $(ALL_LDFLAGS)"
+	@echo "ALL_LIBS: $(ALL_LIBS)"
 	@echo "PD_INCLUDE: $(PD_INCLUDE)"
 	@echo "PD_PATH: $(PD_PATH)"
 	@echo "objectsdir: $(objectsdir)"
 	@echo "LIBRARY_NAME: $(LIBRARY_NAME)"
 	@echo "LIBRARY_VERSION: $(LIBRARY_VERSION)"
 	@echo "SOURCES: $(SOURCES)"
+	@echo "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))"
 	@echo "UNAME: $(UNAME)"
 	@echo "CPU: $(CPU)"
 	@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/externals/vbap/define_loudspeakers.c b/externals/vbap/define_loudspeakers.c
index b2fd3512cc785e7eb9850d90247831e20973a5de..16c5b62bcf1c674e611f06bbe818cc43772c8fd6 100644
--- a/externals/vbap/define_loudspeakers.c
+++ b/externals/vbap/define_loudspeakers.c
@@ -14,14 +14,14 @@ See copyright in file with name LICENSE.txt  */
 // If we are within VBAP (which includes define_loudspeakers), then don't create a main for define_loudspeakres
 void define_loudspeakers_setup(void)
 {
-	def_ls_class = class_new(gensym("define_loudspeakers"), (t_newmethod)def_ls_new, 0, (short)sizeof(t_def_ls), 0, A_GIMME, 0); 
+	def_ls_class = class_new(gensym("define_loudspeakers"), (t_newmethod)def_ls_new, 0, (short)sizeof(t_def_ls), 0, A_GIMME, 0);
 	/* def_ls_new = creation function, A_DEFLONG = its (optional) arguement is a long (32-bit) int */
 	
 	class_addbang(def_ls_class, (t_method)def_ls_bang);			/* the procedure it uses when it gets a bang in the left inlet */
 	class_addmethod(def_ls_class, (t_method)def_ls_read_directions, gensym("ls-directions"), A_GIMME, 0);	
 	class_addmethod(def_ls_class, (t_method)def_ls_read_triplets, gensym("ls-triplets"), A_GIMME, 0);
 
-	post(DFLS_VERSION);
+	logpost(NULL,1, DFLS_VERSION);
 }
 # else /* Max */
 void main(void)
@@ -167,16 +167,21 @@ static void def_ls_read_directions(t_def_ls *x, t_symbol *s, int ac, Atom *av)
 static void ls_angles_to_cart(t_ls *ls)
 // convert angular direction to cartesian
 {
-  float azi = ls->azi;
-  float ele = ls->ele;
-  ls->x = cos((float) azi * atorad) * cos((float) ele * atorad);
-  ls->y = sin((float) azi * atorad) * cos((float) ele * atorad);
-  ls->z = sin((float) ele * atorad);
+  t_float azi = ls->azi;
+  t_float ele = ls->ele;
+  ls->x = cos((t_float) azi * atorad) * cos((t_float) ele * atorad);
+  ls->y = sin((t_float) azi * atorad) * cos((t_float) ele * atorad);
+  ls->z = sin((t_float) ele * atorad);
 }
 
 /* create new instance of object... MUST send it an int even if you do nothing with this int!! */
 static void *def_ls_new(t_symbol *s, int ac, Atom *av)	
 {
+    
+    
+    //post("def_ls_new: AC = %d", ac);
+    
+    
 	// s is object name (we ignore it)
 	t_def_ls *x = (t_def_ls *)newobject(def_ls_class);
 
@@ -195,6 +200,9 @@ static void *def_ls_new(t_symbol *s, int ac, Atom *av)
 void vbap_def_ls(t_def_ls *x, t_symbol *s, int ac, Atom *av)	
 {
 	initContent_ls_directions(x,ac,av); // Initialize object internal data from a ls-directions list
+
+    logpost(NULL,3, "vbap_def_ls:   %ld-D configuration with %ld speakers", x->x_def_ls_dimension, x->x_def_ls_amount );
+    
 	def_ls_bang(x); // calculate and send matrix to vbap
 }
 
@@ -205,7 +213,9 @@ static void initContent_ls_directions(t_def_ls *x,int ac,Atom*av)
 	
 	long d = 0;
 /*	if (av[0].a_type == A_LONG) d = av[0].a_w.w_long;
-	else */ if(av[0].a_type == A_FLOAT) d = (long)av[0].a_w.w_float;
+	else */
+    
+    if(av[0].a_type == A_FLOAT) d = (long)av[0].a_w.w_float;
 	else { error("define-loudspeakers: dimension NaN"); return; }
 
 	if (d==2 || d==3)
@@ -227,7 +237,7 @@ static void initContent_ls_directions(t_def_ls *x,int ac,Atom*av)
     int i;
 	for(i=0; i < x->x_def_ls_amount;i++)
 	{
-		float azi = 0;
+		t_float azi = 0;
 /*		if(av[pointer].a_type == A_LONG) azi = (float) av[pointer].a_w.w_long;
 		else */ if(av[pointer].a_type == A_FLOAT) azi = av[pointer].a_w.w_float;
 		else { error("define-loudspeakers: direction angle #%d NaN",i+1); x->x_ls_read = 0; return; }
@@ -236,7 +246,7 @@ static void initContent_ls_directions(t_def_ls *x,int ac,Atom*av)
 		
 		pointer++;
 
-		float ele = 0; // in 2d elevation is zero
+		t_float ele = 0; // in 2d elevation is zero
 		if(x->x_def_ls_dimension == 3)
 		{  // 3-D 
 /*			if(av[pointer].a_type == A_LONG) ele = (float) av[pointer].a_w.w_long;
@@ -279,10 +289,10 @@ static void choose_ls_triplets(t_def_ls *x)
   int connections[MAX_LS_AMOUNT][MAX_LS_AMOUNT];
   //float angles[MAX_LS_AMOUNT];
   //int sorted_angles[MAX_LS_AMOUNT];
-  float distance_table[((MAX_LS_AMOUNT * (MAX_LS_AMOUNT - 1)) / 2)];
+  t_float distance_table[((MAX_LS_AMOUNT * (MAX_LS_AMOUNT - 1)) / 2)];
   int distance_table_i[((MAX_LS_AMOUNT * (MAX_LS_AMOUNT - 1)) / 2)];
   int distance_table_j[((MAX_LS_AMOUNT * (MAX_LS_AMOUNT - 1)) / 2)];
-  float distance;
+  t_float distance;
   t_ls_set *trip_ptr, *prev, *tmp_ptr;
   int ls_amount = x->x_def_ls_amount;
   t_ls *lss = x->x_ls;
@@ -404,11 +414,11 @@ static void choose_ls_triplets(t_def_ls *x)
 int any_ls_inside_triplet(int a, int b, int c,t_ls lss[MAX_LS_AMOUNT],int ls_amount)
    /* returns 1 if there is loudspeaker(s) inside given ls triplet */
 {
-  float invdet;
+  t_float invdet;
   t_ls *lp1, *lp2, *lp3;
-  float invmx[9];
+  t_float invmx[9];
   int i,j;
-  float tmp;
+  t_float tmp;
   int any_ls_inside, this_inside;
 
   lp1 =  &(lss[a]);
@@ -463,6 +473,9 @@ static void add_ldsp_triplet(int i, int j, int k, t_def_ls *x)
     trip_ptr = trip_ptr->next;
   }
   trip_ptr = (struct t_ls_set*) getbytes (sizeof (struct t_ls_set));
+
+    //post("add_ldsp_triplet getbytes:  %ld", sizeof (struct t_ls_set));
+    
   if(prev == NULL)
     x->x_ls_set = trip_ptr;
   else 
@@ -476,10 +489,10 @@ static void add_ldsp_triplet(int i, int j, int k, t_def_ls *x)
 
 
 
-float vec_angle(t_ls v1, t_ls v2)
+t_float vec_angle(t_ls v1, t_ls v2)
 // angle between two loudspeakers
 {
-  float inner= ((v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)/
+  t_float inner= ((v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)/
               (vec_length(v1) * vec_length(v2)));
   if(inner > 1.0)
     inner= 1.0;
@@ -488,26 +501,26 @@ float vec_angle(t_ls v1, t_ls v2)
   return fabs( acos( inner));
 }
 
-float vec_length(t_ls v1)
+t_float vec_length(t_ls v1)
 // length of a vector
 {
   return (sqrt(v1.x*v1.x + v1.y*v1.y + v1.z*v1.z));
 }
 
-float vec_prod(t_ls v1, t_ls v2)
+t_float vec_prod(t_ls v1, t_ls v2)
 // vector dot product
 {
   return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
 }
 
 
-float vol_p_side_lgth(int i, int j,int k, t_ls  lss[MAX_LS_AMOUNT] )
+t_float vol_p_side_lgth(int i, int j,int k, t_ls  lss[MAX_LS_AMOUNT] )
 {
   /* calculate volume of the parallelepiped defined by the loudspeaker
      direction vectors and divide it with total length of the triangle sides. 
      This is used when removing too narrow triangles. */
 
-  float volper, lgth;
+  t_float volper, lgth;
   t_ls xprod;
   ls_cross_prod(lss[i], lss[j], &xprod);
   volper = fabsf(vec_prod(xprod, lss[k]));
@@ -524,7 +537,7 @@ static void ls_cross_prod(t_ls v1,t_ls v2,
                 t_ls *res) 
 // vector cross product
 {
-  float length;
+  t_float length;
   res->x = (v1.y * v2.z ) - (v1.z * v2.y);
   res->y = (v1.z * v2.x ) - (v1.x * v2.z);
   res->z = (v1.x * v2.y ) - (v1.y * v2.x);
@@ -543,9 +556,11 @@ static int lines_intersect(int i,int j,int k,int l,t_ls  lss[MAX_LS_AMOUNT])
  t_ls v1;
   t_ls v2;
   t_ls v3, neg_v3;
-  //float angle;
-  float dist_ij,dist_kl,dist_iv3,dist_jv3,dist_inv3,dist_jnv3;
-  float dist_kv3,dist_lv3,dist_knv3,dist_lnv3;
+  //t_float angle;
+  t_float dist_ij,dist_kl,dist_iv3,dist_jv3,dist_inv3,dist_jnv3;
+  t_float dist_kv3,dist_lv3,dist_knv3,dist_lnv3;
+  // TODO epsilon needs to be updated for 64-bit/double precision
+  t_float epsilon = 1e-9;
 
   ls_cross_prod(lss[i],lss[j],&v1);
   ls_cross_prod(lss[k],lss[l],&v2);
@@ -567,17 +582,17 @@ static int lines_intersect(int i,int j,int k,int l,t_ls  lss[MAX_LS_AMOUNT])
   dist_lnv3 = (vec_angle(neg_v3,lss[l]));
 
   /* if one of loudspeakers is close to crossing point, don't do anything*/
-  if(fabsf(dist_iv3) <= 0.01 || fabsf(dist_jv3) <= 0.01 || 
-		 fabsf(dist_kv3) <= 0.01 || fabsf(dist_lv3) <= 0.01 ||
-     fabsf(dist_inv3) <= 0.01 || fabsf(dist_jnv3) <= 0.01 || 
-     fabsf(dist_knv3) <= 0.01 || fabsf(dist_lnv3) <= 0.01 )
+  if(fabsf(dist_iv3)  <= epsilon || fabsf(dist_jv3)  <= epsilon || 
+     fabsf(dist_kv3)  <= epsilon || fabsf(dist_lv3)  <= epsilon ||
+     fabsf(dist_inv3) <= epsilon || fabsf(dist_jnv3) <= epsilon || 
+     fabsf(dist_knv3) <= epsilon || fabsf(dist_lnv3) <= epsilon )
     return(0);
 
   // if crossing point is on line between both loudspeakers return 1
-  if (((fabsf(dist_ij - (dist_iv3 + dist_jv3)) <= 0.01 ) &&
-       (fabsf(dist_kl - (dist_kv3 + dist_lv3))  <= 0.01)) ||
-      ((fabsf(dist_ij - (dist_inv3 + dist_jnv3)) <= 0.01)  &&
-       (fabsf(dist_kl - (dist_knv3 + dist_lnv3)) <= 0.01 ))) {
+  if (((fabsf(dist_ij - (dist_iv3 + dist_jv3))   <= epsilon)  &&
+       (fabsf(dist_kl - (dist_kv3 + dist_lv3))   <= epsilon)) ||
+      ((fabsf(dist_ij - (dist_inv3 + dist_jnv3)) <= epsilon)  &&
+       (fabsf(dist_kl - (dist_knv3 + dist_lnv3)) <= epsilon))) {
     return (1);
   } else {
     return (0);
@@ -587,12 +602,15 @@ static int lines_intersect(int i,int j,int k,int l,t_ls  lss[MAX_LS_AMOUNT])
 static void  calculate_3x3_matrixes(t_def_ls *x)
      /* Calculates the inverse matrices for 3D */
 {  
-  float invdet;
+  t_float invdet;
   t_ls *lp1, *lp2, *lp3;
-  float *invmx;
-  //float *ptr;
+  t_float *invmx;
+  //t_float *ptr;
   struct t_ls_set *tr_ptr = x->x_ls_set;
-  int triplet_amount = 0, /*ftable_size,*/i,pointer,list_length=0;
+  
+  unsigned long triplet_amount = 0, /*ftable_size,*/i,pointer,list_length=0; 
+   
+    
   Atom *at;
   t_ls *lss = x->x_ls;
   
@@ -611,7 +629,8 @@ static void  calculate_3x3_matrixes(t_def_ls *x)
   tr_ptr = x->x_ls_set;
   list_length= triplet_amount * 21 + 3;
   at= (Atom *) getbytes(list_length*sizeof(Atom));
-  
+
+
   SETLONG(&at[0], x->x_def_ls_dimension);
   SETLONG(&at[1], x->x_def_ls_amount);
   pointer=2;
@@ -654,11 +673,14 @@ static void  calculate_3x3_matrixes(t_def_ls *x)
     SETFLOAT(&at[pointer], lp2->z); pointer++;
     SETFLOAT(&at[pointer], lp3->z); pointer++;
  
+     
+      
     tr_ptr = tr_ptr->next;
   }
+    
 	sendLoudspeakerMatrices(x,list_length, at);
-//  outlet_anything(x->x_outlet0, gensym("loudspeaker-matrices"), list_length, at);
-  freebytes(at, list_length*sizeof(Atom));
+    
+   freebytes(at, list_length*sizeof(Atom));
 }
 
 
@@ -667,17 +689,17 @@ static void choose_ls_tuplets(t_def_ls *x)
      /* selects the loudspeaker pairs, calculates the inversion
         matrices and stores the data to a global array*/
 {
-  //float atorad = (2 * 3.1415927 / 360) ;
+  //t_float atorad = (2 * 3.1415927 / 360) ;
   int i,j;
-  //float w1,w2;
-  //float p1,p2;
+  //t_float w1,w2;
+  //t_float p1,p2;
   int sorted_lss[MAX_LS_AMOUNT];
   int exist[MAX_LS_AMOUNT];   
   int amount=0;
-  float inv_mat[MAX_LS_AMOUNT][4];  // In 2-D ls amount == max amount of LS pairs
-  float mat[MAX_LS_AMOUNT][4];
-  //float *ptr;   
-  //float *ls_table;
+  t_float inv_mat[MAX_LS_AMOUNT][4];  // In 2-D ls amount == max amount of LS pairs
+  t_float mat[MAX_LS_AMOUNT][4];
+  //t_float *ptr;   
+  //t_float *ls_table;
   t_ls *lss = x->x_ls;
   long ls_amount=x->x_def_ls_amount;
   long list_length;
@@ -718,7 +740,8 @@ static void choose_ls_tuplets(t_def_ls *x)
   // Output
   list_length= amount * 10  + 2;
   at= (Atom *) getbytes(list_length*sizeof(Atom));
-  
+    //post("choose_ls_tuplets getbytes:  %ld", list_length*sizeof(Atom));
+
   SETLONG(&at[0], x->x_def_ls_dimension);
   SETLONG(&at[1], x->x_def_ls_amount);
   pointer=2;
@@ -753,7 +776,9 @@ static void choose_ls_tuplets(t_def_ls *x)
     	pointer++;
     }
   }
-	sendLoudspeakerMatrices(x,list_length, at);
+    //post("choose_ls_tuplets:  before call to sendLoudspeakerMatrices");
+
+    sendLoudspeakerMatrices(x,list_length, at);
   //outlet_anything(x->x_outlet0, gensym("loudspeaker-matrices"), list_length, at);
   freebytes(at, list_length*sizeof(Atom));
 }
@@ -762,10 +787,10 @@ void sort_2D_lss(t_ls lss[MAX_LS_AMOUNT], int sorted_lss[MAX_LS_AMOUNT],
                  int ls_amount)
 // sort loudspeakers according to azimuth angle
 {
-  float tmp, tmp_azi;
-//  float rad2ang = 360.0f / ( 2.0f * M_PI );
+  t_float tmp, tmp_azi;
+//  t_float rad2ang = 360.0f / ( 2.0f * M_PI );
 
-  //float x,y;
+  //t_float x,y;
   /* Transforming angles between -180 and 180 */
   int i;
   for (i=0;i<ls_amount;i++) 
@@ -793,22 +818,22 @@ for (i=0;i<ls_amount;i++)
     }
     sorted_lss[i]=index;
     tmp_azi = (lss[index].azi);
-    lss[index].azi = (tmp_azi + (float) 4000.0);
+    lss[index].azi = (tmp_azi + (t_float) 4000.0);
   }
   for (i=0;i<ls_amount;i++) 
 	{
     tmp_azi = (lss[i].azi);
-    lss[i].azi = (tmp_azi - (float) 4000.0);
+    lss[i].azi = (tmp_azi - (t_float) 4000.0);
   }
 }
   
 
-static int calc_2D_inv_tmatrix(float azi1,float azi2, float inv_mat[4],float mat[4])
+static int calc_2D_inv_tmatrix(t_float azi1,t_float azi2, t_float inv_mat[4],t_float mat[4])
 // calculate inverse 2x2 matrix
 {
-  float x1,x2,x3,x4; /* x1 x3 */
-  //float y1,y2,y3,y4; /* x2 x4 */
-  float det;
+  t_float x1,x2,x3,x4; /* x1 x3 */
+  //t_float y1,y2,y3,y4; /* x2 x4 */
+  t_float det;
   
   mat[0]=x1 = cos(azi1 / rad2ang);
   mat[1]=x2 = sin(azi1 / rad2ang);
diff --git a/externals/vbap/define_loudspeakers.h b/externals/vbap/define_loudspeakers.h
index de5d0a948321e9cb4fabc95765cd28878ca868e5..afaf036f4fd2f7a76727fa30db658db864536db4 100644
--- a/externals/vbap/define_loudspeakers.h
+++ b/externals/vbap/define_loudspeakers.h
@@ -20,16 +20,16 @@ static void ls_angles_to_cart(t_ls *ls);
 static void choose_ls_triplets(t_def_ls *x);
 static int any_ls_inside_triplet(int a, int b, int c,t_ls lss[MAX_LS_AMOUNT],int ls_amount);
 static void add_ldsp_triplet(int i, int j, int k, t_def_ls *x);
-static float vec_angle(t_ls v1, t_ls v2);
-static float vec_length(t_ls v1);
-static float vec_prod(t_ls v1, t_ls v2);
-static float vec_prod(t_ls v1, t_ls v2);
-static float vol_p_side_lgth(int i, int j,int k, t_ls  lss[MAX_LS_AMOUNT] );
+static t_float vec_angle(t_ls v1, t_ls v2);
+static t_float vec_length(t_ls v1);
+static t_float vec_prod(t_ls v1, t_ls v2);
+static t_float vec_prod(t_ls v1, t_ls v2);
+static t_float vol_p_side_lgth(int i, int j,int k, t_ls  lss[MAX_LS_AMOUNT] );
 static void ls_cross_prod(t_ls v1,t_ls v2, t_ls *res);
 static int lines_intersect(int i,int j,int k,int l,t_ls lss[MAX_LS_AMOUNT]);
 static void  calculate_3x3_matrixes(t_def_ls *x);
 static void choose_ls_tuplets(t_def_ls *x);
-static int calc_2D_inv_tmatrix(float azi1,float azi2, float inv_mat[4],float mat[4]);
+static int calc_2D_inv_tmatrix(t_float azi1,t_float azi2, t_float inv_mat[4],t_float mat[4]);
 static void sort_2D_lss(t_ls lss[MAX_LS_AMOUNT], int sorted_lss[MAX_LS_AMOUNT], 
                  int ls_amount);
 static void initContent_ls_directions(t_def_ls *x,int ac,Atom*av);
diff --git a/externals/vbap/rvbap.c b/externals/vbap/rvbap.c
index 75604b9018fdde0fb9371c2cbf63609e43ff33d8..4c7b87a8f5d571083549c825a87c3a3cd101f03c 100644
--- a/externals/vbap/rvbap.c
+++ b/externals/vbap/rvbap.c
@@ -14,6 +14,7 @@ See copyright in file with name LICENSE.txt  */
 
 #ifdef MAXMSP
 #include "ext.h"                /* you must include this - it contains the external object's link to max */
+#define t_float float
 #endif
 
 #ifdef PD 
@@ -33,22 +34,22 @@ typedef struct vbap             /* This defines the object as an entity made up
     t_object x_ob;                
     long x_azi;     // panning direction azimuth
     long x_ele;     // panning direction elevation      
-    float x_dist;   // sound source distance    (1.0-infinity)
+    t_float x_dist; // sound source distance    (1.0-infinity)
     void *x_outlet0;                /* outlet creation - inlets are automatic */
     void *x_outlet1;                
     void *x_outlet2;                
     void *x_outlet3;                
     void *x_outlet4;                
-    float x_set_inv_matx[MAX_LS_SETS][9];  // inverse matrice for each loudspeaker set
-    float x_set_matx[MAX_LS_SETS][9];      // matrice for each loudspeaker set
+    t_float x_set_inv_matx[MAX_LS_SETS][9];// inverse matrice for each loudspeaker set
+    t_float x_set_matx[MAX_LS_SETS][9];    // matrice for each loudspeaker set
     long x_lsset[MAX_LS_SETS][3];          // channel numbers of loudspeakers in each LS set 
     long x_lsset_available;                // have loudspeaker sets been defined with define_loudspeakers
     long x_lsset_amount;                   // amount of loudspeaker sets
     long x_ls_amount;                      // amount of loudspeakers
     long x_dimension;                      // 2 or 3
     long x_spread;                         // speading amount of virtual source (0-100)
-    float x_spread_base[3];                // used to create uniform spreading
-    float x_reverb_gs[MAX_LS_SETS];        // correction value for each loudspeaker set to get equal volume
+    t_float x_spread_base[3];              // used to create uniform spreading
+    t_float x_reverb_gs[MAX_LS_SETS];      // correction value for each loudspeaker set to get equal volume
 } t_rvbap;
 #endif
 
@@ -65,23 +66,23 @@ typedef struct vbap             /* This defines the object as an entity made up
     void *x_outlet2;                
     void *x_outlet3;                
     void *x_outlet4;                
-    float x_set_inv_matx[MAX_LS_SETS][9];  // inverse matrice for each loudspeaker set
-    t_float x_set_matx[MAX_LS_SETS][9];      // matrice for each loudspeaker set
+    t_float x_set_inv_matx[MAX_LS_SETS][9];// inverse matrice for each loudspeaker set
+    t_float x_set_matx[MAX_LS_SETS][9];    // matrice for each loudspeaker set
     long x_lsset[MAX_LS_SETS][3];          // channel numbers of loudspeakers in each LS set 
     long x_lsset_available;                // have loudspeaker sets been defined with define_loudspeakers
     long x_lsset_amount;                   // amount of loudspeaker sets
     long x_ls_amount;                      // amount of loudspeakers
     long x_dimension;                      // 2 or 3
-    t_float x_spread;                         // speading amount of virtual source (0-100)
-    float x_spread_base[3];                // used to create uniform spreading
-    float x_reverb_gs[MAX_LS_SETS];        // correction value for each loudspeaker set to get equal volume
+    t_float x_spread;                      // speading amount of virtual source (0-100)
+    t_float x_spread_base[3];              // used to create uniform spreading
+    t_float x_reverb_gs[MAX_LS_SETS];      // correction value for each loudspeaker set to get equal volume
 } t_rvbap;
 #endif
 
 // Globals
 
-static void new_spread_dir(t_rvbap *x, float spreaddir[3], float vscartdir[3], float spread_base[3]);
-static void new_spread_base(t_rvbap *x, float spreaddir[3], float vscartdir[3]);
+static void new_spread_dir(t_rvbap *x, t_float spreaddir[3], t_float vscartdir[3], t_float spread_base[3]);
+static void new_spread_base(t_rvbap *x, t_float spreaddir[3], t_float vscartdir[3]);
 #ifdef MAXMSP
 static void *rvbap_class;
 static void rvbap_assist(t_rvbap *x, void *b, long m, long a, char *s);
@@ -97,17 +98,17 @@ static void rvbap_ft4(t_rvbap *x, double n);
 #ifdef PD
 static t_class *rvbap_class;
 #endif
-static void cross_prod(float v1[3], float v2[3],
-                float v3[3]);
-static void additive_vbap(float *final_gs, float cartdir[3], t_rvbap *x);
+static void cross_prod(t_float v1[3], t_float v2[3],
+                t_float v3[3]);
+static void additive_vbap(t_float *final_gs, t_float cartdir[3], t_rvbap *x);
 static void rvbap_bang(t_rvbap *x);
 static void rvbap_matrix(t_rvbap *x, t_symbol *s, int ac, t_atom *av);
-static void spread_it(t_rvbap *x, float *final_gs);
+static void spread_it(t_rvbap *x, t_float *final_gs);
 static void *rvbap_new(t_symbol *s, int ac, t_atom *av); // using A_GIMME - typed message list
-static void vbap(float g[3], long ls[3], t_rvbap *x);
-static void angle_to_cart(long azi, long ele, float res[3]);
-static void cart_to_angle(float cvec[3], float avec[3]);
-static void equal_reverb(t_rvbap *x, float *final_gs);
+static void vbap(t_float g[3], long ls[3], t_rvbap *x);
+static void angle_to_cart(long azi, long ele, t_float res[3]);
+static void cart_to_angle(t_float cvec[3], t_float avec[3]);
+static void equal_reverb(t_rvbap *x, t_float *final_gs);
 
 /* above are the prototypes for the methods/procedures/functions you will use */
 
@@ -137,7 +138,7 @@ int main(void)
     addftx((method)rvbap_ft3, 3);
     addftx((method)rvbap_ft4, 4);
     addmess((method)rvbap_matrix, "loudspeaker-matrices", A_GIMME, 0);
-    post("rvbap v1.1, © 2003-2007 by Olaf Matthes, based on vbap by Ville Pulkki");
+    post("rvbap v1.1, © 2003-2007 by Olaf Matthes, based on vbap by Ville Pulkki");
 	return 0;
 }
 
@@ -159,7 +160,7 @@ static void rvbap_assist(t_rvbap *x, void *b, long m, long a, char *s)
                 sprintf(s, "(int) spreading");
                 break;
                 case 4:
-                sprintf(s, "(float) distance");
+                sprintf(s, "(t_float) distance");
                 break;
             }
         break;
@@ -178,7 +179,7 @@ static void rvbap_assist(t_rvbap *x, void *b, long m, long a, char *s)
                 sprintf(s, "(int) actual spreading");
                 break;
                 case 4:
-                sprintf(s, "(float) actual distance");
+                sprintf(s, "(t_float) actual distance");
                 break;
             }
         break;
@@ -187,24 +188,24 @@ static void rvbap_assist(t_rvbap *x, void *b, long m, long a, char *s)
 #endif
 /* end MAXMSP */
 
-static void angle_to_cart(long azi, long ele, float res[3])
+static void angle_to_cart(long azi, long ele, t_float res[3])
 /* converts angular coordinates to cartesian */
 {
-  float atorad = (2.0 * 3.1415927 / 360.0) ;
-  res[0] = cos((float) azi * atorad) * cos((float) ele * atorad);
-  res[1] = sin((float) azi * atorad) * cos((float) ele * atorad);
-  res[2] = sin((float) ele * atorad);
+  t_float atorad = (2.0 * 3.141592653589793 / 360.0) ;
+  res[0] = cos((t_float) azi * atorad) * cos((t_float) ele * atorad);
+  res[1] = sin((t_float) azi * atorad) * cos((t_float) ele * atorad);
+  res[2] = sin((t_float) ele * atorad);
 }
 
-static void cart_to_angle(float cvec[3], float avec[3])
+static void cart_to_angle(t_float cvec[3], t_float avec[3])
 // converts cartesian coordinates to angular
 {
-  float tmp, tmp2, tmp3, tmp4;
-  float atorad = (float)(2.0 * 3.1415927 / 360.0) ;
-  float pi =  (float)3.1415927;
-  float power;
-  float dist, atan_y_per_x, atan_x_pl_y_per_z;
-  float azi, ele;
+  t_float tmp, tmp2, tmp3, tmp4;
+  t_float atorad = (t_float)(2.0 * 3.141592653589793 / 360.0) ;
+  t_float pi =  (t_float)3.141592653589793;
+  t_float power;
+  t_float dist, atan_y_per_x, atan_x_pl_y_per_z;
+  t_float azi, ele;
   
   if(cvec[0]==0.0)
     atan_y_per_x = pi / 2;
@@ -224,24 +225,24 @@ static void cart_to_angle(float cvec[3], float avec[3])
     else
       atan_x_pl_y_per_z = pi/2.0;
   ele = atan_x_pl_y_per_z / atorad;
-  dist = sqrtf(cvec[0] * cvec[0] +cvec[1] * cvec[1] +cvec[2]*cvec[2]);
+  dist = sqrt(cvec[0] * cvec[0] +cvec[1] * cvec[1] +cvec[2]*cvec[2]);
   avec[0]=azi;
   avec[1]=ele;
   avec[2]=dist;
 }
 
 
-static void vbap(float g[3], long ls[3], t_rvbap *x)
+static void vbap(t_float g[3], long ls[3], t_rvbap *x)
 {
   /* calculates gain factors using loudspeaker setup and given direction */
-  float power;
+  t_float power;
   int i,j,k, gains_modified;
-  float small_g;
-  float big_sm_g, gtmp[3];
+  t_float small_g;
+  t_float big_sm_g, gtmp[3];
   long winner_set=0;
-  float cartdir[3];
-  float new_cartdir[3];
-  float new_angle_dir[3];
+  t_float cartdir[3];
+  t_float new_cartdir[3];
+  t_float new_angle_dir[3];
   long dim = x->x_dimension;
   long neg_g_am, best_neg_g_am;
   
@@ -334,11 +335,11 @@ static void vbap(float g[3], long ls[3], t_rvbap *x)
 }
 
 
-static void cross_prod(float v1[3], float v2[3],
-                float v3[3]) 
+static void cross_prod(t_float v1[3], t_float v2[3],
+                t_float v3[3]) 
 // vector cross product            
 {
-  float length;
+  t_float length;
   v3[0] = (v1[1] * v2[2] ) - (v1[2] * v2[1]);
   v3[1] = (v1[2] * v2[0] ) - (v1[0] * v2[2]);
   v3[2] = (v1[0] * v2[1] ) - (v1[1] * v2[0]);
@@ -349,20 +350,20 @@ static void cross_prod(float v1[3], float v2[3],
   v3[2] /= length;
 }
 
-static void additive_vbap(float *final_gs, float cartdir[3], t_rvbap *x)
+static void additive_vbap(t_float *final_gs, t_float cartdir[3], t_rvbap *x)
 // calculates gains to be added to previous gains, used in
 // multiple direction panning (source spreading)
 {
-    float power;
+    t_float power;
     int i,j,k, gains_modified;
-    float small_g;
-    float big_sm_g, gtmp[3];
+    t_float small_g;
+    t_float big_sm_g, gtmp[3];
     long winner_set;
-    float new_cartdir[3];
-    float new_angle_dir[3];
+    t_float new_cartdir[3];
+    t_float new_angle_dir[3];
     long dim = x->x_dimension;
     long neg_g_am, best_neg_g_am;
-    float g[3];
+    t_float g[3];
     long ls[3] = { 0, 0, 0 };
     
     big_sm_g = -100000.0;
@@ -423,13 +424,13 @@ static void additive_vbap(float *final_gs, float cartdir[3], t_rvbap *x)
 }
 
 
-static void new_spread_dir(t_rvbap *x, float spreaddir[3], float vscartdir[3], float spread_base[3])
+static void new_spread_dir(t_rvbap *x, t_float spreaddir[3], t_float vscartdir[3], t_float spread_base[3])
 // subroutine for spreading
 {
-    float beta,m_gamma;
-    float a,b;
-    float pi = 3.1415927;
-    float power;
+    t_float beta,m_gamma;
+    t_float a,b;
+    t_float pi = 3.141592653589793;
+    t_float power;
     
     m_gamma = acos(vscartdir[0] * spread_base[0] +
                     vscartdir[1] * spread_base[1] +
@@ -454,12 +455,12 @@ static void new_spread_dir(t_rvbap *x, float spreaddir[3], float vscartdir[3], f
     spreaddir[2] /= power;
 }
 
-static void new_spread_base(t_rvbap *x, float spreaddir[3], float vscartdir[3])
+static void new_spread_base(t_rvbap *x, t_float spreaddir[3], t_float vscartdir[3])
 // subroutine for spreading
 {
-    float d;
-    float pi = 3.1415927;
-    float power;
+    t_float d;
+    t_float pi = 3.141592653589793;
+    t_float power;
     
     d = cos(x->x_spread/180*pi);
     x->x_spread_base[0] = spreaddir[0] - d * vscartdir[0];
@@ -472,18 +473,18 @@ static void new_spread_base(t_rvbap *x, float spreaddir[3], float vscartdir[3])
     x->x_spread_base[2] /= power;
 }
 
-static void spread_it(t_rvbap *x, float *final_gs)
+static void spread_it(t_rvbap *x, t_float *final_gs)
 // apply the sound signal to multiple panning directions
 // that causes some spreading.
 // See theory in paper V. Pulkki "Uniform spreading of amplitude panned
 // virtual sources" in WASPAA 99
 
 {
-    float vscartdir[3];
-    float spreaddir[16][3];
-    float spreadbase[16][3];
+    t_float vscartdir[3];
+    t_float spreaddir[16][3];
+    t_float spreadbase[16][3];
     long i, spreaddirnum;
-    float power;
+    t_float power;
     if(x->x_dimension == 3){
         spreaddirnum=16;
         angle_to_cart(x->x_azi,x->x_ele,vscartdir);
@@ -547,18 +548,18 @@ static void spread_it(t_rvbap *x, float *final_gs)
 }   
     
 
-static void equal_reverb(t_rvbap *x, float *final_gs)
+static void equal_reverb(t_rvbap *x, t_float *final_gs)
 // calculate constant reverb gains for equally distributed
 // reverb levels
 // this is achieved by calculating gains for a sound source 
 // that is everywhere, i.e. present in all directions
 
 {
-    float vscartdir[3];
-    float spreaddir[16][3];
-    float spreadbase[16][3];
+    t_float vscartdir[3];
+    t_float spreaddir[16][3];
+    t_float spreadbase[16][3];
     long i, spreaddirnum;
-    float power;
+    t_float power;
     if(x->x_dimension == 3){
         spreaddirnum=5;     
         
@@ -606,11 +607,11 @@ static void rvbap_bang(t_rvbap *x)
 // top level, vbap gains are calculated and outputted   
 {
     t_atom at[MAX_LS_AMOUNT]; 
-    float g[3];
+    t_float g[3];
     long ls[3];
     long i;
-    float *final_gs, overdist, oversqrtdist;
-    final_gs = (float *) getbytes(x->x_ls_amount * sizeof(float));
+    t_float *final_gs, overdist, oversqrtdist;
+    final_gs = (t_float *) getbytes(x->x_ls_amount * sizeof(t_float));
     if(x->x_lsset_available ==1){
         vbap(g, ls, x);
         for(i=0;i<x->x_ls_amount;i++)
@@ -666,7 +667,7 @@ static void rvbap_bang(t_rvbap *x)
     }
     else
         post("rvbap: Configure loudspeakers first!");
-    freebytes(final_gs, x->x_ls_amount * sizeof(float)); // bug fix added 9/00
+    freebytes(final_gs, x->x_ls_amount * sizeof(t_float)); // bug fix added 9/00
 }
 
 /*--------------------------------------------------------------------------*/
@@ -682,7 +683,7 @@ static void rvbap_matrix(t_rvbap *x, t_symbol *s, int ac, t_atom *av)
     long i;
     long deb=0;
     long azi = x->x_azi, ele = x->x_ele;    // store original values
-    float g[3];
+    t_float g[3];
     long ls[3];
  
     if(ac>0)
@@ -824,7 +825,7 @@ static void rvbap_in4(t_rvbap *x, long n)                /* x = the instance of
 // distance
 {
     if (n<1) n = 1;
-    x->x_dist = (float)n;                           /* store n in a global variable */
+    x->x_dist = (t_float)n;                           /* store n in a global variable */
     
 }
 
@@ -858,7 +859,7 @@ static void rvbap_ft4(t_rvbap *x, double n)              /* x = the instance of
 // distance
 {
     if (n<1.0) n = 1.0;
-    x->x_dist = (float)n;                           /* store n in a global variable */
+    x->x_dist = (t_float)n;                           /* store n in a global variable */
 }
 
 
@@ -871,7 +872,7 @@ static void *rvbap_new(t_symbol *s, int ac, t_atom *av)
 #ifdef MAXMSP
     x = (t_rvbap *)newobject(rvbap_class);
     
-    floatin(x,4);       /* takes the distance */
+    t_floatin(x,4);       /* takes the distance */
     intin(x,3); 
     intin(x,2);                 /* create a second (int) inlet... remember right-to-left ordering in Max */
     intin(x,1);                 /* create a second (int) inlet... remember right-to-left ordering in Max */
diff --git a/externals/vbap/unittests/define-loudspeaker-unittest.wav b/externals/vbap/unittests/define-loudspeaker-unittest.wav
new file mode 100644
index 0000000000000000000000000000000000000000..d0e52daa52ef33c5d893acff4e614cd949d32af9
Binary files /dev/null and b/externals/vbap/unittests/define-loudspeaker-unittest.wav differ
diff --git a/externals/vbap/unittests/define_loudspeakers-unittest.pd b/externals/vbap/unittests/define_loudspeakers-unittest.pd
new file mode 100644
index 0000000000000000000000000000000000000000..9d1f0a614c1733a45b1d0edb286480216739b0ba
--- /dev/null
+++ b/externals/vbap/unittests/define_loudspeakers-unittest.pd
@@ -0,0 +1,43 @@
+#N canvas 177 32 793 647 10;
+#X text 19 210 In two dimensions \, only specify the azimuth. (for
+example "define_loudspeakers 2 -45 45 0 180";
+#X text 20 80 [define_loudspeakers] works with;
+#X obj 252 80 vbap;
+#X text 15 111 Use [define_loudspeakers] to list the speaker positions.
+The example here defines loudspeakers in three dimensions (the first
+parameter). For each speaker \, define its azimuth and elevation. Here
+we have speakers front left and right with no elevation (-45 0 45 0)
+and front and back with 45 degrees of elevation (0 45 180 45). Send
+the data to:;
+#X msg 428 221 ls-directions 3 -30 0 30 0 -90 0 90 0 0 0 -150 0 150
+0 180 45 -45 45 45 45;
+#X msg 411 158 ls-triplets 1 2 7 2 7 8 1 3 7;
+#X text 431 113 If you are not happy with triangle selections of define_loudspeakers
+\, you can define your own. (for experts only);
+#X text 427 268 2-D setup -> only loudspeaker azimuths specified:;
+#X text 426 283 (2 azi1 azi2 azi3 azi4...);
+#X text 425 184 3-D setup -> (azimuth elevation) pairs are specified:
+;
+#X text 423 202 (3 azi1 ele1 azi2 ele2 ...);
+#X text 637 47 a 2D setup;
+#X text 679 77 a 3D setup;
+#X obj 56 355 testtools/unit-test-frame;
+#X obj 377 14 t b b b b;
+#X msg 56 322 define-loudspeaker-unittest;
+#X obj 56 296 loadbang;
+#X obj 377 79 vbap/define_loudspeakers 3 -45 0 45 0 0 45 180 45;
+#X obj 394 49 vbap/define_loudspeakers 2 -45 45 0 180;
+#X obj 411 303 vbap/define_loudspeakers 2 -40 0 40 80 130 180 -130
+-80;
+#X connect 4 0 19 0;
+#X connect 5 0 19 0;
+#X connect 13 3 14 0;
+#X connect 14 0 17 0;
+#X connect 14 1 18 0;
+#X connect 14 2 5 0;
+#X connect 14 3 4 0;
+#X connect 15 0 13 0;
+#X connect 16 0 15 0;
+#X connect 17 0 13 1;
+#X connect 18 0 13 1;
+#X connect 19 0 13 1;
diff --git a/externals/vbap/unittests/rvbap-unittest.pd b/externals/vbap/unittests/rvbap-unittest.pd
new file mode 100644
index 0000000000000000000000000000000000000000..728fa5d00c1df86ae23f00dfdc5ffafb6ca9c5b2
--- /dev/null
+++ b/externals/vbap/unittests/rvbap-unittest.pd
@@ -0,0 +1,75 @@
+#N canvas 90 22 726 609 10;
+#X obj 38 -190 testtools/unit-test-frame;
+#X text 383 -369 azimuth \, elevation \, spread and distance;
+#N canvas 0 22 450 300 tba 0;
+#X obj 143 51 inlet;
+#X obj 96 49 inlet;
+#X obj 191 51 inlet;
+#X obj 238 51 inlet;
+#X obj 173 180 outlet;
+#X obj 61 178 outlet;
+#X obj 221 180 outlet;
+#X obj 268 180 outlet;
+#X obj 126 180 outlet;
+#X obj 96 73 t b a;
+#X obj 143 72 t b a;
+#X obj 191 72 t b a;
+#X obj 238 72 t b a;
+#X connect 0 0 10 0;
+#X connect 1 0 9 0;
+#X connect 2 0 11 0;
+#X connect 3 0 12 0;
+#X connect 9 0 5 0;
+#X connect 9 1 8 0;
+#X connect 10 0 5 0;
+#X connect 10 1 4 0;
+#X connect 11 0 5 0;
+#X connect 11 1 6 0;
+#X connect 12 0 5 0;
+#X connect 12 1 7 0;
+#X restore 407 -341 pd tba;
+#X obj 342 -494 t b b b b;
+#X obj 446 -415 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X msg 407 -385 60;
+#X msg 446 -385 15;
+#X msg 524 -386 20;
+#X obj 38 -248 loadbang;
+#X obj 393 -440 vbap/define_loudspeakers 3 -45 0 45 0 0 45 180 45;
+#X obj 359 -307 vbap/rvbap 0 0;
+#X msg 485 -385 0;
+#X floatatom 379 -212 5 0 0 0 - - -;
+#X floatatom 399 -235 5 0 0 0 - - -;
+#X floatatom 419 -256 5 0 0 0 - - -;
+#X floatatom 440 -280 5 0 0 0 - - -;
+#X obj 359 -464 vbap/define_loudspeakers 3 -45 45 45 45 0 0 180 0;
+#X text 15 -474 In Pd-extended 0.42 \, [rvbap] crashes when using 2
+dimensional setup.;
+#X msg 38 -219 rvbap-unittest;
+#X connect 0 3 3 0;
+#X connect 2 0 10 0;
+#X connect 2 1 10 1;
+#X connect 2 2 10 2;
+#X connect 2 3 10 3;
+#X connect 2 4 10 4;
+#X connect 3 0 4 0;
+#X connect 3 1 16 0;
+#X connect 3 2 4 0;
+#X connect 3 3 9 0;
+#X connect 4 0 5 0;
+#X connect 4 0 6 0;
+#X connect 4 0 11 0;
+#X connect 4 0 7 0;
+#X connect 5 0 2 0;
+#X connect 6 0 2 1;
+#X connect 7 0 2 3;
+#X connect 8 0 18 0;
+#X connect 9 0 10 0;
+#X connect 10 0 0 1;
+#X connect 10 1 12 0;
+#X connect 10 2 13 0;
+#X connect 10 3 14 0;
+#X connect 10 4 15 0;
+#X connect 11 0 2 2;
+#X connect 16 0 10 0;
+#X connect 18 0 0 0;
diff --git a/externals/vbap/unittests/rvbap-unittest.wav b/externals/vbap/unittests/rvbap-unittest.wav
new file mode 100644
index 0000000000000000000000000000000000000000..7c54c74de21592d3e64033d7c336ffc4c765be99
Binary files /dev/null and b/externals/vbap/unittests/rvbap-unittest.wav differ
diff --git a/externals/vbap/unittests/vbap-unittest.pd b/externals/vbap/unittests/vbap-unittest.pd
new file mode 100644
index 0000000000000000000000000000000000000000..ba5e8d833a8208c9a8dbe3c1e57d188078003d05
--- /dev/null
+++ b/externals/vbap/unittests/vbap-unittest.pd
@@ -0,0 +1,140 @@
+#N canvas 225 22 809 680 10;
+#X text 21 122 In two dimensions \, only specify the azimuth. (for
+example "define_loudspeakers 2 -45 45 0 180";
+#X text 417 17 VBAP and define_loudspeakers;
+#X text 22 166 2 For vbap \, give azimuth and elevation for the desired
+location. Bang the first inlet and vbap will output gain-factors for
+each speaker and the actual location produced. This can be different
+from the desired one depending where your speakers are.;
+#X text 418 46 loudspeaker position definition can also be sent directly
+to a vbap object. This changes the setup information only in a single
+vbap object.;
+#X text 419 94 For an example of how to use vbap with [matrix~] from
+zexy-library \, see vbap-demo.pd.;
+#X text 21 22 1 Use the define_loudspeakers object or message to list
+the speaker positions. The example here defines loudspeakers in three
+dimensions (the first parameter). For each speaker \, define its azimuth
+and elevation. Here we have speakers front left and right with no elevation
+(-45 0 45 0) and front and back with 45 degrees of elevation (0 45
+180 45). Send the data to vbap.;
+#N canvas 283 22 628 620 simple 0;
+#X floatatom 159 198 5 0 0 2 - - -;
+#X floatatom 112 425 10 0 0 0 - - -;
+#X floatatom 181 425 10 0 0 0 - - -;
+#X floatatom 209 349 0 0 0 3 actual_azimuth - -;
+#X floatatom 221 315 0 0 0 3 actual_elevation - -;
+#X floatatom 231 294 7 0 0 1 actual_spreading - -;
+#X obj 162 182 hsl 100 13 -180 180 0 1 empty empty azimuth 10 7 0 10
+-262144 -1 -1 1500 1;
+#X floatatom 237 237 5 0 0 2 - - -;
+#X obj 240 220 hsl 100 13 0 100 0 1 empty empty spread 10 7 0 10 -262144
+-1 -1 700 1;
+#X text 130 134 to output updated values;
+#X obj 112 155 metro 100;
+#X obj 112 133 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X text 197 200 (ignore elevation in 2D \, that's for 3D);
+#X obj 63 524 *~;
+#X obj 92 525 *~;
+#X msg 454 145 dsp 1;
+#X obj 454 169 send pd;
+#X floatatom 250 425 10 0 0 0 - - -;
+#X floatatom 319 425 10 0 0 0 - - -;
+#X obj 123 524 *~;
+#X obj 152 525 *~;
+#X msg 17 48 define_loudspeakers 2 -135 -45 0 45 135;
+#X text 263 37 Define 2D speaker arrangement with speakers at -135
+\, -45 \, 0 \, 45 and 135 degree positions (0 degrees is the center
+front). This is a classic 5.1 setup.;
+#X floatatom 389 425 10 0 0 0 - - -;
+#X obj 72 558 dac~ 1 2 3 4 5;
+#X obj 182 525 *~;
+#X obj 112 267 vbap 0 0 30;
+#X obj 112 376 route 0 1 2 3 4;
+#X obj 13 396 *~ 0.2;
+#X obj 13 374 noise~;
+#X connect 1 0 13 1;
+#X connect 2 0 14 1;
+#X connect 6 0 0 0;
+#X connect 8 0 7 0;
+#X connect 10 0 26 0;
+#X connect 11 0 10 0;
+#X connect 13 0 24 0;
+#X connect 14 0 24 1;
+#X connect 15 0 16 0;
+#X connect 17 0 19 1;
+#X connect 18 0 20 1;
+#X connect 19 0 24 2;
+#X connect 20 0 24 3;
+#X connect 21 0 26 0;
+#X connect 23 0 25 1;
+#X connect 25 0 24 4;
+#X connect 26 0 27 0;
+#X connect 27 0 1 0;
+#X connect 27 1 2 0;
+#X connect 27 2 17 0;
+#X connect 27 3 18 0;
+#X connect 27 4 23 0;
+#X connect 28 0 13 0;
+#X connect 28 0 14 0;
+#X connect 28 0 19 0;
+#X connect 28 0 20 0;
+#X connect 28 0 25 0;
+#X connect 29 0 28 0;
+#X restore 421 139 pd simple 5.1 example;
+#X obj 421 277 vbap/vbap 90 0 30;
+#X obj 100 371 testtools/unit-test-frame;
+#X msg 100 342 vbap;
+#X floatatom 454 342 5 0 0 0 - - -;
+#X floatatom 487 322 5 0 0 0 - - -;
+#X floatatom 520 300 5 0 0 0 - - -;
+#X text 22 244 The spread-parameter can be used to prevent a situation
+where sound is coming from one speaker only \, which would make speaker
+positions "visible". The range is 0 to 100;
+#X text 496 344 azimuth;
+#X text 524 324 elevation;
+#X text 556 300 spread;
+#X obj 100 315 loadbang;
+#N canvas 0 22 504 332 define-loudspeakers 0;
+#X msg 51 87 define_loudspeakers 2 -135 -45 0 45 135;
+#X msg 106 121 define_loudspeakers 3 -45 0 45 0 0 45 180 45;
+#X obj 51 21 inlet;
+#X obj 51 284 outlet;
+#X obj 188 283 outlet;
+#X obj 106 148 t b a;
+#X obj 51 112 t b a;
+#X obj 51 53 t b b b b;
+#X obj 161 199 t b a;
+#X obj 208 245 t b a;
+#X msg 161 172 define_loudspeakers 3 -30 0 30 0 0 45 180 45;
+#X msg 207 217 define_loudspeakers 3 -45 0 45 0 0 30 180 30;
+#X connect 0 0 6 0;
+#X connect 1 0 5 0;
+#X connect 2 0 7 0;
+#X connect 5 0 3 0;
+#X connect 5 1 4 0;
+#X connect 6 0 3 0;
+#X connect 6 1 4 0;
+#X connect 7 0 0 0;
+#X connect 7 1 1 0;
+#X connect 7 2 10 0;
+#X connect 7 3 11 0;
+#X connect 8 0 3 0;
+#X connect 8 1 4 0;
+#X connect 9 0 3 0;
+#X connect 9 1 4 0;
+#X connect 10 0 8 0;
+#X connect 11 0 9 0;
+#X restore 421 237 pd define-loudspeakers;
+#X obj 421 208 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X connect 7 0 8 1;
+#X connect 7 1 10 0;
+#X connect 7 2 11 0;
+#X connect 7 3 12 0;
+#X connect 8 3 19 0;
+#X connect 9 0 8 0;
+#X connect 17 0 9 0;
+#X connect 18 0 7 0;
+#X connect 18 1 7 0;
+#X connect 19 0 18 0;
diff --git a/externals/vbap/unittests/vbap-unittest.wav b/externals/vbap/unittests/vbap-unittest.wav
new file mode 100644
index 0000000000000000000000000000000000000000..1a92557d3fefb2e89ad7ca79c032090a3508910d
Binary files /dev/null and b/externals/vbap/unittests/vbap-unittest.wav differ
diff --git a/externals/vbap/unittests/vbap.wav b/externals/vbap/unittests/vbap.wav
new file mode 100644
index 0000000000000000000000000000000000000000..9d10273ddd8cec22c7b63332b3468f10c8f8d943
Binary files /dev/null and b/externals/vbap/unittests/vbap.wav differ
diff --git a/externals/vbap/vbap-meta.pd b/externals/vbap/vbap-meta.pd
index d95168b3dacb8789cae853ccb3c0f83882115690..8077fd7e9a6c087e985bbaf0d0953420cd90a52e 100644
--- a/externals/vbap/vbap-meta.pd
+++ b/externals/vbap/vbap-meta.pd
@@ -1,7 +1,8 @@
-#N canvas 10 10 200 200 10;
-#N canvas 20 20 420 300 META 0;
+#N canvas 140 22 200 200 10;
+#N canvas 20 22 420 300 META 0;
 #X text 10 30 NAME vbap;
 #X text 10 50 AUTHOR Ville Pulkki;
-#X text 10 70 DESCRIPTION spatialization using Vector Based Amplitude Panning;
-#X text 10 90 VERSION 1.0.3.2;
+#X text 10 70 DESCRIPTION spatialization using Vector Based Amplitude
+Panning;
+#X text 10 107 VERSION 1.1;
 #X restore 10 10 pd META;
diff --git a/externals/vbap/vbap.c b/externals/vbap/vbap.c
index 3bf09fd7ab1e2409c28071e9ef0b4b7117bef759..f1e4052ebd971c17a4813705452ecd05801871f0 100644
--- a/externals/vbap/vbap.c
+++ b/externals/vbap/vbap.c
@@ -14,25 +14,27 @@ See copyright in file with name LICENSE.txt  */
 #include "s_stuff.h"
 
 // Function prototypes
-static void new_spread_dir(t_vbap *x, float spreaddir[3], float vscartdir[3], float spread_base[3]);
-static void new_spread_base(t_vbap *x, float spreaddir[3], float vscartdir[3]);
+static void new_spread_dir(t_vbap *x, t_float spreaddir[3], t_float vscartdir[3], t_float spread_base[3]);
+static void new_spread_base(t_vbap *x, t_float spreaddir[3], t_float vscartdir[3]);
 static void *vbap_class;				
-static void vect_cross_prod(float v1[3], float v2[3],float v3[3]);
-static void additive_vbap(float *final_gs, float cartdir[3], t_vbap *x);
+static void vect_cross_prod(t_float v1[3], t_float v2[3],t_float v3[3]);
+static void additive_vbap(t_float *final_gs, t_float cartdir[3], t_vbap *x);
 static void vbap_bang(t_vbap *x);
+static int vbap_getmem(t_vbap *x, int lsSetCount );
+static void vbap_free(t_vbap *x);
 static void vbap_matrix(t_vbap *x, Symbol *s, int ac, Atom *av);
 #ifndef PD /* Max */
-/* these are for getting data from a cold inlet on Max/MSP, in Pd you use floatinlet_new() in new() */
+/* these are for getting data from a cold inlet on Max/MSP, in Pd you use t_floatinlet_new() in new() */
 void vbap_ft1(t_vbap *x, double n);
 void vbap_ft2(t_vbap *x, double n);
 void vbap_in3(t_vbap *x, long n);
 void vbap_ft4(t_vbap *x, double g);
 #endif
-static void spread_it(t_vbap *x, float *final_gs);
-static void *vbap_new(float azi, float ele, float spread);
-static void vbap(float g[3], long ls[3], t_vbap *x);
-static void angle_to_cart(float azi, float ele, float res[3]);
-static void cart_to_angle(float cvec[3], float avec[3]);
+static void spread_it(t_vbap *x, t_float *final_gs);
+static void *vbap_new(t_float azi, t_float ele, t_float spread);
+static void vbap(t_float g[3], long ls[3], t_vbap *x);
+static void angle_to_cart(t_float azi, t_float ele, t_float res[3]);
+static void cart_to_angle(t_float cvec[3], t_float avec[3]);
 
 /*****************************************************
 	 INCLUDE ALL define_loudspeakers functions directly into VBAP
@@ -77,7 +79,7 @@ void vbap_assist(t_vbap *x, void *b, long m, long a, char *s)
 #ifdef PD
 void vbap_setup(void)
 {
-	vbap_class = class_new(gensym("vbap"), (t_newmethod)vbap_new, 0, (short)sizeof(t_vbap), 0, 
+	vbap_class = class_new(gensym("vbap"), (t_newmethod)vbap_new, (t_method) vbap_free, (short)sizeof(t_vbap), 0,
                            A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); 
 
 	class_addbang(vbap_class, (t_method)vbap_bang);	
@@ -95,7 +97,9 @@ void vbap_setup(void)
     class_addmethod(vbap_class, (t_method)def_ls_read_directions, gensym("ls-directions"), A_GIMME, 0);	
     class_addmethod(vbap_class, (t_method)def_ls_read_triplets, gensym("ls-triplets"), A_GIMME, 0);
 
-	post(VBAP_VERSION);
+	logpost(NULL, 1, VBAP_VERSION);
+    //post(VBAP_VERSION);
+
 }
 #else /* MAX */
 void main(void)
@@ -152,6 +156,14 @@ static void *vbap_new(t_float azi, t_float ele, t_float spread)
 	x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
 	x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
 	x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
+    
+    
+    
+    // allocate space for the runtime matricies
+//    if (!vbap_getmem(x, MAX_LS_SETS))
+//        return( NULL );
+//    
+    
 #else /* Max */
 	t_vbap *x = (t_vbap *)newobject(vbap_class);
 
@@ -167,7 +179,9 @@ static void *vbap_new(t_float azi, t_float ele, t_float spread)
 	x->x_outlet0 = listout(x);
 #endif /* PD */
 	
-	x->x_spread_base[0] = 0.0;
+    x->x_ls_setCount = 0;       // refers to memory dynamically allocated when a define_loudspeakers config is received
+
+    x->x_spread_base[0] = 0.0;
 	x->x_spread_base[1] = 1.0;
 	x->x_spread_base[2] = 0.0;
 	x->x_lsset_available =0;
@@ -180,7 +194,90 @@ static void *vbap_new(t_float azi, t_float ele, t_float spread)
 }
 
 
-static void angle_to_cart(float azi, float ele, float res[3])
+// currently can allocate upto 256K to support up to 44 channels in 3D
+// note:  to save memory, the required memory for a given configuration could instead,  be dynamically allocated by calling this method from the vbap_matrix() method
+static int vbap_getmem(t_vbap *x, int lsSetCount )
+{
+
+#ifdef PD
+
+    int i;
+    
+    if ( x->x_ls_setCount ) vbap_free(x);
+    
+    //was t_float x_set_inv_matx[MAX_LS_SETS][9];
+    x->x_set_inv_matx = getbytes( sizeof( t_float* ) * lsSetCount);
+    
+    if(!x->x_set_inv_matx) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof( t_float* ) * lsSetCount); return(0);}
+    
+    for (i = 0; i < lsSetCount; i++)
+    {
+        x->x_set_inv_matx[i] = getbytes( sizeof(t_float) * MATRIX_DIM );
+        if(!x->x_set_inv_matx[i]) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof(t_float) * MATRIX_DIM ); return(0);}
+    }
+    
+    
+    //was t_float x_set_matx[MAX_LS_SETS][9];
+    x->x_set_matx = getbytes( sizeof( t_float* ) * lsSetCount);
+
+    if(!x->x_set_matx) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof( t_float* ) * lsSetCount); return(0);}
+
+    for (i = 0; i < lsSetCount; i++)
+    {
+        x->x_set_matx[i] = getbytes( sizeof(t_float) * MATRIX_DIM );
+        if(!x->x_set_matx[i]) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof(t_float) * MATRIX_DIM ); return(0);}
+  }
+    
+    
+    //was long x_lsset[MAX_LS_SETS][3];
+    x->x_lsset = getbytes( sizeof( long * ) * lsSetCount);
+    
+    if(!x->x_lsset) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof( long * ) * lsSetCount); return(0);}
+    
+    for (i = 0; i < lsSetCount; i++)
+    {
+        x->x_lsset[i] = getbytes( sizeof( long ) * SPEAKER_SET_DIM );
+        if(!x->x_lsset[i]) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof(long) * SPEAKER_SET_DIM ); return(0);}
+   }
+    
+    unsigned long memallocd = 2 * ( sizeof(t_float *) * lsSetCount  *  sizeof(t_float) * MATRIX_DIM) + ( sizeof(long *) * lsSetCount *  sizeof(long) * SPEAKER_SET_DIM);
+    
+    logpost(NULL, 3, "vbap_new:  %ldK bytes allocated for instance", memallocd /1000);
+    
+    x->x_ls_setCount = lsSetCount;
+
+#endif
+    return(1);
+    
+}
+
+
+// free any allocated memory for instance
+static void vbap_free(t_vbap *x)
+{
+    int i;
+
+    if (! x->x_ls_setCount) return;
+    
+    for (i = 0; i <  x->x_ls_setCount; i++)
+    {
+        freebytes( x->x_set_inv_matx[i], (sizeof(t_float) * MATRIX_DIM ));    // = getbytes( sizeof(t_float) * MATRIX_DIM );
+        freebytes( x->x_set_matx[i],  sizeof(t_float) * MATRIX_DIM);
+   }
+  
+    freebytes(x->x_set_inv_matx, (sizeof( t_float* ) *  x->x_ls_setCount));
+    freebytes(x->x_set_matx, sizeof( t_float* ) *  x->x_ls_setCount);
+
+
+    for (i = 0; i <   x->x_ls_setCount; i++)
+    {
+        freebytes(x->x_lsset[i], sizeof( long ) * SPEAKER_SET_DIM );
+    }
+ 
+    freebytes( x->x_lsset, sizeof( long * ) *  x->x_ls_setCount);
+}
+
+static void angle_to_cart(t_float azi, t_float ele, t_float res[3])
 // converts angular coordinates to cartesian
 { 
   res[0] = cos(azi * atorad) * cos( ele * atorad);
@@ -188,13 +285,13 @@ static void angle_to_cart(float azi, float ele, float res[3])
   res[2] = sin( ele * atorad);
 }
 
-static void cart_to_angle(float cvec[3], float avec[3])
+static void cart_to_angle(t_float cvec[3], t_float avec[3])
 // converts cartesian coordinates to angular
 {
   //float tmp, tmp2, tmp3, tmp4;
   //float power;
-  float dist, atan_y_per_x, atan_x_pl_y_per_z;
-  float azi, ele;
+  t_float dist, atan_y_per_x, atan_x_pl_y_per_z;
+  t_float azi, ele;
   
   if(cvec[0]==0.0)
   	atan_y_per_x = M_PI / 2;
@@ -223,17 +320,17 @@ static void cart_to_angle(float cvec[3], float avec[3])
 }
 
 
-static void vbap(float g[3], long ls[3], t_vbap *x)
+static void vbap(t_float g[3], long ls[3], t_vbap *x)
 {
   /* calculates gain factors using loudspeaker setup and given direction */
-  float power;
+  t_float power;
   int i,j,k, gains_modified;
-  float small_g;
-  float big_sm_g, gtmp[3];
+  t_float small_g;
+  t_float big_sm_g, gtmp[3];
   long winner_set = 0;
-  float cartdir[3];
-  float new_cartdir[3];
-  float new_angle_dir[3];
+  t_float cartdir[3];
+  t_float new_cartdir[3];
+  t_float new_angle_dir[3];
   long dim = x->x_dimension;
   long neg_g_am, best_neg_g_am;
   
@@ -327,7 +424,7 @@ static void vbap(float g[3], long ls[3], t_vbap *x)
  	 	} else new_cartdir[2] = 0;
  	 	cart_to_angle(new_cartdir,new_angle_dir);
  	 	x->x_azi = (new_angle_dir[0] );
-		post("[vbap] use azimuth %g",x->x_azi );
+		//post("[vbap] use azimuth %g",x->x_azi );
  	 	x->x_ele = (new_angle_dir[1]);
  	 }
   //}
@@ -339,11 +436,11 @@ static void vbap(float g[3], long ls[3], t_vbap *x)
 }
 
 
-static void vect_cross_prod(float v1[3], float v2[3],
-                float v3[3]) 
+static void vect_cross_prod(t_float v1[3], t_float v2[3],
+                t_float v3[3]) 
 // vector cross product            
 {
-  float length;
+  t_float length;
   v3[0] = (v1[1] * v2[2] ) - (v1[2] * v2[1]);
   v3[1] = (v1[2] * v2[0] ) - (v1[0] * v2[2]);
   v3[2] = (v1[0] * v2[1] ) - (v1[1] * v2[0]);
@@ -354,20 +451,20 @@ static void vect_cross_prod(float v1[3], float v2[3],
   v3[2] /= length;
 }
 
-static void additive_vbap(float *final_gs, float cartdir[3], t_vbap *x)
+static void additive_vbap(t_float *final_gs, t_float cartdir[3], t_vbap *x)
 // calculates gains to be added to previous gains, used in
 // multiple direction panning (source spreading)
 {
-	float power;
+	t_float power;
     int i,j,k, gains_modified;
-  	float small_g;
-  	float big_sm_g, gtmp[3];
+  	t_float small_g;
+  	t_float big_sm_g, gtmp[3];
   	long winner_set;
   	//float new_cartdir[3];
   	//float new_angle_dir[3];
   	long dim = x->x_dimension;
   	long neg_g_am, best_neg_g_am;
-	float g[3] = {0,0,0};
+	t_float g[3] = {0,0,0};
 	long ls[3] = {0,0,0};
 	
   	big_sm_g = -100000.0;
@@ -415,17 +512,18 @@ static void additive_vbap(float *final_gs, float cartdir[3], t_vbap *x)
   		
   		final_gs[ls[0]-1] += g[0];
   		final_gs[ls[1]-1] += g[1];
-  		final_gs[ls[2]-1] += g[2];
+  		if (dim==3)
+  			final_gs[ls[2]-1] += g[2];
   	}
 }
 
 
-static void new_spread_dir(t_vbap *x, float spreaddir[3], float vscartdir[3], float spread_base[3])
+static void new_spread_dir(t_vbap *x, t_float spreaddir[3], t_float vscartdir[3], t_float spread_base[3])
 // subroutine for spreading
 {
-	float beta,gamma;
-	float a,b;
-	float power;
+	t_float beta,gamma;
+	t_float a,b;
+	t_float power;
 	
 	gamma = acos(vscartdir[0] * spread_base[0] +
 					vscartdir[1] * spread_base[1] +
@@ -450,11 +548,11 @@ static void new_spread_dir(t_vbap *x, float spreaddir[3], float vscartdir[3], fl
   	spreaddir[2] /= power;
 }
 
-static void new_spread_base(t_vbap *x, float spreaddir[3], float vscartdir[3])
+static void new_spread_base(t_vbap *x, t_float spreaddir[3], t_float vscartdir[3])
 // subroutine for spreading
 {
-	float d;
-	float power;
+	t_float d;
+	t_float power;
 	
 	d = cos(x->x_spread/180*M_PI);
 	x->x_spread_base[0] = spreaddir[0] - d * vscartdir[0];
@@ -467,18 +565,18 @@ static void new_spread_base(t_vbap *x, float spreaddir[3], float vscartdir[3])
   	x->x_spread_base[2] /= power;
 }
 
-static void spread_it(t_vbap *x, float *final_gs)
+static void spread_it(t_vbap *x, t_float *final_gs)
 // apply the sound signal to multiple panning directions
 // that causes some spreading.
 // See theory in paper V. Pulkki "Uniform spreading of amplitude panned
 // virtual sources" in WASPAA 99
 
 {
-	float vscartdir[3];
-	float spreaddir[16][3];
-	float spreadbase[16][3];
+	t_float vscartdir[3];
+	t_float spreaddir[16][3];
+	t_float spreadbase[16][3];
 	long i, spreaddirnum;
-	float power;
+	t_float power;
 	if(x->x_dimension == 3){
 		spreaddirnum=16;
 		angle_to_cart(x->x_azi,x->x_ele,vscartdir);
@@ -546,10 +644,11 @@ static void vbap_bang(t_vbap *x)
 // top level, vbap gains are calculated and outputted	
 {
 	Atom at[MAX_LS_AMOUNT]; 
-	float g[3];
+	t_float g[3];
 	long ls[3];
 	long i;
-	float *final_gs = (float *) getbytes(x->x_ls_amount * sizeof(float));
+ 
+	t_float *final_gs = (t_float *) getbytes(x->x_ls_amount * sizeof(t_float));
 
 	if(x->x_lsset_available ==1)
 	{
@@ -558,7 +657,8 @@ static void vbap_bang(t_vbap *x)
 			final_gs[i]=0.0; 			
 		for(i=0;i<x->x_dimension;i++)
 		{
-			final_gs[ls[i]-1]=g[i];  
+			final_gs[ls[i]-1]=g[i];
+            //post("VBAP: PRE_SPREAD: %f", (t_float)final_gs[i]);
 		}
 		if(x->x_spread != 0)
 		{
@@ -567,7 +667,9 @@ static void vbap_bang(t_vbap *x)
 		for(i=0;i<x->x_ls_amount;i++) 
 		{
 #ifdef PD
-			SETFLOAT(&at[0], (t_float)i);	
+            
+
+            SETFLOAT(&at[0], (t_float)i);
 			SETFLOAT(&at[1], (t_float)final_gs[i]);
 			outlet_list(x->x_obj.ob_outlet, &s_list, 2, at);
 #else /* Max */
@@ -584,7 +686,7 @@ static void vbap_bang(t_vbap *x)
 	else
 		error("vbap: Configure loudspeakers first!");
 
-	freebytes(final_gs, x->x_ls_amount * sizeof(float)); // bug fix added 9/00
+	freebytes(final_gs, x->x_ls_amount * sizeof(t_float)); // bug fix added 9/00
 }
 
 /*--------------------------------------------------------------------------*/
@@ -597,8 +699,14 @@ static void vbap_matrix(t_vbap *x, Symbol *s, int ac, Atom *av)
 	{
 		int d = 0;
  		/*if(av[datapointer].a_type == A_LONG) d = av[datapointer++].a_w.w_long;
-		else*/ if(av[datapointer].a_type == A_FLOAT) d = (long)av[datapointer++].a_w.w_float;
-		else { error("vbap: Dimension NaN"); x->x_lsset_available=0; return; }
+		else*/
+        if (av[datapointer].a_type == A_FLOAT)
+            d = (long)av[datapointer++].a_w.w_float;
+		else
+        {
+            error("vbap: Dimension NaN"); x->x_lsset_available=0;
+            return;
+        }
 
 		if (d!=2 && d!=3) { error("vbap %s: Dimension can be only 2 or 3",s->s_name); x->x_lsset_available=0; return; }
 
@@ -616,25 +724,40 @@ static void vbap_matrix(t_vbap *x, Symbol *s, int ac, Atom *av)
 
 		x->x_ls_amount = a;
 	}
- 	
+
 	long counter = (ac - 2) / ((x->x_dimension * x->x_dimension*2) + x->x_dimension);
- 	x->x_lsset_amount=counter;
+    
+    
+ 
+    if (counter-1 > MAX_LS_SETS) { error("vbap %s: loudspeaker definitions exceed maximum number of speakers",s->s_name); x->x_lsset_available=0; return; }
+
+    vbap_getmem(x, counter);        // PD only:  allocate memory (frees any previously allocated memory automatically)
+    
+    x->x_lsset_amount=counter;
+    
 
  	if(counter==0) { error("vbap %s: not enough parameters",s->s_name); x->x_lsset_available=0; return; }
  	
 	long setpointer=0;
 	long i;
- 
- 	while(counter-- > 0)
+    
+    long db_dim = x->x_dimension;
+    
+    while(counter-- > 0)
 	{
- 		for(i=0; i < x->x_dimension; i++)
+ 
+        for(i=0; i < x->x_dimension; i++)
 		{
 # ifdef PD
- 			if(av[datapointer].a_type == A_FLOAT)
+            
+            if(av[datapointer].a_type == A_FLOAT)
 			{
                 x->x_lsset[setpointer][i]=(long)av[datapointer++].a_w.w_float;
- 			}
- 			else { error("vbap %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0; return; }
+  			}
+ 			else { error("vbap AA %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0; return; }
+
+            
+            
 # else /* Max */
  			if(av[datapointer].a_type == A_LONG)
 			{
@@ -643,26 +766,35 @@ static void vbap_matrix(t_vbap *x, Symbol *s, int ac, Atom *av)
  			else { error("vbap %s: param %d is not an in",s->s_name,datapointer); x->x_lsset_available=0; return; }
 # endif /* PD */
  		}	
- 		for(i=0; i < x->x_dimension*x->x_dimension; i++)
+
+ 		
+        for(i=0; i < x->x_dimension*x->x_dimension; i++)
 		{
- 			if(av[datapointer].a_type == A_FLOAT)
+
+            if(av[datapointer].a_type == A_FLOAT)
 			{
  				x->x_set_inv_matx[setpointer][i]=av[datapointer++].a_w.w_float;
  			}
- 			else { error("vbap %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0; return; }
+ 			else { error("vbap BB %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0; return; }
  		}
  		
+
  		for(i=0; i < x->x_dimension*x->x_dimension; i++)
 		{
+            
+            
  			if(av[datapointer].a_type == A_FLOAT)
 			{
  				x->x_set_matx[setpointer][i]=av[datapointer++].a_w.w_float;
  			}
- 			else { error("vbap %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0; return; }
+ 			else {
+                error("vbap %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0;
+                 return;
+            }
  			
  		}
- 	
+	
  		setpointer++;
 	}
 	if (_enable_trace) post("vbap: Loudspeaker setup configured!");
-}
+ }
diff --git a/externals/vbap/vbap.h b/externals/vbap/vbap.h
index dd588ac3f4a472f70b81f885f50c8b0e110a72cb..ecd388c40757f4d8605e50b5ee5b89678bc31181 100644
--- a/externals/vbap/vbap.h
+++ b/externals/vbap/vbap.h
@@ -10,21 +10,38 @@
 	#define M_PI        3.14159265358979323846264338327950288   /* pi */
 #endif
 
-#define MAX_LS_SETS 100			// maximum number of loudspeaker sets (triplets or pairs) allowed
-#define MAX_LS_AMOUNT 55    // maximum amount of loudspeakers, can be increased
+#ifdef PD
+//                              Revised by Z. Settel to dynamically allocate memory
+    #define MAX_LS_SETS 745     // maximum number of loudspeaker sets (triplets or pairs) allowed -- allows for up to 44 speakers in 3D config
+//#define MAX_LS_SETS 100	// former maximum value crashed for 3D speaker configurations with more than 13 speakers
+//#define MAX_LS_SETS 571	// example: for up to 32 speakers in 3D config
+
+#else   // Max
+
+#define MAX_LS_SETS 100	 // maximum number of loudspeaker sets (triplets or pairs) allowed - This can crash when too many speakers are defined
+
+#endif
+
+#define MATRIX_DIM 9   // hard-coded matrx dimension for the algorithm
+#define SPEAKER_SET_DIM 3  // hard-coded speaker set dimension for the algorithm
+
+#define MAX_LS_AMOUNT 55    // maximum amount of loudspeakers, can be increased, but see comments next to MAX_LS_SETS above
 #define MIN_VOL_P_SIDE_LGTH 0.01  
 
-#define VBAP_VERSION "vbap - v1.0.3.1 - 20 Nov 2010 - (c) Ville Pulkki 1999-2006 (Pd port by HCS)"
-#define DFLS_VERSION "define_loudspeakers - v1.0.3.1 - 20 Nov 2010 - (c) Ville Pulkki 1999-2006"
+#define VBAP_VERSION "vbap - v1.1 - 14 Aug. 2014 - (c) Ville Pulkki 1999-2006 (Pd port by HCS)"
+#define DFLS_VERSION "define_loudspeakers - v1.0.3.2 - 20 Nov 2010 - (c) Ville Pulkki 1999-2006"
 
-static float rad2ang = 360.0 / ( 2.0f * M_PI );
-static float atorad = (2.0f * M_PI) / 360.0f ;
+static t_float rad2ang = 360.0 / ( 2.0f * M_PI );
+static t_float atorad = (2.0f * M_PI) / 360.0f ;
 
 #ifdef VBAP_OBJECT
-	// We are inside vbap object, so sending matrix from define_loudspeakers is a simple call to the vbap receiver...
-	#define sendLoudspeakerMatrices(x,list_length, at) \
-					vbap_matrix(x, gensym("loudspeaker-matrices"),list_length, at); \
-					vbap_bang(x)
+
+//We are inside vbap object, so sending matrix from define_loudspeakers is a simple call to the vbap receiver...
+
+#define sendLoudspeakerMatrices(x,list_length, at) \
+ 					vbap_matrix(x, gensym("loudspeaker-matrices"),list_length, at); \
+ 					vbap_bang(x)
+
 #else
 	// We are inside define_loudspeaker object, send matrix to outlet
 	#define sendLoudspeakerMatrices(x,list_length, at) \
@@ -35,11 +52,11 @@ static float atorad = (2.0f * M_PI) / 360.0f ;
 /* A struct for a loudspeaker instance */
 typedef struct 
 {  					// distance value is 1.0 == unit vectors
-  float x;  // cartesian coordinates
-  float y;
-  float z;
-  float azi;  // polar coordinates
-  float ele;
+  t_float x;  // cartesian coordinates
+  t_float y;
+  t_float z;
+  t_float azi;  // polar coordinates
+  t_float ele;
   int channel_nbr;  // which speaker channel number 
 } t_ls;
 
@@ -47,7 +64,7 @@ typedef struct
 typedef struct t_ls_set 
 {
   int ls_nos[3];  // channel numbers
-  float inv_mx[9]; // inverse 3x3 or 2x2 matrix
+  t_float inv_mx[9]; // inverse 3x3 or 2x2 matrix
   struct t_ls_set *next;  // next set (triplet or pair)
 } t_ls_set;
 
@@ -55,27 +72,40 @@ typedef struct t_ls_set
 	typedef struct vbap				/* This defines the object as an entity made up of other things */
 	{
 		t_object x_obj;				
-		float x_azi; 	// panning direction azimuth
-		float x_ele;		// panning direction elevation			
+		t_float x_azi; 	// panning direction azimuth
+		t_float x_ele;		// panning direction elevation			
 		void *x_outlet0;				/* outlet creation - inlets are automatic */
 		void *x_outlet1;				
 		void *x_outlet2;				
 		void *x_outlet3;				
-		void *x_outlet4;				
-		float x_set_inv_matx[MAX_LS_SETS][9];  // inverse matrice for each loudspeaker set
-		float x_set_matx[MAX_LS_SETS][9];      // matrice for each loudspeaker set
-		long x_lsset[MAX_LS_SETS][3];          // channel numbers of loudspeakers in each LS set 
+		void *x_outlet4;
+
 		long x_lsset_available;                // have loudspeaker sets been defined with define_loudspeakers
 		long x_lsset_amount;								   // amount of loudspeaker sets
-		long x_ls_amount;                      // amount of loudspeakers
+        long x_ls_amount;                      // amount of loudspeakers
 		long x_dimension;                      // 2 or 3
+        
 # ifdef PD
+        // memory for data sets is now allocated dynamically in each instance
+                        // WAS t_float x_set_inv_matx[MAX_LS_SETS][9];
+		t_float **x_set_inv_matx;  // inverse matrice for each loudspeaker set
+                          // WAS t_float x_set_matx[MAX_LS_SETS][9];
+        t_float **x_set_matx;     // matrice for each loudspeaker set
+		                // WAS long x_lsset[MAX_LS_SETS][3];
+ 		long **x_lsset;          // channel numbers of loudspeakers in each LS set
+
 		t_float x_spread;                      // speading amount of virtual source (0-100)
-# else /* Max */
-		long x_spread;                         // speading amount of virtual source (0-100)
+
+# else /* Max */        // memory allocation not tested for max, so it is allocated in the struct, as it was before
+
+        t_float x_set_inv_matx[MAX_LS_SETS][9];  // inverse matrice for each loudspeaker set
+        t_float x_set_matx[MAX_LS_SETS][9];      // matrice for each loudspeaker set
+		long x_lsset[MAX_LS_SETS][3];          // channel numbers of loudspeakers in each LS set
+        
+        long x_spread;                         // speading amount of virtual source (0-100)
 		double x_gain;                         // general gain control (0-2)
 # endif /* PD */
-		float x_spread_base[3];                // used to create uniform spreading
+		t_float x_spread_base[3];                // used to create uniform spreading
 
 		// define_loudspeaker data
 		long x_ls_read;	 						// 1 if loudspeaker directions have been read
@@ -84,6 +114,7 @@ typedef struct t_ls_set
 		t_ls_set *x_ls_set;					// loudspeaker sets
 		long x_def_ls_amount;				// number of loudspeakers
 		long x_def_ls_dimension;		// 2 (horizontal arrays) or 3 (3d setups)
+        long x_ls_setCount;       // the number of Loudspeaker sets used for an instance's current loudspeaker configuration
 	} t_vbap;
 
 	// define loudspeaker data type...